From dcbca46e7522160166c48504a7a6f8c8a8b51bba Mon Sep 17 00:00:00 2001 From: Verathian Date: Tue, 21 Dec 2021 22:15:29 -0500 Subject: [PATCH 01/98] Leaderboard Scoring Updates --- dGame/LeaderboardManager.cpp | 169 ++++++++++++++++++++++++++++++++--- dGame/LeaderboardManager.h | 22 +++-- resources/worldconfig.ini | 6 +- 3 files changed, 178 insertions(+), 19 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 0efe9c77..327e6f63 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -3,8 +3,10 @@ #include "Database.h" #include "EntityManager.h" #include "Character.h" +#include "Game.h" #include "GameMessages.h" #include "dLogger.h" +#include "dConfig.h" Leaderboard::Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector entries, LWOOBJID relatedPlayer, LeaderboardType leaderboardType) { @@ -90,6 +92,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t 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 ShootingGallery: @@ -97,8 +100,11 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t highscore = false; break; case Racing: + if (time >= storedTime) + highscore = false; + break; case MonumentRace: - if (time > storedTime) + if (time >= storedTime) highscore = false; break; case FootRace: @@ -106,8 +112,18 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t highscore = false; break; case Survival: + if (classicSurvivalScoring) { + if (time <= storedTime) { // Based on time (LU live) + highscore = false; + } + } + else { + if (score <= storedScore) // Based on score (DLU) + highscore = false; + } + break; case SurvivalNS: - if (score < storedScore || time >= storedTime) + if (time >= storedTime) highscore = false; break; default: @@ -125,7 +141,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t delete result; if (any) { - auto* statement = Database::CreatePreppedStmt("UPDATE leaderboard SET time = ?, score = ? WHERE character_id = ? AND game_id = ?"); + 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()); @@ -134,6 +150,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t 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); @@ -149,15 +166,53 @@ Leaderboard *LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoTy auto leaderboardType = GetLeaderboardType(gameID); std::string query; + bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1"; switch (infoType) { case InfoType::Standings: - query = leaderboardType == MonumentRace ? standingsQueryAsc : standingsQuery; + 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; + default: + query = standingsTimeQueryAsc; // SurvivalNS, MonumentRace, and Racing are all based on the shortest time. + } break; case InfoType::Friends: - query = leaderboardType == MonumentRace ? friendsQueryAsc : friendsQuery; + 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; + default: + query = friendsTimeQueryAsc; // SurvivalNS, MonumentRace, and Racing are all based on the shortest time. + } break; + default: - query = leaderboardType == MonumentRace ? topPlayersQueryAsc : topPlayersQuery; + 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; + default: + query = topPlayersTimeQueryAsc; // SurvivalNS, MonumentRace, and Racing are all based on the shortest time. + } } auto* statement = Database::CreatePreppedStmt(query); @@ -220,7 +275,7 @@ LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) { return LeaderboardType::None; } -const std::string LeaderboardManager::topPlayersQuery = +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 " @@ -231,7 +286,7 @@ const std::string LeaderboardManager::topPlayersQuery = "SELECT time, score, leaderboard_rank, id, name, last_played " "FROM leaderboard_vales LIMIT 11;"; -const std::string LeaderboardManager::friendsQuery = +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 " @@ -249,7 +304,7 @@ const std::string LeaderboardManager::friendsQuery = "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::standingsQuery = +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 " @@ -265,7 +320,7 @@ const std::string LeaderboardManager::standingsQuery = "FROM leaderboard_vales, personal_values " "WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; -const std::string LeaderboardManager::topPlayersQueryAsc = +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 " @@ -276,7 +331,7 @@ const std::string LeaderboardManager::topPlayersQueryAsc = "SELECT time, score, leaderboard_rank, id, name, last_played " "FROM leaderboard_vales LIMIT 11;"; -const std::string LeaderboardManager::friendsQueryAsc = +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 " @@ -294,7 +349,7 @@ const std::string LeaderboardManager::friendsQueryAsc = "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::standingsQueryAsc = +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 " @@ -309,3 +364,93 @@ const std::string LeaderboardManager::standingsQueryAsc = "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;"; \ No newline at end of file diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index ce092462..c4479f1a 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -60,11 +60,21 @@ public: static LeaderboardType GetLeaderboardType(uint32_t gameID); private: static LeaderboardManager* address; - static const std::string topPlayersQuery; - static const std::string friendsQuery; - static const std::string standingsQuery; - static const std::string topPlayersQueryAsc; - static const std::string friendsQueryAsc; - static const std::string standingsQueryAsc; + + // 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; }; diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index d8d8ef87..b1fec1a6 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -52,4 +52,8 @@ solo_racing=0 disable_anti_speedhack=0 # 0 or 1, check server fdb (res/CDServer.fdb) against clients -check_fdb=0 \ No newline at end of file +check_fdb=0 + +# 0 or 1, DLU leaderboards will rate Avant Gardens Survival based on score by default. +# This option should be set to 1 if you would like it to reflect the game when it was live (scoring based on time). +classic_survival_scoring=0 From 3cb16ddb5f8e57d916644099d407cad79b67396b Mon Sep 17 00:00:00 2001 From: Verathian Date: Tue, 21 Dec 2021 22:30:37 -0500 Subject: [PATCH 02/98] Leaderboard Scoring Updates --- dGame/LeaderboardManager.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 327e6f63..210dee92 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -123,7 +123,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t } break; case SurvivalNS: - if (time >= storedTime) + if (score < storedScore || time >= storedTime) highscore = false; break; default: @@ -150,7 +150,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t delete statement; } else { - // Note: last_played will be set to sysdate by default when inserting into leaderboard + // 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); @@ -174,13 +174,16 @@ Leaderboard *LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoTy query = standingsScoreQuery; // Shooting gallery is based on the highest score. break; case FootRace: - query = standingsTimeQuery; // The higher your time, the better (for 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; // SurvivalNS, MonumentRace, and Racing are all based on the shortest time. + query = standingsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. } break; case InfoType::Friends: @@ -189,13 +192,16 @@ Leaderboard *LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoTy query = friendsScoreQuery; // Shooting gallery is based on the highest score. break; case FootRace: - query = friendsTimeQuery; // The higher your time, the better (for 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; // SurvivalNS, MonumentRace, and Racing are all based on the shortest time. + query = friendsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. } break; @@ -205,13 +211,16 @@ Leaderboard *LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoTy query = topPlayersScoreQuery; // Shooting gallery is based on the highest score. break; case FootRace: - query = topPlayersTimeQuery; // The higher your time, the better (for 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; // SurvivalNS, MonumentRace, and Racing are all based on the shortest time. + query = topPlayersTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. } } From f2b3b0bf660a8e3ce0584d92942edc00daef7b64 Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Mon, 3 Jan 2022 21:40:07 -0800 Subject: [PATCH 03/98] Check user input for the "/runmacro" command Presents users from specifying a file path, and looking up macros in the expected folder. --- dGame/dUtilities/SlashCommandHandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 47704d2b..5147cf16 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -611,6 +611,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "runmacro" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (args.size() != 1) return; + // Only process if input does not contain separator charaters + if (args[0].find("/") != std::string::npos) return; + if (args[0].find("\\") != std::string::npos) return; + std::ifstream infile("./res/macros/" + args[0] + ".scm"); if (infile.good()) { From 590ccc78aa97ea4d0c055f61d4e3061e9ba721bf Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Wed, 5 Jan 2022 21:52:33 -0500 Subject: [PATCH 04/98] Add proper sanitizing for input to SQLite database. Adds function `ExecuteQueryWithArgs(query, ...)` to allow for queries with user input. There is a known issue, that the funciton does not work with std::string. All strings must be converted to c strings. --- dDatabase/CDClientDatabase.h | 14 ++ dGame/dBehaviors/Behavior.cpp | 39 ++--- dGame/dUtilities/SlashCommandHandler.cpp | 203 ++++++++++++----------- 3 files changed, 137 insertions(+), 119 deletions(-) diff --git a/dDatabase/CDClientDatabase.h b/dDatabase/CDClientDatabase.h index fbb1dc86..5028e0bd 100644 --- a/dDatabase/CDClientDatabase.h +++ b/dDatabase/CDClientDatabase.h @@ -40,4 +40,18 @@ namespace CDClientDatabase { */ CppSQLite3Query ExecuteQuery(const std::string& query); + //! Queries the CDClient and parses arguments + /*! + \param query The query with formatted arguments + \return the results of the query + */ + // Due to the template, implementation must be in the header. + template + CppSQLite3Query ExecuteQueryWithArgs(const std::string& query, Args... args) { + CppSQLite3Buffer sqlBuf; + sqlBuf.format(query.c_str(), args...); + + std::string safe_query = (const char *) sqlBuf; + return ExecuteQuery(safe_query); + } }; diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 4769df7e..56a09c57 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -89,21 +89,21 @@ Behavior* Behavior::GetBehavior(const uint32_t behaviorId) Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { auto* cached = GetBehavior(behaviorId); - + if (cached != nullptr) { return cached; } - + if (behaviorId == 0) { return new EmptyBehavior(0); } - + const auto templateId = GetBehaviorTemplate(behaviorId); Behavior* behavior = nullptr; - + switch (templateId) { case BehaviorTemplates::BEHAVIOR_EMPTY: break; @@ -266,7 +266,7 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) if (behavior == nullptr) { //Game::logger->Log("Behavior", "Failed to load unimplemented template id (%i)!\n", templateId); - + behavior = new EmptyBehavior(behaviorId); } @@ -293,7 +293,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) return BehaviorTemplates::BEHAVIOR_EMPTY; } - + const auto id = static_cast(result.getIntField(0)); result.finalize(); @@ -319,7 +319,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID return; } - + auto* renderComponent = targetEntity->GetComponent(); const auto typeString = GeneralUtils::UTF16ToWTF8(type); @@ -342,29 +342,30 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID if (renderComponent == nullptr) { GameMessages::SendPlayFXEffect(targetEntity, effectId, type, pair->second, secondary, 1, 1, true); - + return; } renderComponent->PlayEffect(effectId, type, pair->second, secondary); - + return; } } - - std::stringstream query; - + + CppSQLite3Query result; if (!type.empty()) { - query << "SELECT effectName FROM BehaviorEffect WHERE effectType = '" << typeString << "' AND effectID = " << std::to_string(effectId) << ";"; + result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT effectName FROM BehaviorEffect WHERE effectType = %Q AND effectID = %u;", + typeString.c_str(), effectId); } else { - query << "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << ";"; + result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = %u;", + effectId); } - auto result = CDClientDatabase::ExecuteQuery(query.str()); - if (result.eof() || result.fieldIsNull(0)) { return; @@ -375,7 +376,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID if (type.empty()) { const auto typeResult = result.getStringField(1); - + type = GeneralUtils::ASCIIToUTF16(typeResult); m_effectType = new std::string(typeResult); @@ -388,7 +389,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID if (renderComponent == nullptr) { GameMessages::SendPlayFXEffect(targetEntity, effectId, type, name, secondary, 1, 1, true); - + return; } @@ -431,7 +432,7 @@ Behavior::Behavior(const uint32_t behaviorId) } this->m_templateId = static_cast(result.getIntField(0)); - + this->m_effectId = result.getIntField(1); if (!result.fieldIsNull(2)) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 6b1c932b..fa601946 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -66,22 +66,22 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; std::vector args; - + uint32_t breakIndex = 0; for (uint32_t i = 1; i < command.size(); ++i) { if (command[i] == L' ') { breakIndex = i; break; } - + chatCommand.push_back(static_cast(command[i])); breakIndex++; } - + uint32_t index = ++breakIndex; while (true) { std::string arg; - + while (index < command.size()) { if (command[index] == L' ') { args.push_back(arg); @@ -89,24 +89,24 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit index++; continue; } - + arg.push_back(static_cast(command[index])); index++; } - + if (arg != "") { args.push_back(arg); } - + break; } //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"\n", GeneralUtils::UTF16ToWTF8(command).c_str()); - + User* user = UserManager::Instance()->GetUser(sysAddr); if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { if (args.size() != 1) return; - + uint32_t level; if (!GeneralUtils::TryParse(args[0], level)) @@ -129,7 +129,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (level == entity->GetGMLevel()) return; bool success = user->GetMaxGMLevel() >= level; - + if (success) { if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN) { @@ -174,10 +174,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit character->SetPvpEnabled(!character->GetPvpEnabled()); EntityManager::Instance()->SerializeEntity(entity); - + std::stringstream message; message << character->GetName() << " changed their PVP flag to " << std::to_string(character->GetPvpEnabled()) << "!"; - + ChatPackets::SendSystemMessage(UNASSIGNED_SYSTEM_ADDRESS, GeneralUtils::ASCIIToUTF16(message.str()), true); return; @@ -206,14 +206,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit { std::stringstream message; message << "Your latest ping: " << std::to_string(Game::server->GetLatestPing(sysAddr)) << "ms"; - + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message.str())); } else { std::stringstream message; message << "Your average ping: " << std::to_string(Game::server->GetPing(sysAddr)) << "ms"; - + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message.str())); } return; @@ -293,7 +293,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit Game::logger->Log("SlashCommandHandler", "Sending \n%s\n", customText.c_str()); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", &args); - + delete visiable; delete text; }); @@ -301,7 +301,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "leave-zone")) { + if (chatCommand == "leave-zone") { const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID(); auto newZone = 1100; @@ -322,10 +322,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (currentZone == newZone) { ChatPackets::SendSystemMessage(sysAddr, u"You are not in an instanced zone."); - + return; } - + ChatPackets::SendSystemMessage(sysAddr, u"Leaving zone..."); const auto objid = entity->GetObjectID(); @@ -354,10 +354,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit }); } - if ((chatCommand == "join" && !args.empty())) { + if (chatCommand == "join" && !args.empty()) { ChatPackets::SendSystemMessage(sysAddr, u"Requesting private map..."); const auto& password = args[0]; - + ZoneInstanceManager::Instance()->RequestPrivateZone(Game::server, false, password, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort); @@ -386,12 +386,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "resurrect") { ScriptedActivityComponent* scriptedActivityComponent = dZoneManager::Instance()->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."); return; } - + GameMessages::SendResurrect(entity); } @@ -414,7 +414,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit stmt->setString(2, GeneralUtils::UTF16ToWTF8(command).c_str()); stmt->execute(); delete stmt; - + if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0 int32_t minifigItemId; if (!GeneralUtils::TryParse(args[1], minifigItemId)) { @@ -452,7 +452,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit 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); ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId))); @@ -463,15 +463,15 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first)); } - + ChatPackets::SendSystemMessage(sysAddr, u"Current: " + GeneralUtils::ASCIIToUTF16(entity->GetCharacter()->GetTargetScene())); return; } - + if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { int32_t emoteID; - + if (!GeneralUtils::TryParse(args[0], emoteID)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid emote ID."); @@ -503,7 +503,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { float boost; - + if (!GeneralUtils::TryParse(args[0], boost)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid boost."); @@ -527,7 +527,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->SetVar(u"freecam", state); GameMessages::SendSetPlayerControlScheme(entity, static_cast(state ? 9 : 1)); - + ChatPackets::SendSystemMessage(sysAddr, u"Toggled freecam."); return; } @@ -540,9 +540,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid control scheme."); return; } - + GameMessages::SendSetPlayerControlScheme(entity, static_cast(scheme)); - + ChatPackets::SendSystemMessage(sysAddr, u"Switched control scheme."); return; } @@ -564,7 +564,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit AMFArrayValue args; args.InsertValue("state", value); GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "pushGameState", &args); - + ChatPackets::SendSystemMessage(sysAddr, u"Switched UI state."); delete value; @@ -578,7 +578,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit AMFArrayValue amfArgs; amfArgs.InsertValue("visible", value); GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, args[0], &amfArgs); - + ChatPackets::SendSystemMessage(sysAddr, u"Toggled UI state."); delete value; @@ -596,12 +596,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid size."); return; } - + InventoryComponent* inventory = static_cast(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); if (inventory) { auto* items = inventory->GetInventory(ITEMS); - + items->SetSize(size); } @@ -626,7 +626,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit else { ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?"); } - + return; } @@ -640,7 +640,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id."); return; } - + auto comp = static_cast(entity->GetComponent(COMPONENT_TYPE_MISSION)); if (comp) comp->AcceptMission(missionID, true); return; @@ -656,7 +656,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id."); return; } - + auto comp = static_cast(entity->GetComponent(COMPONENT_TYPE_MISSION)); if (comp) comp->CompleteMission(missionID, true); return; @@ -698,7 +698,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id."); return; } - + auto* comp = static_cast(entity->GetComponent(COMPONENT_TYPE_MISSION)); if (comp == nullptr) { @@ -710,7 +710,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (mission == nullptr) { return; } - + mission->SetMissionState(MissionState::MISSION_STATE_ACTIVE); return; @@ -792,7 +792,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid item LOT."); return; } - + InventoryComponent * inventory = static_cast(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); inventory->AddItem(itemLOT, 1); @@ -840,7 +840,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (receiverID == 0) { ChatPackets::SendSystemMessage(sysAddr, u"Failed to find that player"); - + return; } @@ -867,7 +867,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ins->setInt(11, 1); ins->execute(); delete ins; - + ChatPackets::SendSystemMessage(sysAddr, u"Mail sent"); return; @@ -884,7 +884,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::ASCIIToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); } - + if (chatCommand == "title" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { std::string name = entity->GetCharacter()->GetName() + " - "; @@ -902,19 +902,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (args.size() == 3) { float x, y, z; - + if (!GeneralUtils::TryParse(args[0], x)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid x."); return; } - + if (!GeneralUtils::TryParse(args[1], y)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid y."); return; } - + if (!GeneralUtils::TryParse(args[2], z)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid z."); @@ -924,7 +924,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit pos.SetX(x); pos.SetY(y); pos.SetZ(z); - + Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to %f, %f, %f\n", entity->GetObjectID(), pos.x, pos.y, pos.z); GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); } else if (args.size() == 2) { @@ -946,7 +946,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit pos.SetY(0.0f); pos.SetZ(z); - + Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to X: %f, Z: %f\n", entity->GetObjectID(), pos.x, pos.z); GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); } else { @@ -1019,7 +1019,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (player == nullptr) { auto* accountQuery = Database::CreatePreppedStmt("SELECT account_id, id FROM charinfo WHERE name=? LIMIT 1;"); - + accountQuery->setString(1, args[0]); auto result = accountQuery->executeQuery(); @@ -1029,7 +1029,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit while (result->next()) { accountId = result->getUInt(1); characterId = result->getUInt64(2); - + characterId = GeneralUtils::SetBit(characterId, OBJECT_BIT_CHARACTER); characterId = GeneralUtils::SetBit(characterId, OBJECT_BIT_PERSISTENT); } @@ -1087,7 +1087,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit userUpdate->executeUpdate(); delete userUpdate; - + char buffer[32] = "brought up for review.\0"; if (expire != 1) @@ -1096,12 +1096,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit // Format: Mo, 15.06.2009 20:20:00 std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm); } - + const auto timeStr = GeneralUtils::ASCIIToUTF16(std::string(buffer)); ChatPackets::SendSystemMessage(sysAddr, u"Muted: " + GeneralUtils::ASCIIToUTF16(args[0]) + u" until " + timeStr); - //Notify chat about it + //Notify chat about it CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_MUTE_UPDATE); @@ -1144,7 +1144,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (player == nullptr) { auto* accountQuery = Database::CreatePreppedStmt("SELECT account_id FROM charinfo WHERE name=? LIMIT 1;"); - + accountQuery->setString(1, args[0]); auto result = accountQuery->executeQuery(); @@ -1190,7 +1190,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } //------------------------------------------------- - + if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto dest = static_cast(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); if (dest) { @@ -1201,13 +1201,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination(999); dest->SetMaxImagination(999.0f); } - + EntityManager::Instance()->SerializeEntity(entity); } if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { int32_t celebration; - + if (!GeneralUtils::TryParse(args[0], celebration)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid celebration."); @@ -1216,7 +1216,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration); } - + if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto dest = static_cast(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); if (dest) { @@ -1230,7 +1230,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - + if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto dest = static_cast(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); if (dest) { @@ -1241,23 +1241,27 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - + if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { - std::string query = "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE '%" + args[0] + "%' OR `name` LIKE '%" + args[0] + "%' OR `description` LIKE '%" + args[0] + "%'"; - auto tables = CDClientDatabase::ExecuteQuery(query.c_str()); + std::string query = "%" + args[0] + "%"; + const char* query_cstr = query.c_str(); + auto tables = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE %Q OR `name` LIKE %Q OR `description` LIKE %Q LIMIT 50", + query_cstr, query_cstr, query_cstr); + while (!tables.eof()) { std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1); ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message, message.size())); tables.nextRow(); } } - + if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { ControllablePhysicsComponent* comp = static_cast(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); if (!comp) return; uint32_t lot; - + if (!GeneralUtils::TryParse(args[0], lot)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid lot."); @@ -1301,7 +1305,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto position = entity->GetPosition(); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(position.x)) + u", " + (GeneralUtils::to_u16string(position.y)) + u", " + (GeneralUtils::to_u16string(position.z)) + u">"); - + std::cout << position.x << ", " << position.y << ", " << position.z << std::endl; } @@ -1358,7 +1362,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); - + return; } @@ -1378,7 +1382,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit { destroyableComponent->SetIsGMImmune(state); } - + return; } @@ -1405,7 +1409,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit { buffComponent->ApplyBuff(id, duration, entity->GetObjectID()); } - + return; } @@ -1440,10 +1444,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } const auto objid = entity->GetObjectID(); - + if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery bool darwin = true; //Putting this on true, as I'm sick of having to wait 3-4 seconds on a transfer while trying to quickly moderate properties - + Character* character = entity->GetCharacter(); if (character) { std::string lowerName = character->GetName(); @@ -1488,7 +1492,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); }); - + return; }); } else { @@ -1519,7 +1523,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto& password = args[2]; ZoneInstanceManager::Instance()->CreatePrivateZone(Game::server, zone, clone, password); - + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16("Sent request for private zone with password: " + password)); return; @@ -1594,7 +1598,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } } - + if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); @@ -1676,13 +1680,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage( sysAddr, - GeneralUtils::ASCIIToUTF16(Metrics::MetricVariableToString(variable)) + - u": " + - GeneralUtils::to_u16string(Metrics::ToMiliseconds(metric->average)) + + GeneralUtils::ASCIIToUTF16(Metrics::MetricVariableToString(variable)) + + u": " + + GeneralUtils::to_u16string(Metrics::ToMiliseconds(metric->average)) + u"ms" ); } - + ChatPackets::SendSystemMessage( sysAddr, u"Peak RSS: " + GeneralUtils::to_u16string((float) ((double) Metrics::GetPeakRSS() / 1.024e6)) + @@ -1729,11 +1733,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } std::u16string message = u"Ran loot drops looking for " - + GeneralUtils::to_u16string(targetLot) - + u", " - + GeneralUtils::to_u16string(loops) - + u" times. It ran " - + GeneralUtils::to_u16string(totalRuns) + + GeneralUtils::to_u16string(targetLot) + + u", " + + GeneralUtils::to_u16string(loops) + + u" times. It ran " + + GeneralUtils::to_u16string(totalRuns) + u" times. Averaging out at " + GeneralUtils::to_u16string((float) totalRuns / loops); @@ -1764,7 +1768,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto closestDistance = 0.0f; const auto candidates = EntityManager::Instance()->GetEntitiesByComponent(component); - + for (auto* candidate : candidates) { if (candidate->GetLOT() == 1 || candidate->GetLOT() == 8092) @@ -1776,16 +1780,16 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit { continue; } - + if (closest == nullptr) { closest = candidate; closestDistance = NiPoint3::Distance(candidate->GetPosition(), reference); - + continue; } - + const auto distance = NiPoint3::Distance(candidate->GetPosition(), reference); if (distance < closestDistance) @@ -1812,7 +1816,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit header << info.name << " [" << std::to_string(info.id) << "]" << " " << std::to_string(closestDistance) << " " << std::to_string(closest->IsSleeping()); ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(header.str())); - + for (const auto& pair : closest->GetComponents()) { auto id = pair.first; @@ -1825,7 +1829,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (args.size() >= 2) - { + { if (args[1] == "-m" && args.size() >= 3) { auto* movingPlatformComponent = closest->GetComponent(); @@ -1869,7 +1873,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto postion = closest->GetPosition(); ChatPackets::SendSystemMessage( - sysAddr, + sysAddr, GeneralUtils::ASCIIToUTF16("< " + std::to_string(postion.x) + ", " + std::to_string(postion.y) + ", " + std::to_string(postion.z) + " >") ); } @@ -1936,35 +1940,35 @@ bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) { case 98: case 1000: case 1001: - + case 1100: case 1101: case 1150: case 1151: case 1152: - + case 1200: case 1201: case 1250: case 1251: case 1260: - + case 1300: case 1350: case 1351: - + case 1400: case 1401: case 1450: case 1451: - + case 1600: case 1601: case 1602: case 1603: case 1604: - + case 1800: case 1900: case 2000: @@ -1973,11 +1977,11 @@ bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) { case 58005: case 58006: return true; - + default: return false; } - + return false; } @@ -1998,7 +2002,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: titleValue = nullptr; messageValue = nullptr; - //Notify chat about it + //Notify chat about it CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ANNOUNCEMENT); @@ -2010,4 +2014,3 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } - From 4796b551addd73395f87a10baf1309664127b78f Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Thu, 6 Jan 2022 16:05:03 -0500 Subject: [PATCH 05/98] Additional SQLite lookup sanitizing with CDClientDatabase::ExecuteQueryWithArgs() --- dDatabase/Tables/CDBehaviorParameterTable.cpp | 8 +++----- dGame/dComponents/RenderComponent.cpp | 14 ++++++-------- dGame/dInventory/ItemSet.cpp | 16 ++++++---------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index b29a8267..2a1554cb 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -59,11 +59,9 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s } #ifndef CDCLIENT_CACHE_ALL - std::stringstream query; - - query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(behaviorID); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + auto tableData = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = %u;", + behaviorID); m_Entries.insert_or_assign(behaviorID, 0); diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index aeb56f56..b4787d40 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -198,14 +198,12 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e return; } - std::stringstream query; + const std::string effectType_str = GeneralUtils::UTF16ToWTF8(effectType); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = %d AND effectType = %Q);", + effectId, effectType_str.c_str()); - query << "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << " AND effectType = '" << GeneralUtils::UTF16ToWTF8(effectType) << "');"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof() || result.fieldIsNull(0)) - { + if (result.eof() || result.fieldIsNull(0)) { result.finalize(); m_DurationCache[effectId] = 0; @@ -214,7 +212,7 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e return; } - + effect->time = static_cast(result.getFloatField(0)); result.finalize(); diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index d1e74df4..93e86a81 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -15,11 +15,9 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) this->m_PassiveAbilities = ItemSetPassiveAbility::FindAbilities(id, m_InventoryComponent->GetParent(), this); - std::stringstream query; - - query << "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = " << std::to_string(id); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = %u;", + id); if (result.eof()) { @@ -33,11 +31,9 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) continue; } - std::stringstream skillQuery; - - skillQuery << "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = " << std::to_string(result.getIntField(i)); - - auto skillResult = CDClientDatabase::ExecuteQuery(skillQuery.str()); + auto skillResult = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = %d;", + result.getIntField(i)); if (skillResult.eof()) { From e5f7d164cbf958cabd6f6f7da9cf56356e565c18 Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Thu, 6 Jan 2022 21:12:47 -0500 Subject: [PATCH 06/98] Additional SQLite lookup sanitizing. Using CDClientDatabase::ExecuteQueryWithArgs() across all known lookups. --- dGame/dBehaviors/Behavior.cpp | 31 ++++++------------- dGame/dBehaviors/SwitchMultipleBehavior.cpp | 16 +++++----- dGame/dComponents/BaseCombatAIComponent.cpp | 17 ++++------ dGame/dComponents/BuffComponent.cpp | 8 ++--- dGame/dComponents/DestroyableComponent.cpp | 7 ++--- dGame/dComponents/InventoryComponent.cpp | 18 +++++------ dGame/dComponents/MissionComponent.cpp | 7 ++--- dGame/dComponents/PetComponent.cpp | 11 +++---- .../PropertyManagementComponent.cpp | 16 ++++------ .../RocketLaunchpadControlComponent.cpp | 8 ++--- dGame/dComponents/SkillComponent.cpp | 25 ++++++--------- dGame/dGameMessages/GameMessages.cpp | 8 ++--- dGame/dInventory/Item.cpp | 8 ++--- dGame/dUtilities/Preconditions.cpp | 11 +++---- dWorldServer/WorldServer.cpp | 8 ++--- dZoneManager/dZoneManager.cpp | 5 +-- 16 files changed, 75 insertions(+), 129 deletions(-) diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 56a09c57..2e3290f7 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -275,13 +275,10 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) return behavior; } -BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) -{ - std::stringstream query; - - query << "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = " << std::to_string(behaviorId); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); +BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = %u;", + behaviorId); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -409,15 +406,9 @@ Behavior::Behavior(const uint32_t behaviorId) this->m_templateId = BehaviorTemplates::BEHAVIOR_EMPTY; } - /* - * Get standard info - */ - - std::stringstream query; - - query << "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = " << std::to_string(behaviorId); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = %u;", + behaviorId); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -490,11 +481,9 @@ std::map Behavior::GetParameterNames() const { std::map parameters; - std::stringstream query; - - query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(this->m_behaviorId); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + auto tableData = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = %u;", + this->m_behaviorId); while (!tableData.eof()) { diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index 691e8b53..062ae9f0 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -39,15 +39,13 @@ void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStre // TODO } -void SwitchMultipleBehavior::Load() -{ - const auto b = std::to_string(this->m_behaviorId); - std::stringstream query; - query << "SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, " - << "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = " << b << " AND bP2.parameterID LIKE 'value %' " - << "AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value " - << "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = " << b << " AND bP1.parameterID LIKE 'behavior %'"; - auto result = CDClientDatabase::ExecuteQuery(query.str()); +void SwitchMultipleBehavior::Load() { + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, " + "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = %u AND bP2.parameterID LIKE 'value %' " + "AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value " + "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = %u AND bP1.parameterID LIKE 'behavior %';", + this->m_behaviorId, this->m_behaviorId); while (!result.eof()) { const auto behavior_id = static_cast(result.getFloatField(1)); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index ae929d57..994f49c4 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -35,11 +35,9 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) m_SoftTimer = 5.0f; //Grab the aggro information from BaseCombatAI: - std::stringstream componentQuery; - - componentQuery << "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = " << std::to_string(id); - - auto componentResult = CDClientDatabase::ExecuteQuery(componentQuery.str()); + auto componentResult = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = %u;", + id); if (!componentResult.eof()) { @@ -64,12 +62,9 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) /* * Find skills */ - - std::stringstream query; - - query << "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(parent->GetLOT()) << " )"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = %d);", + parent->GetLOT()); while (!result.eof()) { const auto skillId = static_cast(result.getIntField(0)); diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index 06c859c8..afa5b321 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -371,11 +371,9 @@ const std::vector& BuffComponent::GetBuffParameters(int32_t buffI return pair->second; } - std::stringstream query; - - query << "SELECT * FROM BuffParameters WHERE BuffID = " << std::to_string(buffId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT * FROM BuffParameters WHERE BuffID = %d;", + buffId); std::vector parameters {}; diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index fb4dfe61..91ff8b6e 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -373,11 +373,8 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore m_FactionIDs.push_back(factionID); m_DirtyHealth = true; - std::stringstream query; - - query << "SELECT enemyList FROM Factions WHERE faction = " << std::to_string(factionID); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT enemyList FROM Factions WHERE faction = %d;", factionID); if (result.eof()) return; diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 50ea26b1..1f9b4cc6 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1136,22 +1136,18 @@ bool InventoryComponent::IsEquipped(const LOT lot) const return false; } -void InventoryComponent::CheckItemSet(const LOT lot) -{ +void InventoryComponent::CheckItemSet(const LOT lot) { // Check if the lot is in the item set cache - if (std::find(m_ItemSetsChecked.begin(), m_ItemSetsChecked.end(), lot) != m_ItemSetsChecked.end()) - { + if (std::find(m_ItemSetsChecked.begin(), m_ItemSetsChecked.end(), lot) != m_ItemSetsChecked.end()) { return; } - std::stringstream query; + std::cout << "INVENTORY CHECK" << std::endl; + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT setID FROM ItemSets WHERE itemIDs LIKE '%%%d%%';", + lot); - query << "SELECT setID FROM ItemSets WHERE itemIDs LIKE '%" << std::to_string(lot) << "%'"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - while (!result.eof()) - { + while (!result.eof()) { const auto id = result.getIntField(0); bool found = false; diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index a0e63914..5945394b 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -450,11 +450,8 @@ const std::vector& MissionComponent::QueryAchievements(MissionTaskType } bool MissionComponent::RequiresItem(const LOT lot) { - std::stringstream query; - - query << "SELECT type FROM Objects WHERE id = " << std::to_string(lot); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT type FROM Objects WHERE id = %d;", lot); if (result.eof()) { return false; diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index e605908f..8c51791a 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -166,13 +166,10 @@ void PetComponent::OnUse(Entity* originator) std::string buildFile; - if (cached == buildCache.end()) - { - std::stringstream query; - - query << "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = " << std::to_string(m_Parent->GetLOT()) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + if (cached == buildCache.end()) { + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = %d;", + m_Parent->GetLOT()); if (result.eof()) { diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index bf89eb22..543f99a2 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -40,11 +40,9 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); - std::stringstream query; - - query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT id FROM PropertyTemplate WHERE mapID = %d;", + (int) zoneId); if (result.eof() || result.fieldIsNull(0)) { @@ -97,12 +95,10 @@ void PropertyManagementComponent::SetOwner(Entity* value) std::vector PropertyManagementComponent::GetPaths() const { const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); - - std::stringstream query {}; - query << "SELECT path FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT path FROM PropertyTemplate WHERE mapID = %u;", + zoneId); std::vector paths {}; diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 049a44b6..a117fffc 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -18,11 +18,9 @@ #include "PacketUtils.h" RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) { - std::stringstream query; - - query << "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = " << std::to_string(rocketId); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = %d;", + rocketId); if (!result.eof() && !result.fieldIsNull(0)) { diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 0846f014..4396c669 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -86,14 +86,11 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B const auto sync_entry = this->m_managedProjectiles.at(index); - std::stringstream query; + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = %d);", + sync_entry.lot); - query << "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(sync_entry.lot) << ")"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof()) - { + if (result.eof()) { Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", sync_entry.lot); return; @@ -428,8 +425,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) { auto* other = EntityManager::Instance()->GetEntity(entry.branchContext.target); - if (other == nullptr) - { + if (other == nullptr) { if (entry.branchContext.target != LWOOBJID_EMPTY) { Game::logger->Log("SkillComponent", "Invalid projectile target (%llu)!\n", entry.branchContext.target); @@ -438,14 +434,11 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) return; } - std::stringstream query; + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = %d);", + entry.lot); - query << "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(entry.lot) << ")"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof()) - { + if (result.eof()) { Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", entry.lot); return; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index cd7910b4..0e30244b 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2509,11 +2509,9 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); - std::stringstream query; - - query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT id FROM PropertyTemplate WHERE mapID = %d;", + (int) zoneId); if (result.eof() || result.fieldIsNull(0)) { return; diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 20f5321a..92a208cb 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -386,11 +386,9 @@ void Item::DisassembleModel() const auto componentId = table->GetByIDAndType(GetLot(), COMPONENT_TYPE_RENDER); - std::stringstream query; - - query << "SELECT render_asset FROM RenderComponent WHERE id = " << std::to_string(componentId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT render_asset FROM RenderComponent WHERE id = %d;", + componentId); if (result.eof()) { diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index b29af130..5b68685c 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -15,13 +15,10 @@ std::map Preconditions::cache = {}; -Precondition::Precondition(const uint32_t condition) -{ - std::stringstream query; - - query << "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = " << std::to_string(condition) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); +Precondition::Precondition(const uint32_t condition) { + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = %u;", + condition); if (result.eof()) { diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 2a6cbaa5..ce3774e9 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -1059,11 +1059,9 @@ void HandlePacket(Packet* packet) { const auto zoneId = Game::server->GetZoneID(); const auto cloneId = g_CloneID; - std::stringstream query; - - query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT id FROM PropertyTemplate WHERE mapID = %u;", + zoneId); if (result.eof() || result.fieldIsNull(0)) { Game::logger->Log("WorldServer", "No property templates found for zone %d, not sending BBB\n", zoneId); diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index d2188f4f..6ed6c719 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -26,8 +26,9 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { LOT zoneControlTemplate = 2365; - std::stringstream query; - auto result = CDClientDatabase::ExecuteQuery("SELECT zoneControlTemplate, ghostdistance_min, ghostdistance FROM ZoneTable WHERE zoneID = " + std::to_string(zoneID.GetMapID())); + auto result = CDClientDatabase::ExecuteQueryWithArgs( + "SELECT zoneControlTemplate, ghostdistance_min, ghostdistance FROM ZoneTable WHERE zoneID = %d;", + (int) zoneID.GetMapID()); if (!result.eof()) { zoneControlTemplate = result.getIntField("zoneControlTemplate", 2365); From 3de393250340ad27aa2dcac39afe9ed93c114959 Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Wed, 12 Jan 2022 22:48:27 -0500 Subject: [PATCH 07/98] Comply with Xiphoseer required changes. Remove the CDClientDatabase::ExecuteQueryWithArgs() function and replace it with CDClientDatabase::CreatePreppedStmt(). This prevents a developer from accidently using %s, or incorrectly passing std::string, and causing a silent error. --- dDatabase/CDClientDatabase.cpp | 5 + dDatabase/CDClientDatabase.h | 12 +- dDatabase/Tables/CDBehaviorParameterTable.cpp | 8 +- dGame/dBehaviors/Behavior.cpp | 52 +++-- dGame/dBehaviors/SwitchMultipleBehavior.cpp | 10 +- dGame/dComponents/BaseCombatAIComponent.cpp | 16 +- dGame/dComponents/BuffComponent.cpp | 8 +- dGame/dComponents/DestroyableComponent.cpp | 7 +- dGame/dComponents/InventoryComponent.cpp | 186 +++++++++--------- dGame/dComponents/MissionComponent.cpp | 7 +- dGame/dComponents/PetComponent.cpp | 8 +- .../PropertyManagementComponent.cpp | 16 +- dGame/dComponents/RenderComponent.cpp | 10 +- .../RocketLaunchpadControlComponent.cpp | 8 +- dGame/dComponents/SkillComponent.cpp | 15 +- dGame/dGameMessages/GameMessages.cpp | 8 +- dGame/dInventory/Item.cpp | 8 +- dGame/dInventory/ItemSet.cpp | 16 +- dGame/dUtilities/Preconditions.cpp | 8 +- dGame/dUtilities/SlashCommandHandler.cpp | 12 +- dWorldServer/WorldServer.cpp | 8 +- dZoneManager/dZoneManager.cpp | 8 +- 22 files changed, 247 insertions(+), 189 deletions(-) diff --git a/dDatabase/CDClientDatabase.cpp b/dDatabase/CDClientDatabase.cpp index d61d6fe7..d09b2daa 100644 --- a/dDatabase/CDClientDatabase.cpp +++ b/dDatabase/CDClientDatabase.cpp @@ -13,3 +13,8 @@ void CDClientDatabase::Connect(const std::string& filename) { CppSQLite3Query CDClientDatabase::ExecuteQuery(const std::string& query) { return conn->execQuery(query.c_str()); } + +//! Makes prepared statements +CppSQLite3Statement CDClientDatabase::CreatePreppedStmt(const std::string& query) { + return conn->compileStatement(query.c_str()); +} diff --git a/dDatabase/CDClientDatabase.h b/dDatabase/CDClientDatabase.h index 5028e0bd..91e9ee10 100644 --- a/dDatabase/CDClientDatabase.h +++ b/dDatabase/CDClientDatabase.h @@ -43,15 +43,7 @@ namespace CDClientDatabase { //! Queries the CDClient and parses arguments /*! \param query The query with formatted arguments - \return the results of the query + \return prepared SQLite Statement */ - // Due to the template, implementation must be in the header. - template - CppSQLite3Query ExecuteQueryWithArgs(const std::string& query, Args... args) { - CppSQLite3Buffer sqlBuf; - sqlBuf.format(query.c_str(), args...); - - std::string safe_query = (const char *) sqlBuf; - return ExecuteQuery(safe_query); - } + CppSQLite3Statement CreatePreppedStmt(const std::string& query); }; diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index 2a1554cb..3087ba6d 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -59,9 +59,11 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s } #ifndef CDCLIENT_CACHE_ALL - auto tableData = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = %u;", - behaviorID); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorID); + + auto tableData = query.execQuery(); m_Entries.insert_or_assign(behaviorID, 0); diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 2e3290f7..351a4ada 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -276,9 +276,11 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) } BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = %u;", - behaviorId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorId); + + auto result = query.execQuery(); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -349,18 +351,24 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID } } + // The SQlite result object becomes invalid if the query object leaves scope. + // So both queries are defined before the if statement CppSQLite3Query result; - if (!type.empty()) - { - result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT effectName FROM BehaviorEffect WHERE effectType = %Q AND effectID = %u;", - typeString.c_str(), effectId); - } - else - { - result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = %u;", - effectId); + auto typeQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT effectName FROM BehaviorEffect WHERE effectType = ? AND effectID = ?;"); + + auto idQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = ?;"); + + if (!type.empty()) { + typeQuery.bind(1, typeString.c_str()); + typeQuery.bind(2, (int) effectId); + + result = typeQuery.execQuery(); + } else { + idQuery.bind(1, (int) effectId); + + result = idQuery.execQuery(); } if (result.eof() || result.fieldIsNull(0)) @@ -406,9 +414,11 @@ Behavior::Behavior(const uint32_t behaviorId) this->m_templateId = BehaviorTemplates::BEHAVIOR_EMPTY; } - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = %u;", - behaviorId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorId); + + auto result = query.execQuery(); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -481,9 +491,11 @@ std::map Behavior::GetParameterNames() const { std::map parameters; - auto tableData = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = %u;", - this->m_behaviorId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); + query.bind(1, (int) this->m_behaviorId); + + auto tableData = query.execQuery(); while (!tableData.eof()) { diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index 062ae9f0..93662060 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -40,12 +40,14 @@ void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStre } void SwitchMultipleBehavior::Load() { - auto result = CDClientDatabase::ExecuteQueryWithArgs( + auto query = CDClientDatabase::CreatePreppedStmt( "SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, " - "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = %u AND bP2.parameterID LIKE 'value %' " + "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = ?1 AND bP2.parameterID LIKE 'value %' " "AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value " - "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = %u AND bP1.parameterID LIKE 'behavior %';", - this->m_behaviorId, this->m_behaviorId); + "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = ?1 AND bP1.parameterID LIKE 'behavior %';"); + query.bind(1, (int) this->m_behaviorId); + + auto result = query.execQuery(); while (!result.eof()) { const auto behavior_id = static_cast(result.getFloatField(1)); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 994f49c4..4d82036f 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -35,9 +35,11 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) m_SoftTimer = 5.0f; //Grab the aggro information from BaseCombatAI: - auto componentResult = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = %u;", - id); + auto componentQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = ?;"); + componentQuery.bind(1, (int) id); + + auto componentResult = componentQuery.execQuery(); if (!componentResult.eof()) { @@ -62,9 +64,11 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) /* * Find skills */ - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = %d);", - parent->GetLOT()); + auto skillQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); + skillQuery.bind(1, (int) parent->GetLOT()); + + auto result = skillQuery.execQuery(); while (!result.eof()) { const auto skillId = static_cast(result.getIntField(0)); diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index afa5b321..9c12e87d 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -371,10 +371,12 @@ const std::vector& BuffComponent::GetBuffParameters(int32_t buffI return pair->second; } - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT * FROM BuffParameters WHERE BuffID = %d;", - buffId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT * FROM BuffParameters WHERE BuffID = ?;"); + query.bind(1, (int) buffId); + auto result = query.execQuery(); + std::vector parameters {}; while (!result.eof()) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 91ff8b6e..1afd4b58 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -373,8 +373,11 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore m_FactionIDs.push_back(factionID); m_DirtyHealth = true; - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT enemyList FROM Factions WHERE faction = %d;", factionID); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT enemyList FROM Factions WHERE faction = ?;"); + query.bind(1, (int) factionID); + + auto result = query.execQuery(); if (result.eof()) return; diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 1f9b4cc6..bedb912d 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -50,18 +50,18 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do auto items = inventoryComponentTable->Query([=](const CDInventoryComponent entry) { return entry.id == componentId; }); auto slot = 0u; - + for (const auto& item : items) { if (!item.equip || !Inventory::IsValidItem(item.itemid)) { continue; } - + const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); const auto& info = Inventory::FindItemComponent(item.itemid); - + UpdateSlot(info.equipLocation, { id, static_cast(item.itemid), item.count, slot++ }); } } @@ -86,7 +86,7 @@ Inventory* InventoryComponent::GetInventory(const eInventoryType type) case eInventoryType::VAULT_ITEMS: size = 40u; break; - + default: break; } @@ -173,7 +173,7 @@ void InventoryComponent::AddItem( auto* missions = static_cast(this->m_Parent->GetComponent(COMPONENT_TYPE_MISSION)); auto* inventory = GetInventory(inventoryType); - + if (!config.empty() || bound) { const auto slot = inventory->FindEmptySlot(); @@ -184,7 +184,7 @@ void InventoryComponent::AddItem( return; } - + auto* item = new Item(lot, inventory, slot, count, config, parent, showFlyingLoot, isModMoveAndEquip, subKey, bound); if (missions != nullptr && !IsTransferInventory(inventoryType)) @@ -196,7 +196,7 @@ void InventoryComponent::AddItem( } const auto info = Inventory::FindItemComponent(lot); - + auto left = count; int32_t outOfSpace = 0; @@ -211,7 +211,7 @@ void InventoryComponent::AddItem( { stack = 1; } - + auto* existing = FindItemByLot(lot, inventoryType); if (existing != nullptr) @@ -235,7 +235,7 @@ void InventoryComponent::AddItem( const auto size = std::min(left, stack); left -= size; - + int32_t slot; if (preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot)) @@ -248,7 +248,7 @@ void InventoryComponent::AddItem( { slot = inventory->FindEmptySlot(); } - + if (slot == -1) { auto* player = dynamic_cast(GetParent()); @@ -271,9 +271,9 @@ void InventoryComponent::AddItem( { GameMessages::SendDropClientLoot(this->m_Parent, this->m_Parent->GetObjectID(), lot, 0, this->m_Parent->GetPosition(), 1); } - + break; - + default: break; } @@ -323,7 +323,7 @@ void InventoryComponent::RemoveItem(const LOT lot, const uint32_t count, eInvent { break; } - + const auto delta = std::min(left, item->GetCount()); item->SetCount(item->GetCount() - delta); @@ -338,11 +338,11 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in { return; } - + auto* origin = item->GetInventory(); - + const auto lot = item->GetLot(); - + if (item->GetConfig().empty() && !item->GetBound() || (item->GetBound() && item->GetInfo().isBOP)) { auto left = std::min(count, origin->GetLotCount(lot)); @@ -380,7 +380,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in { config.push_back(data->Copy()); } - + const auto delta = std::min(item->GetCount(), count); AddItem(lot, delta, inventory, config, LWOOBJID_EMPTY, showFlyingLot, isModMoveAndEquip, LWOOBJID_EMPTY, origin->GetType(), 0, item->GetBound(), preferredSlot); @@ -438,7 +438,7 @@ Item* InventoryComponent::FindItemByLot(const LOT lot, eInventoryType inventoryT return inventory->FindItemByLot(lot, ignoreEquipped, ignoreBound); } -Item* InventoryComponent::FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType) +Item* InventoryComponent::FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType) { if (inventoryType == INVALID) { @@ -597,7 +597,7 @@ void InventoryComponent::LoadXml(tinyxml2::XMLDocument* document) unsigned int count; bool bound; LWOOBJID subKey = LWOOBJID_EMPTY; - + itemElement->QueryAttribute("id", &id); itemElement->QueryAttribute("l", &lot); itemElement->QueryAttribute("eq", &equipped); @@ -608,23 +608,23 @@ void InventoryComponent::LoadXml(tinyxml2::XMLDocument* document) // Begin custom xml auto parent = LWOOBJID_EMPTY; - + itemElement->QueryAttribute("parent", &parent); // End custom xml std::vector config; auto* extraInfo = itemElement->FirstChildElement("x"); - + if (extraInfo) { std::string modInfo = extraInfo->Attribute("ma"); - + LDFBaseData* moduleAssembly = new LDFData(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(modInfo.substr(2, modInfo.size() - 1))); - + config.push_back(moduleAssembly); } - + const auto* item = new Item(id, lot, inventory, slot, count, bound, config, parent, subKey); if (equipped) @@ -702,7 +702,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) bags->LinkEndChild(bag); } - + auto* items = inventoryElement->FirstChildElement("items"); if (items == nullptr) @@ -756,10 +756,10 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) itemElement->LinkEndChild(extraInfo); } - + bagElement->LinkEndChild(itemElement); } - + items->LinkEndChild(bagElement); } } @@ -769,13 +769,13 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b if (bIsInitialUpdate || m_Dirty) { outBitStream->Write(true); - + outBitStream->Write(m_Equipped.size()); for (const auto& pair : m_Equipped) { const auto item = pair.second; - + if (bIsInitialUpdate) { AddItemSkills(item.lot); @@ -783,19 +783,19 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b outBitStream->Write(item.id); outBitStream->Write(item.lot); - + outBitStream->Write0(); - + outBitStream->Write(item.count > 0); if (item.count > 0) outBitStream->Write(item.count); - + outBitStream->Write(item.slot != 0); if (item.slot != 0) outBitStream->Write(item.slot); - + outBitStream->Write0(); - + outBitStream->Write0(); //TODO: This is supposed to be true and write the assemblyPartLOTs when they're present. - + outBitStream->Write1(); } @@ -805,7 +805,7 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b { outBitStream->Write(false); } - + outBitStream->Write(false); } @@ -814,7 +814,7 @@ void InventoryComponent::ResetFlags() m_Dirty = false; } -void InventoryComponent::Update(float deltaTime) +void InventoryComponent::Update(float deltaTime) { for (auto* set : m_Itemsets) { @@ -843,7 +843,7 @@ void InventoryComponent::UpdateSlot(const std::string& location, EquippedItem it UnEquipItem(old); } } - + m_Equipped.insert_or_assign(location, item); m_Dirty = true; @@ -855,14 +855,14 @@ void InventoryComponent::RemoveSlot(const std::string& location) { return; } - + m_Equipped.erase(location); m_Dirty = true; } void InventoryComponent::EquipItem(Item* item, const bool skipChecks) -{ +{ if (!Inventory::IsValidItem(item->GetLot())) { return; @@ -908,7 +908,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) const auto building = character->GetBuildMode(); const auto type = static_cast(item->GetInfo().itemType); - + if (item->GetLot() == 8092 && m_Parent->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { EntityInfo info {}; @@ -976,7 +976,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { return; } - + if (type == ITEM_TYPE_LOOT_MODEL || type == ITEM_TYPE_VEHICLE) { return; @@ -995,12 +995,12 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) const auto lot = item->GetLot(); CheckItemSet(lot); - + for (auto* set : m_Itemsets) { set->OnEquip(lot); } - + if (lot == 1727) GameMessages::SendSetJetpackMode(m_Parent, false, true, false); if (lot == 7292) GameMessages::SendSetJetpackMode(m_Parent, true, true, false); if (lot == 14442) GameMessages::SendSetJetpackMode(m_Parent, false, true, true); @@ -1011,11 +1011,11 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) } GenerateProxies(item); - + UpdateSlot(item->GetInfo().equipLocation, { item->GetId(), item->GetLot(), item->GetCount(), item->GetSlot() }); ApplyBuff(item->GetLot()); - + AddItemSkills(item->GetLot()); EntityManager::Instance()->SerializeEntity(m_Parent); @@ -1029,7 +1029,7 @@ void InventoryComponent::UnEquipItem(Item* item) } const auto lot = item->GetLot(); - + if (!Inventory::IsValidItem(lot)) { return; @@ -1047,11 +1047,11 @@ void InventoryComponent::UnEquipItem(Item* item) if (lot == 14442) GameMessages::SendSetJetpackMode(m_Parent, false, false, true); RemoveBuff(item->GetLot()); - + RemoveItemSkills(item->GetLot()); RemoveSlot(item->GetInfo().equipLocation); - + PurgeProxies(item); EntityManager::Instance()->SerializeEntity(m_Parent); @@ -1069,7 +1069,7 @@ void InventoryComponent::ApplyBuff(const LOT lot) const const auto buffs = FindBuffs(lot, true); for (const auto buff : buffs) - { + { SkillComponent::HandleUnmanaged(buff, m_Parent->GetObjectID()); } } @@ -1142,10 +1142,13 @@ void InventoryComponent::CheckItemSet(const LOT lot) { return; } - std::cout << "INVENTORY CHECK" << std::endl; - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT setID FROM ItemSets WHERE itemIDs LIKE '%%%d%%';", - lot); + const std::string lot_query = "%" + std::to_string(lot) + "%"; + + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT setID FROM ItemSets WHERE itemIDs LIKE ?;"); + query.bind(1, lot_query.c_str()); + + auto result = query.execQuery(); while (!result.eof()) { const auto id = result.getIntField(0); @@ -1173,11 +1176,11 @@ void InventoryComponent::CheckItemSet(const LOT lot) { } m_ItemSetsChecked.push_back(lot); - + result.finalize(); } -void InventoryComponent::SetConsumable(LOT lot) +void InventoryComponent::SetConsumable(LOT lot) { m_Consumable = lot; } @@ -1197,13 +1200,13 @@ void InventoryComponent::AddItemSkills(const LOT lot) { return; } - + const auto index = m_Skills.find(slot); if (index != m_Skills.end()) { const auto old = index->second; - + GameMessages::SendRemoveSkill(m_Parent, old); } @@ -1213,7 +1216,7 @@ void InventoryComponent::AddItemSkills(const LOT lot) { return; } - + GameMessages::SendAddSkill(m_Parent, skill, static_cast(slot)); m_Skills.insert_or_assign(slot, skill); @@ -1222,14 +1225,14 @@ void InventoryComponent::AddItemSkills(const LOT lot) void InventoryComponent::RemoveItemSkills(const LOT lot) { const auto info = Inventory::FindItemComponent(lot); - + const auto slot = FindBehaviorSlot(static_cast(info.itemType)); - + if (slot == BehaviorSlot::Invalid) { return; } - + const auto index = m_Skills.find(slot); if (index == m_Skills.end()) @@ -1242,7 +1245,7 @@ void InventoryComponent::RemoveItemSkills(const LOT lot) GameMessages::SendRemoveSkill(m_Parent, old); m_Skills.erase(slot); - + if (slot == BehaviorSlot::Primary) { m_Skills.insert_or_assign(BehaviorSlot::Primary, 1); @@ -1251,7 +1254,7 @@ void InventoryComponent::RemoveItemSkills(const LOT lot) } } -void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger) +void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger) { for (auto* set : m_Itemsets) { @@ -1278,7 +1281,7 @@ bool InventoryComponent::HasAnyPassive(const std::vectorGetObjectID()); @@ -1288,7 +1291,7 @@ void InventoryComponent::DespawnPet() } } -void InventoryComponent::SpawnPet(Item* item) +void InventoryComponent::SpawnPet(Item* item) { auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID()); @@ -1307,11 +1310,11 @@ void InventoryComponent::SpawnPet(Item* item) info.pos = m_Parent->GetPosition(); info.rot = NiQuaternion::IDENTITY; info.spawnerID = m_Parent->GetObjectID(); - + auto* pet = EntityManager::Instance()->CreateEntity(info); auto* petComponent = pet->GetComponent(); - + if (petComponent != nullptr) { petComponent->Activate(item); @@ -1320,7 +1323,7 @@ void InventoryComponent::SpawnPet(Item* item) EntityManager::Instance()->ConstructEntity(pet); } -void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) +void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) { m_Pets.insert_or_assign(id, data); } @@ -1341,7 +1344,7 @@ bool InventoryComponent::IsPet(LWOOBJID id) const return pair != m_Pets.end(); } -void InventoryComponent::RemoveDatabasePet(LWOOBJID id) +void InventoryComponent::RemoveDatabasePet(LWOOBJID id) { m_Pets.erase(id); } @@ -1364,7 +1367,7 @@ BehaviorSlot InventoryComponent::FindBehaviorSlot(const eItemType type) } } -bool InventoryComponent::IsTransferInventory(eInventoryType type) +bool InventoryComponent::IsTransferInventory(eInventoryType type) { return type == VENDOR_BUYBACK || type == VAULT_ITEMS || type == VAULT_MODELS || type == TEMP_ITEMS || type == TEMP_MODELS; } @@ -1415,12 +1418,12 @@ std::vector InventoryComponent::FindBuffs(const LOT lot, bool castOnEq continue; } - + if (missions != nullptr && castOnEquip) { missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, result.skillID); } - + buffs.push_back(static_cast(entry.behaviorID)); } } @@ -1428,18 +1431,18 @@ std::vector InventoryComponent::FindBuffs(const LOT lot, bool castOnEq return buffs; } -void InventoryComponent::SetNPCItems(const std::vector& items) +void InventoryComponent::SetNPCItems(const std::vector& items) { m_Equipped.clear(); auto slot = 0u; - + for (const auto& item : items) { const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); const auto& info = Inventory::FindItemComponent(item); - + UpdateSlot(info.equipLocation, { id, static_cast(item), 1, slot++ }, true); } @@ -1474,9 +1477,9 @@ std::vector InventoryComponent::GenerateProxies(Item* parent) { return proxies; } - + subItems.erase(std::remove_if(subItems.begin(), subItems.end(), ::isspace), subItems.end()); - + std::stringstream stream(subItems); std::string segment; std::vector lots; @@ -1491,7 +1494,7 @@ std::vector InventoryComponent::GenerateProxies(Item* parent) { Game::logger->Log("InventoryComponent", "Failed to parse proxy (%s): (%s)!\n", segment.c_str(), exception.what()); } - } + } for (const auto lot : lots) { @@ -1508,7 +1511,7 @@ std::vector InventoryComponent::GenerateProxies(Item* parent) proxies.push_back(proxy); } - + return proxies; } @@ -1517,7 +1520,7 @@ std::vector InventoryComponent::FindProxies(const LWOOBJID parent) auto* inventory = GetInventory(ITEM_SETS); std::vector proxies; - + for (const auto& pair : inventory->GetItems()) { auto* item = pair.second; @@ -1559,7 +1562,7 @@ bool InventoryComponent::IsParentValid(Item* root) } const auto id = root->GetId(); - + for (const auto& pair : m_Inventories) { const auto items = pair.second->GetItems(); @@ -1581,7 +1584,7 @@ bool InventoryComponent::IsParentValid(Item* root) void InventoryComponent::CheckProxyIntegrity() { std::vector dead; - + for (const auto& pair : m_Inventories) { const auto& items = pair.second->GetItems(); @@ -1596,7 +1599,7 @@ void InventoryComponent::CheckProxyIntegrity() { continue; } - + if (IsValidProxy(parent)) { continue; @@ -1621,7 +1624,7 @@ void InventoryComponent::CheckProxyIntegrity() for (const auto& candidate : items) { auto* item = candidate.second; - + const auto parent = item->GetParent(); if (parent != LWOOBJID_EMPTY) @@ -1653,7 +1656,7 @@ void InventoryComponent::CheckProxyIntegrity() void InventoryComponent::PurgeProxies(Item* item) { const auto root = item->GetParent(); - + if (root != LWOOBJID_EMPTY) { item = FindItemById(root); @@ -1662,7 +1665,7 @@ void InventoryComponent::PurgeProxies(Item* item) { UnEquipItem(item); } - + return; } @@ -1676,7 +1679,7 @@ void InventoryComponent::PurgeProxies(Item* item) } } -void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) +void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) { auto* petInventoryElement = document->FirstChildElement("obj")->FirstChildElement("pet"); @@ -1694,7 +1697,7 @@ void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) LWOOBJID id; LOT lot; int32_t moderationStatus; - + petElement->QueryAttribute("id", &id); petElement->QueryAttribute("l", &lot); petElement->QueryAttribute("m", &moderationStatus); @@ -1711,7 +1714,7 @@ void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) } } -void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document) +void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document) { auto* petInventoryElement = document->FirstChildElement("obj")->FirstChildElement("pet"); @@ -1733,8 +1736,7 @@ void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document) petElement->SetAttribute("m", pet.second.moderationState); petElement->SetAttribute("n", pet.second.name.c_str()); petElement->SetAttribute("t", 0); - + petInventoryElement->LinkEndChild(petElement); } } - diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index 5945394b..1b809f48 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -450,8 +450,11 @@ const std::vector& MissionComponent::QueryAchievements(MissionTaskType } bool MissionComponent::RequiresItem(const LOT lot) { - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT type FROM Objects WHERE id = %d;", lot); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT type FROM Objects WHERE id = ?;"); + query.bind(1, (int) lot); + + auto result = query.execQuery(); if (result.eof()) { return false; diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 8c51791a..b31cd35f 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -167,9 +167,11 @@ void PetComponent::OnUse(Entity* originator) std::string buildFile; if (cached == buildCache.end()) { - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = %d;", - m_Parent->GetLOT()); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = ?;"); + query.bind(1, (int) m_Parent->GetLOT()); + + auto result = query.execQuery(); if (result.eof()) { diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 543f99a2..d685e8e9 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -40,9 +40,11 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT id FROM PropertyTemplate WHERE mapID = %d;", - (int) zoneId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT id FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); + + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { @@ -96,9 +98,11 @@ std::vector PropertyManagementComponent::GetPaths() const { const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT path FROM PropertyTemplate WHERE mapID = %u;", - zoneId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT path FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); + + auto result = query.execQuery(); std::vector paths {}; diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index b4787d40..faec4ab6 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -199,9 +199,13 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e } const std::string effectType_str = GeneralUtils::UTF16ToWTF8(effectType); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = %d AND effectType = %Q);", - effectId, effectType_str.c_str()); + + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = ? AND effectType = ?);"); + query.bind(1, effectId); + query.bind(2, effectType_str.c_str()); + + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { result.finalize(); diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index a117fffc..507c75cb 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -18,10 +18,12 @@ #include "PacketUtils.h" RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) { - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = %d;", - rocketId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = ?;"); + query.bind(1, rocketId); + auto result = query.execQuery(); + if (!result.eof() && !result.fieldIsNull(0)) { m_TargetZone = result.getIntField(0); diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 4396c669..b5896d16 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -86,9 +86,11 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B const auto sync_entry = this->m_managedProjectiles.at(index); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = %d);", - sync_entry.lot); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); + query.bind(1, (int) sync_entry.lot); + + auto result = query.execQuery(); if (result.eof()) { Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", sync_entry.lot); @@ -434,9 +436,10 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) return; } - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = %d);", - entry.lot); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); + query.bind(1, (int) entry.lot); + auto result = query.execQuery(); if (result.eof()) { Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", entry.lot); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 0e30244b..5b6b8a8c 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2509,9 +2509,11 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT id FROM PropertyTemplate WHERE mapID = %d;", - (int) zoneId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT id FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); + + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { return; diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 92a208cb..77256a20 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -386,9 +386,11 @@ void Item::DisassembleModel() const auto componentId = table->GetByIDAndType(GetLot(), COMPONENT_TYPE_RENDER); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT render_asset FROM RenderComponent WHERE id = %d;", - componentId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT render_asset FROM RenderComponent WHERE id = ?;"); + query.bind(1, (int) componentId); + + auto result = query.execQuery(); if (result.eof()) { diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index 93e86a81..70b77a70 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -15,9 +15,11 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) this->m_PassiveAbilities = ItemSetPassiveAbility::FindAbilities(id, m_InventoryComponent->GetParent(), this); - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = %u;", - id); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = ?;"); + query.bind(1, (int) id); + + auto result = query.execQuery(); if (result.eof()) { @@ -31,9 +33,11 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) continue; } - auto skillResult = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = %d;", - result.getIntField(i)); + auto skillQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = ?;"); + skillQuery.bind(1, result.getIntField(i)); + + auto skillResult = skillQuery.execQuery(); if (skillResult.eof()) { diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index 5b68685c..da149498 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -16,9 +16,11 @@ std::map Preconditions::cache = {}; Precondition::Precondition(const uint32_t condition) { - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = %u;", - condition); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = ?;"); + query.bind(1, (int) condition); + + auto result = query.execQuery(); if (result.eof()) { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index fa601946..feb85d1a 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1243,11 +1243,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { - std::string query = "%" + args[0] + "%"; - const char* query_cstr = query.c_str(); - auto tables = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE %Q OR `name` LIKE %Q OR `description` LIKE %Q LIMIT 50", - query_cstr, query_cstr, query_cstr); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); + + const std::string query_text = "%" + args[0] + "%"; + query.bind(1, query_text.c_str()); + + auto tables = query.execQuery(); while (!tables.eof()) { std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index ce3774e9..1c7f42a7 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -1059,9 +1059,11 @@ void HandlePacket(Packet* packet) { const auto zoneId = Game::server->GetZoneID(); const auto cloneId = g_CloneID; - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT id FROM PropertyTemplate WHERE mapID = %u;", - zoneId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT id FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); + + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { Game::logger->Log("WorldServer", "No property templates found for zone %d, not sending BBB\n", zoneId); diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 6ed6c719..181d8310 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -26,9 +26,11 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { LOT zoneControlTemplate = 2365; - auto result = CDClientDatabase::ExecuteQueryWithArgs( - "SELECT zoneControlTemplate, ghostdistance_min, ghostdistance FROM ZoneTable WHERE zoneID = %d;", - (int) zoneID.GetMapID()); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT zoneControlTemplate, ghostdistance_min, ghostdistance FROM ZoneTable WHERE zoneID = ?;"); + query.bind(1, (int) zoneID.GetMapID()); + + auto result = query.execQuery(); if (!result.eof()) { zoneControlTemplate = result.getIntField("zoneControlTemplate", 2365); From 4ff84e073060f8bebacb07a711a01e5a65f45abc Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Sat, 15 Jan 2022 13:37:43 -0500 Subject: [PATCH 08/98] Fix whitespace --- dDatabase/Tables/CDBehaviorParameterTable.cpp | 36 +++++++++---------- dGame/dBehaviors/Behavior.cpp | 8 ++--- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index 3087ba6d..6044a858 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -4,19 +4,19 @@ //! Constructor CDBehaviorParameterTable::CDBehaviorParameterTable(void) { #ifdef CDCLIENT_CACHE_ALL - auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); - while (!tableData.eof()) { - CDBehaviorParameter entry; - entry.behaviorID = tableData.getIntField(0, -1); - entry.parameterID = tableData.getStringField(1, ""); - entry.value = tableData.getFloatField(2, -1.0f); + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); + while (!tableData.eof()) { + CDBehaviorParameter entry; + entry.behaviorID = tableData.getIntField(0, -1); + entry.parameterID = tableData.getStringField(1, ""); + entry.value = tableData.getFloatField(2, -1.0f); //Check if we have an entry with this ID: auto it = m_entries.find(entry.behaviorID); if (it != m_entries.end()) { it->second.insert(std::make_pair(entry.parameterID, entry.value)); } - else { + else { //Otherwise, insert it: m_entries.insert(std::make_pair(entry.behaviorID, std::map())); auto jit = m_entries.find(entry.behaviorID); @@ -25,8 +25,8 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { jit->second.insert(std::make_pair(entry.parameterID, entry.value)); } - tableData.nextRow(); - } + tableData.nextRow(); + } tableData.finalize(); #endif @@ -37,10 +37,10 @@ CDBehaviorParameterTable::~CDBehaviorParameterTable(void) { } //! Returns the table's name std::string CDBehaviorParameterTable::GetName(void) const { - return "BehaviorParameter"; + return "BehaviorParameter"; } -float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name) +float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name) { size_t hash = 0; GeneralUtils::hash_combine(hash, behaviorID); @@ -60,16 +60,16 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s #ifndef CDCLIENT_CACHE_ALL auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); - query.bind(1, (int) behaviorID); + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorID); auto tableData = query.execQuery(); m_Entries.insert_or_assign(behaviorID, 0); - + while (!tableData.eof()) { - const std::string parameterID = tableData.getStringField(0, ""); - const float value = tableData.getFloatField(1, 0); + const std::string parameterID = tableData.getStringField(0, ""); + const float value = tableData.getFloatField(1, 0); size_t parameterHash = 0; GeneralUtils::hash_combine(parameterHash, behaviorID); @@ -77,8 +77,8 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s m_Entries.insert_or_assign(parameterHash, value); - tableData.nextRow(); - } + tableData.nextRow(); + } const auto& it2 = m_Entries.find(hash); if (it2 != m_Entries.end()) { diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 351a4ada..1f666c05 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -276,11 +276,11 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) } BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { - auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;"); - query.bind(1, (int) behaviorId); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorId); - auto result = query.execQuery(); + auto result = query.execQuery(); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) From 9dfa401b27d2bdd81ec0ad4f67057556f658977e Mon Sep 17 00:00:00 2001 From: TheMatt2 Date: Sat, 15 Jan 2022 14:02:14 -0500 Subject: [PATCH 09/98] Fix whitespace Convert to tabs and remove trailing whitespace --- dGame/dBehaviors/Behavior.cpp | 10 ++-- dGame/dComponents/DestroyableComponent.cpp | 60 +++++++++---------- .../RocketLaunchpadControlComponent.cpp | 20 +++---- dGame/dComponents/SkillComponent.cpp | 50 ++++++++-------- dGame/dInventory/ItemSet.cpp | 28 ++++----- dGame/dUtilities/Preconditions.cpp | 20 +++---- dGame/dUtilities/SlashCommandHandler.cpp | 6 +- dZoneManager/dZoneManager.cpp | 22 +++---- 8 files changed, 108 insertions(+), 108 deletions(-) diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 1f666c05..668329b1 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -185,8 +185,8 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) break; case BehaviorTemplates::BEHAVIOR_JETPACK: break; case BehaviorTemplates::BEHAVIOR_SKILL_EVENT: - behavior = new SkillEventBehavior(behaviorId); - break; + behavior = new SkillEventBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_CONSUME_ITEM: break; case BehaviorTemplates::BEHAVIOR_SKILL_CAST_FAILED: behavior = new SkillCastFailedBehavior(behaviorId); @@ -414,11 +414,11 @@ Behavior::Behavior(const uint32_t behaviorId) this->m_templateId = BehaviorTemplates::BEHAVIOR_EMPTY; } - auto query = CDClientDatabase::CreatePreppedStmt( + auto query = CDClientDatabase::CreatePreppedStmt( "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = ?;"); query.bind(1, (int) behaviorId); - auto result = query.execQuery(); + auto result = query.execQuery(); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -493,7 +493,7 @@ std::map Behavior::GetParameterNames() const auto query = CDClientDatabase::CreatePreppedStmt( "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); - query.bind(1, (int) this->m_behaviorId); + query.bind(1, (int) this->m_behaviorId); auto tableData = query.execQuery(); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 1afd4b58..ed12a439 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -105,7 +105,7 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write0(); //Contains info about immunities this object has, but it's left out for now. } - outBitStream->Write(m_DirtyHealth || bIsInitialUpdate); + outBitStream->Write(m_DirtyHealth || bIsInitialUpdate); if (m_DirtyHealth || bIsInitialUpdate) { outBitStream->Write(m_iHealth); outBitStream->Write(m_fMaxHealth); @@ -113,12 +113,12 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_fMaxArmor); outBitStream->Write(m_iImagination); outBitStream->Write(m_fMaxImagination); - + outBitStream->Write(m_DamageToAbsorb); outBitStream->Write(IsImmune()); outBitStream->Write(m_IsGMImmune); outBitStream->Write(m_IsShielded); - + outBitStream->Write(m_fMaxHealth); outBitStream->Write(m_fMaxArmor); outBitStream->Write(m_fMaxImagination); @@ -129,14 +129,14 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn } outBitStream->Write(m_IsSmashable); - + if (bIsInitialUpdate) { outBitStream->Write(m_IsDead); outBitStream->Write(m_IsSmashed); - + if (m_IsSmashable) { outBitStream->Write(m_HasBricks); - + if (m_ExplodeFactor != 1.0f) { outBitStream->Write1(); outBitStream->Write(m_ExplodeFactor); @@ -145,10 +145,10 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn } } } - + m_DirtyHealth = false; } - + if (m_DirtyThreatList || bIsInitialUpdate) { outBitStream->Write1(); outBitStream->Write(m_HasThreats); @@ -166,7 +166,7 @@ void DestroyableComponent::LoadFromXML(tinyxml2::XMLDocument* doc) { } auto* buffComponent = m_Parent->GetComponent(); - + if (buffComponent != nullptr) { buffComponent->LoadFromXML(doc); } @@ -186,9 +186,9 @@ void DestroyableComponent::UpdateXml(tinyxml2::XMLDocument* doc) { Game::logger->Log("DestroyableComponent", "Failed to find dest tag!\n"); return; } - + auto* buffComponent = m_Parent->GetComponent(); - + if (buffComponent != nullptr) { buffComponent->UpdateXml(doc); } @@ -233,7 +233,7 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - + delete amount; delete type; } @@ -279,7 +279,7 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - + delete amount; delete type; } @@ -325,7 +325,7 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - + delete amount; delete type; } @@ -340,7 +340,7 @@ void DestroyableComponent::SetDamageToAbsorb(int32_t value) m_DamageToAbsorb = value; } -void DestroyableComponent::SetDamageReduction(int32_t value) +void DestroyableComponent::SetDamageReduction(int32_t value) { m_DirtyHealth = true; m_DamageReduction = value; @@ -352,7 +352,7 @@ void DestroyableComponent::SetIsImmune(bool value) m_ImmuneStacks = value ? 1 : 0; } -void DestroyableComponent::SetIsGMImmune(bool value) +void DestroyableComponent::SetIsGMImmune(bool value) { m_DirtyHealth = true; m_IsGMImmune = value; @@ -375,7 +375,7 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore auto query = CDClientDatabase::CreatePreppedStmt( "SELECT enemyList FROM Factions WHERE faction = ?;"); - query.bind(1, (int) factionID); + query.bind(1, (int) factionID); auto result = query.execQuery(); @@ -387,10 +387,10 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore std::stringstream ss(list_string); std::string token; - + while (std::getline(ss, token, ',')) { if (token.empty()) continue; - + auto id = std::stoi(token); auto exclude = std::find(m_FactionIDs.begin(), m_FactionIDs.end(), id) != m_FactionIDs.end(); @@ -404,7 +404,7 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore { continue; } - + AddEnemyFaction(id); } @@ -521,7 +521,7 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor if (quickbuild != nullptr) { const auto state = quickbuild->GetState(); - + if (state != REBUILD_COMPLETED) { return false; @@ -568,7 +568,7 @@ void DestroyableComponent::Imagine(const int32_t deltaImagination) { auto current = static_cast(GetImagination()); const auto max = static_cast(GetMaxImagination()); - + current += deltaImagination; current = std::min(current, max); @@ -641,7 +641,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, bool e damage -= absorbDamage; absorb -= absorbDamage; - + const auto armorDamage = std::min(damage, armor); damage -= armorDamage; @@ -663,7 +663,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, bool e { EntityManager::Instance()->SerializeEntity(m_Parent); } - + auto* attacker = EntityManager::Instance()->GetEntity(source); m_Parent->OnHit(attacker); m_Parent->OnHitOrHealResult(attacker, sourceDamage); @@ -741,7 +741,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } } - + const auto isPlayer = m_Parent->IsPlayer(); GameMessages::SendDie( @@ -783,14 +783,14 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType auto* member = EntityManager::Instance()->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); if (member == nullptr) continue; - LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); + LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); } } } @@ -821,7 +821,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } coinsTotal -= coinsToLoose; - + LootGenerator::Instance().DropLoot(m_Parent, m_Parent, -1, coinsToLoose, coinsToLoose); } @@ -862,7 +862,7 @@ void DestroyableComponent::PopImmunity(int32_t stacks) m_ImmuneStacks -= stacks; } -void DestroyableComponent::FixStats() +void DestroyableComponent::FixStats() { auto* entity = GetParent(); @@ -920,7 +920,7 @@ void DestroyableComponent::FixStats() // Add the stats const auto& info = mission->GetClientInfo(); - + maxHealth += info.reward_maxhealth; maxImagination += info.reward_maximagination; } diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 507c75cb..2a4c138e 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -19,11 +19,11 @@ RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) { auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = ?;"); + "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = ?;"); query.bind(1, rocketId); auto result = query.execQuery(); - + if (!result.eof() && !result.fieldIsNull(0)) { m_TargetZone = result.getIntField(0); @@ -59,7 +59,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option { return; } - + TellMasterToPrepZone(zone); // This also gets triggered by a proximity monitor + item equip, I will set that up when havok is ready @@ -80,7 +80,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option { rocket = inventoryComponent->FindItemById(optionalRocketID); } - + if (rocket == nullptr) { rocket = inventoryComponent->FindItemById(characterComponent->GetLastRocketItemID()); @@ -131,7 +131,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option } } } - + // Store the last used rocket item's ID characterComponent->SetLastRocketItemID(rocket->GetId()); @@ -140,13 +140,13 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option character->SaveXMLToDatabase(); SetSelectedMapId(originator->GetObjectID(), zone); - + GameMessages::SendFireEventClientSide(m_Parent->GetObjectID(), originator->GetSystemAddress(), u"RocketEquipped", rocket->GetId(), cloneId, -1, originator->GetObjectID()); rocket->Equip(true); - + GameMessages::SendChangeObjectWorldState(rocket->GetId(), WORLDSTATE_ATTACHED, UNASSIGNED_SYSTEM_ADDRESS); - + EntityManager::Instance()->SerializeEntity(originator); } @@ -167,7 +167,7 @@ void RocketLaunchpadControlComponent::OnProximityUpdate(Entity* entering, std::s // Proximity rockets are handled by item equipment } -void RocketLaunchpadControlComponent::SetSelectedMapId(LWOOBJID player, LWOMAPID mapID) +void RocketLaunchpadControlComponent::SetSelectedMapId(LWOOBJID player, LWOMAPID mapID) { m_SelectedMapIds[player] = mapID; } @@ -181,7 +181,7 @@ LWOMAPID RocketLaunchpadControlComponent::GetSelectedMapId(LWOOBJID player) cons return index->second; } -void RocketLaunchpadControlComponent::SetSelectedCloneId(LWOOBJID player, LWOCLONEID cloneId) +void RocketLaunchpadControlComponent::SetSelectedCloneId(LWOOBJID player, LWOCLONEID cloneId) { m_SelectedCloneIds[player] = cloneId; } diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index b5896d16..7e8b20e3 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -36,11 +36,11 @@ bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t s auto* behavior = Behavior::CreateBehavior(behaviorId); const auto branch = BehaviorBranchContext(target, 0); - + behavior->Handle(context, bitStream, branch); context->ExecuteUpdates(); - + return !context->failed; } @@ -76,11 +76,11 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B break; } } - + if (index == -1) { Game::logger->Log("SkillComponent", "Failed to find projectile id (%llu)!\n", projectileId); - + return; } @@ -88,7 +88,7 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B auto query = CDClientDatabase::CreatePreppedStmt( "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); - query.bind(1, (int) sync_entry.lot); + query.bind(1, (int) sync_entry.lot); auto result = query.execQuery(); @@ -112,7 +112,7 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B { branch.target = target; } - + behavior->Handle(sync_entry.context, bitStream, branch); this->m_managedProjectiles.erase(this->m_managedProjectiles.begin() + index); @@ -126,7 +126,7 @@ void SkillComponent::RegisterPlayerProjectile(const LWOOBJID projectileId, Behav entry.branchContext = branch; entry.lot = lot; entry.id = projectileId; - + this->m_managedProjectiles.push_back(entry); } @@ -138,7 +138,7 @@ void SkillComponent::Update(const float deltaTime) } std::map keep {}; - + for (const auto& pair : this->m_managedBehaviors) { auto* context = pair.second; @@ -147,7 +147,7 @@ void SkillComponent::Update(const float deltaTime) { continue; } - + if (context->clientInitalized) { context->CalculateUpdate(deltaTime); @@ -161,7 +161,7 @@ void SkillComponent::Update(const float deltaTime) if (context->syncEntries.empty() && context->timerEntries.empty()) { auto any = false; - + for (const auto& projectile : this->m_managedProjectiles) { if (projectile.context == context) @@ -177,13 +177,13 @@ void SkillComponent::Update(const float deltaTime) context->Reset(); delete context; - + context = nullptr; continue; } } - + keep.insert_or_assign(pair.first, context); } @@ -251,9 +251,9 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c context->caster = m_Parent->GetObjectID(); context->clientInitalized = clientInitalized; - + context->foundTarget = target != LWOOBJID_EMPTY || ignoreTarget || clientInitalized; - + behavior->Calculate(context, bitStream, { target, 0}); for (auto* script : CppScripts::GetEntityScripts(m_Parent)) { @@ -275,7 +275,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c { // Echo start skill GameMessages::EchoStartSkill start; - + start.iCastType = 0; start.skillID = skillId; start.uiSkillHandle = context->skillUId; @@ -350,7 +350,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) const auto targetPosition = target->GetPosition(); const auto closestPoint = Vector3::ClosestPointOnLine(entry.lastPosition, position, targetPosition); - + const auto distance = Vector3::DistanceSquared(targetPosition, closestPoint); if (distance > 3 * 3) @@ -396,12 +396,12 @@ void SkillComponent::CalculateUpdate(const float deltaTime) } entry.lastPosition = position; - + managedProjectile = entry; } - + std::vector valid; - + for (auto& entry : this->m_managedProjectiles) { if (entry.calculation) @@ -409,7 +409,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) if (entry.time >= entry.maxTime) { entry.branchContext.target = LWOOBJID_EMPTY; - + SyncProjectileCalculation(entry); continue; @@ -450,13 +450,13 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) const auto behaviorId = static_cast(result.getIntField(0)); result.finalize(); - + auto* behavior = Behavior::CreateBehavior(behaviorId); auto* bitStream = new RakNet::BitStream(); behavior->Calculate(entry.context, bitStream, entry.branchContext); - + GameMessages::DoClientProjectileImpact projectileImpact; projectileImpact.sBitStream.assign((char*) bitStream->GetData(), bitStream->GetNumberOfBytesUsed()); @@ -492,19 +492,19 @@ void SkillComponent::HandleUnmanaged(const uint32_t behaviorId, const LWOOBJID t delete bitStream; - delete context; + delete context; } void SkillComponent::HandleUnCast(const uint32_t behaviorId, const LWOOBJID target) { auto* context = new BehaviorContext(target); - + context->caster = target; auto* behavior = Behavior::CreateBehavior(behaviorId); behavior->UnCast(context, { target }); - + delete context; } diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index 70b77a70..feddd757 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -25,7 +25,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) { return; } - + for (auto i = 0; i < 5; ++i) { if (result.fieldIsNull(i)) @@ -35,7 +35,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) auto skillQuery = CDClientDatabase::CreatePreppedStmt( "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = ?;"); - skillQuery.bind(1, result.getIntField(i)); + skillQuery.bind(1, result.getIntField(i)); auto skillResult = skillQuery.execQuery(); @@ -49,10 +49,10 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) if (skillResult.fieldIsNull(0)) { skillResult.nextRow(); - + continue; } - + const auto skillId = skillResult.getIntField(0); switch (i) @@ -75,7 +75,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) default: break; } - + skillResult.nextRow(); } } @@ -83,7 +83,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) std::string ids = result.getStringField(5); ids.erase(std::remove_if(ids.begin(), ids.end(), ::isspace), ids.end()); - + std::istringstream stream(ids); std::string token; @@ -99,9 +99,9 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) m_Items.push_back(value); } } - + m_Equipped = {}; - + for (const auto item : m_Items) { if (inventoryComponent->IsEquipped(item)) @@ -141,11 +141,11 @@ void ItemSet::OnEquip(const LOT lot) auto* skillComponent = m_InventoryComponent->GetParent()->GetComponent(); auto* missionComponent = m_InventoryComponent->GetParent()->GetComponent(); - + for (const auto skill : skillSet) { auto* skillTable = CDClientManager::Instance()->GetTable("SkillBehavior"); - + const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID; missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, skill); @@ -167,11 +167,11 @@ void ItemSet::OnUnEquip(const LOT lot) { return; } - + const auto& skillSet = GetSkillSet(m_Equipped.size()); m_Equipped.erase(index); - + if (skillSet.empty()) { return; @@ -199,7 +199,7 @@ uint32_t ItemSet::GetID() const return m_ID; } -void ItemSet::Update(float deltaTime) +void ItemSet::Update(float deltaTime) { for (auto& passiveAbility : m_PassiveAbilities) { @@ -207,7 +207,7 @@ void ItemSet::Update(float deltaTime) } } -void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger) +void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger) { for (auto& passiveAbility : m_PassiveAbilities) { diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index da149498..6921343b 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -16,18 +16,18 @@ std::map Preconditions::cache = {}; Precondition::Precondition(const uint32_t condition) { - auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = ?;"); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = ?;"); query.bind(1, (int) condition); - auto result = query.execQuery(); + auto result = query.execQuery(); if (result.eof()) { this->type = PreconditionType::ItemEquipped; this->count = 1; this->values = { 0 }; - + Game::logger->Log("Precondition", "Failed to find precondition of id (%i)!\n", condition); return; @@ -98,11 +98,11 @@ bool Precondition::Check(Entity* player, bool evaluateCosts) const } auto passedAny = false; - + for (const auto value : values) { const auto passed = CheckValue(player, value, evaluateCosts); - + if (passed && any) { return true; @@ -221,7 +221,7 @@ PreconditionExpression::PreconditionExpression(const std::string& conditions) return; } - + std::stringstream a; std::stringstream b; @@ -309,16 +309,16 @@ bool PreconditionExpression::Check(Entity* player, bool evaluateCosts) const { return true; } - + const auto a = Preconditions::Check(player, condition, evaluateCosts); if (!a) { GameMessages::SendNotifyClientFailedPrecondition(player->GetObjectID(), player->GetSystemAddress(), u"", condition); } - + const auto b = next == nullptr ? true : next->Check(player); - + return m_or ? a || b : a && b; } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index feb85d1a..966b80eb 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1242,12 +1242,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); + "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); const std::string query_text = "%" + args[0] + "%"; - query.bind(1, query_text.c_str()); + query.bind(1, query_text.c_str()); auto tables = query.execQuery(); diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 181d8310..70dcec90 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -16,7 +16,7 @@ dZoneManager* dZoneManager::m_Address = nullptr; void dZoneManager::Initialize(const LWOZONEID& zoneID) { Game::logger->Log("dZoneManager", "Preparing zone: %i/%i/%i\n", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID()); - + int64_t startTime = 0; int64_t endTime = 0; @@ -27,7 +27,7 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { LOT zoneControlTemplate = 2365; auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT zoneControlTemplate, ghostdistance_min, ghostdistance FROM ZoneTable WHERE zoneID = ?;"); + "SELECT zoneControlTemplate, ghostdistance_min, ghostdistance FROM ZoneTable WHERE zoneID = ?;"); query.bind(1, (int) zoneID.GetMapID()); auto result = query.execQuery(); @@ -54,7 +54,7 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { m_pZone->Initalize(); endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); - + Game::logger->Log("dZoneManager", "Zone prepared in: %llu ms\n", (endTime - startTime)); VanityUtilities::SpawnVanity(); @@ -62,13 +62,13 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { dZoneManager::~dZoneManager() { if (m_pZone) delete m_pZone; - + for (std::pair p : m_Spawners) { if (p.second) { delete p.second; p.second = nullptr; } - + m_Spawners.erase(p.first); } } @@ -130,7 +130,7 @@ void dZoneManager::Update(float deltaTime) { LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) { auto objectId = info.spawnerID; - + if (objectId == LWOOBJID_EMPTY) { objectId = ObjectIDManager::Instance()->GenerateObjectID(); @@ -139,18 +139,18 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) info.spawnerID = objectId; } - + auto* spawner = new Spawner(info); EntityInfo entityInfo{}; entityInfo.id = objectId; entityInfo.lot = 176; - + auto* entity = EntityManager::Instance()->CreateEntity(entityInfo, nullptr, nullptr, false, objectId); EntityManager::Instance()->ConstructEntity(entity); - + AddSpawner(objectId, spawner); return objectId; @@ -203,9 +203,9 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) spawner->Deactivate(); Game::logger->Log("dZoneManager", "Destroying spawner (%llu)\n", id); - + m_Spawners.erase(id); - + delete spawner; } From 81af1f382ed34d0f095e8453a3e1fd18a50244e5 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Tue, 17 May 2022 10:18:50 -0500 Subject: [PATCH 10/98] get zones from settings --- .../dComponents/RocketLaunchLupComponent.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/dGame/dComponents/RocketLaunchLupComponent.cpp b/dGame/dComponents/RocketLaunchLupComponent.cpp index fa2a5b16..1c5f71c0 100644 --- a/dGame/dComponents/RocketLaunchLupComponent.cpp +++ b/dGame/dComponents/RocketLaunchLupComponent.cpp @@ -6,16 +6,13 @@ RocketLaunchLupComponent::RocketLaunchLupComponent(Entity* parent) : Component(parent) { m_Parent = parent; - - // get the lup worlds from the cdclient - std::string query = "SELECT * FROM LUPZoneIDs;"; - auto results = CDClientDatabase::ExecuteQuery(query); - while (!results.eof()) { - // fallback to 1600 incase there is an issue - m_LUPWorlds.push_back(results.getIntField(0, 1600)); - results.nextRow(); + std::string zoneString = GeneralUtils::UTF16ToWTF8(m_Parent->GetVar(u"MultiZoneIDs")); + std::stringstream ss(zoneString); + for (int i; ss >> i;) { + m_LUPWorlds.push_back(i); + if (ss.peek() == ';') + ss.ignore(); } - results.finalize(); } RocketLaunchLupComponent::~RocketLaunchLupComponent() {} @@ -29,11 +26,7 @@ void RocketLaunchLupComponent::OnUse(Entity* originator) { } void RocketLaunchLupComponent::OnSelectWorld(Entity* originator, uint32_t index) { - // Add one to index because the actual LUP worlds start at index 1. - index++; - auto* rocketLaunchpadControlComponent = m_Parent->GetComponent(); - if (!rocketLaunchpadControlComponent) return; rocketLaunchpadControlComponent->Launch(originator, m_LUPWorlds[index], 0); From ca55fccb27722eaf50e8572f300846f5c03e7b14 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Tue, 17 May 2022 10:20:36 -0500 Subject: [PATCH 11/98] remove cdclient include --- dGame/dComponents/RocketLaunchLupComponent.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dGame/dComponents/RocketLaunchLupComponent.cpp b/dGame/dComponents/RocketLaunchLupComponent.cpp index 1c5f71c0..3c326540 100644 --- a/dGame/dComponents/RocketLaunchLupComponent.cpp +++ b/dGame/dComponents/RocketLaunchLupComponent.cpp @@ -1,5 +1,4 @@ #include "RocketLaunchLupComponent.h" -#include "CDClientDatabase.h" #include "RocketLaunchpadControlComponent.h" #include "InventoryComponent.h" #include "CharacterComponent.h" From 729e79eadbff2fd9bb73d0573573526face9c73a Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Tue, 17 May 2022 19:12:43 -0500 Subject: [PATCH 12/98] resolves #556 --- dScripts/ActMine.cpp | 53 +++++++++++++++++++++++++++++++++++++++++ dScripts/ActMine.h | 18 ++++++++++++++ dScripts/CppScripts.cpp | 3 +++ 3 files changed, 74 insertions(+) create mode 100644 dScripts/ActMine.cpp create mode 100644 dScripts/ActMine.h diff --git a/dScripts/ActMine.cpp b/dScripts/ActMine.cpp new file mode 100644 index 00000000..9cc116b1 --- /dev/null +++ b/dScripts/ActMine.cpp @@ -0,0 +1,53 @@ +#include "ActMine.h" +#include "SkillComponent.h" +#include "DestroyableComponent.h" +#include "RebuildComponent.h" + +void ActMine::OnStartup(Entity* self) { + self->SetVar(u"RebuildComplete", false); + self->SetProximityRadius(MINE_RADIUS, "mineRadius"); +} + +void ActMine::OnRebuildNotifyState(Entity* self, eRebuildState state) +{ + if (state == eRebuildState::REBUILD_COMPLETED) { + auto* rebuild = self->GetComponent(); + if (rebuild) { + auto* builder = rebuild->GetBuilder(); + self->SetVar(u"Builder", builder->GetObjectID()); + } + + self->SetVar(u"RebuildComplete", true); + self->SetVar(u"NumWarnings", 0); + self->AddToGroup("reset"); + } + +} + +void ActMine::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { + auto* detroyable = self->GetComponent(); + if (!detroyable) return; + if (status == "ENTER" && self->GetVar(u"RebuildComplete") == true && detroyable->IsEnemy(entering)) { + GameMessages::SendPlayFXEffect(self->GetObjectID(), 242, u"orange", "sirenlight_B"); + self->AddTimer("Tick", TICK_TIME); + } +} + +void ActMine::OnTimerDone(Entity* self, std::string timerName) { + if (timerName == "Tick") { + if (self->GetVar(u"NumWarnings") >= MAX_WARNINGS){ + auto* skill = self->GetComponent(); + if (!skill) return; + skill->CalculateBehavior(SKILL_ID, BEHAVIOR_ID, LWOOBJID_EMPTY); + self->AddTimer("BlowedUp", BLOWED_UP_TIME); + } else { + GameMessages::SendPlayFXEffect(self->GetObjectID(), 242, u"orange", "sirenlight_B"); + self->AddTimer("Tick", TICK_TIME); + self->SetVar(u"NumWarnings", self->GetVar(u"NumWarnings") + 1); + } + } + + if (timerName == "BlowedUp") { + self->Kill(self); + } +} \ No newline at end of file diff --git a/dScripts/ActMine.h b/dScripts/ActMine.h new file mode 100644 index 00000000..85efadcc --- /dev/null +++ b/dScripts/ActMine.h @@ -0,0 +1,18 @@ +#pragma once +#include "CppScripts.h" + +class ActMine : public CppScripts::Script { + public: + void OnStartup(Entity* self); + void OnRebuildNotifyState(Entity* self, eRebuildState state) override; + void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status); + void OnTimerDone(Entity* self, std::string timerName); + private: + int MAX_WARNINGS = 3; + float MINE_RADIUS = 10.0; + float TICK_TIME = 0.25; + float BLOWED_UP_TIME = 0.1; + uint32_t SKILL_ID = 317; + uint32_t BEHAVIOR_ID = 3719; +}; + diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 4381823a..9e402a21 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -164,6 +164,7 @@ #include "BaseFootRaceManager.h" #include "PropertyPlatform.h" #include "MailBoxServer.h" +#include "ActMine.h" // Racing Scripts #include "RaceImagineCrateServer.h" @@ -591,6 +592,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr return new VeBricksampleServer(); else if (scriptName == "scripts\\02_server\\Map\\General\\L_MAIL_BOX_SERVER.lua") script = new MailBoxServer(); + else if (scriptName == "scripts\\ai\\ACT\\L_ACT_MINE.lua") + script = new ActMine(); //Racing: else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\RACE_IMAGINE_CRATE_SERVER.lua") From 03a5aa4da0935d82dbe1a848f5d3185e647cdd59 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Tue, 17 May 2022 21:27:08 -0500 Subject: [PATCH 13/98] climbable server side settings --- dGame/dComponents/SimplePhysicsComponent.cpp | 21 ++++++++++---- dGame/dComponents/SimplePhysicsComponent.h | 29 ++++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/dGame/dComponents/SimplePhysicsComponent.cpp b/dGame/dComponents/SimplePhysicsComponent.cpp index 8a4cff4e..58bcee18 100644 --- a/dGame/dComponents/SimplePhysicsComponent.cpp +++ b/dGame/dComponents/SimplePhysicsComponent.cpp @@ -17,6 +17,17 @@ SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* par m_Position = m_Parent->GetDefaultPosition(); m_Rotation = m_Parent->GetDefaultRotation(); m_IsDirty = true; + + std::u16string climbable_type = m_Parent->GetVar(u"climbable"); + if (climbable_type == u"wall") { + SetClimbableType(CLIMBABLE_TYPE_WALL); + } else if (climbable_type == u"ladder") { + SetClimbableType(CLIMBABLE_TYPE_LADDER); + } else if (climbable_type == u"wallstick") { + SetClimbableType(CLIMBABLE_TYPE_WALL_STICK); + } else { + SetClimbableType(CLIMBABLE_TYPE_NOT); + } } SimplePhysicsComponent::~SimplePhysicsComponent() { @@ -24,10 +35,10 @@ SimplePhysicsComponent::~SimplePhysicsComponent() { void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { if (bIsInitialUpdate) { - outBitStream->Write0(); // climbable - outBitStream->Write(0); // climbableType + outBitStream->Write(m_ClimbableType > 0); + outBitStream->Write(m_ClimbableType); } - + outBitStream->Write(m_DirtyVelocity || bIsInitialUpdate); if (m_DirtyVelocity || bIsInitialUpdate) { outBitStream->Write(m_Velocity); @@ -46,7 +57,7 @@ void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIs { outBitStream->Write0(); } - + outBitStream->Write(m_IsDirty || bIsInitialUpdate); if (m_IsDirty || bIsInitialUpdate) { outBitStream->Write(m_Position.x); @@ -66,7 +77,7 @@ uint32_t SimplePhysicsComponent::GetPhysicsMotionState() const return m_PhysicsMotionState; } -void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) +void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) { m_PhysicsMotionState = value; } diff --git a/dGame/dComponents/SimplePhysicsComponent.h b/dGame/dComponents/SimplePhysicsComponent.h index 081b056b..bff84522 100644 --- a/dGame/dComponents/SimplePhysicsComponent.h +++ b/dGame/dComponents/SimplePhysicsComponent.h @@ -14,16 +14,24 @@ class Entity; +enum eClimbableType : int32_t { + CLIMBABLE_TYPE_NOT, + CLIMBABLE_TYPE_LADDER, + CLIMBABLE_TYPE_WALL, + CLIMBABLE_TYPE_WALL_STICK +}; + + /** * Component that serializes locations of entities to the client */ class SimplePhysicsComponent : public Component { public: static const uint32_t ComponentType = COMPONENT_TYPE_SIMPLE_PHYSICS; - + SimplePhysicsComponent(uint32_t componentID, Entity* parent); ~SimplePhysicsComponent() override; - + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); /** @@ -86,6 +94,18 @@ public: */ void SetPhysicsMotionState(uint32_t value); + /** + * Returns the ClimbableType of this entity + * @return the ClimbableType of this entity + */ + const eClimbableType& GetClimabbleType() { return m_ClimbableType; } + + /** + * Sets the ClimbableType of this entity + * @param value the ClimbableType to set + */ + void SetClimbableType(const eClimbableType& value) { m_ClimbableType = value; } + private: /** @@ -122,6 +142,11 @@ private: * The current physics motion state */ uint32_t m_PhysicsMotionState = 0; + + /** + * Whether or not the entity is climbable + */ + eClimbableType m_ClimbableType = CLIMBABLE_TYPE_NOT; }; #endif // SIMPLEPHYSICSCOMPONENT_H From 9169d844e2ba6593204319f236a2a58ec74018fa Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Tue, 17 May 2022 21:38:36 -0500 Subject: [PATCH 14/98] explicit set to 0 --- dGame/dComponents/SimplePhysicsComponent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dComponents/SimplePhysicsComponent.h b/dGame/dComponents/SimplePhysicsComponent.h index bff84522..6ad4cac6 100644 --- a/dGame/dComponents/SimplePhysicsComponent.h +++ b/dGame/dComponents/SimplePhysicsComponent.h @@ -15,7 +15,7 @@ class Entity; enum eClimbableType : int32_t { - CLIMBABLE_TYPE_NOT, + CLIMBABLE_TYPE_NOT = 0, CLIMBABLE_TYPE_LADDER, CLIMBABLE_TYPE_WALL, CLIMBABLE_TYPE_WALL_STICK From 813aca9d20141783750d8e77f6482379c17722d3 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Wed, 18 May 2022 06:36:21 -0500 Subject: [PATCH 15/98] resolve comments --- dGame/dComponents/SimplePhysicsComponent.cpp | 10 +++++----- dGame/dComponents/SimplePhysicsComponent.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dGame/dComponents/SimplePhysicsComponent.cpp b/dGame/dComponents/SimplePhysicsComponent.cpp index 58bcee18..8a052313 100644 --- a/dGame/dComponents/SimplePhysicsComponent.cpp +++ b/dGame/dComponents/SimplePhysicsComponent.cpp @@ -18,15 +18,15 @@ SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* par m_Rotation = m_Parent->GetDefaultRotation(); m_IsDirty = true; - std::u16string climbable_type = m_Parent->GetVar(u"climbable"); + const auto& climbable_type = m_Parent->GetVar(u"climbable"); if (climbable_type == u"wall") { - SetClimbableType(CLIMBABLE_TYPE_WALL); + SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL); } else if (climbable_type == u"ladder") { - SetClimbableType(CLIMBABLE_TYPE_LADDER); + SetClimbableType(eClimbableType::CLIMBABLE_TYPE_LADDER); } else if (climbable_type == u"wallstick") { - SetClimbableType(CLIMBABLE_TYPE_WALL_STICK); + SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL_STICK); } else { - SetClimbableType(CLIMBABLE_TYPE_NOT); + SetClimbableType(eClimbableType::CLIMBABLE_TYPE_NOT); } } diff --git a/dGame/dComponents/SimplePhysicsComponent.h b/dGame/dComponents/SimplePhysicsComponent.h index 6ad4cac6..49e6be5b 100644 --- a/dGame/dComponents/SimplePhysicsComponent.h +++ b/dGame/dComponents/SimplePhysicsComponent.h @@ -14,7 +14,7 @@ class Entity; -enum eClimbableType : int32_t { +enum class eClimbableType : int32_t { CLIMBABLE_TYPE_NOT = 0, CLIMBABLE_TYPE_LADDER, CLIMBABLE_TYPE_WALL, @@ -146,7 +146,7 @@ private: /** * Whether or not the entity is climbable */ - eClimbableType m_ClimbableType = CLIMBABLE_TYPE_NOT; + eClimbableType m_ClimbableType = eClimbableType::CLIMBABLE_TYPE_NOT; }; #endif // SIMPLEPHYSICSCOMPONENT_H From 06df15717c05ce07ded563094b70c74ade1e3a59 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Thu, 19 May 2022 08:40:50 -0500 Subject: [PATCH 16/98] maybe fix it --- dGame/dComponents/SimplePhysicsComponent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/SimplePhysicsComponent.cpp b/dGame/dComponents/SimplePhysicsComponent.cpp index 8a052313..c9a42971 100644 --- a/dGame/dComponents/SimplePhysicsComponent.cpp +++ b/dGame/dComponents/SimplePhysicsComponent.cpp @@ -35,8 +35,8 @@ SimplePhysicsComponent::~SimplePhysicsComponent() { void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { if (bIsInitialUpdate) { - outBitStream->Write(m_ClimbableType > 0); - outBitStream->Write(m_ClimbableType); + outBitStream->Write(m_ClimbableType != eClimbableType::CLIMBABLE_TYPE_NOT); + outBitStream->Write(m_ClimbableType); } outBitStream->Write(m_DirtyVelocity || bIsInitialUpdate); From cdb2cf034449767b7a18dcaa6512b806d957a582 Mon Sep 17 00:00:00 2001 From: Jasper Reddin Date: Mon, 23 May 2022 21:59:31 -0500 Subject: [PATCH 17/98] Added Comprehensive Slash Command Documentation (#402) * Added documentation for all available commands * Adjust formatting, removing backtick characters * Replace HTML tables with Markdown tables * Formatting changes * Suggestions from @sersorrel in #402 and other minor edits * Add detailed usage for /inspect (thanks to @sersorrel for this information, in discussion of #402) --- docs/Commands.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 docs/Commands.md diff --git a/docs/Commands.md b/docs/Commands.md new file mode 100644 index 00000000..4d169c76 --- /dev/null +++ b/docs/Commands.md @@ -0,0 +1,140 @@ +# In-game commands + +Here is a summary of the commands available in-game. All commands are prefixed by `/` and typed in the in-game chat window. Some commands requires admin privileges. Operands within `<>` are required, operands within `()` are not. For the full list of in-game commands, please checkout [the source file](../dGame/dUtilities/SlashCommandHandler.cpp). + +## General Commands + +|Command|Usage|Description|Admin Level Requirement| +|--- |--- |--- |--- | +|credits|`/credits`|Displays the names of the people behind Darkflame Universe.|| +|die|`/die`|Smashes the player.|| +|info|`/info`|Displays server info to the user, including where to find the server's source code.|| +|instanceinfo|`/instanceinfo`|Displays in the chat the current zone, clone, and instance id.|| +|ping|`/ping (-l)`|Displays in chat your average ping. If the `-l` flag is used, the latest ping is displayed.|| +|pvp|`/pvp`|Toggle your PVP flag.|| +|resurrect|`/resurrect`|Resurrects the player.|| +|requestmailcount|`/requestmailcount`|Sends notification with number of unread messages in the player's mailbox.|| +|skip-ags|`/skip-ags`|Skips the Avant Gardens Survival minigame mission, "Impress the Sentinel Faction".|| +|skip-sg|`/skip-sg`|Skips the Shooting Gallery minigame mission, "Monarch of the Sea".|| +|who|`/who`|Displays in chat all players on the instance.|| + +## Moderation Commands + +|Command|Usage|Description|Admin Level Requirement| +|--- |--- |--- |--- | +|gmlevel|`/gmlevel `|Within the authorized range of levels for the current account, changes the character's game master level to the specified value. This is required to use certain commands. Aliases: `/setgmlevel`, `/makegm`.|| +|kick|`/kick `|Kicks the player off the server.|2| +|mailitem|`/mailitem `|Mails an item to the given player. The mailed item has predetermined content. The sender name is set to "Darkflame Universe." The title of the message is "Lost item." The body of the message is "This is a replacement item for one you lost."|3| +|ban|`/ban `|Bans a user from the server.|4| +|approveproperty|`/approveproperty`|Approves the property the player is currently visiting.|5| +|mute|`/mute (days) (hours)`|Mute player for the given amount of time. If no time is given, the mute is indefinite.|6| +|gmimmune|`/gmimmunve `|Sets the character's GMImmune state, where value can be one of "1", to make yourself immune to damage, or "0" to undo.|8| +|gminvis|`/gminvis`|Toggles invisibility for the character, though it's currently a bit buggy. Requires nonzero GM Level for the character, but the account must have a GM level of 8.|8| +|setname|`/setname `|Sets a temporary name for your player. The name resets when you log out.|8| +|title|`/title `|Temporarily appends your player's name with " - <title>". This resets when you log out.|8| + +## Server Operation Commands + +|Command|Usage|Description|Admin Level Requirement| +|--- |--- |--- |--- | +|announce|`/announce`|Sends a announcement. `/setanntitle` and `/setannmsg` must be called first to configure the announcement.|8| +|config-set|`/config-set <key> <value>`|Set configuration item.|8| +|config-get|`/config-get <key>`|Get current value of a configuration item.|8| +|kill|`/kill <username>`|Smashes the character whom the given user is playing.|8| +|metrics|`/metrics`|Prints some information about the server's performance.|8| +|setannmsg|`/setannmsg <title>`|Sets the message of an announcement.|8| +|setanntitle|`/setanntitle <title>`|Sets the title of an announcement.|8| +|shutdownuniverse|`/shutdownuniverse`|Sends a shutdown message to the master server. This will send an announcement to all players that the universe will shut down in 10 minutes.|9| + +## Development Commands + +These commands are primarily for development and testing. The usage of many of these commands relies on knowledge of the codebase and client SQLite database. + +|Command|Usage|Description|Admin Level Requirement| +|--- |--- |--- |--- | +|fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.|| +|join|`/join <password>`|Joins a private zone with given password.|| +|leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.|| +|setminifig|`/setminifig <body part> <minifig item id>`|Alters your player's minifig. Body part can be one of "Eyebrows", "Eyes", "HairColor", "HairStyle", "Pants", "LeftHand", "Mouth", "RightHand", "Shirt", or "Hands". Changing minifig parts could break the character so this command is limited to GMs.|1| +|testmap|`/testmap <zone> (force) (clone-id)`|Transfers you to the given zone by id and clone id. Add "force" to skip checking if the zone is accessible (this can softlock your character, though, if you e.g. try to teleport to Frostburgh).|1| +|reportproxphys|`/reportproxphys`|Prints to console the position and radius of proximity sensors.|6| +|spawnphysicsverts|`/spawnphysicsverts`|Spawns a 1x1 brick at all vertices of phantom physics objects.|6| +|teleport|`/teleport <x> (y) <z>`|Teleports you. If no Y is given, you are teleported to the height of the terrain or physics object at (x, z). Alias: `/tele`.|6| +|activatespawner|`/activatespawner <spawner name>`|Activates spawner by name.|8| +|addmission|`/addmission <mission id>`|Accepts the mission, adding it to your journal.|8| +|boost|`/boost`|Adds a passive boost action if you are in a vehicle.|8| +|buff|`/buff <id> <duration>`|Applies the buff with the given id for the given number of seconds.|8| +|buffme|`/buffme`|Sets health, armor, and imagination to 999.|8| +|buffmed|`/buffmed`|Sets health, armor, and imagination to 9.|8| +|clearflag|`/clearflag <flag id>`|Removes the given health or inventory flag from your player. Equivalent of calling `/setflag off <flag id>`.|8| +|completemission|`/completemission <mission id>`|Completes the mission, removing it from your journal.|8| +|createprivate|`/createprivate <zone id> <clone id> <password>`|Creates a private zone with password.|8| +|debugui|`/debugui`|Toggle Debug UI.|8| +|dismount|`/dismount`|Dismounts you from the vehicle.|8| +|force-save|`/force-save`|While saving to database usually happens on regular intervals and when you disconnect from the server, this command saves your player's data to the database.|8| +|freecam|`/freecam`|Toggles freecam mode.|8| +|freemoney|`/freemoney <coins>`|Gives coins.|8| +|getnavmeshheight|`/getnavmeshheight`|Displays the navmesh height at your current position.|8| +|giveuscore|`/giveuscore <uscore>`|Gives uscore.|8| +|gmadditem|`/gmadditem <id> (count)`|Adds the given item to your inventory by id.|8| +|inspect|`/inspect <component> (-m <waypoint> \| -a <animation> \| -s \| -p \| -f (faction) \| -t)`|Finds the closest entity with the given component or LDF variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the the IDs of all components the entity has. See [Detailed `/inspect` Usage](#detailed-inspect-usage) below.|8| +|list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one.|8| +|locrow|`/locrow`|Prints the your current position and rotation information to the console.|8| +|lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query.|8| +|playanimation|`/playanimation <id>`|Plays animation with given ID. Alias: `/playanim`.|8| +|playeffect|`/playeffect <effect id> <effect type> <effect name>`|Plays an effect.|8| +|playlvlfx|`/playlvlfx`|Plays the level up animation on your character.|8| +|playrebuildfx|`/playrebuildfx`|Plays the quickbuild animation on your character.|8| +|pos|`/pos`|Displays your current position in chat and in the console.|8| +|refillstats|`/refillstats`|Refills health, armor, and imagination to their maximum level.|8| +|reforge|`/reforge <base item id> <reforged item id>`|Reforges an item.|8| +|resetmission|`/resetmission <mission id>`|Sets the state of the mission to accepted but not yet started.|8| +|rot|`/rot`|Displays your current rotation in chat and in the console.|8| +|runmacro|`/runmacro <macro>`|Runs any command macro found in `./res/macros/`|8| +|setcontrolscheme|`/setcontrolscheme <scheme number>`|Sets the character control scheme to the specified number.|8| +|setcurrency|`/setcurrency <coins>`|Sets your coins.|8| +|setflag|`/setflag (value) <flag id>`|Sets the given inventory or health flag to the given value, where value can be one of "on" or "off". If no value is given, by default this adds the flag to your character (equivalent of calling `/setflag on <flag id>`).|8| +|setinventorysize|`/setinventorysize <size>`|Sets your inventory size to the given size. Alias: `/setinvsize`|8| +|setuistate|`/setuistate <ui state>`|Changes UI state.|8| +|spawn|`/spawn <id>`|Spawns an object at your location by id.|8| +|speedboost|`/speedboost <amount>`|Sets the speed multiplier to the given amount. `/speedboost 1.5` will set the speed multiplier to 1.5x the normal speed.|8| +|startcelebration|`/startcelebration <id>`|Starts a celebration effect on your character.|8| +|stopeffect|`/stopeffect <effect id>`|Stops the given effect.|8| +|toggle|`/toggle <ui state>`|Toggles UI state.|8| +|tpall|`/tpall`|Teleports all characters to your current position.|8| +|triggerspawner|`/triggerspawner <spawner name>`|Triggers spawner by name.|8| +|unlock-emote|`/unlock-emote <emote id>`|Unlocks for your character the emote of the given id.|8| +|crash|`/crash`|Crashes the server.|9| +|rollloot|`/rollloot <loot matrix index> <item id> <amount>`|Rolls loot matrix.|9| + +## Detailed `/inspect` Usage + +`/inspect <component> (-m <waypoint> | -a <animation> | -s | -p | -f (faction) | -t)` + +Finds the closest entity with the given component or LDF variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the the IDs of all components the entity has. + +### `/inspect` Options + +* `-m`: If the entity has a moving platform component, sends it to the given waypoint, or stops the platform if `waypoint` is `-1`. +* `-a`: Plays the given animation on the entity. +* `-s`: Prints the entity's settings and spawner ID. +* `-p`: Prints the entity's position +* `-f`: If the entity has a destroyable component, prints whether the entity is smashable and its friendly and enemy faction IDs; if `faction` is specified, adds that faction to the entity. +* `-t`: If the entity has a phantom physics component, prints the effect type, direction, directional multiplier, and whether the effect is active; in any case, if the entity has a trigger, prints the trigger ID. + +## Game Master Levels + +There are 9 Game master levels + +|Level|Variable Name|Description| +|--- |--- |--- | +|0|GAME_MASTER_LEVEL_CIVILIAN|Normal player| +|1|GAME_MASTER_LEVEL_FORUM_MODERATOR|Forum moderator. No permissions on live servers.| +|2|GAME_MASTER_LEVEL_JUNIOR_MODERATOR|Can kick/mute and pull chat logs| +|3|GAME_MASTER_LEVEL_MODERATOR|Can return lost items| +|4|GAME_MASTER_LEVEL_SENIOR_MODERATOR|Can ban| +|5|GAME_MASTER_LEVEL_LEAD_MODERATOR|Can approve properties| +|6|GAME_MASTER_LEVEL_JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.| +|7|GAME_MASTER_LEVEL_INACTIVE_DEVELOPER|Inactive developer, limited permissions.| +|8|GAME_MASTER_LEVEL_DEVELOPER|Active developer, full permissions on live.| +|9|GAME_MASTER_LEVEL_OPERATOR|Can shutdown server for restarts & updates.| From f8d73ccbc5a3589e281ffd4027d44c564c714b7a Mon Sep 17 00:00:00 2001 From: HailStorm32 <demetriv.s.7@gmail.com> Date: Wed, 25 May 2022 02:03:40 +0000 Subject: [PATCH 18/98] Fixed display logic for NS Survival leaderboard --- dGame/LeaderboardManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 210dee92..bb8697e6 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -123,7 +123,7 @@ void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t } break; case SurvivalNS: - if (score < storedScore || time >= storedTime) + if (!(score > storedScore || (time < storedTime && score >= storedScore))) highscore = false; break; default: @@ -462,4 +462,4 @@ const std::string LeaderboardManager::standingsTimeQueryAsc = " 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;"; \ No newline at end of file +"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; From 915b779f0314c25c22ab201de99928577c27bdaf Mon Sep 17 00:00:00 2001 From: luke-sparks <49217947+luke-sparks@users.noreply.github.com> Date: Wed, 25 May 2022 10:32:18 -0700 Subject: [PATCH 19/98] Update Docker.md with buildkit and submodule notes. (#458) * Update Docker.md Add link to enabling docker buildkit. Add note to remember to clone submodules. * Remove unpacked client option Unpacked client does not have required directories/files (e.g. /versions/trunk.txt) and thus the packed client is required. * Add note about renaming CDClient.fdb DarkflameSetup will fail because it cannot find cdclient.fdb. However, CDClient.fdb exists. Renaming it fixes the issue. * Remove extra "client" --- Docker.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Docker.md b/Docker.md index ba52c39c..7d5f7bc6 100644 --- a/Docker.md +++ b/Docker.md @@ -4,7 +4,7 @@ - [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker) - [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop) -- LEGO® Universe Client (packed or unpacked). Check the main [README](./README.md) for details on this. +- LEGO® Universe packed Client. Check the main [README](./README.md) for details on this. ## Run server inside Docker @@ -21,6 +21,15 @@ **NOTE #2**: To stop the server simply run `docker compose down` and to restart it just run `docker compose up -d` again. No need to run all the steps above every time. +**NOTE #3**: Docker buildkit needs to be enabled. https://docs.docker.com/develop/develop-images/build_enhancements/#to-enable-buildkit-builds + +**NOTE #4**: Make sure to run the following in the repo root directory after cloning so submodules are also downloaded. +``` +git submodule init +git submodule update +``` +**NOTE #5**: If DarkflameSetup fails due to not having cdclient.fdb, rename CDClient.fdb (in the same folder) to cdclient.fdb + ## Disable brickbuildfix If you don't need the http server running on port 80 do this: From 445c01d485f577a4b51e208e88c402585c1763b6 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Thu, 26 May 2022 00:41:42 +0100 Subject: [PATCH 20/98] Add instructions on solving missing DLL issue (#379) * Add instructions on solving missing DLL issue * Repair formatting to be consistent --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 42848839..d6678084 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ cmake .. cmake --build . ``` +Once built you must also move all DLLs from `build/_deps/mysql-src/lib64` or else you encounter missing DLL errors ### Windows builds (WSL) This section will go through how to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) and building in a Linux environment under Windows. WSL requires Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11. From c6f871d42b4c442fdbc3b7b86e0b95fb124af877 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Fri, 27 May 2022 15:25:57 -0500 Subject: [PATCH 21/98] only make teams for minigames if we have more than one participant --- .../dComponents/ScriptedActivityComponent.cpp | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 026fafce..4d62fb0b 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -487,22 +487,24 @@ void ActivityInstance::StartZone() { return; auto* leader = participants[0]; - - CBITSTREAM; - PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_CREATE_TEAM); - - bitStream.Write(leader->GetObjectID()); - bitStream.Write(m_Participants.size()); - - for (const auto& participant : m_Participants) { - bitStream.Write(participant); - } - LWOZONEID zoneId = LWOZONEID(m_ActivityInfo.instanceMapID, 0, leader->GetCharacter()->GetPropertyCloneID()); - bitStream.Write(zoneId); + // only make a team if we have more than one participant + if (participants.size() > 1){ + CBITSTREAM; + PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_CREATE_TEAM); - Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); + bitStream.Write(leader->GetObjectID()); + bitStream.Write(m_Participants.size()); + + for (const auto& participant : m_Participants) { + bitStream.Write(participant); + } + + bitStream.Write(zoneId); + + Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); + } const auto cloneId = GeneralUtils::GenerateRandomNumber<uint32_t>(1, UINT32_MAX); for (Entity* player : participants) { From 66215da37aea515c2754a6a03ee0106b818e3a28 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Tue, 31 May 2022 00:24:55 -0500 Subject: [PATCH 22/98] Fix overrides in ActMine (#568) --- dScripts/ActMine.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dScripts/ActMine.h b/dScripts/ActMine.h index 85efadcc..ae6ef17e 100644 --- a/dScripts/ActMine.h +++ b/dScripts/ActMine.h @@ -3,10 +3,10 @@ class ActMine : public CppScripts::Script { public: - void OnStartup(Entity* self); + void OnStartup(Entity* self) override; void OnRebuildNotifyState(Entity* self, eRebuildState state) override; - void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status); - void OnTimerDone(Entity* self, std::string timerName); + void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override; + void OnTimerDone(Entity* self, std::string timerName) override; private: int MAX_WARNINGS = 3; float MINE_RADIUS = 10.0; From 33cc3a3dd9f3387e36778483122eb5391d1c9fc9 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:58:51 -0700 Subject: [PATCH 23/98] Corrected string to long conversion For Windows, the definition for a long is 32 bits, not 64 bits like on other operating systems. This caused an issue on Windows only where a number larger than 32 bits was attempted to be converted to a long, the WorldServer would crash. This commit replaces all instances of `stol` with `stoull` to further define a long and reduce ambiguity of number length. --- dCommon/LDFFormat.cpp | 2 +- dDatabase/Tables/CDItemComponentTable.cpp | 2 +- dScripts/BaseFootRaceManager.cpp | 2 +- dScripts/NjMonastryBossInstance.cpp | 2 +- dScripts/SpawnPetBaseServer.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dCommon/LDFFormat.cpp b/dCommon/LDFFormat.cpp index 13fcb5cb..8290faec 100644 --- a/dCommon/LDFFormat.cpp +++ b/dCommon/LDFFormat.cpp @@ -54,7 +54,7 @@ LDFBaseData * LDFBaseData::DataFromString(const std::string& format) { } case LDF_TYPE_S32: { - int32_t data = static_cast<int32_t>(stol(dataArray[1])); + int32_t data = static_cast<int32_t>(stoull(dataArray[1])); return new LDFData<int32_t>(key, data); } diff --git a/dDatabase/Tables/CDItemComponentTable.cpp b/dDatabase/Tables/CDItemComponentTable.cpp index 149b2ce8..698f72a4 100644 --- a/dDatabase/Tables/CDItemComponentTable.cpp +++ b/dDatabase/Tables/CDItemComponentTable.cpp @@ -168,7 +168,7 @@ std::map<LOT, uint32_t> CDItemComponentTable::ParseCraftingCurrencies(const CDIt // Checking for 2 here, not sure what to do when there's more stuff than expected if (amountSplit.size() == 2) { currencies.insert({ - std::stol(amountSplit[0]), + std::stoull(amountSplit[0]), std::stoi(amountSplit[1]) }); } diff --git a/dScripts/BaseFootRaceManager.cpp b/dScripts/BaseFootRaceManager.cpp index 0c5d9f19..0da51bc5 100644 --- a/dScripts/BaseFootRaceManager.cpp +++ b/dScripts/BaseFootRaceManager.cpp @@ -12,7 +12,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::stol(splitArguments[1])); + const auto player = EntityManager::Instance()->GetEntity(std::stoull(splitArguments[1])); if (player != nullptr) { if (eventName == "updatePlayer") { diff --git a/dScripts/NjMonastryBossInstance.cpp b/dScripts/NjMonastryBossInstance.cpp index 17c4b296..c6c8e324 100644 --- a/dScripts/NjMonastryBossInstance.cpp +++ b/dScripts/NjMonastryBossInstance.cpp @@ -99,7 +99,7 @@ void NjMonastryBossInstance::OnPlayerExit(Entity *self, Entity *player) { void NjMonastryBossInstance::OnActivityTimerDone(Entity *self, const std::string &name) { auto split = GeneralUtils::SplitString(name, TimerSplitChar); auto timerName = split[0]; - auto objectID = split.size() > 1 ? (LWOOBJID) std::stol(split[1]) : LWOOBJID_EMPTY; + auto objectID = split.size() > 1 ? (LWOOBJID) std::stoull(split[1]) : LWOOBJID_EMPTY; if (timerName == WaitingForPlayersTimer) { StartFight(self); diff --git a/dScripts/SpawnPetBaseServer.cpp b/dScripts/SpawnPetBaseServer.cpp index 4706da1d..d23e371a 100644 --- a/dScripts/SpawnPetBaseServer.cpp +++ b/dScripts/SpawnPetBaseServer.cpp @@ -55,7 +55,7 @@ bool SpawnPetBaseServer::CheckNumberOfPets(Entity *self, Entity* user) { if (petID.empty()) continue; - const auto* spawnedPet = EntityManager::Instance()->GetEntity(std::stol(petID)); + const auto* spawnedPet = EntityManager::Instance()->GetEntity(std::stoull(petID)); if (spawnedPet == nullptr) continue; From d8cde40b4959bd10b9ab3341ae1460c41a190bc4 Mon Sep 17 00:00:00 2001 From: Shane Clark <ff.shane.clark@outlook.com> Date: Sat, 11 Jun 2022 18:31:58 -0600 Subject: [PATCH 24/98] Fix unhealthy docker containers (#574) * Add curl to brickfix dockerfile. * Add curl to AccountManager docker. * Fix issue preventing container from building. --- docker/AccountManager.Dockerfile | 2 +- docker/brickfix.Dockerfile | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/AccountManager.Dockerfile b/docker/AccountManager.Dockerfile index dd56e3b9..60226339 100644 --- a/docker/AccountManager.Dockerfile +++ b/docker/AccountManager.Dockerfile @@ -8,7 +8,7 @@ COPY ./thirdparty/AccountManager . ADD docker/credentials_example.py credentials.py ADD docker/resources_example.py resources.py -RUN apk add libffi-dev build-base --no-cache && pip3 install -r requirements.txt +RUN apk add curl libffi-dev build-base --no-cache && pip3 install -r requirements.txt EXPOSE 5000 CMD python3 app.py diff --git a/docker/brickfix.Dockerfile b/docker/brickfix.Dockerfile index 20a9444a..3323cd65 100644 --- a/docker/brickfix.Dockerfile +++ b/docker/brickfix.Dockerfile @@ -1,5 +1,7 @@ # syntax=docker/dockerfile:1 FROM python:3.9.9-slim +RUN apt-get update && \ + apt-get install curl -y WORKDIR /empty_dir EXPOSE 80 CMD python -m http.server 80 From 30c8326c3e218e6c2fda049775baa0b7e117e09c Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 11 Jun 2022 20:50:01 -0700 Subject: [PATCH 25/98] Move owner override Mover owner override to be earlier so that we dont try to get the team of an entity that doesnt have a team and may be a child entity of a player. Tested changes with a team of two players and players were correctly given credit for kills --- dGame/dComponents/DestroyableComponent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index da5db382..72194568 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -696,10 +696,10 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (owner != nullptr) { - auto* team = TeamManager::Instance()->GetTeam(owner->GetObjectID()); - owner = owner->GetOwner(); // If the owner is overwritten, we collect that here + auto* team = TeamManager::Instance()->GetTeam(owner->GetObjectID()); + const auto isEnemy = m_Parent->GetComponent<BaseCombatAIComponent>() != nullptr; auto* inventoryComponent = owner->GetComponent<InventoryComponent>(); From fbf0b59ff191ee60cd22480b0d2d589f565cb4a1 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 12 Jun 2022 10:56:01 -0700 Subject: [PATCH 26/98] Fix item getter for moving items This fixes an issue where the item would get overwritten and would effectively fetch a "random" item in the inventory to move instead of the requested one. --- dGame/dComponents/InventoryComponent.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8c5ec269..22b86f17 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -353,8 +353,6 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in while (left > 0) { - item = origin->FindItemByLot(lot, ignoreEquipped); - if (item == nullptr) { item = origin->FindItemByLot(lot, false); From 81431cfcbda58135293a7612f81dd7e774f7575a Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 12 Jun 2022 11:44:45 -0700 Subject: [PATCH 27/98] Address bricks selling 1 at a time Bricks have a stack size of zero in the cdclient so we need to make sure to give them a full stack size of 999 as we do for the bricks inventory with the selling inventory. --- dGame/dComponents/InventoryComponent.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8c5ec269..02ddd3c8 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -208,7 +208,8 @@ void InventoryComponent::AddItem( auto stack = static_cast<uint32_t>(info.stackSize); - if (inventoryType == eInventoryType::BRICKS) + // info.itemType of 1 is item type brick + if (inventoryType == eInventoryType::BRICKS || (stack == 0 && info.itemType == 1)) { stack = 999; } From ef8ea13d9955d6663f938ca8aa98b894436a645b Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 12 Jun 2022 19:25:28 -0700 Subject: [PATCH 28/98] Don't give activity loot for Battle of Nimbus Station Address an issue on Brick Mesa where Battle of Nimbus Station was dropping activity loot. Tested completing Battle of Nimbus Station and ending early and was not given loot as is expected. --- dScripts/ActivityManager.cpp | 4 ++-- dScripts/ActivityManager.h | 2 +- dScripts/BaseWavesServer.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index f84963df..af055abb 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -48,7 +48,7 @@ float_t ActivityManager::GetActivityValue(Entity *self, const LWOOBJID playerID, } void ActivityManager::StopActivity(Entity *self, const LWOOBJID playerID, const uint32_t score, - const uint32_t value1, const uint32_t value2, bool quit) { + const uint32_t value1, const uint32_t value2, bool quit, bool givingActivityLoot) { int32_t gameID = 0; auto* sac = self->GetComponent<ScriptedActivityComponent>(); @@ -70,7 +70,7 @@ void ActivityManager::StopActivity(Entity *self, const LWOOBJID playerID, const SetActivityValue(self, playerID, 1, value1); SetActivityValue(self, playerID, 2, value2); - LootGenerator::Instance().GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); + if (givingActivityLoot) 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); diff --git a/dScripts/ActivityManager.h b/dScripts/ActivityManager.h index 3b5783ad..39d587c7 100644 --- a/dScripts/ActivityManager.h +++ b/dScripts/ActivityManager.h @@ -17,7 +17,7 @@ public: static float_t GetActivityValue(Entity *self, LWOOBJID playerID, uint32_t valueIndex) ; 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 StopActivity(Entity *self, LWOOBJID playerID, uint32_t score, uint32_t value1 = 0, uint32_t value2 = 0, bool quit = false, bool givingActivityLoot = true); 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/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index ac8da8a7..20ddc5e4 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -371,7 +371,7 @@ void BaseWavesServer::GameOver(Entity *self, bool won) { missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, time, self->GetObjectID(), self->GetVar<std::string>(MissionTypeVariable)); } - StopActivity(self, playerID, wave, time, score); + StopActivity(self, playerID, wave, time, score, false, false); } } From 842cb80137a49657e0d2e8c1a603760814fcae38 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Mon, 13 Jun 2022 04:19:27 +0100 Subject: [PATCH 29/98] Revert "Don't give activity loot for Battle of Nimbus Station" --- dScripts/ActivityManager.cpp | 4 ++-- dScripts/ActivityManager.h | 2 +- dScripts/BaseWavesServer.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index af055abb..f84963df 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -48,7 +48,7 @@ float_t ActivityManager::GetActivityValue(Entity *self, const LWOOBJID playerID, } void ActivityManager::StopActivity(Entity *self, const LWOOBJID playerID, const uint32_t score, - const uint32_t value1, const uint32_t value2, bool quit, bool givingActivityLoot) { + const uint32_t value1, const uint32_t value2, bool quit) { int32_t gameID = 0; auto* sac = self->GetComponent<ScriptedActivityComponent>(); @@ -70,7 +70,7 @@ void ActivityManager::StopActivity(Entity *self, const LWOOBJID playerID, const SetActivityValue(self, playerID, 1, value1); SetActivityValue(self, playerID, 2, value2); - if (givingActivityLoot) LootGenerator::Instance().GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); + 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); diff --git a/dScripts/ActivityManager.h b/dScripts/ActivityManager.h index 39d587c7..3b5783ad 100644 --- a/dScripts/ActivityManager.h +++ b/dScripts/ActivityManager.h @@ -17,7 +17,7 @@ public: static float_t GetActivityValue(Entity *self, LWOOBJID playerID, uint32_t valueIndex) ; 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, bool givingActivityLoot = true); + void StopActivity(Entity *self, LWOOBJID playerID, uint32_t score, uint32_t value1 = 0, uint32_t value2 = 0, bool quit = false); 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/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 20ddc5e4..ac8da8a7 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -371,7 +371,7 @@ void BaseWavesServer::GameOver(Entity *self, bool won) { missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, time, self->GetObjectID(), self->GetVar<std::string>(MissionTypeVariable)); } - StopActivity(self, playerID, wave, time, score, false, false); + StopActivity(self, playerID, wave, time, score); } } From a61c6e5e41ae3f7b75a5ddf11370dcb32d63e296 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 13 Jun 2022 00:45:17 -0700 Subject: [PATCH 30/98] Add /setlevel slash command Add the setlevel slash command. Command accepts parameters of the requested level and a player to set the level of. This also adjects the uscore of the player accordingly. The player must re-log upon using the command to see any updates to themselves or others. --- dGame/dUtilities/SlashCommandHandler.cpp | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 90f32f69..8631f760 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1306,6 +1306,74 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MODERATION); } + if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) + { + // We may be trying to set a specific players level to a level. If so override the entity with the requested players. + std::string requestedPlayerToSetLevelOf = ""; + if (args.size() > 1) { + requestedPlayerToSetLevelOf = args[1]; + + auto requestedPlayer = Player::GetPlayer(requestedPlayerToSetLevelOf); + + if (!requestedPlayer) { + ChatPackets::SendSystemMessage(sysAddr, u"No player found with username: (" + GeneralUtils::ASCIIToUTF16(requestedPlayerToSetLevelOf) + u")."); + return; + } + + if (!requestedPlayer->GetOwner()) { + ChatPackets::SendSystemMessage(sysAddr, u"No entity found with username: (" + GeneralUtils::ASCIIToUTF16(requestedPlayerToSetLevelOf) + u")."); + return; + } + + entity = requestedPlayer->GetOwner(); + } + uint32_t requestedLevel; + uint32_t oldLevel; + // first check the level is valid + + if (!GeneralUtils::TryParse(args[0], requestedLevel)) + { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid level."); + return; + } + // query to set our uscore to the correct value for this level + + auto characterComponent = entity->GetComponent<CharacterComponent>(); + auto query = CDClientDatabase::CreatePreppedStmt("SELECT requiredUScore from LevelProgressionLookup WHERE id = ?;"); + query.bind(1, (int)requestedLevel); + auto result = query.execQuery(); + + if (result.eof()) return; + + // Set the UScore first + oldLevel = characterComponent->GetLevel(); + characterComponent->SetUScore(result.getIntField(0, characterComponent->GetUScore())); + + // handle level up for each level we have passed if we set our level to be higher than the current one. + if (oldLevel < requestedLevel) { + while (oldLevel < requestedLevel) { + oldLevel+=1; + characterComponent->SetLevel(oldLevel); + characterComponent->HandleLevelUp(); + } + } else { + characterComponent->SetLevel(requestedLevel); + } + + if (requestedPlayerToSetLevelOf != "") { + ChatPackets::SendSystemMessage( + sysAddr, u"Set " + GeneralUtils::ASCIIToUTF16(requestedPlayerToSetLevelOf) + u"'s level to " + GeneralUtils::to_u16string(requestedLevel) + + u" and UScore to " + GeneralUtils::to_u16string(characterComponent->GetUScore()) + + u". Relog to see changes."); + } else { + ChatPackets::SendSystemMessage( + sysAddr, u"Set your level to " + GeneralUtils::to_u16string(requestedLevel) + + u" and UScore to " + GeneralUtils::to_u16string(characterComponent->GetUScore()) + + u". Relog to see changes."); + } + return; + } + if (chatCommand == "pos" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { const auto position = entity->GetPosition(); From 1179f5a2fe33a13ba9cda8d7654467db6c7a16f2 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 13 Jun 2022 00:45:29 -0700 Subject: [PATCH 31/98] Add setlevel to commands doc --- docs/Commands.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Commands.md b/docs/Commands.md index 4d169c76..b5588f68 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -104,6 +104,7 @@ These commands are primarily for development and testing. The usage of many of t |tpall|`/tpall`|Teleports all characters to your current position.|8| |triggerspawner|`/triggerspawner <spawner name>`|Triggers spawner by name.|8| |unlock-emote|`/unlock-emote <emote id>`|Unlocks for your character the emote of the given id.|8| +|Set Level|`/setlevel <requested_level> (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 <loot matrix index> <item id> <amount>`|Rolls loot matrix.|9| From 8bdd5b6e2c127322f9a8bba18b58cacb72506229 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:58:38 -0700 Subject: [PATCH 32/98] Address quickbuilds being unbuildable Address an issue where quickbuilds would become unbuildable. The main issue lied within serializing parent/child info too often for some reason / serializing it when the info wasnt dirty. Only serializing this info when it is actually dirty and has changed has addressed the issue and allows quickbuilds to never break. --- dGame/Entity.cpp | 7 +++++-- dGame/Entity.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 132a0eb7..960439bf 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -79,6 +79,7 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_Components = {}; m_DieCallbacks = {}; m_PhantomCollisionCallbacks = {}; + m_IsParentChildDirty = true; m_Settings = info.settings; m_NetworkSettings = info.networkSettings; @@ -974,8 +975,9 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke } else outBitStream->Write0(); //No GM Level } - outBitStream->Write((m_ParentEntity != nullptr || m_ChildEntities.size() > 0)); - if (m_ParentEntity || m_ChildEntities.size() > 0) { + outBitStream->Write((m_ParentEntity != nullptr || m_ChildEntities.size() > 0) && (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION)); + if ((m_ParentEntity != nullptr || m_ChildEntities.size() > 0) && (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION)) { + m_IsParentChildDirty = false; outBitStream->Write(m_ParentEntity != nullptr); if (m_ParentEntity) { outBitStream->Write(m_ParentEntity->GetObjectID()); @@ -1661,6 +1663,7 @@ void Entity::RegisterCoinDrop(uint64_t count) { } void Entity::AddChild(Entity* child) { + m_IsParentChildDirty = true; m_ChildEntities.push_back(child); } diff --git a/dGame/Entity.h b/dGame/Entity.h index cef7b97f..f2bc4237 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -322,6 +322,8 @@ protected: int8_t m_Observers = 0; + bool m_IsParentChildDirty = true; + /* * Collision */ From 7dfcd22a2eec9bf91998146b827faa765d5ca629 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:59:30 -0700 Subject: [PATCH 33/98] Properly place build activator The build activator as a result of the previous changes was spawning at the wrong position. This commit pulls the activators position from the settings (should they exist) and sets them accordingly. --- dGame/dComponents/RebuildComponent.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index abee5e16..538fdeed 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -22,6 +22,16 @@ RebuildComponent::RebuildComponent(Entity* entity) : Component(entity) { { m_Precondition = new PreconditionExpression(GeneralUtils::UTF16ToWTF8(checkPreconditions)); } + + auto positionAsVector = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rebuild_activators"), 31); + if (positionAsVector.size() == 3) { + m_ActivatorPosition.x = std::stof(positionAsVector[0]); + m_ActivatorPosition.y = std::stof(positionAsVector[1]); + m_ActivatorPosition.z = std::stof(positionAsVector[2]); + } else { + m_ActivatorPosition = m_Parent->GetPosition(); + } + SpawnActivator(); } RebuildComponent::~RebuildComponent() { From 09c459a083640ed42262837fd490fbd87803806b Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 15 Jun 2022 23:04:03 -0700 Subject: [PATCH 34/98] Added comment --- dGame/Entity.cpp | 2 ++ dGame/dComponents/RebuildComponent.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 960439bf..79512737 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -975,6 +975,8 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke } else outBitStream->Write0(); //No GM Level } + + // Only serialize parent / child info should the info be dirty (changed) or if this is the construction of the entity. outBitStream->Write((m_ParentEntity != nullptr || m_ChildEntities.size() > 0) && (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION)); if ((m_ParentEntity != nullptr || m_ChildEntities.size() > 0) && (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION)) { m_IsParentChildDirty = false; diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 538fdeed..25b7eb1b 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -23,6 +23,8 @@ RebuildComponent::RebuildComponent(Entity* entity) : Component(entity) { m_Precondition = new PreconditionExpression(GeneralUtils::UTF16ToWTF8(checkPreconditions)); } + // Should a setting that has the build activator position exist, fetch that setting here and parse it for position. + // It is assumed that the user who sets this setting uses the correct character delimiter (character 31) auto positionAsVector = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rebuild_activators"), 31); if (positionAsVector.size() == 3) { m_ActivatorPosition.x = std::stof(positionAsVector[0]); From 4a39221dd0446c8507eb873b8fff7784797a4b46 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 16 Jun 2022 08:38:38 -0700 Subject: [PATCH 35/98] Address reviews Changed the activator position parsing to have TryParse so that we dont throw an exception trying to load the position. Should the loading of the activator position fail the game will default to the position of the entity. change delimiter value to hex Updated the character delimiter used for rebuild_activator settings to use hex Remove extra parsing of activator position in Entity.cpp we were parsing the activator position but when doing so where we were, this was after we had ended up spawning the activator since that is now in the constructor of the rebuild component. The extra parsing has been removed. Simplify dirty parent/child info Simplify the if condition for parent child info. This info only needs to be written should it be changed (dirty) or if the packet being sent is a construction, meaning that a requesting player needs all base data and needs to know what parents/children an entity has at that time. get rid of extra parenthesis Left over extra parenthesis were around these conditions on accident --- dGame/Entity.cpp | 17 ++--------------- dGame/dComponents/RebuildComponent.cpp | 14 ++++++++------ 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 79512737..16b2f0af 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -562,19 +562,6 @@ void Entity::Initialize() comp->SetPostImaginationCost(rebCompData[0].post_imagination_cost); comp->SetTimeBeforeSmash(rebCompData[0].time_before_smash); - const auto rebuildActivatorValue = GetVarAsString(u"rebuild_activators"); - - if (!rebuildActivatorValue.empty()) { - std::vector<std::string> split = GeneralUtils::SplitString(rebuildActivatorValue, 0x1f); - NiPoint3 pos; - - pos.x = std::stof(split[0]); - pos.y = std::stof(split[1]); - pos.z = std::stof(split[2]); - - comp->SetActivatorPosition(pos); - } - const auto rebuildResetTime = GetVar<float>(u"rebuild_reset_time"); if (rebuildResetTime != 0.0f) { @@ -977,8 +964,8 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke } // Only serialize parent / child info should the info be dirty (changed) or if this is the construction of the entity. - outBitStream->Write((m_ParentEntity != nullptr || m_ChildEntities.size() > 0) && (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION)); - if ((m_ParentEntity != nullptr || m_ChildEntities.size() > 0) && (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION)) { + outBitStream->Write(m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION); + if (m_IsParentChildDirty || packetType == PACKET_TYPE_CONSTRUCTION) { m_IsParentChildDirty = false; outBitStream->Write(m_ParentEntity != nullptr); if (m_ParentEntity) { diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 25b7eb1b..5e313a7a 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -24,15 +24,17 @@ RebuildComponent::RebuildComponent(Entity* entity) : Component(entity) { } // Should a setting that has the build activator position exist, fetch that setting here and parse it for position. - // It is assumed that the user who sets this setting uses the correct character delimiter (character 31) - auto positionAsVector = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rebuild_activators"), 31); - if (positionAsVector.size() == 3) { - m_ActivatorPosition.x = std::stof(positionAsVector[0]); - m_ActivatorPosition.y = std::stof(positionAsVector[1]); - m_ActivatorPosition.z = std::stof(positionAsVector[2]); + // It is assumed that the user who sets this setting uses the correct character delimiter (character 31 or in hex 0x1F) + auto positionAsVector = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rebuild_activators"), 0x1F); + if (positionAsVector.size() == 3 && + GeneralUtils::TryParse(positionAsVector[0], m_ActivatorPosition.x) && + GeneralUtils::TryParse(positionAsVector[1], m_ActivatorPosition.y) && + GeneralUtils::TryParse(positionAsVector[2], m_ActivatorPosition.z)) { } else { + Game::logger->Log("RebuildComponent", "Failed to find activator position for lot %i. Defaulting to parents position.\n", m_Parent->GetLOT()); m_ActivatorPosition = m_Parent->GetPosition(); } + SpawnActivator(); } From 531c4a594c1d549dc961364771ddd04ae9e791bb Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 16 Jun 2022 17:50:33 -0700 Subject: [PATCH 36/98] remove children We need to make sure we are actually deleting children from the vector of children when they are deleted as entities. --- dGame/Entity.cpp | 14 ++++++++++++++ dGame/Entity.h | 1 + 2 files changed, 15 insertions(+) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 16b2f0af..e7a7bd17 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -125,6 +125,9 @@ Entity::~Entity() { m_Components.erase(pair.first); } + if (m_ParentEntity) { + m_ParentEntity->RemoveChild(this); + } } void Entity::Initialize() @@ -1656,6 +1659,17 @@ void Entity::AddChild(Entity* child) { m_ChildEntities.push_back(child); } +void Entity::RemoveChild(Entity* child) { + if (!child) return; + for (auto entity = m_ChildEntities.begin(); entity != m_ChildEntities.end(); entity++) { + if (*entity && (*entity)->GetObjectID() == child->GetObjectID()) { + m_IsParentChildDirty = true; + m_ChildEntities.erase(entity); + return; + } + } +} + void Entity::AddTimer(std::string name, float time) { EntityTimer* timer = new EntityTimer(name, time); m_Timers.push_back(timer); diff --git a/dGame/Entity.h b/dGame/Entity.h index f2bc4237..c804deaa 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -143,6 +143,7 @@ public: void SetProximityRadius(dpEntity* entity, std::string name); void AddChild(Entity* child); + void RemoveChild(Entity* child); void AddTimer(std::string name, float time); void AddCallbackTimer(float time, std::function<void()> callback); bool HasTimer(const std::string& name); From 136937184e2683fa38befdb8734fcd4866345d26 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 17 Jun 2022 22:18:46 -0700 Subject: [PATCH 37/98] Add to common vars and dnet Added values to enums on dnet and common vars that were missing --- dCommon/dCommonVars.h | 6 ++++++ dNet/dMessageIdentifiers.h | 1 + 2 files changed, 7 insertions(+) diff --git a/dCommon/dCommonVars.h b/dCommon/dCommonVars.h index cbecdd37..a52a1dc6 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dCommonVars.h @@ -415,6 +415,12 @@ enum eReplicaComponentType : int32_t { COMPONENT_TYPE_MODEL = 5398484 //look man idk }; +enum class UseItemResponse : uint32_t { + NoImaginationForPet = 1, + FailedPrecondition, + MountsNotAllowed +}; + /** * Represents the different types of inventories an entity may have */ diff --git a/dNet/dMessageIdentifiers.h b/dNet/dMessageIdentifiers.h index 8e20ab54..5b2ff639 100644 --- a/dNet/dMessageIdentifiers.h +++ b/dNet/dMessageIdentifiers.h @@ -376,6 +376,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_NOTIFY_PET_TAMING_PUZZLE_SELECTED = 675, GAME_MSG_SHOW_PET_ACTION_BUTTON = 692, GAME_MSG_SET_EMOTE_LOCK_STATE = 693, + GAME_MSG_USE_ITEM_REQUIREMENTS_RESPONSE = 703, GAME_MSG_PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT = 713, GAME_MSG_DOWNLOAD_PROPERTY_DATA = 716, GAME_MSG_QUERY_PROPERTY_DATA = 717, From e28b084395ca77ce33861ab62161da9e0ff67a47 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 17 Jun 2022 22:19:28 -0700 Subject: [PATCH 38/98] Add GM Added GM for UseItemRequirementsResponse that was missing in current implementation --- dGame/dGameMessages/GameMessages.cpp | 12 ++++++++++++ dGame/dGameMessages/GameMessages.h | 1 + 2 files changed, 13 insertions(+) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 58aba14d..6e6236a6 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1363,6 +1363,18 @@ void GameMessages::SendUseItemResult(Entity* entity, LOT templateID, bool useIte SEND_PACKET } +void GameMessages::SendUseItemRequirementsResponse(LWOOBJID objectID, const SystemAddress& sysAddr, UseItemResponse itemResponse) { + CBITSTREAM + CMSGHEADER + + bitStream.Write(objectID); + bitStream.Write(GAME_MSG::GAME_MSG_USE_ITEM_REQUIREMENTS_RESPONSE); + + bitStream.Write(itemResponse); + + SEND_PACKET +} + void GameMessages::SendMoveInventoryBatch(Entity* entity, uint32_t stackCount, int srcInv, int dstInv, const LWOOBJID& iObjID) { CBITSTREAM CMSGHEADER diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 602cb4b2..1d42eebc 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -372,6 +372,7 @@ namespace GameMessages { void SendActivityPause(LWOOBJID objectId, bool pause = false, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS); void SendStartActivityTime(LWOOBJID objectId, float_t startTime, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS); void SendRequestActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr, bool bStart, LWOOBJID userID); + void SendUseItemRequirementsResponse(LWOOBJID objectID, const SystemAddress& sysAddr, UseItemResponse itemResponse); // SG: From 35ea3d35aed8a02c0f82740de71872bbca3f5575 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 17 Jun 2022 23:53:09 -0700 Subject: [PATCH 39/98] Add pet imagination draining Address an issue where pets did not consume imagination when they were spawned. --- dGame/dComponents/InventoryComponent.cpp | 8 ++++ dGame/dComponents/PetComponent.cpp | 52 ++++++++++++++++++++++++ dGame/dComponents/PetComponent.h | 13 ++++++ 3 files changed, 73 insertions(+) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index cf17b0ac..bc589e7b 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1351,6 +1351,14 @@ void InventoryComponent::SpawnPet(Item* item) } } + // First check if we can summon the pet. You need 1 imagination to do so. + auto destroyableComponent = m_Parent->GetComponent<DestroyableComponent>(); + + if (destroyableComponent && destroyableComponent->GetImagination() <= 0) { + GameMessages::SendUseItemRequirementsResponse(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), UseItemResponse::NoImaginationForPet); + return; + } + EntityInfo info {}; info.lot = item->GetLot(); info.pos = m_Parent->GetPosition(); diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index a36d59e3..caefbf68 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -81,6 +81,20 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId) : Component(par if (!checkPreconditions.empty()) { SetPreconditions(checkPreconditions); } + // Get the imagination drain rate from the CDClient + auto query = CDClientDatabase::CreatePreppedStmt("SELECT imaginationDrainRate FROM PetComponent WHERE id = ?;"); + + query.bind(1, static_cast<int>(componentId)); + + auto result = query.execQuery(); + + // Should a result not exist for this pet default to 60 seconds. + if (!result.eof() && !result.fieldIsNull(0)) { + imaginationDrainRate = result.getFloatField(0, 60.0f); + } else { + imaginationDrainRate = 60.0f; + } + result.finalize(); } void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) @@ -899,6 +913,8 @@ void PetComponent::Wander() void PetComponent::Activate(Item* item, bool registerPet) { + AddDrainImaginationTimer(item); + m_ItemId = item->GetId(); m_DatabaseId = item->GetSubKey(); @@ -968,6 +984,42 @@ void PetComponent::Activate(Item* item, bool registerPet) GameMessages::SendShowPetActionButton(m_Owner, 3, true, owner->GetSystemAddress()); } +void PetComponent::AddDrainImaginationTimer(Item* item) { + auto playerInventory = item->GetInventory(); + if (!playerInventory) return; + + auto playerInventoryComponent = playerInventory->GetComponent(); + if (!playerInventoryComponent) return; + + auto playerEntity = playerInventoryComponent->GetParent(); + if (!playerEntity) return; + + auto playerDestroyableComponent = playerEntity->GetComponent<DestroyableComponent>(); + if (!playerDestroyableComponent) return; + + // Drain by 1 when you summon pet or when this method is called + playerDestroyableComponent->Imagine(-1); + + // Set this to a variable so when this is called back from the player the timer doesn't fire off. + m_Parent->AddCallbackTimer(imaginationDrainRate, [playerDestroyableComponent, this, item](){ + if (!playerDestroyableComponent) { + Game::logger->Log("PetComponent", "No petComponent and/or no playerDestroyableComponent\n"); + return; + } + + // If we are out of imagination despawn the pet. + if (playerDestroyableComponent->GetImagination() == 0) { + this->Deactivate(); + auto playerEntity = playerDestroyableComponent->GetParent(); + if (!playerEntity) return; + + GameMessages::SendUseItemRequirementsResponse(playerEntity->GetObjectID(), playerEntity->GetSystemAddress(), UseItemResponse::NoImaginationForPet); + } + + this->AddDrainImaginationTimer(item); + }); +} + void PetComponent::Deactivate() { GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), -1, u"despawn", "", LWOOBJID_EMPTY, 1, 1, true); diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 845cfe31..9139575a 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -203,6 +203,14 @@ public: */ static PetComponent* GetActivePet(LWOOBJID owner); + /** + * Adds the timer to the owner of this pet to drain imagination at the rate + * specified by the parameter imaginationDrainRate + * + * @param item The item that represents this pet in the inventory. + */ + void AddDrainImaginationTimer(Item* item); + private: /** @@ -346,4 +354,9 @@ private: * Preconditions that need to be met before an entity can tame this pet */ PreconditionExpression* m_Preconditions; + + /** + * The rate at which imagination is drained from the user for having the pet out. + */ + float imaginationDrainRate; }; \ No newline at end of file From e415d96a9ddf832ae396f242b350bd233658b03e Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 18 Jun 2022 00:03:27 -0700 Subject: [PATCH 40/98] Added config setting Added a config setting to allow players to disable pets consuming imagination. This value defaults to zero as a feature of DLU. --- dGame/dComponents/InventoryComponent.cpp | 3 ++- dGame/dComponents/PetComponent.cpp | 3 +++ resources/worldconfig.ini | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index bc589e7b..b7eae8bf 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -24,6 +24,7 @@ #include "dZoneManager.h" #include "PropertyManagementComponent.h" #include "DestroyableComponent.h" +#include "dConfig.h" InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) { @@ -1354,7 +1355,7 @@ void InventoryComponent::SpawnPet(Item* item) // First check if we can summon the pet. You need 1 imagination to do so. auto destroyableComponent = m_Parent->GetComponent<DestroyableComponent>(); - if (destroyableComponent && destroyableComponent->GetImagination() <= 0) { + if (Game::config->GetValue("pets_imagination") == "1" && destroyableComponent && destroyableComponent->GetImagination() <= 0) { GameMessages::SendUseItemRequirementsResponse(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), UseItemResponse::NoImaginationForPet); return; } diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index caefbf68..87f7278b 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -16,6 +16,7 @@ #include "../dWorldServer/ObjectIDManager.h" #include "Game.h" +#include "dConfig.h" #include "dChatFilter.h" #include "Database.h" @@ -985,6 +986,8 @@ void PetComponent::Activate(Item* item, bool registerPet) } void PetComponent::AddDrainImaginationTimer(Item* item) { + if (Game::config->GetValue("pets_imagination") == "0") return; + auto playerInventory = item->GetInventory(); if (!playerInventory) return; diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index b1fec1a6..bba17b38 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -57,3 +57,6 @@ check_fdb=0 # 0 or 1, DLU leaderboards will rate Avant Gardens Survival based on score by default. # This option should be set to 1 if you would like it to reflect the game when it was live (scoring based on time). classic_survival_scoring=0 + +# If this value is 1, pets will consume imagination as they did in live. if 0 they will not consume imagination at all. +pets_imagination=0 From 0774ab930da85725dabcf37ac6b32ef6c1e529c2 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 18 Jun 2022 00:09:05 -0700 Subject: [PATCH 41/98] inverted config check Since most people are not regularly updating their config files, this needs to assume the value is disabled rather than enabled. --- 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 87f7278b..891f0d1d 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -986,7 +986,7 @@ void PetComponent::Activate(Item* item, bool registerPet) } void PetComponent::AddDrainImaginationTimer(Item* item) { - if (Game::config->GetValue("pets_imagination") == "0") return; + if (Game::config->GetValue("pets_imagination") != "1") return; auto playerInventory = item->GetInventory(); if (!playerInventory) return; From 2a0616d0e9a9f25ce6d0244bbe199cafdec6e85d Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 18 Jun 2022 00:14:24 -0700 Subject: [PATCH 42/98] Dont take imagination on initial tame --- dGame/dComponents/PetComponent.cpp | 14 +++++++------- dGame/dComponents/PetComponent.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 891f0d1d..23dcf5e6 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -651,7 +651,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) inventoryComponent->SetDatabasePet(petSubKey, databasePet); - Activate(item, false); + Activate(item, false, true); m_Timer = 0; @@ -912,9 +912,9 @@ void PetComponent::Wander() m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / info.wanderSpeed; } -void PetComponent::Activate(Item* item, bool registerPet) +void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { - AddDrainImaginationTimer(item); + AddDrainImaginationTimer(item, fromTaming); m_ItemId = item->GetId(); m_DatabaseId = item->GetSubKey(); @@ -985,9 +985,9 @@ void PetComponent::Activate(Item* item, bool registerPet) GameMessages::SendShowPetActionButton(m_Owner, 3, true, owner->GetSystemAddress()); } -void PetComponent::AddDrainImaginationTimer(Item* item) { +void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) { if (Game::config->GetValue("pets_imagination") != "1") return; - + auto playerInventory = item->GetInventory(); if (!playerInventory) return; @@ -1000,8 +1000,8 @@ void PetComponent::AddDrainImaginationTimer(Item* item) { auto playerDestroyableComponent = playerEntity->GetComponent<DestroyableComponent>(); if (!playerDestroyableComponent) return; - // Drain by 1 when you summon pet or when this method is called - playerDestroyableComponent->Imagine(-1); + // Drain by 1 when you summon pet or when this method is called, but not when we have just tamed this pet. + if (!fromTaming) playerDestroyableComponent->Imagine(-1); // Set this to a variable so when this is called back from the player the timer doesn't fire off. m_Parent->AddCallbackTimer(imaginationDrainRate, [playerDestroyableComponent, this, item](){ diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 9139575a..913cbc56 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -82,7 +82,7 @@ public: * @param item the item to create the pet from * @param registerPet notifies the client that the pet was spawned, not necessary if this pet is being tamed */ - void Activate(Item* item, bool registerPet = true); + void Activate(Item* item, bool registerPet = true, bool fromTaming = false); /** * Despawns the pet @@ -209,7 +209,7 @@ public: * * @param item The item that represents this pet in the inventory. */ - void AddDrainImaginationTimer(Item* item); + void AddDrainImaginationTimer(Item* item, bool fromTaming = false); private: From 2e224cb15111bcbfcf5b1e6238f71699a8c7a049 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 18 Jun 2022 13:25:34 -0700 Subject: [PATCH 43/98] update name Pets will take imagination by default now --- dGame/dComponents/InventoryComponent.cpp | 2 +- dGame/dComponents/PetComponent.cpp | 2 +- resources/worldconfig.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index b7eae8bf..e47f5bb5 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1355,7 +1355,7 @@ void InventoryComponent::SpawnPet(Item* item) // First check if we can summon the pet. You need 1 imagination to do so. auto destroyableComponent = m_Parent->GetComponent<DestroyableComponent>(); - if (Game::config->GetValue("pets_imagination") == "1" && destroyableComponent && destroyableComponent->GetImagination() <= 0) { + if (Game::config->GetValue("pets_take_imagination") == "1" && destroyableComponent && destroyableComponent->GetImagination() <= 0) { GameMessages::SendUseItemRequirementsResponse(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), UseItemResponse::NoImaginationForPet); return; } diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 23dcf5e6..d54087aa 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -986,7 +986,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) } void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) { - if (Game::config->GetValue("pets_imagination") != "1") return; + if (Game::config->GetValue("pets_take_imagination") != "1") return; auto playerInventory = item->GetInventory(); if (!playerInventory) return; diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index bba17b38..a665f059 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -59,4 +59,4 @@ check_fdb=0 classic_survival_scoring=0 # If this value is 1, pets will consume imagination as they did in live. if 0 they will not consume imagination at all. -pets_imagination=0 +pets_take_imagination=1 From de47210f152772b03e485421e82474cabc31c6fe Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 18 Jun 2022 23:51:04 -0700 Subject: [PATCH 44/98] Move to new branch Added comments Added some comments and changed a variable name to be less ambiguous. --- dGame/Entity.cpp | 16 --------------- dGame/EntityManager.cpp | 43 +++++++++++++++++++++++------------------ dGame/Player.cpp | 17 ++++++++++++++++ 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index e7a7bd17..01c1540b 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -99,22 +99,6 @@ Entity::~Entity() { m_Character->SaveXMLToDatabase(); } - if (IsPlayer()) { - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); - for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { - script->OnPlayerExit(zoneControl, this); - } - - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_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)) { - script->OnPlayerExit(scriptEntity, this); - } - } - } - } - CancelAllTimers(); CancelCallbackTimers(); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index aacb2bc8..96a2328f 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -217,37 +217,42 @@ void EntityManager::UpdateEntities(const float deltaTime) { m_EntitiesToKill.clear(); - for (const auto& entry : m_EntitiesToDelete) + for (const auto entry : m_EntitiesToDelete) { - auto* entity = GetEntity(entry); + // Get all this info first before we delete the player. + auto entityToDelete = GetEntity(entry); - m_Entities.erase(entry); + auto networkIdToErase = entityToDelete->GetNetworkId(); - const auto& iter = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity); + const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); - if (iter != m_EntitiesToGhost.end()) + if (entityToDelete != nullptr) { - m_EntitiesToGhost.erase(iter); - } - - if (entity != nullptr) - { - if (entity->GetNetworkId() != 0) + // If we are a player run through the player destructor. + if (entityToDelete->IsPlayer()) { - m_LostNetworkIds.push(entity->GetNetworkId()); - } - - if (entity->IsPlayer()) - { - delete dynamic_cast<Player*>(entity); + delete dynamic_cast<Player*>(entityToDelete); } else { - delete entity; + delete entityToDelete; } - entity = nullptr; + entityToDelete = nullptr; + + if (networkIdToErase != 0) + { + m_LostNetworkIds.push(networkIdToErase); + } } + + if (ghostingToDelete != m_EntitiesToGhost.end()) + { + m_EntitiesToGhost.erase(ghostingToDelete); + } + + m_Entities.erase(entry); + } m_EntitiesToDelete.clear(); diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 634d4a68..350ddca5 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -13,6 +13,7 @@ #include "dZoneManager.h" #include "CharacterComponent.h" #include "Mail.h" +#include "CppScripts.h" std::vector<Player*> Player::m_Players = {}; @@ -329,5 +330,21 @@ Player::~Player() return; } + if (IsPlayer()) { + Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { + script->OnPlayerExit(zoneControl, this); + } + + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_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)) { + script->OnPlayerExit(scriptEntity, this); + } + } + } + } + m_Players.erase(iter); } From 9cf534dc0ae2c7a7037b796e8744947548cd6ac4 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 19 Jun 2022 00:14:33 -0700 Subject: [PATCH 45/98] Move to new branch Added comments Added some comments and changed a variable name to be less ambiguous. --- dGame/Entity.cpp | 16 --------------- dGame/EntityManager.cpp | 43 +++++++++++++++++++++++------------------ dGame/Player.cpp | 17 ++++++++++++++++ 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index e7a7bd17..01c1540b 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -99,22 +99,6 @@ Entity::~Entity() { m_Character->SaveXMLToDatabase(); } - if (IsPlayer()) { - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); - for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { - script->OnPlayerExit(zoneControl, this); - } - - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_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)) { - script->OnPlayerExit(scriptEntity, this); - } - } - } - } - CancelAllTimers(); CancelCallbackTimers(); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index aacb2bc8..96a2328f 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -217,37 +217,42 @@ void EntityManager::UpdateEntities(const float deltaTime) { m_EntitiesToKill.clear(); - for (const auto& entry : m_EntitiesToDelete) + for (const auto entry : m_EntitiesToDelete) { - auto* entity = GetEntity(entry); + // Get all this info first before we delete the player. + auto entityToDelete = GetEntity(entry); - m_Entities.erase(entry); + auto networkIdToErase = entityToDelete->GetNetworkId(); - const auto& iter = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity); + const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); - if (iter != m_EntitiesToGhost.end()) + if (entityToDelete != nullptr) { - m_EntitiesToGhost.erase(iter); - } - - if (entity != nullptr) - { - if (entity->GetNetworkId() != 0) + // If we are a player run through the player destructor. + if (entityToDelete->IsPlayer()) { - m_LostNetworkIds.push(entity->GetNetworkId()); - } - - if (entity->IsPlayer()) - { - delete dynamic_cast<Player*>(entity); + delete dynamic_cast<Player*>(entityToDelete); } else { - delete entity; + delete entityToDelete; } - entity = nullptr; + entityToDelete = nullptr; + + if (networkIdToErase != 0) + { + m_LostNetworkIds.push(networkIdToErase); + } } + + if (ghostingToDelete != m_EntitiesToGhost.end()) + { + m_EntitiesToGhost.erase(ghostingToDelete); + } + + m_Entities.erase(entry); + } m_EntitiesToDelete.clear(); diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 634d4a68..350ddca5 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -13,6 +13,7 @@ #include "dZoneManager.h" #include "CharacterComponent.h" #include "Mail.h" +#include "CppScripts.h" std::vector<Player*> Player::m_Players = {}; @@ -329,5 +330,21 @@ Player::~Player() return; } + if (IsPlayer()) { + Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { + script->OnPlayerExit(zoneControl, this); + } + + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_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)) { + script->OnPlayerExit(scriptEntity, this); + } + } + } + } + m_Players.erase(iter); } From 968114199b0585c51d3c75ca86b5fe112773ae87 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 19 Jun 2022 00:44:49 -0700 Subject: [PATCH 46/98] The shooting Gallery now properly ends when a player leaves the instance The shooting Gallery now properly ends when a player leaves the instance Frakjaw player update Update the Frakjaw battle instance script to remove players when they leave the instance Simplify comparison Simplify comparison for entity pointer to be implicit --- dGame/EntityManager.cpp | 2 +- dScripts/NjMonastryBossInstance.cpp | 24 +++++++++++++++++++++--- dScripts/SGCannon.cpp | 5 +++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 96a2328f..db60a1d1 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -226,7 +226,7 @@ void EntityManager::UpdateEntities(const float deltaTime) { const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); - if (entityToDelete != nullptr) + if (entityToDelete) { // If we are a player run through the player destructor. if (entityToDelete->IsPlayer()) diff --git a/dScripts/NjMonastryBossInstance.cpp b/dScripts/NjMonastryBossInstance.cpp index c6c8e324..27de7439 100644 --- a/dScripts/NjMonastryBossInstance.cpp +++ b/dScripts/NjMonastryBossInstance.cpp @@ -91,9 +91,27 @@ void NjMonastryBossInstance::OnPlayerLoaded(Entity *self, Entity *player) { void NjMonastryBossInstance::OnPlayerExit(Entity *self, Entity *player) { UpdatePlayer(self, player->GetObjectID(), true); - //TODO: Add functionality to dynamically turn off the large team variable when enough players leave. - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PlayerLeft", 0, 0, - player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); + // Fetch the total players loaded from the vars + auto totalPlayersLoaded = self->GetVar<std::vector<LWOOBJID> >(TotalPlayersLoadedVariable); + + // Find the player to remove + auto playerToRemove = std::find(totalPlayersLoaded.begin(), totalPlayersLoaded.end(), player->GetObjectID()); + + // If we found the player remove them from out list of players + if (playerToRemove != totalPlayersLoaded.end()) { + totalPlayersLoaded.erase(playerToRemove); + } else { + Game::logger->Log("NjMonastryBossInstance", "Failed to remove player at exit.\n"); + } + + // Set the players loaded var back + self->SetVar<std::vector<LWOOBJID>>(TotalPlayersLoadedVariable, totalPlayersLoaded); + + // Since this is an exit method, check if enough players have left. If enough have left + // resize the instance to account for such. + if (totalPlayersLoaded.size() <= 2) self->SetVar<bool>(LargeTeamVariable, false); + + GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PlayerLeft", 0, 0, player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); } void NjMonastryBossInstance::OnActivityTimerDone(Entity *self, const std::string &name) { diff --git a/dScripts/SGCannon.cpp b/dScripts/SGCannon.cpp index a5c2c843..3912364c 100644 --- a/dScripts/SGCannon.cpp +++ b/dScripts/SGCannon.cpp @@ -144,8 +144,9 @@ void SGCannon::OnMessageBoxResponse(Entity *self, Entity *sender, int32_t button if (player != nullptr) { if (button == 1 && identifier == u"Shooting_Gallery_Stop") { - static_cast<Player*>(player)->SendToZone(1300); - + UpdatePlayer(self, player->GetObjectID(), true); + RemovePlayer(player->GetObjectID()); + StopGame(self, true); return; } From 29199f4755452cfa47b3bdb4072484310be4299f Mon Sep 17 00:00:00 2001 From: Avery <averysumner@gmail.com> Date: Sun, 19 Jun 2022 18:34:18 -0700 Subject: [PATCH 47/98] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d6678084..f02bb67b 100644 --- a/README.md +++ b/README.md @@ -401,7 +401,7 @@ Here is a summary of the commands available in-game. All commands are prefixed b * DarwinAnim8or * Wincent01 * Mick -* averysumner +* averysumner (codeshaunted) * Jon002 * Jonny * Xiphoseer From 43377caa3be46e515091ae8c626688eaf7438d91 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 20 Jun 2022 21:02:52 -0700 Subject: [PATCH 48/98] Added item precondition checks Added item precondition checks for items so players who do not meet the conditions cannot use the items. tested with the faction bag tokens and they only gave the tokens when a player met all the preconditions or was a Game Master of level 6+ --- dGame/dInventory/Item.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 8f464d36..0d254e5b 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -311,7 +311,9 @@ bool Item::UseNonEquip() const auto success = !packages.empty(); - Game::logger->Log("Item", "Used (%i) with (%d)\n", lot, success); + auto inventoryComponent = inventory->GetComponent(); + + auto playerEntity = inventoryComponent->GetParent(); if (subKey != LWOOBJID_EMPTY) { @@ -324,8 +326,7 @@ bool Item::UseNonEquip() return true; } } - - if (success) + if (success && (playerEntity->GetGMLevel() >= eGameMasterLevel::GAME_MASTER_LEVEL_JUNIOR_DEVELOPER || this->GetPreconditionExpression()->Check(playerEntity))) { auto* entityParent = inventory->GetComponent()->GetParent(); @@ -342,7 +343,7 @@ bool Item::UseNonEquip() LootGenerator::Instance().GiveLoot(inventory->GetComponent()->GetParent(), result, eLootSourceType::LOOT_SOURCE_CONSUMPTION); } - + Game::logger->Log("Item", "Used (%i)\n", lot); inventory->GetComponent()->RemoveItem(lot, 1); } From 6b30292efd76c3d56e58d2ba76a74b9d5d161757 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 20 Jun 2022 22:22:32 -0700 Subject: [PATCH 49/98] Fix issue with dropship computer The dropship computer now no longer gives a player a second mission item should they interact with it again after mission completion --- dScripts/AmDropshipComputer.cpp | 4 ++-- dScripts/AmDropshipComputer.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dScripts/AmDropshipComputer.cpp b/dScripts/AmDropshipComputer.cpp index 836b09b0..dfc17474 100644 --- a/dScripts/AmDropshipComputer.cpp +++ b/dScripts/AmDropshipComputer.cpp @@ -27,12 +27,12 @@ void AmDropshipComputer::OnUse(Entity* self, Entity* user) return; } - if (inventoryComponent->GetLotCount(12323) != 0) + if (inventoryComponent->GetLotCount(m_NexusTalonDataCard) != 0 || missionComponent->GetMission(979)->GetMissionState() == MissionState::MISSION_STATE_COMPLETE) { return; } - inventoryComponent->AddItem(12323, 1, eLootSourceType::LOOT_SOURCE_NONE); + inventoryComponent->AddItem(m_NexusTalonDataCard, 1, eLootSourceType::LOOT_SOURCE_NONE); } void AmDropshipComputer::OnDie(Entity* self, Entity* killer) diff --git a/dScripts/AmDropshipComputer.h b/dScripts/AmDropshipComputer.h index 9b28d92d..620770af 100644 --- a/dScripts/AmDropshipComputer.h +++ b/dScripts/AmDropshipComputer.h @@ -8,4 +8,6 @@ public: void OnUse(Entity* self, Entity* user) override; void OnDie(Entity* self, Entity* killer) override; void OnTimerDone(Entity* self, std::string timerName) override; +private: + const LOT m_NexusTalonDataCard = 12323; }; From 09d50faf7912731baf1df12649aba7b4b1da4fec Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 06:40:19 +0100 Subject: [PATCH 50/98] Add new contributors to contributions list --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f02bb67b..4a082061 100644 --- a/README.md +++ b/README.md @@ -405,6 +405,8 @@ Here is a summary of the commands available in-game. All commands are prefixed b * Jon002 * Jonny * Xiphoseer +* EmosewaMC +* Aronwk ### Research and tools * lcdr From e24ad43dc5669c714631c559c0729eb36394981c Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 06:44:21 +0100 Subject: [PATCH 51/98] Update Credits markdown data --- vanity/CREDITS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vanity/CREDITS.md b/vanity/CREDITS.md index e4a67c81..b7c9e5cf 100644 --- a/vanity/CREDITS.md +++ b/vanity/CREDITS.md @@ -7,6 +7,8 @@ Mick averysumner Jon002 Jonny +EmosewaMC +Aronwk ## Research & Tooling Xiphoseer From cb6d91cfb297909a897026c3a774520ff3fec0db Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 06:44:40 +0100 Subject: [PATCH 52/98] Revert "Update Credits markdown data" This reverts commit e24ad43dc5669c714631c559c0729eb36394981c. --- vanity/CREDITS.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/vanity/CREDITS.md b/vanity/CREDITS.md index b7c9e5cf..e4a67c81 100644 --- a/vanity/CREDITS.md +++ b/vanity/CREDITS.md @@ -7,8 +7,6 @@ Mick averysumner Jon002 Jonny -EmosewaMC -Aronwk ## Research & Tooling Xiphoseer From c5f2f4b7080412fa67e15667b88022c68d9c119f Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 06:45:19 +0100 Subject: [PATCH 53/98] Update CREDITS.md --- vanity/CREDITS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vanity/CREDITS.md b/vanity/CREDITS.md index e4a67c81..b7c9e5cf 100644 --- a/vanity/CREDITS.md +++ b/vanity/CREDITS.md @@ -7,6 +7,8 @@ Mick averysumner Jon002 Jonny +EmosewaMC +Aronwk ## Research & Tooling Xiphoseer From ea94de16cd7ec63e018fee63dd78da4639e42110 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 06:48:35 +0100 Subject: [PATCH 54/98] Update Xiphoseers position on the project --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a082061..c1aa42a5 100644 --- a/README.md +++ b/README.md @@ -404,12 +404,12 @@ Here is a summary of the commands available in-game. All commands are prefixed b * averysumner (codeshaunted) * Jon002 * Jonny -* Xiphoseer * EmosewaMC * Aronwk ### Research and tools * lcdr +* Xiphoseer ### Community management * Neal From ef0873075f9e7bcc165f6da8198fa35656eab8c5 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 07:04:41 +0100 Subject: [PATCH 55/98] Reflect the same order as that in the CREDITS.md file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1aa42a5..ceba456a 100644 --- a/README.md +++ b/README.md @@ -408,8 +408,8 @@ Here is a summary of the commands available in-game. All commands are prefixed b * Aronwk ### Research and tools -* lcdr * Xiphoseer +* lcdr ### Community management * Neal From c0d05b00df3f8bf96a52f1ecb672c4a02a281ae7 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 09:03:31 +0100 Subject: [PATCH 56/98] Replace list with new formatting --- README.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index ceba456a..0a0c5d73 100644 --- a/README.md +++ b/README.md @@ -396,31 +396,33 @@ Here is a summary of the commands available in-game. All commands are prefixed b </tbody> </table> -## Credits -### Contributors to DLUv3 -* DarwinAnim8or -* Wincent01 -* Mick -* averysumner (codeshaunted) -* Jon002 -* Jonny -* EmosewaMC -* Aronwk +## Current DLU Team +### Developers +* [EmosewaMC](https://github.com/EmosewaMC) +* [Aronwk](https://github.com/aronwk-aaron) +* [Jettford](https://github.com/Jettford) -### Research and tools -* Xiphoseer -* lcdr - -### Community management -* Neal - -### Former contributors +## Original DLU Team (Pre-FOSS) +### Developers +* [DarwinAnim8or](DarwinAnim8or) +* [Wincent01](https://github.com/Wincent01) +* [Mick](https://github.com/MickVermeulen) +* [averysumner](https://github.com/codeshaunted) +* [Jon002](https://github.com/jaller200) +* [Jonny](https://github.com/cuzitsjonny) * TheMachine * Matthew -* Raine +* [Raine](https://github.com/Rainebannister) * Bricknave -### Special thanks +### Research and tools +* [lcdr](https://github.com/lcdr) +* [Xiphoseer](https://github.com/Xiphoseer) + +### Community management +* [Neal](https://github.com/NealSpellman) + +## Special thanks * humanoid24 * pwjones1969 * BlasterBuilder for the logo From fb81c0c9a2e2ed2af6f3a8936f9fc6f1b0fd231b Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 09:04:31 +0100 Subject: [PATCH 57/98] Update CREDITS.md with more accurate information --- vanity/CREDITS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vanity/CREDITS.md b/vanity/CREDITS.md index b7c9e5cf..be9f4c1c 100644 --- a/vanity/CREDITS.md +++ b/vanity/CREDITS.md @@ -4,11 +4,12 @@ DarwinAnim8or (Max) Wincent01 Mick -averysumner +averysumner (codeshaunted) Jon002 Jonny EmosewaMC Aronwk +Jettford ## Research & Tooling Xiphoseer From 8e9c48cce09ced87ffcf46c9af3db27d51d4dc71 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 21 Jun 2022 23:57:47 +0100 Subject: [PATCH 58/98] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a0c5d73..a6e2548b 100644 --- a/README.md +++ b/README.md @@ -396,13 +396,13 @@ Here is a summary of the commands available in-game. All commands are prefixed b </tbody> </table> -## Current DLU Team +## Current Maintainers and Developers ### Developers * [EmosewaMC](https://github.com/EmosewaMC) * [Aronwk](https://github.com/aronwk-aaron) * [Jettford](https://github.com/Jettford) -## Original DLU Team (Pre-FOSS) +## Previous Maintainers and Developers (Pre-FOSS) ### Developers * [DarwinAnim8or](DarwinAnim8or) * [Wincent01](https://github.com/Wincent01) From 9bfff533c3e0a9b9e8437278cea4a6480a842c30 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Wed, 22 Jun 2022 00:04:45 +0100 Subject: [PATCH 59/98] Update Darwins link on the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a6e2548b..32f047f8 100644 --- a/README.md +++ b/README.md @@ -404,7 +404,7 @@ Here is a summary of the commands available in-game. All commands are prefixed b ## Previous Maintainers and Developers (Pre-FOSS) ### Developers -* [DarwinAnim8or](DarwinAnim8or) +* [DarwinAnim8or](https://github.com/DarwinAnim8or) * [Wincent01](https://github.com/Wincent01) * [Mick](https://github.com/MickVermeulen) * [averysumner](https://github.com/codeshaunted) From 6a7c6da01ab39ebb2acfa4992e803fe786820088 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Wed, 22 Jun 2022 00:35:24 +0100 Subject: [PATCH 60/98] Update to simpler list. --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 32f047f8..74e80ff8 100644 --- a/README.md +++ b/README.md @@ -396,14 +396,13 @@ Here is a summary of the commands available in-game. All commands are prefixed b </tbody> </table> -## Current Maintainers and Developers -### Developers +## Credits +### Contributors to DLU Post Launch * [EmosewaMC](https://github.com/EmosewaMC) * [Aronwk](https://github.com/aronwk-aaron) * [Jettford](https://github.com/Jettford) -## Previous Maintainers and Developers (Pre-FOSS) -### Developers +### Contributors to DLU Pre Launch * [DarwinAnim8or](https://github.com/DarwinAnim8or) * [Wincent01](https://github.com/Wincent01) * [Mick](https://github.com/MickVermeulen) @@ -422,7 +421,13 @@ Here is a summary of the commands available in-game. All commands are prefixed b ### Community management * [Neal](https://github.com/NealSpellman) -## Special thanks +### Former contributors +* TheMachine +* Matthew +* Raine +* Bricknave + +### Special thanks * humanoid24 * pwjones1969 * BlasterBuilder for the logo From 1b222a64c30b7195e78a47130a0de55bcdbc4223 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Tue, 21 Jun 2022 20:07:44 -0500 Subject: [PATCH 61/98] removing myself from the situation --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 74e80ff8..835d60a3 100644 --- a/README.md +++ b/README.md @@ -399,7 +399,6 @@ Here is a summary of the commands available in-game. All commands are prefixed b ## Credits ### Contributors to DLU Post Launch * [EmosewaMC](https://github.com/EmosewaMC) -* [Aronwk](https://github.com/aronwk-aaron) * [Jettford](https://github.com/Jettford) ### Contributors to DLU Pre Launch From 5dd4086bd5fc6fe075ff18920575f6414531e321 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Tue, 21 Jun 2022 20:10:44 -0500 Subject: [PATCH 62/98] yoink I just want mounts to work, this isn't fun --- vanity/CREDITS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/vanity/CREDITS.md b/vanity/CREDITS.md index be9f4c1c..e130cfb3 100644 --- a/vanity/CREDITS.md +++ b/vanity/CREDITS.md @@ -8,7 +8,6 @@ averysumner (codeshaunted) Jon002 Jonny EmosewaMC -Aronwk Jettford ## Research & Tooling From 00f7a5c4d626fa17043291926cdff9faaa64ca45 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Wed, 22 Jun 2022 08:57:36 +0100 Subject: [PATCH 63/98] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 835d60a3..7a5bf5b8 100644 --- a/README.md +++ b/README.md @@ -397,11 +397,11 @@ Here is a summary of the commands available in-game. All commands are prefixed b </table> ## Credits -### Contributors to DLU Post Launch +## Active Contributors * [EmosewaMC](https://github.com/EmosewaMC) * [Jettford](https://github.com/Jettford) -### Contributors to DLU Pre Launch +## DLU Team * [DarwinAnim8or](https://github.com/DarwinAnim8or) * [Wincent01](https://github.com/Wincent01) * [Mick](https://github.com/MickVermeulen) From 94e161df55ed3bf28e4c71c0758299540247ba84 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 24 Jun 2022 15:26:09 -0500 Subject: [PATCH 64/98] Address players leaving Battle of Nimbus Station causing a crash that wont save (#600) --- dScripts/BaseWavesServer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index ac8da8a7..29706f52 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -60,8 +60,11 @@ void BaseWavesServer::BaseStartup(Entity* self) { // Done void BaseWavesServer::BasePlayerExit(Entity* self, Entity* player) { - state.waitingPlayers.erase(std::find(state.waitingPlayers.begin(), state.waitingPlayers.end(), player->GetObjectID())); - state.players.erase(std::find(state.players.begin(), state.players.end(), player->GetObjectID())); + auto waitingPlayerToErase = std::find(state.waitingPlayers.begin(), state.waitingPlayers.end(), player->GetObjectID()); + if (waitingPlayerToErase != state.waitingPlayers.end()) state.waitingPlayers.erase(waitingPlayerToErase); + + auto playerToErase = std::find(state.players.begin(), state.players.end(), player->GetObjectID()); + if (playerToErase != state.players.end()) state.players.erase(playerToErase); if (!self->GetNetworkVar<bool>(WavesStartedVariable)) { PlayerConfirmed(self); From 670a2de95b6152f9584980ac89fa0b0ce53d4cc2 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 27 Jun 2022 21:36:18 -0700 Subject: [PATCH 65/98] Address issue with Inventor Beehive and Buccaneer Monkey ability on valiant weapon (#604) * Add Script Add the FireFirstSkillonStartup script to allow for scripts that use this to function. * Add comments --- dScripts/CppScripts.cpp | 4 +++- dScripts/FireFirstSkillonStartup.cpp | 24 ++++++++++++++++++++++++ dScripts/FireFirstSkillonStartup.h | 12 ++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 dScripts/FireFirstSkillonStartup.cpp create mode 100644 dScripts/FireFirstSkillonStartup.h diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 9e402a21..26bde33e 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -165,6 +165,7 @@ #include "PropertyPlatform.h" #include "MailBoxServer.h" #include "ActMine.h" +#include "FireFirstSkillonStartup.h" // Racing Scripts #include "RaceImagineCrateServer.h" @@ -804,7 +805,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = new LegoDieRoll(); else if (scriptName == "scripts\\EquipmentScripts\\BuccaneerValiantShip.lua") script = new BuccaneerValiantShip(); - + else if (scriptName == "scripts\\EquipmentScripts\\FireFirstSkillonStartup.lua") + script = new FireFirstSkillonStartup(); // FB else if (scriptName == "scripts\\ai\\NS\\WH\\L_ROCKHYDRANT_BROKEN.lua") script = new RockHydrantBroken(); diff --git a/dScripts/FireFirstSkillonStartup.cpp b/dScripts/FireFirstSkillonStartup.cpp new file mode 100644 index 00000000..da1b420e --- /dev/null +++ b/dScripts/FireFirstSkillonStartup.cpp @@ -0,0 +1,24 @@ +#include "FireFirstSkillonStartup.h" +#include "Entity.h" +#include "SkillComponent.h" +#include "CDClientDatabase.h" +#include "CDObjectSkillsTable.h" + +void FireFirstSkillonStartup::OnStartup(Entity* self) { + auto skillComponent = self->GetComponent<SkillComponent>(); + if (!skillComponent) return; + + // Get the skill IDs of this object. + CDObjectSkillsTable* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + std::vector<CDObjectSkills> skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == self->GetLOT()); }); + + // For each skill, cast it with the associated behavior ID. + for (auto skill : skills) { + CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehavior behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID); + + // Should parent entity be null, make the originator self. + const auto target = self->GetParentEntity() ? self->GetParentEntity()->GetObjectID() : self->GetObjectID(); + skillComponent->CalculateBehavior(skill.skillID, behaviorData.behaviorID, LWOOBJID_EMPTY, false, false, target); + } +} \ No newline at end of file diff --git a/dScripts/FireFirstSkillonStartup.h b/dScripts/FireFirstSkillonStartup.h new file mode 100644 index 00000000..ad182e70 --- /dev/null +++ b/dScripts/FireFirstSkillonStartup.h @@ -0,0 +1,12 @@ +#pragma once +#ifndef __FIREFIRSTSKILLONSTARTUP__H__ +#define __FIREFIRSTSKILLONSTARTUP__H__ + +#include "CppScripts.h" + +class FireFirstSkillonStartup : public CppScripts::Script { + public: + void OnStartup(Entity* self) override; +}; + +#endif //!__FIREFIRSTSKILLONSTARTUP__H__ From a55162775e1d13d2e137e1942b1f1d05fb3f0438 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 28 Jun 2022 23:17:45 -0700 Subject: [PATCH 66/98] Address incorrect stun played by growl speakers (#605) Add the FireFirstSkillonStartup script to allow for scripts that use this to function. Add comments Fix QB Stunner scripts Use SetVar for variable Remember that variables for scripts need to be stored in the entity since a script can be used across multiple entities. Remove unused variable Specify Unsigned Int Start skill asap, not next tick --- dScripts/QbEnemyStunner.cpp | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/dScripts/QbEnemyStunner.cpp b/dScripts/QbEnemyStunner.cpp index ba089844..9f0cb8fc 100644 --- a/dScripts/QbEnemyStunner.cpp +++ b/dScripts/QbEnemyStunner.cpp @@ -13,16 +13,32 @@ void QbEnemyStunner::OnRebuildComplete(Entity* self, Entity* target) destroyable->SetFaction(115); } - auto* skillComponent = self->GetComponent<SkillComponent>(); + auto skillComponent = self->GetComponent<SkillComponent>(); + if (!skillComponent) return; - if (skillComponent != nullptr) - { - skillComponent->CalculateBehavior(499, 6095, LWOOBJID_EMPTY); + // Get the skill IDs of this object. + CDObjectSkillsTable* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + auto skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == self->GetLOT()); }); + std::map<uint32_t, uint32_t> skillBehaviorMap; + // For each skill, cast it with the associated behavior ID. + for (auto skill : skills) { + CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehavior behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID); + + skillBehaviorMap.insert(std::make_pair(skill.skillID, behaviorData.behaviorID)); } - self->AddTimer("TickTime", 1); + // If there are no skills found, insert a default skill to use. + if (skillBehaviorMap.size() == 0) { + skillBehaviorMap.insert(std::make_pair(499U, 6095U)); + } + + // Start all skills associated with the object next tick + self->AddTimer("TickTime", 0); self->AddTimer("PlayEffect", 20); + + self->SetVar<std::map<uint32_t, uint32_t>>(u"skillBehaviorMap", skillBehaviorMap); } void QbEnemyStunner::OnTimerDone(Entity* self, std::string timerName) @@ -45,9 +61,16 @@ void QbEnemyStunner::OnTimerDone(Entity* self, std::string timerName) if (skillComponent != nullptr) { - skillComponent->CalculateBehavior(499, 6095, LWOOBJID_EMPTY); + auto skillBehaviorMap = self->GetVar<std::map<uint32_t, uint32_t>>(u"skillBehaviorMap"); + if (skillBehaviorMap.size() == 0) { + // Should no skills have been found, default to the mermaid stunner + skillComponent->CalculateBehavior(499U, 6095U, LWOOBJID_EMPTY); + } else { + for (auto pair : skillBehaviorMap) { + skillComponent->CalculateBehavior(pair.first, pair.second, LWOOBJID_EMPTY); + } + } } - self->AddTimer("TickTime", 1); } } From 1497d9b35a2b9edbbb91cc330f8f2d4cc4244d86 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Wed, 29 Jun 2022 18:50:24 -0500 Subject: [PATCH 67/98] breakout possessor from char comp (#606) * breakout possessor from char comp Use the correct component for possessor cleanup scirps that were using possessor improperly beginnings of mounts * fix comments added bounds check --- dCommon/dCommonVars.h | 4 +- dGame/Entity.cpp | 26 +++++---- dGame/dComponents/CharacterComponent.cpp | 8 --- dGame/dComponents/CharacterComponent.h | 23 -------- dGame/dComponents/InventoryComponent.cpp | 12 +--- dGame/dComponents/PossessorComponent.cpp | 40 +++++-------- dGame/dComponents/PossessorComponent.h | 61 +++++++++++++------- dGame/dComponents/RacingControlComponent.cpp | 1 - dScripts/SGCannon.cpp | 7 ++- 9 files changed, 76 insertions(+), 106 deletions(-) diff --git a/dCommon/dCommonVars.h b/dCommon/dCommonVars.h index a52a1dc6..4cbdb61c 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dCommonVars.h @@ -407,8 +407,8 @@ enum eReplicaComponentType : int32_t { COMPONENT_TYPE_MISSION = 84, //!< The Mission Component COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97, //!< The LUP Launchpad Componen COMPONENT_TYPE_RAIL_ACTIVATOR = 104, - COMPONENT_TYPE_POSSESSOR = 107, //!< The Component 107 - COMPONENT_TYPE_POSSESSABLE = 108, //!< The Component 108 + COMPONENT_TYPE_POSSESSABLE = 108, //!< The Possessable Component + COMPONENT_TYPE_POSSESSOR = 110, //!< The Possessor Component COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 01c1540b..bb7e0335 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -435,6 +435,8 @@ void Entity::Initialize() }*/ if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_CHARACTER) > 0 || m_Character) { + // Character Component always has a possessor component + m_Components.insert(std::make_pair(COMPONENT_TYPE_POSSESSOR, new PossessorComponent(this))); CharacterComponent* comp = new CharacterComponent(this, m_Character); m_Components.insert(std::make_pair(COMPONENT_TYPE_CHARACTER, comp)); } @@ -606,10 +608,6 @@ void Entity::Initialize() m_Components.insert(std::make_pair(COMPONENT_TYPE_RENDER, render)); } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_POSSESSOR) > 0) || m_Character) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_POSSESSOR, new PossessorComponent(this))); - } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MISSION_OFFER) > 0) || m_Character) { m_Components.insert(std::make_pair(COMPONENT_TYPE_MISSION_OFFER, new MissionOfferComponent(this, m_TemplateID))); } @@ -1057,8 +1055,15 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType } CharacterComponent* characterComponent; - if (TryGetComponent(COMPONENT_TYPE_CHARACTER, characterComponent)) - { + if (TryGetComponent(COMPONENT_TYPE_CHARACTER, characterComponent)) { + + PossessorComponent* possessorComponent; + if (TryGetComponent(COMPONENT_TYPE_POSSESSOR, possessorComponent)) { + possessorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); + } else { + // Should never happen, but just to be safe + outBitStream->Write0(); + } characterComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } @@ -1164,11 +1169,10 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType outBitStream->Write<uint32_t>(0x40000000); } - PossessorComponent* possessorComponent; - if (TryGetComponent(COMPONENT_TYPE_POSSESSOR, possessorComponent)) - { - possessorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); - } + // BBB Component, unused currently + // Need to to write0 so that is serlaizese correctly + // TODO: Implement BBB Component + outBitStream->Write0(); /* if (m_Trigger != nullptr) diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index f7941af8..14354cb5 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -10,7 +10,6 @@ #include "InventoryComponent.h" #include "ControllablePhysicsComponent.h" #include "EntityManager.h" -#include "PossessorComponent.h" #include "VehiclePhysicsComponent.h" #include "GameMessages.h" #include "Item.h" @@ -81,13 +80,6 @@ CharacterComponent::~CharacterComponent() { } void CharacterComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - outBitStream->Write(m_IsRacing); - if (m_IsRacing) { - outBitStream->Write1(); - outBitStream->Write(m_VehicleObjectID); - outBitStream->Write<uint8_t>(0); - } - outBitStream->Write1(); outBitStream->Write(m_Level); outBitStream->Write0(); diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 99c8a098..2a0d860b 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -143,24 +143,6 @@ public: */ void SetIsRacing(bool isRacing) { m_IsRacing = isRacing; } - /** - * Gets the (optional) object ID of the vehicle the character is currently in - * @return the object ID of the vehilce the character is in - */ - const LWOOBJID GetVehicleObjectID() const { return m_VehicleObjectID; } - - /** - * Sets the (optional) object ID of the vehicle the character is currently in - * @param vehicleObjectID the ID of the vehicle the character is in - */ - void SetVehicleObjectID(LWOOBJID vehicleObjectID) { m_VehicleObjectID = vehicleObjectID; } - - /** - * Sets the possesible type that's currently used, merely used by the shooting gallery if it's 0 - * @param value the possesible type to set - */ - void SetPossessableType(uint8_t value) { m_PossessableType = value; } - /** * Gets whether this character has PvP enabled, allowing combat between players * @return @@ -304,11 +286,6 @@ private: */ bool m_IsRacing; - /** - * The object ID of the vehicle the character is currently in - */ - LWOOBJID m_VehicleObjectID; - /** * Possessible type, used by the shooting gallery */ diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index e47f5bb5..950536ab 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -986,19 +986,11 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) // #107 auto* possessorComponent = m_Parent->GetComponent<PossessorComponent>(); - if (possessorComponent != nullptr) - { - previousPossessorID = possessorComponent->GetPossessable(); - possessorComponent->SetPossessable(carEntity->GetObjectID()); - } + if (possessorComponent) possessorComponent->SetPossessable(carEntity->GetObjectID()); auto* characterComponent = m_Parent->GetComponent<CharacterComponent>(); - if (characterComponent != nullptr) - { - characterComponent->SetIsRacing(true); - characterComponent->SetVehicleObjectID(carEntity->GetObjectID()); - } + if (characterComponent) characterComponent->SetIsRacing(true); EntityManager::Instance()->ConstructEntity(carEntity); EntityManager::Instance()->SerializeEntity(m_Parent); diff --git a/dGame/dComponents/PossessorComponent.cpp b/dGame/dComponents/PossessorComponent.cpp index 4f532805..4ace324b 100644 --- a/dGame/dComponents/PossessorComponent.cpp +++ b/dGame/dComponents/PossessorComponent.cpp @@ -1,35 +1,21 @@ #include "PossessorComponent.h" -PossessorComponent::PossessorComponent(Entity* parent) : Component(parent) -{ - m_Possessable = LWOOBJID_EMPTY; +PossessorComponent::PossessorComponent(Entity* parent) : Component(parent) { + m_Possessable = LWOOBJID_EMPTY; } -PossessorComponent::~PossessorComponent() -{ - -} +PossessorComponent::~PossessorComponent() {} -void PossessorComponent::SetPossessable(LWOOBJID value) -{ - m_Possessable = value; -} -LWOOBJID PossessorComponent::GetPossessable() const -{ - return m_Possessable; -} -void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) -{ - outBitStream->Write(m_Possessable != LWOOBJID_EMPTY); - if (m_Possessable != LWOOBJID_EMPTY) - { - outBitStream->Write(m_Possessable); - } -} - -void PossessorComponent::Update(float deltaTime) -{ - +void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { + outBitStream->Write(m_DirtyPossesor || bIsInitialUpdate); + if (m_DirtyPossesor || bIsInitialUpdate) { + m_DirtyPossesor = false; + outBitStream->Write(m_Possessable != LWOOBJID_EMPTY); + if (m_Possessable != LWOOBJID_EMPTY) { + outBitStream->Write(m_Possessable); + } + outBitStream->Write(m_PossessableType); + } } diff --git a/dGame/dComponents/PossessorComponent.h b/dGame/dComponents/PossessorComponent.h index 0c1a436e..f3389274 100644 --- a/dGame/dComponents/PossessorComponent.h +++ b/dGame/dComponents/PossessorComponent.h @@ -8,31 +8,48 @@ * Represents an entity that can posess other entities. Generally used by players to drive a car. */ class PossessorComponent : public Component { -public: - static const uint32_t ComponentType = COMPONENT_TYPE_POSSESSOR; - - PossessorComponent(Entity* parent); - ~PossessorComponent() override; + public: + static const uint32_t ComponentType = COMPONENT_TYPE_POSSESSOR; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - void Update(float deltaTime) override; + PossessorComponent(Entity* parent); + ~PossessorComponent() override; - /** - * Sets the entity that this entity is possessing - * @param value the ID of the entity this ID should posess - */ - void SetPossessable(LWOOBJID value); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - /** - * Returns the entity that this entity is currently posessing - * @return the entity that this entity is currently posessing - */ - LWOOBJID GetPossessable() const; + /** + * Sets the entity that this entity is possessing + * @param value the ID of the entity this ID should posess + */ + void SetPossessable(LWOOBJID value) { m_Possessable = value; m_DirtyPossesor = true; } -private: + /** + * Sets the possesible type that's currently used, merely used by the shooting gallery if it's 0 + * @param value the possesible type to set + */ + void SetPossessableType(uint8_t value) { m_PossessableType = value; m_DirtyPossesor = true; } - /** - * The ID of the entity this entity is possessing (e.g. the ID of a car) - */ - LWOOBJID m_Possessable; + /** + * Returns the entity that this entity is currently posessing + * @return the entity that this entity is currently posessing + */ + LWOOBJID GetPossessable() const { return m_Possessable; } + + private: + + /** + * The ID of the entity this entity is possessing (e.g. the ID of a car) + */ + LWOOBJID m_Possessable; + + /** + * @brief possessable type + * + */ + uint8_t m_PossessableType; + + /** + * @brief if the possessor is dirty + * + */ + bool m_DirtyPossesor; }; diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 1d86b274..d8794114 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -219,7 +219,6 @@ void RacingControlComponent::LoadPlayerVehicle(Entity *player, if (characterComponent != nullptr) { characterComponent->SetIsRacing(true); - characterComponent->SetVehicleObjectID(carEntity->GetObjectID()); } // Init the player's racing entry. diff --git a/dScripts/SGCannon.cpp b/dScripts/SGCannon.cpp index 3912364c..2deacdde 100644 --- a/dScripts/SGCannon.cpp +++ b/dScripts/SGCannon.cpp @@ -107,9 +107,12 @@ void SGCannon::OnActivityStateChangeRequest(Entity *self, LWOOBJID senderID, int if (characterComponent != nullptr) { characterComponent->SetIsRacing(true); - characterComponent->SetVehicleObjectID(self->GetObjectID()); - characterComponent->SetPossessableType(0); characterComponent->SetCurrentActivity(2); + auto possessor = player->GetComponent<PossessorComponent>(); + if(possessor) { + possessor->SetPossessable(self->GetObjectID()); + possessor->SetPossessableType(0); + } EntityManager::Instance()->SerializeEntity(player); } From eaa962f265bb8e77ffdb929a27ab2a89b1a12520 Mon Sep 17 00:00:00 2001 From: jumpy-badger <the.jumpy.badger@gmail.com> Date: Mon, 4 Jul 2022 05:33:05 +0100 Subject: [PATCH 68/98] Add Aarch64 support (#231) * added mariadb-connector-cpp submodule * raknet aarch64 support * fix compile errors * mariadb connector swap (in progress) * update CMakeLists, add preprocessor definition to switch between mysql and mariadb connectors * update types with missing aarch64 check * corrected adding extra flag to properly compile mariadbconn in CMakeLists * updated readme with arm builds section * fix build failure if test folder does not exist * Remove mysql connector from all builds, add mariadbconnector to windows build * readd Linux check for backtrace lib to CMakeLists.txt * Separate system specific mariadbconncpp extra compile flags * Copy dlls to exes directory once built * fetch prebuilt binaries on windows so that ClangCL can be used * Delay load dll so that plugin directory is set correctly * Fixed typo in glibcxx compile flag * whitespacing, spaces -> tabs * Updated README.md, included instructions to update * Updated README.md added libssl-dev requirement and removed mysql connector references from macOS builds section * apple compile fixes for zlib and shared library name * add windows arm64 checks to raknet * remove extra . in shared library location * Setup plugins directory for the connector to search in, pass openssl_root_dir on for apple * Fix copy paths for single config generators and non windows * change plugin folder location, another single config generator fix * GENERATOR_IS_MULTI_CONFIG is a property not a variable * Fixed a few errors after merge * Fix plugin directory path, force windows to look at the right folder * fixed directory name for make_directory command * Update README.md Updated MacOS, Windows build instructions. * set INSTALL_PLUGINDIR so that the right directory is used * Support for relative rpath for docker build * added mariadb-connector-cpp submodule * raknet aarch64 support * fix compile errors * mariadb connector swap (in progress) * update CMakeLists, add preprocessor definition to switch between mysql and mariadb connectors * update types with missing aarch64 check * corrected adding extra flag to properly compile mariadbconn in CMakeLists * updated readme with arm builds section * fix build failure if test folder does not exist * Remove mysql connector from all builds, add mariadbconnector to windows build * readd Linux check for backtrace lib to CMakeLists.txt * Separate system specific mariadbconncpp extra compile flags * Copy dlls to exes directory once built * fetch prebuilt binaries on windows so that ClangCL can be used * Delay load dll so that plugin directory is set correctly * Fixed typo in glibcxx compile flag * whitespacing, spaces -> tabs * Updated README.md, included instructions to update * Updated README.md added libssl-dev requirement and removed mysql connector references from macOS builds section * apple compile fixes for zlib and shared library name * add windows arm64 checks to raknet * Setup plugins directory for the connector to search in, pass openssl_root_dir on for apple * Fix copy paths for single config generators and non windows * change plugin folder location, another single config generator fix * GENERATOR_IS_MULTI_CONFIG is a property not a variable * Fixed a few errors after merge * Fix plugin directory path, force windows to look at the right folder * fixed directory name for make_directory command * Update README.md Updated MacOS, Windows build instructions. * set INSTALL_PLUGINDIR so that the right directory is used * Support for relative rpath for docker build * Rebase on main * Remove extra git submodule * Update CMakeLists.txt * Remove CMakeLists.txt file from mariadb Remove the CMakeLists.txt file from the mariaDBConnector so we dont build the tests. Also add a config option to the CMakeVariables.txt so you can build the connector with multiple jobs * Compile on windows Specify the mariadbcpp.dll file location with a defined absolute path so windows knows it actually exists. * default to 1 job Default mariadb jobs running in parallel to 1 instead of 4 * Move mariadbcpp.dll file to the expected directory on windows * Changed plugin Updated the plugin location from the project binary directory to the expected location, the mariadb binary directory. * Addressed windows dll issues by moving files to the expected directory instead of a directory that wouldnt get created * Update README Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com> Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> --- .gitmodules | 4 + CMakeLists.txt | 240 ++++++++++++------ CMakeVariables.txt | 2 + README.md | 53 ++-- dDatabase/Database.cpp | 16 +- dDatabase/Database.h | 8 +- dGame/LeaderboardManager.cpp | 17 +- .../dComponents/PropertyEntranceComponent.cpp | 12 +- .../PropertyManagementComponent.cpp | 4 +- dGame/dUtilities/Mail.cpp | 6 +- dMasterServer/MasterServer.cpp | 4 + docker/Dockerfile | 4 +- tests/CMakeLists.txt | 6 +- thirdparty/mariadb-connector-cpp | 1 + thirdparty/raknet/Source/FileList.cpp | 2 +- thirdparty/raknet/Source/Gen_RPC8.h | 13 + thirdparty/raknet/Source/Types.h | 8 +- 17 files changed, 271 insertions(+), 129 deletions(-) create mode 160000 thirdparty/mariadb-connector-cpp diff --git a/.gitmodules b/.gitmodules index 086ee95c..6fb56bde 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,10 @@ [submodule "thirdparty/libbcrypt"] path = thirdparty/libbcrypt url = https://github.com/trusch/libbcrypt.git +[submodule "thirdparty/mariadb-connector-cpp"] + path = thirdparty/mariadb-connector-cpp + url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git + ignore = dirty [submodule "thirdparty/docker-utils"] path = thirdparty/docker-utils url = https://github.com/lcdr/utils.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 9492abcb..663225ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,12 +45,6 @@ endif() if(WIN32) include(FetchContent) -FetchContent_Declare( - mysql - URL https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-8.0.27-winx64.zip - URL_HASH MD5=e3c53f6e4d0a72fde2713f7597bf9468 -) - FetchContent_Declare( zlib URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip @@ -58,48 +52,35 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(zlib) -FetchContent_MakeAvailable(mysql) set(ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR}) set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") # Why? add_library(ZLIB::ZLIB ALIAS zlib) # You're welcome endif(WIN32) -if(UNIX) -if(APPLE) -else() -include(FetchContent) -FetchContent_Declare( - mysql - URL https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-8.0.27-linux-glibc2.12-x86-64bit.tar.gz - URL_HASH MD5=12f086b76c11022cc7139b41a36cdf9e -) +if(UNIX AND NOT APPLE) + include(FetchContent) + if (__include_backtrace__ AND __compile_backtrace__) + FetchContent_Declare( + backtrace + GIT_REPOSITORY https://github.com/ianlancetaylor/libbacktrace.git + ) -FetchContent_MakeAvailable(mysql) + FetchContent_MakeAvailable(backtrace) -if (__include_backtrace__ AND __compile_backtrace__) - FetchContent_Declare( - backtrace - GIT_REPOSITORY https://github.com/ianlancetaylor/libbacktrace.git - ) + if (NOT EXISTS ${backtrace_SOURCE_DIR}/.libs) + set(backtrace_make_cmd "${backtrace_SOURCE_DIR}/configure --prefix=\"/usr\" --enable-shared --with-system-libunwind") - FetchContent_MakeAvailable(backtrace) - - if (NOT EXISTS ${backtrace_SOURCE_DIR}/.libs) - set(backtrace_make_cmd "${backtrace_SOURCE_DIR}/configure --prefix=\"/usr\" --enable-shared --with-system-libunwind") - - execute_process( - COMMAND bash -c "cd ${backtrace_SOURCE_DIR} && ${backtrace_make_cmd} && make && cd ${CMAKE_SOURCE_DIR}" - ) - endif() - - link_directories(${backtrace_SOURCE_DIR}/.libs/) - include_directories(${backtrace_SOURCE_DIR}) -endif(__include_backtrace__) + execute_process( + COMMAND bash -c "cd ${backtrace_SOURCE_DIR} && ${backtrace_make_cmd} && make && cd ${CMAKE_SOURCE_DIR}" + ) + endif() + link_directories(${backtrace_SOURCE_DIR}/.libs/) + include_directories(${backtrace_SOURCE_DIR}) + endif(__include_backtrace__) endif() -endif(UNIX) # Set the version set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") @@ -161,20 +142,9 @@ configure_file("${CMAKE_SOURCE_DIR}/vanity/NPC.xml" "${CMAKE_BINARY_DIR}/vanity/ # 3rdparty includes include_directories(${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/) -if(UNIX) - if(APPLE) - include_directories(/usr/local/include/) - include_directories(/usr/local/mysql-connector-c++/include/jdbc/) - include_directories(/usr/local/mysql-connector-c++/include/jdbc/cppconn/) - else() - include_directories(${mysql_SOURCE_DIR}/include/jdbc/) - include_directories(${mysql_SOURCE_DIR}/include/jdbc/cppconn/) - endif(APPLE) -endif(UNIX) -if(WIN32) -include_directories(${mysql_SOURCE_DIR}/include/jdbc) -include_directories(${mysql_SOURCE_DIR}/include/jdbc/cppconn) -endif(WIN32) +if(APPLE) + include_directories(/usr/local/include/) +endif(APPLE) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include) @@ -209,27 +179,8 @@ include_directories(${PROJECT_SOURCE_DIR}/thirdparty/cpplinq/) include_directories(${PROJECT_SOURCE_DIR}/dNet/) include_directories(${PROJECT_SOURCE_DIR}/dScripts/) -# Default to linking to libmysql -set(MYSQL_LIB mysql) -if(WIN32) -set(MYSQL_LIB mysqlcppconn) -endif(WIN32) - # Lib folders: link_directories(${PROJECT_BINARY_DIR}) -if(UNIX) - if(APPLE) - link_directories(/usr/local/mysql-connector-c++/lib64/) - else() - link_directories(${mysql_SOURCE_DIR}/lib64/) - - # Link to libmysqlcppconn on Linux - set(MYSQL_LIB mysqlcppconn) - endif(APPLE) -endif(UNIX) -if(WIN32) -link_directories(${mysql_SOURCE_DIR}/lib64/vs14) -endif(WIN32) # Source Code file( @@ -376,6 +327,145 @@ if(MSVC) add_compile_options("/wd4267") endif(MSVC) +# mariadb connector cpp +# On Windows ClangCL can't compile the connector from source but can link to an msvc compiled one, +# so prefer the prebuilt binaries unless MARIADB_BUILD_SOURCE is specified +if(WIN32 AND NOT MARIADB_BUILD_SOURCE) + set(MARIADB_MSI_DIR "${PROJECT_BINARY_DIR}/msi") + set(MARIADB_CONNECTOR_DIR "${PROJECT_BINARY_DIR}/mariadbcpp") + set(MARIADB_C_CONNECTOR_DIR "${MARIADB_CONNECTOR_DIR}/MariaDB/MariaDB Connector C 64-bit") + set(MARIADB_CPP_CONNECTOR_DIR "${MARIADB_CONNECTOR_DIR}/MariaDB/MariaDB C++ Connector 64-bit") + + 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" ) + 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) + endif() + + if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.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) + 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) + 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) + execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) + endif() + + set(MARIADB_SHARED_LIBRARY_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll") + set(MARIADB_IMPLIB_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.lib") + set(MARIADB_INCLUDE_DIR "${MARIADB_CPP_CONNECTOR_DIR}/include/mariadb") + + add_custom_target(mariadb_connector_cpp) + add_custom_command(TARGET mariadb_connector_cpp POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll" + "${MARIADB_C_CONNECTOR_DIR}/lib/libmariadb.dll" + "${PROJECT_BINARY_DIR}") + + # MariaDB uses plugins that the database needs to load, the prebuilt binaries by default will try to find the libraries in system directories, + # so set this define and the servers will set the MARIADB_PLUGIN_DIR environment variable to the appropriate directory. + # Plugin directory is determined at dll load time (this will happen before main()) so we need to delay the dll load so that we can set the environment variable + add_link_options(/DELAYLOAD:${MARIADB_SHARED_LIBRARY_LOCATION}) + add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${MARIADB_CPP_CONNECTOR_DIR}/plugin") +else() # Build from source + + include(ExternalProject) + if(WIN32) + set(MARIADB_EXTRA_COMPILE_FLAGS /EHsc) + set(MARIADB_EXTRA_CMAKE_ARGS -DWITH_MSI=OFF) + elseif(APPLE) + set(MARIADB_EXTRA_COMPILE_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0) + set(MARIADB_EXTRA_CMAKE_ARGS -DWITH_EXTERNAL_ZLIB=ON -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}) + else() + set(MARIADB_EXTRA_COMPILE_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0) + endif() + + ExternalProject_Add(mariadb_connector_cpp + SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp + CMAKE_ARGS "-DCMAKE_CXX_FLAGS:STRING= ${MARIADB_EXTRA_COMPILE_FLAGS}" + -DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN} + -DCMAKE_INSTALL_PREFIX=./mariadbcpp # Points the connector to the correct plugin directory + -DINSTALL_PLUGINDIR=plugin + ${MARIADB_EXTRA_CMAKE_ARGS} + PREFIX "${PROJECT_BINARY_DIR}/mariadbcpp" + BUILD_COMMAND cmake --build . --config RelWithDebInfo -j${__maria_db_connector_compile_jobs__} + INSTALL_COMMAND "") + + ExternalProject_Get_Property(mariadb_connector_cpp BINARY_DIR) + + if(WIN32) + set(MARIADB_SHARED_LIBRARY_NAME mariadbcpp.dll) + set(MARIADB_PLUGIN_SUFFIX .dll) + set(MARIADB_IMPLIB_LOCATION "${BINARY_DIR}/RelWithDebInfo/mariadbcpp.lib") + + # When built from source windows only seems to check same folder as exe instead specified folder, so use + # environment variable to force it + add_link_options(/DELAYLOAD:mariadbcpp.dll) + add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${PROJECT_BINARY_DIR}/mariadbcpp/plugin") + else() + set(MARIADB_SHARED_LIBRARY_NAME libmariadbcpp${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(MARIADB_PLUGIN_SUFFIX .so) + endif() + + get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(isMultiConfig) + set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/RelWithDebInfo/${MARIADB_SHARED_LIBRARY_NAME}") + set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}/$<CONFIG>") + set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb/RelWithDebInfo") + else() + set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}") + set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}") + set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb") + endif() + + set(MARIADB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include/") + + add_custom_command(TARGET mariadb_connector_cpp POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + ${BINARY_DIR}/mariadbcpp/plugin + ${MARIADB_SHARED_LIBRARY_COPY_LOCATION} + + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${MARIADB_SHARED_LIBRARY_LOCATION} + ${MARIADB_SHARED_LIBRARY_COPY_LOCATION} + + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${MARIADB_PLUGINS_LOCATION}/caching_sha2_password${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/client_ed25519${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/dialog${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/mysql_clear_password${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/sha256_password${MARIADB_PLUGIN_SUFFIX} + ${BINARY_DIR}/mariadbcpp/plugin) +endif() + +# Remove the CMakeLists.txt file from the tests folder for the maria-db-connector so we dont compile the tests. +if(EXISTS "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") + file(REMOVE "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") +endif() + +add_library (mariadbConnCpp SHARED IMPORTED) +set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_LOCATION ${MARIADB_SHARED_LIBRARY_LOCATION}) +if(WIN32) + set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_IMPLIB ${MARIADB_IMPLIB_LOCATION}) +endif() +target_include_directories(mariadbConnCpp INTERFACE ${MARIADB_INCLUDE_DIR}) +add_dependencies(mariadbConnCpp mariadb_connector_cpp) + # 3rdparty static libraries: #add_library(zlib ${SOURCES_ZLIB}) add_library(raknet ${SOURCES_RAKNET}) @@ -395,6 +485,10 @@ add_library(dPhysics ${SOURCES_DPHYSICS}) target_link_libraries(dNet dCommon) #Needed because otherwise linker errors occur. target_link_libraries(dCommon ZLIB::ZLIB) target_link_libraries(dCommon libbcrypt) +target_link_libraries(dDatabase mariadbConnCpp) +target_link_libraries(dNet dDatabase) +target_link_libraries(dGame dDatabase) +target_link_libraries(dChatFilter dDatabase) if(WIN32) target_link_libraries(raknet ws2_32) @@ -417,7 +511,7 @@ target_link_libraries(WorldServer dPhysics) target_link_libraries(WorldServer detour) target_link_libraries(WorldServer recast) target_link_libraries(WorldServer raknet) -target_link_libraries(WorldServer ${MYSQL_LIB}) +target_link_libraries(WorldServer mariadbConnCpp) if(UNIX) target_link_libraries(WorldServer pthread) target_link_libraries(WorldServer dl) @@ -437,7 +531,7 @@ target_link_libraries(AuthServer dCommon) target_link_libraries(AuthServer dDatabase) target_link_libraries(AuthServer dNet) target_link_libraries(AuthServer raknet) -target_link_libraries(AuthServer ${MYSQL_LIB}) +target_link_libraries(AuthServer mariadbConnCpp) if(UNIX) target_link_libraries(AuthServer pthread) target_link_libraries(AuthServer dl) @@ -448,7 +542,7 @@ target_link_libraries(MasterServer dCommon) target_link_libraries(MasterServer dDatabase) target_link_libraries(MasterServer dNet) target_link_libraries(MasterServer raknet) -target_link_libraries(MasterServer ${MYSQL_LIB}) +target_link_libraries(MasterServer mariadbConnCpp) if(UNIX) target_link_libraries(MasterServer pthread) target_link_libraries(MasterServer dl) @@ -460,7 +554,7 @@ target_link_libraries(ChatServer dChatFilter) target_link_libraries(ChatServer dDatabase) target_link_libraries(ChatServer dNet) target_link_libraries(ChatServer raknet) -target_link_libraries(ChatServer ${MYSQL_LIB}) +target_link_libraries(ChatServer mariadbConnCpp) if(UNIX) target_link_libraries(ChatServer pthread) target_link_libraries(ChatServer dl) diff --git a/CMakeVariables.txt b/CMakeVariables.txt index b50b4446..ed0cfce8 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -16,3 +16,5 @@ NET_VERSION=171022 # Set __include_backtrace__ to 1 to includes the backtrace library for better crashlogs. # __compile_backtrace__=1 # Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries. +__maria_db_connector_compile_jobs__=1 +# Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with. \ No newline at end of file diff --git a/README.md b/README.md index 7a5bf5b8..79a1f27c 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ Development of the latest iteration of Darkflame Universe has been done primaril ```bash git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer ``` - **Python** Some tools utilized to streamline the setup process require Python 3, make sure you have it installed. @@ -44,7 +43,7 @@ This was done make sure that older and incomplete clients wouldn't produce false If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number. ### Linux builds -Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. +Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required. CMake must be version 3.14 or higher! @@ -71,22 +70,19 @@ make ``` ### MacOS builds +Ensure `cmake`, `zlib` and `open ssl` are installed as well as a compiler (e.g `clang` or `gcc`). -**Download precompiled MySQL connector** +In the repository root folder run the following. Ensure -DOPENSSL_ROOT_DIR=/path/to/openssl points to your openssl install location ```bash -# Install required tools -brew install boost mysql-connector-c++ +# Create the build directory, preserving it if it already exists +mkdir -p build +cd build -# Symlinks for finding the required modules -sudo ln -s /usr/local/mysql-connector-c++/lib64/libmysqlcppconn.dylib /usr/local/mysql-connector-c++/lib64/libmysql.dylib -sudo ln -s /usr/local/mysql-connector-c++/lib64/libcrypto.1.1.dylib /usr/local/mysql/lib/libcrypto.1.1.dylib -``` +# Run CMake to generate build files +cmake .. -DOPENSSL_ROOT_DIR=/path/to/openssl -Then follow the Linux build steps (gcc is not required), but before running `make`, run the following to make sure all the libs are available in the build folder: - -```bash -sudo ln -s /usr/local/mysql-connector-c++/lib64/libssl.1.1.dylib /path/to/build/folder/libssl.1.1.dylib -sudo ln -s /usr/local/mysql-connector-c++/lib64/libcrypto.1.1.dylib /path/to/build/folder/libcrypto.1.1.dylib +# Get cmake to build the project. If make files are being used then using make and appending `-j` and the amount of cores to utilize may be preferable, for example `make -j8` +cmake --build . --config Release ``` ### Windows builds (native) @@ -102,10 +98,20 @@ cd build cmake .. :: Run CMake with build flag to build -cmake --build . +cmake --build . --config Release ``` +**Windows for ARM** has not been tested but should build by doing the following +```batch +:: Create the build directory +mkdir build +cd build -Once built you must also move all DLLs from `build/_deps/mysql-src/lib64` or else you encounter missing DLL errors +:: Run CMake to generate make files +cmake .. -DMARIADB_BUILD_SOURCE=ON + +:: Run CMake with build flag to build +cmake --build . --config Release +``` ### Windows builds (WSL) This section will go through how to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) and building in a Linux environment under Windows. WSL requires Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11. @@ -129,6 +135,21 @@ sudo apt install build-essential [**Follow the Linux instructions**](#linux-builds) +### ARM builds +AArch64 builds should work on linux and MacOS using their respective build steps. Windows ARM should build but it has not been tested + +### Updating your build +To update your server to the latest version navigate to your cloned directory +```bash +cd /path/to/DarkflameServer +``` +run the following commands to update to the latest changes +```bash +git pull +git submodule update --init --recursive +``` +now follow the build section for your system + ## Setting up the environment ### Database diff --git a/dDatabase/Database.cpp b/dDatabase/Database.cpp index 7ba138cf..ef4faa52 100644 --- a/dDatabase/Database.cpp +++ b/dDatabase/Database.cpp @@ -10,7 +10,6 @@ sql::Driver * Database::driver; sql::Connection * Database::con; void Database::Connect(const string& host, const string& database, const string& username, const string& password) { - driver = get_driver_instance(); //To bypass debug issues: std::string newHost = "tcp://" + host; @@ -19,11 +18,15 @@ void Database::Connect(const string& host, const string& database, const string& const char* szUsername = username.c_str(); const char* szPassword = password.c_str(); - con = driver->connect(szHost, szUsername, szPassword); - con->setSchema(szDatabase); + driver = sql::mariadb::get_driver_instance(); - bool myTrue = true; - con->setClientOption("MYSQL_OPT_RECONNECT", &myTrue); + sql::Properties properties; + properties["hostName"] = szHost; + properties["user"] = szUsername; + properties["password"] = szPassword; + properties["autoReconnect"] = "true"; + con = driver->connect(properties); + con->setSchema(szDatabase); } //Connect void Database::Destroy(std::string source) { @@ -74,4 +77,5 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) { auto* stmt = con->prepareStatement(str); return stmt; -} //CreatePreppedStmt \ No newline at end of file +} //CreatePreppedStmt + diff --git a/dDatabase/Database.h b/dDatabase/Database.h index 6e458065..e972b0ca 100644 --- a/dDatabase/Database.h +++ b/dDatabase/Database.h @@ -1,13 +1,7 @@ #pragma once #include <string> -#include <mysql_connection.h> -#include <cppconn/driver.h> -#include <cppconn/exception.h> -#include <cppconn/resultset.h> -#include <cppconn/statement.h> -#include <cppconn/prepared_statement.h> -#include <cppconn/sqlstring.h> +#include <conncpp.hpp> class MySqlException : public std::runtime_error { public: diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index bb8697e6..793d402c 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -247,14 +247,15 @@ Leaderboard *LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoTy uint32_t index = 0; while (res->next()) { - entries.push_back({ - res->getUInt64(4), - res->getString(5), - res->getUInt(1), - res->getUInt(2), - res->getUInt(3), - res->getUInt(6) - }); + 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++; } diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 6779d1c3..1d631e88 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -172,8 +172,8 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl // If the player has a property this query will have a single result. if (playerPropertyLookupResults->next()) { const auto cloneId = playerPropertyLookupResults->getUInt64(4); - const auto propertyName = playerPropertyLookupResults->getString(5).asStdString(); - const auto propertyDescription = playerPropertyLookupResults->getString(6).asStdString(); + const auto propertyName = std::string(playerPropertyLookupResults->getString(5).c_str()); + const auto propertyDescription = std::string(playerPropertyLookupResults->getString(6).c_str()); const auto privacyOption = playerPropertyLookupResults->getInt(9); const auto modApproved = playerPropertyLookupResults->getBoolean(10); const auto dateLastUpdated = playerPropertyLookupResults->getInt64(11); @@ -212,8 +212,8 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl const auto propertyId = propertyEntry->getUInt64(1); const auto owner = propertyEntry->getInt(2); const auto cloneId = propertyEntry->getUInt64(4); - const auto propertyNameFromDb = propertyEntry->getString(5).asStdString(); - const auto propertyDescriptionFromDb = propertyEntry->getString(6).asStdString(); + const auto propertyNameFromDb = std::string(propertyEntry->getString(5).c_str()); + const auto propertyDescriptionFromDb = std::string(propertyEntry->getString(6).c_str()); const auto privacyOption = propertyEntry->getInt(9); const auto modApproved = propertyEntry->getBoolean(10); const auto dateLastUpdated = propertyEntry->getInt(11); @@ -239,7 +239,7 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl continue; } else { isOwned = cloneId == character->GetPropertyCloneID(); - ownerName = nameResult->getString(1).asStdString(); + ownerName = std::string(nameResult->getString(1).c_str()); } delete nameResult; @@ -346,4 +346,4 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl propertiesLeft = nullptr; GameMessages::SendPropertySelectQuery(m_Parent->GetObjectID(), startIndex, numberOfProperties - (startIndex + numResults) > 0, character->GetPropertyCloneID(), false, true, entries, sysAddr); -} \ No newline at end of file +} diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 7f82ae27..7faf9394 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -75,7 +75,7 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo this->moderatorRequested = propertyEntry->getInt(10) == 0 && rejectionReason == "" && privacyOption == PropertyPrivacyOption::Public; this->LastUpdatedTime = propertyEntry->getUInt64(11); this->claimedTime = propertyEntry->getUInt64(12); - this->rejectionReason = propertyEntry->getString(13).asStdString(); + this->rejectionReason = std::string(propertyEntry->getString(13).c_str()); this->reputation = propertyEntry->getUInt(14); Load(); @@ -865,7 +865,7 @@ void PropertyManagementComponent::OnQueryPropertyData(Entity* originator, const result->next(); - const auto reason = result->getString(1).asStdString();; + const auto reason = std::string(result->getString(1).c_str()); const auto modApproved = result->getInt(2); if (reason != "") { moderatorRequested = false; diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 79e99c7d..7e77cd77 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -306,9 +306,9 @@ void Mail::HandleDataRequest(RakNet::BitStream* packet, const SystemAddress& sys WriteToPacket(&bitStream, body, 400); WriteToPacket(&bitStream, sender, 32);*/ - WriteStringAsWString(&bitStream, res->getString(7), 50); //subject - WriteStringAsWString(&bitStream, res->getString(8), 400); //body - WriteStringAsWString(&bitStream, res->getString(3), 32); //sender + WriteStringAsWString(&bitStream, res->getString(7).c_str(), 50); //subject + WriteStringAsWString(&bitStream, res->getString(8).c_str(), 400); //body + WriteStringAsWString(&bitStream, res->getString(3).c_str(), 32); //sender bitStream.Write(uint32_t(0)); bitStream.Write(uint64_t(0)); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index e1e4728f..ac49b1a1 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -61,6 +61,10 @@ int main(int argc, char** argv) { Diagnostics::SetProcessFileName(argv[0]); Diagnostics::Initialize(); +#if defined(_WIN32) && defined(MARIADB_PLUGIN_DIR_OVERRIDE) + _putenv_s("MARIADB_PLUGIN_DIR", MARIADB_PLUGIN_DIR_OVERRIDE); +#endif + //Triggers the shutdown sequence at application exit std::atexit(ShutdownSequence); signal(SIGINT, [](int) { ShutdownSequence(); }); diff --git a/docker/Dockerfile b/docker/Dockerfile index 98a9b93d..27387e22 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -35,7 +35,7 @@ RUN echo "Build server" && \ mkdir -p cmake_build && \ cd cmake_build && \ sed -i -e "s/171022/${BUILD_VERSION}/g" ../CMakeVariables.txt && \ - cmake .. && \ + cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \ make -j $BUILD_THREADS RUN unzip /build/resources/navmeshes.zip -d /build/cmake_build/res/maps @@ -56,4 +56,4 @@ RUN mkdir -p /build/cmake_build && ln -s /app/_deps /build/cmake_build/_deps COPY docker/start_server.sh /start_server.sh -CMD [ "/start_server.sh" ] \ No newline at end of file +CMD [ "/start_server.sh" ] diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index eab4bbc9..85f4bda4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,7 +8,11 @@ create_test_sourcelist (Tests # add the executable add_executable (CommonCxxTests ${Tests}) target_link_libraries(CommonCxxTests dCommon raknet) - + +if(WIN32) + target_link_libraries(CommonCxxTests ws2_32) +endif(WIN32) + # remove the test driver source file set (TestsToRun ${Tests}) remove (TestsToRun CommonCxxTests.cpp) diff --git a/thirdparty/mariadb-connector-cpp b/thirdparty/mariadb-connector-cpp new file mode 160000 index 00000000..3fbdf8fa --- /dev/null +++ b/thirdparty/mariadb-connector-cpp @@ -0,0 +1 @@ +Subproject commit 3fbdf8fa337d532861f6a61494a72dbce6402f8b diff --git a/thirdparty/raknet/Source/FileList.cpp b/thirdparty/raknet/Source/FileList.cpp index ebb2a706..c432ce85 100644 --- a/thirdparty/raknet/Source/FileList.cpp +++ b/thirdparty/raknet/Source/FileList.cpp @@ -3,7 +3,7 @@ #include <assert.h> #if defined(_WIN32) || defined(__CYGWIN__) #include <io.h> -#elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) +#elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __aarch64__ ) #include <sys/io.h> #endif #include "DS_Queue.h" diff --git a/thirdparty/raknet/Source/Gen_RPC8.h b/thirdparty/raknet/Source/Gen_RPC8.h index b29a1fc9..029383c4 100644 --- a/thirdparty/raknet/Source/Gen_RPC8.h +++ b/thirdparty/raknet/Source/Gen_RPC8.h @@ -133,6 +133,7 @@ namespace GenRPC #define AUTO_RPC_ABI_PPC 4 // first 6 args (even if float) in int reg; first 13 floats in reg. // parameter passing area with shadow area. +#define AUTO_RPC_ABI_AARCH64 5 // Configure the parameters for the system. #if defined(__i386__) || defined( _M_IX86 ) || defined( __INTEL__ ) @@ -176,6 +177,18 @@ typedef double HardwareReal; typedef unsigned long long NaturalWord; typedef double HardwareReal; // could be changed to __float128 on AMD64/nonwin +#elif defined( __aarch64__ ) || defined (_M_ARM64) +#define AUTO_RPC_ABI AUTO_RPC_ABI_AARCH64 +#define AUTO_RPC_AUTORPC_WORD 64 +#define AUTO_RPC_INT_REG_PARAMS 8 +#define AUTO_RPC_FLOAT_REG_PARAMS 8 +#define AUTO_RPC_PARAMETER_REFERENCE_THRESHOLD 0 +#define AUTO_RPC_INT_SHADOW_OF_FLOATS 0 +#define AUTO_RPC_ALLOC_SEPARATE_FLOATS 1 +#define AUTO_RPC_CREATE_FLOAT_MAP 0 +typedef unsigned long long NaturalWord; +typedef double HardwareReal; + #elif defined ( _PS3 ) typedef double HardwareReal; typedef unsigned long long NaturalWord; diff --git a/thirdparty/raknet/Source/Types.h b/thirdparty/raknet/Source/Types.h index b0690c8e..ef85c2a9 100644 --- a/thirdparty/raknet/Source/Types.h +++ b/thirdparty/raknet/Source/Types.h @@ -92,8 +92,8 @@ defined(__amd64) || defined(__amd64__) || \ defined(__alpha__) || defined(__alpha) || defined(__ia64) || defined(__ia64__) || \ defined(_M_ALPHA) || defined(ns32000) || defined(__ns32000__) || defined(sequent) || \ - defined(MIPSEL) || defined(_MIPSEL) || defined(sun386) || defined(__sun386__) - + defined(MIPSEL) || defined(_MIPSEL) || defined(sun386) || defined(__sun386__) || \ + defined(__aarch64__) || defined (_M_ARM64) # define HOST_ENDIAN_IS_LITTLE #else @@ -128,8 +128,8 @@ namespace cat defined(__amd64) || defined(__amd64__) || defined(_M_X64) || \ defined(__alpha__) || defined(__alpha) || defined(__ia64) || defined(__ia64__) || \ defined(_M_ALPHA) || defined(ns32000) || defined(__ns32000__) || defined(sequent) || \ - defined(MIPSEL) || defined(_MIPSEL) || defined(sun386) || defined(__sun386__) - + defined(MIPSEL) || defined(_MIPSEL) || defined(sun386) || defined(__sun386__) || \ + defined(__aarch64__) || defined (_M_ARM64) # define LITTLE_ENDIAN #else From 6e2936504c9dcf3a5ca45cb8db0a23f866f052c9 Mon Sep 17 00:00:00 2001 From: Daniel Seiler <hi@dseiler.eu> Date: Mon, 4 Jul 2022 10:30:11 +0200 Subject: [PATCH 69/98] Improve CI (#345) * Don't upload artifacts unless on main * Fix if/endif mismatch warning * Add thirdparty CMakeLists * Keep more warnings around * Remove more RakNet warnings * Fix indentation and divided the cmake into libraries and bins - Each library and binary got their own CMakeLists.txt - Indentation was fixed everywhere - Weird if statement flows replaced * Revert "Fix indentation and divided the cmake into libraries and bins" This reverts commit 005a12424ea40248e539957609b0aca150ee614a. * Add async value assignments Resolves a warning where on some compilers this thread would _not_ be run async and would instead be run synchronous with the main thread, halting execution. * Revert "Add async value assignments" This commit was meant to be done on a seaparate branch but was accidentally pushed upstream to this branch. * Fix Merge Conflict * Resolve errors Resolve errors with using continue() outside a foreach loop. * breakout mariadb to thirdparty cmake Move the mariadb cmake to its own directory to make each cmake file more focussed. Co-authored-by: Jett <55758076+Jettford@users.noreply.github.com> Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> --- .github/workflows/build-and-test.yml | 1 + CMakeLists.txt | 233 +++------------------------ thirdparty/CMakeLists.txt | 206 +++++++++++++++++++++++ 3 files changed, 228 insertions(+), 212 deletions(-) create mode 100644 thirdparty/CMakeLists.txt diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 667434d2..0e7785d9 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -32,6 +32,7 @@ jobs: testPreset: "ci-${{matrix.os}}" - name: artifacts uses: actions/upload-artifact@v2 + if: ${{ github.ref == 'ref/head/main' }} with: name: build-${{matrix.os}} path: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 663225ef..facab5a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,29 +11,27 @@ string(REPLACE "\n" ";" variables ${variables}) # Set the cmake variables, formatted as "VARIABLE #" in variables foreach(variable ${variables}) # If the string contains a #, skip it - if("${variable}" MATCHES "#") - continue() - endif() - + if(NOT "${variable}" MATCHES "#") + # Split the variable into name and value - string(REPLACE "=" ";" variable ${variable}) + string(REPLACE "=" ";" variable ${variable}) # Check that the length of the variable is 2 (name and value) - list(LENGTH variable length) - if(NOT ${length} EQUAL 2) - continue() - endif() + list(LENGTH variable length) + if(${length} EQUAL 2) - list(GET variable 0 variable_name) - list(GET variable 1 variable_value) + list(GET variable 0 variable_name) + list(GET variable 1 variable_value) - # Set the variable - set(${variable_name} ${variable_value}) + # Set the variable + set(${variable_name} ${variable_value}) - # Add compiler definition - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}") + # Add compiler definition + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}") - message(STATUS "Variable: ${variable_name} = ${variable_value}") + message(STATUS "Variable: ${variable_name} = ${variable_value}") + endif() + endif() endforeach() # On windows it's better to build this from source, as there's no way FindZLIB is gonna find it @@ -79,7 +77,7 @@ if(UNIX AND NOT APPLE) link_directories(${backtrace_SOURCE_DIR}/.libs/) include_directories(${backtrace_SOURCE_DIR}) - endif(__include_backtrace__) + endif() endif() # Set the version @@ -182,6 +180,9 @@ include_directories(${PROJECT_SOURCE_DIR}/dScripts/) # Lib folders: link_directories(${PROJECT_BINARY_DIR}) +# Third-Party libraries +add_subdirectory(thirdparty) + # Source Code file( GLOB SOURCES @@ -214,47 +215,6 @@ RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" ${PROJECT_SOURCE_DIR}/dChatServer/*.cpp ) -# Source Code for raknet -file( -GLOB SOURCES_RAKNET -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/*.cpp -) - -# Source Code for recast -file( -GLOB SOURCES_RECAST -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Source/*.cpp -) - -# Source Code for detour -file( -GLOB SOURCES_DETOUR -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Source/*.cpp -) - -# Source Code for tinyxml2 -file( -GLOB SOURCES_TINYXML2 -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.cpp -) - -# Source Code for libbcrypt -file( -GLOB SOURCES_LIBBCRYPT -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/*.c -${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/src/*.c -) - # Source Code for dCommon file( GLOB SOURCES_DCOMMON @@ -278,8 +238,6 @@ LIST_DIRECTORIES false RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" ${PROJECT_SOURCE_DIR}/dDatabase/*.cpp ${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.cpp -${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.cpp -${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.c ) # Source Code for dNet @@ -327,153 +285,6 @@ if(MSVC) add_compile_options("/wd4267") endif(MSVC) -# mariadb connector cpp -# On Windows ClangCL can't compile the connector from source but can link to an msvc compiled one, -# so prefer the prebuilt binaries unless MARIADB_BUILD_SOURCE is specified -if(WIN32 AND NOT MARIADB_BUILD_SOURCE) - set(MARIADB_MSI_DIR "${PROJECT_BINARY_DIR}/msi") - set(MARIADB_CONNECTOR_DIR "${PROJECT_BINARY_DIR}/mariadbcpp") - set(MARIADB_C_CONNECTOR_DIR "${MARIADB_CONNECTOR_DIR}/MariaDB/MariaDB Connector C 64-bit") - set(MARIADB_CPP_CONNECTOR_DIR "${MARIADB_CONNECTOR_DIR}/MariaDB/MariaDB C++ Connector 64-bit") - - 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" ) - 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) - endif() - - if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.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) - 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) - 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) - execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) - endif() - - set(MARIADB_SHARED_LIBRARY_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll") - set(MARIADB_IMPLIB_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.lib") - set(MARIADB_INCLUDE_DIR "${MARIADB_CPP_CONNECTOR_DIR}/include/mariadb") - - add_custom_target(mariadb_connector_cpp) - add_custom_command(TARGET mariadb_connector_cpp POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll" - "${MARIADB_C_CONNECTOR_DIR}/lib/libmariadb.dll" - "${PROJECT_BINARY_DIR}") - - # MariaDB uses plugins that the database needs to load, the prebuilt binaries by default will try to find the libraries in system directories, - # so set this define and the servers will set the MARIADB_PLUGIN_DIR environment variable to the appropriate directory. - # Plugin directory is determined at dll load time (this will happen before main()) so we need to delay the dll load so that we can set the environment variable - add_link_options(/DELAYLOAD:${MARIADB_SHARED_LIBRARY_LOCATION}) - add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${MARIADB_CPP_CONNECTOR_DIR}/plugin") -else() # Build from source - - include(ExternalProject) - if(WIN32) - set(MARIADB_EXTRA_COMPILE_FLAGS /EHsc) - set(MARIADB_EXTRA_CMAKE_ARGS -DWITH_MSI=OFF) - elseif(APPLE) - set(MARIADB_EXTRA_COMPILE_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0) - set(MARIADB_EXTRA_CMAKE_ARGS -DWITH_EXTERNAL_ZLIB=ON -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}) - else() - set(MARIADB_EXTRA_COMPILE_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0) - endif() - - ExternalProject_Add(mariadb_connector_cpp - SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp - CMAKE_ARGS "-DCMAKE_CXX_FLAGS:STRING= ${MARIADB_EXTRA_COMPILE_FLAGS}" - -DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN} - -DCMAKE_INSTALL_PREFIX=./mariadbcpp # Points the connector to the correct plugin directory - -DINSTALL_PLUGINDIR=plugin - ${MARIADB_EXTRA_CMAKE_ARGS} - PREFIX "${PROJECT_BINARY_DIR}/mariadbcpp" - BUILD_COMMAND cmake --build . --config RelWithDebInfo -j${__maria_db_connector_compile_jobs__} - INSTALL_COMMAND "") - - ExternalProject_Get_Property(mariadb_connector_cpp BINARY_DIR) - - if(WIN32) - set(MARIADB_SHARED_LIBRARY_NAME mariadbcpp.dll) - set(MARIADB_PLUGIN_SUFFIX .dll) - set(MARIADB_IMPLIB_LOCATION "${BINARY_DIR}/RelWithDebInfo/mariadbcpp.lib") - - # When built from source windows only seems to check same folder as exe instead specified folder, so use - # environment variable to force it - add_link_options(/DELAYLOAD:mariadbcpp.dll) - add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${PROJECT_BINARY_DIR}/mariadbcpp/plugin") - else() - set(MARIADB_SHARED_LIBRARY_NAME libmariadbcpp${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(MARIADB_PLUGIN_SUFFIX .so) - endif() - - get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(isMultiConfig) - set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/RelWithDebInfo/${MARIADB_SHARED_LIBRARY_NAME}") - set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}/$<CONFIG>") - set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb/RelWithDebInfo") - else() - set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}") - set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}") - set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb") - endif() - - set(MARIADB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include/") - - add_custom_command(TARGET mariadb_connector_cpp POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory - ${BINARY_DIR}/mariadbcpp/plugin - ${MARIADB_SHARED_LIBRARY_COPY_LOCATION} - - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${MARIADB_SHARED_LIBRARY_LOCATION} - ${MARIADB_SHARED_LIBRARY_COPY_LOCATION} - - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${MARIADB_PLUGINS_LOCATION}/caching_sha2_password${MARIADB_PLUGIN_SUFFIX} - ${MARIADB_PLUGINS_LOCATION}/client_ed25519${MARIADB_PLUGIN_SUFFIX} - ${MARIADB_PLUGINS_LOCATION}/dialog${MARIADB_PLUGIN_SUFFIX} - ${MARIADB_PLUGINS_LOCATION}/mysql_clear_password${MARIADB_PLUGIN_SUFFIX} - ${MARIADB_PLUGINS_LOCATION}/sha256_password${MARIADB_PLUGIN_SUFFIX} - ${BINARY_DIR}/mariadbcpp/plugin) -endif() - -# Remove the CMakeLists.txt file from the tests folder for the maria-db-connector so we dont compile the tests. -if(EXISTS "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") - file(REMOVE "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") -endif() - -add_library (mariadbConnCpp SHARED IMPORTED) -set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_LOCATION ${MARIADB_SHARED_LIBRARY_LOCATION}) -if(WIN32) - set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_IMPLIB ${MARIADB_IMPLIB_LOCATION}) -endif() -target_include_directories(mariadbConnCpp INTERFACE ${MARIADB_INCLUDE_DIR}) -add_dependencies(mariadbConnCpp mariadb_connector_cpp) - -# 3rdparty static libraries: -#add_library(zlib ${SOURCES_ZLIB}) -add_library(raknet ${SOURCES_RAKNET}) -add_library(tinyxml2 ${SOURCES_TINYXML2}) -add_library(detour ${SOURCES_DETOUR}) -add_library(recast ${SOURCES_RECAST}) -add_library(libbcrypt ${SOURCES_LIBBCRYPT}) - # Our static libraries: add_library(dCommon ${SOURCES_DCOMMON}) add_library(dChatFilter ${SOURCES_DCHATFILTER}) @@ -482,6 +293,7 @@ add_library(dNet ${SOURCES_DNET}) add_library(dGame ${SOURCES_DGAME}) add_library(dZoneManager ${SOURCES_DZM}) add_library(dPhysics ${SOURCES_DPHYSICS}) +target_link_libraries(dDatabase sqlite3) target_link_libraries(dNet dCommon) #Needed because otherwise linker errors occur. target_link_libraries(dCommon ZLIB::ZLIB) target_link_libraries(dCommon libbcrypt) @@ -513,9 +325,6 @@ target_link_libraries(WorldServer recast) target_link_libraries(WorldServer raknet) target_link_libraries(WorldServer mariadbConnCpp) if(UNIX) -target_link_libraries(WorldServer pthread) -target_link_libraries(WorldServer dl) - if(NOT APPLE AND __include_backtrace__) target_link_libraries(WorldServer backtrace) target_link_libraries(MasterServer backtrace) @@ -567,9 +376,9 @@ endif(UNIX) # Disabled unknown pragmas because Linux doesn't understand Windows pragmas. if(UNIX) if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -Wno-unused-result -Wno-unknown-pragmas -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -Wno-unused-result -Wno-unknown-pragmas -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC") endif() if (__dynamic) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt new file mode 100644 index 00000000..ce24ecd3 --- /dev/null +++ b/thirdparty/CMakeLists.txt @@ -0,0 +1,206 @@ +# Source Code for raknet +file( +GLOB SOURCES_RAKNET +LIST_DIRECTORIES false +RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" +${CMAKE_CURRENT_SOURCE_DIR}/raknet/Source/*.cpp +) + +# Source Code for recast +file( +GLOB SOURCES_RECAST +LIST_DIRECTORIES false +RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" +${CMAKE_CURRENT_SOURCE_DIR}/recastnavigation/Recast/Source/*.cpp +) + +# Source Code for detour +file( +GLOB SOURCES_DETOUR +LIST_DIRECTORIES false +RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" +${CMAKE_CURRENT_SOURCE_DIR}/recastnavigation/Detour/Source/*.cpp +) + +# Source Code for tinyxml2 +file( +GLOB SOURCES_TINYXML2 +LIST_DIRECTORIES false +RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" +${CMAKE_CURRENT_SOURCE_DIR}/tinyxml2/tinyxml2.cpp +) + +# Source Code for libbcrypt +file( +GLOB SOURCES_LIBBCRYPT +LIST_DIRECTORIES false +RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" +${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/*.c +${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/src/*.c +) + +file( +GLOB SOURCES_SQLITE3 +LIST_DIRECTORIES false +RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" +${CMAKE_CURRENT_SOURCE_DIR}/SQLite/*.cpp +${CMAKE_CURRENT_SOURCE_DIR}/SQLite/*.c +) + +# mariadb connector cpp +# On Windows ClangCL can't compile the connector from source but can link to an msvc compiled one, +# so prefer the prebuilt binaries unless MARIADB_BUILD_SOURCE is specified +if(WIN32 AND NOT MARIADB_BUILD_SOURCE) + set(MARIADB_MSI_DIR "${PROJECT_BINARY_DIR}/msi") + set(MARIADB_CONNECTOR_DIR "${PROJECT_BINARY_DIR}/mariadbcpp") + set(MARIADB_C_CONNECTOR_DIR "${MARIADB_CONNECTOR_DIR}/MariaDB/MariaDB Connector C 64-bit") + set(MARIADB_CPP_CONNECTOR_DIR "${MARIADB_CONNECTOR_DIR}/MariaDB/MariaDB C++ Connector 64-bit") + + 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" ) + 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) + endif() + + if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.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) + 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) + 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) + execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) + endif() + + set(MARIADB_SHARED_LIBRARY_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll") + set(MARIADB_IMPLIB_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.lib") + set(MARIADB_INCLUDE_DIR "${MARIADB_CPP_CONNECTOR_DIR}/include/mariadb") + + add_custom_target(mariadb_connector_cpp) + add_custom_command(TARGET mariadb_connector_cpp POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll" + "${MARIADB_C_CONNECTOR_DIR}/lib/libmariadb.dll" + "${PROJECT_BINARY_DIR}") + + # MariaDB uses plugins that the database needs to load, the prebuilt binaries by default will try to find the libraries in system directories, + # so set this define and the servers will set the MARIADB_PLUGIN_DIR environment variable to the appropriate directory. + # Plugin directory is determined at dll load time (this will happen before main()) so we need to delay the dll load so that we can set the environment variable + add_link_options(/DELAYLOAD:${MARIADB_SHARED_LIBRARY_LOCATION}) + add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${MARIADB_CPP_CONNECTOR_DIR}/plugin") +else() # Build from source + + include(ExternalProject) + if(WIN32) + set(MARIADB_EXTRA_COMPILE_FLAGS /EHsc) + set(MARIADB_EXTRA_CMAKE_ARGS -DWITH_MSI=OFF) + elseif(APPLE) + set(MARIADB_EXTRA_COMPILE_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0) + set(MARIADB_EXTRA_CMAKE_ARGS -DWITH_EXTERNAL_ZLIB=ON -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}) + else() + set(MARIADB_EXTRA_COMPILE_FLAGS -D_GLIBCXX_USE_CXX11_ABI=0) + endif() + + ExternalProject_Add(mariadb_connector_cpp + SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp + CMAKE_ARGS "-DCMAKE_CXX_FLAGS:STRING= ${MARIADB_EXTRA_COMPILE_FLAGS}" + -DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN} + -DCMAKE_INSTALL_PREFIX=./mariadbcpp # Points the connector to the correct plugin directory + -DINSTALL_PLUGINDIR=plugin + ${MARIADB_EXTRA_CMAKE_ARGS} + PREFIX "${PROJECT_BINARY_DIR}/mariadbcpp" + BUILD_COMMAND cmake --build . --config RelWithDebInfo -j${__maria_db_connector_compile_jobs__} + INSTALL_COMMAND "") + + ExternalProject_Get_Property(mariadb_connector_cpp BINARY_DIR) + + if(WIN32) + set(MARIADB_SHARED_LIBRARY_NAME mariadbcpp.dll) + set(MARIADB_PLUGIN_SUFFIX .dll) + set(MARIADB_IMPLIB_LOCATION "${BINARY_DIR}/RelWithDebInfo/mariadbcpp.lib") + + # When built from source windows only seems to check same folder as exe instead specified folder, so use + # environment variable to force it + add_link_options(/DELAYLOAD:mariadbcpp.dll) + add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${PROJECT_BINARY_DIR}/mariadbcpp/plugin") + else() + set(MARIADB_SHARED_LIBRARY_NAME libmariadbcpp${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(MARIADB_PLUGIN_SUFFIX .so) + endif() + + get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(isMultiConfig) + set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/RelWithDebInfo/${MARIADB_SHARED_LIBRARY_NAME}") + set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}/$<CONFIG>") + set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb/RelWithDebInfo") + message(STATUS "1 ${CMAKE_SOURCE_DIR}") + else() + set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}") + set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}") + set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb") + endif() + + set(MARIADB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include/") + + add_custom_command(TARGET mariadb_connector_cpp POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + ${BINARY_DIR}/mariadbcpp/plugin + ${MARIADB_SHARED_LIBRARY_COPY_LOCATION} + + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${MARIADB_SHARED_LIBRARY_LOCATION} + ${MARIADB_SHARED_LIBRARY_COPY_LOCATION} + + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${MARIADB_PLUGINS_LOCATION}/caching_sha2_password${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/client_ed25519${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/dialog${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/mysql_clear_password${MARIADB_PLUGIN_SUFFIX} + ${MARIADB_PLUGINS_LOCATION}/sha256_password${MARIADB_PLUGIN_SUFFIX} + ${BINARY_DIR}/mariadbcpp/plugin) +endif() + +# Remove the CMakeLists.txt file from the tests folder for the maria-db-connector so we dont compile the tests. +if(EXISTS "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") + file(REMOVE "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") +endif() + +add_library(mariadbConnCpp SHARED IMPORTED GLOBAL) +set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_LOCATION ${MARIADB_SHARED_LIBRARY_LOCATION}) +if(WIN32) + set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_IMPLIB ${MARIADB_IMPLIB_LOCATION}) +endif() +target_include_directories(mariadbConnCpp INTERFACE ${MARIADB_INCLUDE_DIR}) +add_dependencies(mariadbConnCpp mariadb_connector_cpp) + +# 3rdparty static libraries: +#add_library(zlib ${SOURCES_ZLIB}) +add_library(raknet ${SOURCES_RAKNET}) +add_library(tinyxml2 ${SOURCES_TINYXML2}) +add_library(detour ${SOURCES_DETOUR}) +add_library(recast ${SOURCES_RECAST}) +add_library(libbcrypt ${SOURCES_LIBBCRYPT}) +add_library(sqlite3 ${SOURCES_SQLITE3}) + +if(UNIX) +target_link_libraries(sqlite3 pthread dl m) + +# -Wno-unused-result -Wno-unknown-pragmas -fpermissive +target_compile_options(sqlite3 PRIVATE "-Wno-return-local-addr" "-Wno-maybe-uninitialized") +target_compile_options(raknet PRIVATE "-Wno-write-strings" "-Wformat-overflow=0" "-Wformat=0") +target_compile_options(libbcrypt PRIVATE "-Wno-implicit-function-declaration" "-Wno-int-conversion") +endif(UNIX) \ No newline at end of file From 8a54e7ccd26cbbecc92598abbc64512dc07cd3e4 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 4 Jul 2022 15:24:45 -0700 Subject: [PATCH 70/98] Implement Precompiled Headers (#591) When applied, this will speed up compile times dramatically. --- CMakeLists.txt | 56 +++++++++++++++++++ dGame/dBehaviors/BehaviorSlot.h | 5 ++ dGame/dComponents/InventoryComponent.h | 5 ++ .../PropertySelectQueryProperty.h | 5 ++ dGame/dInventory/Inventory.h | 5 ++ dGame/dMission/Mission.h | 5 ++ dGame/dMission/MissionLockState.h | 5 ++ dGame/dMission/MissionTask.h | 5 ++ dGame/dMission/MissionTaskType.h | 5 ++ dPhysics/dpCollisionGroups.h | 2 + 10 files changed, 98 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index facab5a7..6cf311d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,6 +240,35 @@ ${PROJECT_SOURCE_DIR}/dDatabase/*.cpp ${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.cpp ) +file( + GLOB HEADERS_DDATABASE + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dDatabase/*.h + ${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.h + ${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h +) + +file( + GLOB HEADERS_DZONEMANAGER + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dZoneManager/*.h +) + +file( + GLOB HEADERS_DCOMMON + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dCommon/*.h +) + +file( + GLOB HEADERS_DGAME + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dGame/Entity.h + ${PROJECT_SOURCE_DIR}/dGame/dGameMessages/GameMessages.h + ${PROJECT_SOURCE_DIR}/dGame/EntityManager.h + ${PROJECT_SOURCE_DIR}/dScripts/CppScripts.h +) + # Source Code for dNet file( GLOB SOURCES_DNET @@ -312,6 +341,33 @@ add_executable(AuthServer ${SOURCES_AUTH}) add_executable(MasterServer ${SOURCES_MASTER}) add_executable(ChatServer ${SOURCES_CHAT}) +# Add out precompiled headers +target_precompile_headers( + dGame PRIVATE + ${HEADERS_DGAME} +) + +target_precompile_headers( + dZoneManager PRIVATE + ${HEADERS_DZONEMANAGER} +) + +# Need to specify to use the CXX compiler language here or else we get errors including <string>. +target_precompile_headers( + dDatabase PRIVATE + "$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>" +) + +target_precompile_headers( + dCommon PRIVATE + ${HEADERS_DCOMMON} +) + +target_precompile_headers( + tinyxml2 PRIVATE + "$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>" +) + # Target libraries to link to: target_link_libraries(WorldServer dCommon) target_link_libraries(WorldServer dChatFilter) diff --git a/dGame/dBehaviors/BehaviorSlot.h b/dGame/dBehaviors/BehaviorSlot.h index 54ba5708..af0d4e03 100644 --- a/dGame/dBehaviors/BehaviorSlot.h +++ b/dGame/dBehaviors/BehaviorSlot.h @@ -1,5 +1,8 @@ #pragma once +#ifndef BEHAVIORSLOT_H +#define BEHAVIORSLOT_H + enum class BehaviorSlot { Invalid = -1, @@ -9,3 +12,5 @@ enum class BehaviorSlot Head, Consumable }; + +#endif diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index bf18d132..1fda5942 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -1,5 +1,8 @@ #pragma once +#ifndef INVENTORYCOMPONENT_H +#define INVENTORYCOMPONENT_H + #include <map> #include <stack> @@ -445,3 +448,5 @@ private: */ void UpdatePetXml(tinyxml2::XMLDocument* document); }; + +#endif diff --git a/dGame/dGameMessages/PropertySelectQueryProperty.h b/dGame/dGameMessages/PropertySelectQueryProperty.h index 61fa7b86..e633f41b 100644 --- a/dGame/dGameMessages/PropertySelectQueryProperty.h +++ b/dGame/dGameMessages/PropertySelectQueryProperty.h @@ -1,5 +1,8 @@ #pragma once +#ifndef PROPERTYSELECTQUERY_H +#define PROPERTYSELECTQUERY_H + #include "Entity.h" class PropertySelectQueryProperty final @@ -24,3 +27,5 @@ public: float PerformanceCost = 0; // The performance cost of the property uint32_t PerformanceIndex = 0; // The performance index of the property? Always 0? }; + +#endif diff --git a/dGame/dInventory/Inventory.h b/dGame/dInventory/Inventory.h index 0d3d9e69..b65a2040 100644 --- a/dGame/dInventory/Inventory.h +++ b/dGame/dInventory/Inventory.h @@ -1,5 +1,8 @@ #pragma once +#ifndef INVENTORY_H +#define INVENTORY_H + #include <map> #include <vector> @@ -182,3 +185,5 @@ private: */ static std::vector<LOT> m_GameMasterRestrictedItems; }; + +#endif diff --git a/dGame/dMission/Mission.h b/dGame/dMission/Mission.h index cca72daf..4fb6c60f 100644 --- a/dGame/dMission/Mission.h +++ b/dGame/dMission/Mission.h @@ -1,5 +1,8 @@ #pragma once +#ifndef MISSION_H +#define MISSION_H + #include <vector> #include <string> @@ -259,3 +262,5 @@ private: */ std::vector<MissionTask*> m_Tasks; }; + +#endif diff --git a/dGame/dMission/MissionLockState.h b/dGame/dMission/MissionLockState.h index 417c066a..e2dcedd7 100644 --- a/dGame/dMission/MissionLockState.h +++ b/dGame/dMission/MissionLockState.h @@ -1,8 +1,13 @@ #pragma once +#ifndef MISSIONLOCKSTATE_H +#define MISSIONLOCKSTATE_H + enum class MissionLockState : int { MISSION_LOCK_LOCKED, MISSION_LOCK_NEW, MISSION_LOCK_UNLOCKED, }; + +#endif diff --git a/dGame/dMission/MissionTask.h b/dGame/dMission/MissionTask.h index b77b9c59..3fcbbe3d 100644 --- a/dGame/dMission/MissionTask.h +++ b/dGame/dMission/MissionTask.h @@ -1,5 +1,8 @@ #pragma once +#ifndef MISSIONTASK_H +#define MISSIONTASK_H + #include "CDMissionTasksTable.h" #include "MissionTaskType.h" #include "dCommonVars.h" @@ -180,3 +183,5 @@ private: */ void CheckCompletion() const; }; + +#endif diff --git a/dGame/dMission/MissionTaskType.h b/dGame/dMission/MissionTaskType.h index 263bf470..345f8fff 100644 --- a/dGame/dMission/MissionTaskType.h +++ b/dGame/dMission/MissionTaskType.h @@ -1,5 +1,8 @@ #pragma once +#ifndef MISSIONTASKTYPE_H +#define MISSIONTASKTYPE_H + //! An enum for mission task types enum class MissionTaskType : int { MISSION_TASK_TYPE_UNKNOWN = -1, //!< The task type is unknown @@ -24,3 +27,5 @@ enum class MissionTaskType : int { MISSION_TASK_TYPE_PLACE_MODEL = 25, //!< A task for picking up a model MISSION_TASK_TYPE_VISIT_PROPERTY = 30 //!< A task for visiting a property }; + +#endif diff --git a/dPhysics/dpCollisionGroups.h b/dPhysics/dpCollisionGroups.h index 7a6830eb..5853070f 100644 --- a/dPhysics/dpCollisionGroups.h +++ b/dPhysics/dpCollisionGroups.h @@ -1,5 +1,7 @@ #pragma once +#include <cstdint> + /* * Collision Groups */ From cc25ec01514210b0743ab2a7d95705601fbd3c46 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 4 Jul 2022 21:48:56 -0700 Subject: [PATCH 71/98] Add Venture Vision Behavior (#609) Add the Venture Vision behavior and associated functionality. Pet digs still do not show up however. The Kit bonus for factions have been tested and properly grant and take away the buff when it is casted and uncasted. Tested as well using multiple Venture Vision behaviors at once and the vision only went away when there were zero equipped at once. Remove extra includes Convert to Tabs Remove extra forward declaration --- dGame/dBehaviors/Behavior.cpp | 5 ++- dGame/dBehaviors/VentureVisionBehavior.cpp | 47 ++++++++++++++++++++++ dGame/dBehaviors/VentureVisionBehavior.h | 41 +++++++++++++++++++ dGame/dComponents/CharacterComponent.cpp | 29 +++++++++++++ dGame/dComponents/CharacterComponent.h | 20 +++++++++ 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 dGame/dBehaviors/VentureVisionBehavior.cpp create mode 100644 dGame/dBehaviors/VentureVisionBehavior.h diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index df24af92..7305ed2d 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -45,6 +45,7 @@ #include "InterruptBehavior.h" #include "PlayEffectBehavior.h" #include "DamageAbsorptionBehavior.h" +#include "VentureVisionBehavior.h" #include "BlockBehavior.h" #include "ClearTargetBehavior.h" #include "PullToPointBehavior.h" @@ -176,7 +177,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) case BehaviorTemplates::BEHAVIOR_LOOT_BUFF: behavior = new LootBuffBehavior(behaviorId); break; - case BehaviorTemplates::BEHAVIOR_VENTURE_VISION: break; + case BehaviorTemplates::BEHAVIOR_VENTURE_VISION: + behavior = new VentureVisionBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_SPAWN_OBJECT: behavior = new SpawnBehavior(behaviorId); break; diff --git a/dGame/dBehaviors/VentureVisionBehavior.cpp b/dGame/dBehaviors/VentureVisionBehavior.cpp new file mode 100644 index 00000000..9061deb7 --- /dev/null +++ b/dGame/dBehaviors/VentureVisionBehavior.cpp @@ -0,0 +1,47 @@ +#include "VentureVisionBehavior.h" +#include "BehaviorBranchContext.h" +#include "CharacterComponent.h" +#include "BehaviorContext.h" + +void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch){ + + const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target); + + if (targetEntity) { + auto characterComponent = targetEntity->GetComponent<CharacterComponent>(); + + if (characterComponent) { + if (m_show_collectibles) characterComponent->AddVentureVisionEffect(m_ShowCollectibles); + if (m_show_minibosses) characterComponent->AddVentureVisionEffect(m_ShowMiniBosses); + if (m_show_pet_digs) characterComponent->AddVentureVisionEffect(m_ShowPetDigs); + } + + if (branch.duration > 0) context->RegisterTimerBehavior(this, branch); + } +} + +void VentureVisionBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { + const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target); + + if (targetEntity) { + auto characterComponent = targetEntity->GetComponent<CharacterComponent>(); + + if (characterComponent) { + if (m_show_collectibles) characterComponent->RemoveVentureVisionEffect(m_ShowCollectibles); + if (m_show_minibosses) characterComponent->RemoveVentureVisionEffect(m_ShowMiniBosses); + if (m_show_pet_digs) characterComponent->RemoveVentureVisionEffect(m_ShowPetDigs); + } + } +} + +void VentureVisionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + UnCast(context, branch); +} + +void VentureVisionBehavior::Load(){ + this->m_show_pet_digs = GetBoolean("show_pet_digs"); + + this->m_show_minibosses = GetBoolean("show_minibosses"); + + this->m_show_collectibles = GetBoolean("show_collectibles"); +} diff --git a/dGame/dBehaviors/VentureVisionBehavior.h b/dGame/dBehaviors/VentureVisionBehavior.h new file mode 100644 index 00000000..96b2642b --- /dev/null +++ b/dGame/dBehaviors/VentureVisionBehavior.h @@ -0,0 +1,41 @@ +#pragma once + +#ifndef __VENTUREVISIONBEHAVIOR__H__ +#define __VENTUREVISIONBEHAVIOR__H__ + +#include "Behavior.h" + +class VentureVisionBehavior final : public Behavior +{ +public: + bool m_show_pet_digs; + + bool m_show_minibosses; + + bool m_show_collectibles; + + const std::string m_ShowCollectibles = "bShowCollectibles"; + + const std::string m_ShowMiniBosses = "bShowMiniBosses"; + + const std::string m_ShowPetDigs = "bShowPetDigs"; + + + /* + * Inherited + */ + + explicit VentureVisionBehavior(const uint32_t behaviorId) : Behavior(behaviorId) + { + } + + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + + void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override; + + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + + void Load() override; +}; + +#endif //!__VENTUREVISIONBEHAVIOR__H__ diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 14354cb5..dd2b69bb 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -785,3 +785,32 @@ ZoneStatistics& CharacterComponent::GetZoneStatisticsForMap(LWOMAPID mapID) { m_ZoneStatistics.insert({ mapID, {0, 0, 0, 0, 0 } }); return m_ZoneStatistics.at(mapID); } + +void CharacterComponent::AddVentureVisionEffect(std::string ventureVisionType) { + const auto ventureVisionTypeIterator = m_ActiveVentureVisionEffects.find(ventureVisionType); + + if (ventureVisionTypeIterator != m_ActiveVentureVisionEffects.end()) { + ventureVisionTypeIterator->second = ++ventureVisionTypeIterator->second; + } else { + // If the effect it not found, insert it into the active effects. + m_ActiveVentureVisionEffects.insert(std::make_pair(ventureVisionType, 1U)); + } + + UpdateClientMinimap(true, ventureVisionType); +} + +void CharacterComponent::RemoveVentureVisionEffect(std::string ventureVisionType) { + const auto ventureVisionTypeIterator = m_ActiveVentureVisionEffects.find(ventureVisionType); + + if (ventureVisionTypeIterator != m_ActiveVentureVisionEffects.end()) { + ventureVisionTypeIterator->second = --ventureVisionTypeIterator->second; + UpdateClientMinimap(ventureVisionTypeIterator->second != 0U, ventureVisionType); + } +} + +void CharacterComponent::UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const { + if (!m_Parent) return; + AMFArrayValue arrayToSend; + arrayToSend.InsertValue(ventureVisionType, showFaction ? static_cast<AMFValue*>(new AMFTrueValue()) : static_cast<AMFValue*>(new AMFFalseValue())); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent ? m_Parent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS, "SetFactionVisibility", &arrayToSend); +} diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 2a0d860b..c7706325 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -274,12 +274,32 @@ public: */ void UpdatePlayerStatistic(StatisticID updateID, uint64_t updateValue = 1); + /** + * Add a venture vision effect to the player minimap. + */ + void AddVentureVisionEffect(std::string ventureVisionType); + + /** + * Remove a venture vision effect from the player minimap. + * When an effect hits 0 active effects, it is deactivated. + */ + void RemoveVentureVisionEffect(std::string ventureVisionType); + + /** + * Update the client minimap to reveal the specified factions + */ + void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const; + /** * Character info regarding this character, including clothing styles, etc. */ Character* m_Character; private: + /** + * The map of active venture vision effects + */ + std::map<std::string, uint32_t> m_ActiveVentureVisionEffects; /** * Whether this character is racing From 8cdb3889153142bddb9f6bdbf52b020c70f36af0 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 4 Jul 2022 23:00:10 -0700 Subject: [PATCH 72/98] Optimize scripts for faster compilation (#597) * Implement Precompiled Headers * First volume of optimizations * Scripts A-B Gonna be doing this in alphabetical order now. * C Scripts and remove unneeded includes from base cppscripts header Remove the MissionComponent and Loot includes from all base scripts and place their needed includes in the respective scripts. * D scripts * F scripts * F scripts 2 Finish up removing extraneous includes from scripts that start with the letter F * G scripts Removing extraneous includes from scripts that start with the letter G * I scripts Removing extraneous includes from scripts that start with the letter I * M-Z scripts Removing extraneous includes from scripts that start with the letter M-Z * Revert "Implement Precompiled Headers" This reverts commit d79d8d499135207e5510184628f4f59f4002e1a5. * Revert "Revert "Implement Precompiled Headers"" This reverts commit 0597faf308fb405f424c6e545b9ed70765e3c797. * Add back in PCH Add back in PCH * Fix CMake Whitespace Remove duplicate file glob Remove newline --- .../dComponents/PropertyManagementComponent.cpp | 1 + dGame/dComponents/RebuildComponent.cpp | 2 ++ dGame/dMission/MissionState.h | 5 +++++ dGame/dUtilities/VanityUtilities.cpp | 2 ++ dScripts/ActNinjaTurret.cpp | 8 -------- dScripts/ActSharkPlayerDeathTrigger.cpp | 17 +++++------------ dScripts/ActSharkPlayerDeathTrigger.h | 3 +-- dScripts/ActivityManager.cpp | 1 + dScripts/AgBugsprayer.cpp | 1 - dScripts/AgBusDoor.cpp | 2 -- dScripts/AgCagedBricksServer.cpp | 6 +++++- dScripts/AgFans.cpp | 3 +++ dScripts/AgFans.h | 3 --- dScripts/AgImagSmashable.h | 1 - dScripts/AgJetEffectServer.cpp | 8 -------- dScripts/AgJetEffectServer.h | 4 ---- dScripts/AgLaserSensorServer.cpp | 4 ++++ dScripts/AgLaserSensorServer.h | 6 ++---- dScripts/AgMonumentBirds.cpp | 1 - dScripts/AgPropGuard.cpp | 2 +- dScripts/AgSalutingNpcs.cpp | 1 - dScripts/AgShipPlayerDeathTrigger.cpp | 4 ---- dScripts/AgSpaceStuff.cpp | 2 -- dScripts/AgSurvivalBuffStation.cpp | 1 - dScripts/AgSurvivalSpiderling.cpp | 1 - dScripts/AgTurret.cpp | 2 -- dScripts/AllCrateChicken.cpp | 2 -- dScripts/AmConsoleTeleportServer.cpp | 3 ++- dScripts/AmConsoleTeleportServer.h | 2 -- dScripts/AmDarklingDragon.cpp | 5 ----- dScripts/AmDarklingMech.cpp | 1 - dScripts/AmDarklingMech.h | 3 --- dScripts/AmDrawBridge.cpp | 1 - dScripts/AmDropshipComputer.cpp | 1 - dScripts/AmShieldGenerator.cpp | 1 - dScripts/AmShieldGeneratorQuickbuild.cpp | 1 - dScripts/AmSkullkinDrill.cpp | 12 ------------ dScripts/AmSkullkinTower.cpp | 1 - dScripts/BaseConsoleTeleportServer.cpp | 2 -- dScripts/BaseEnemyMech.cpp | 4 ---- dScripts/BasePropertyServer.cpp | 7 +++---- dScripts/BasePropertyServer.h | 2 -- dScripts/BaseRandomServer.cpp | 4 ++-- dScripts/BaseRandomServer.h | 6 +++--- dScripts/BaseSurvivalServer.cpp | 2 ++ dScripts/BaseSurvivalServer.h | 1 - dScripts/BaseWavesServer.cpp | 2 ++ dScripts/BaseWavesServer.h | 1 - dScripts/BootyDigServer.cpp | 2 ++ dScripts/BossSpiderQueenEnemyServer.cpp | 7 +++++-- dScripts/BossSpiderQueenEnemyServer.h | 8 +++----- dScripts/BuccaneerValiantShip.cpp | 1 - dScripts/BurningTile.cpp | 2 -- dScripts/CatapultBaseServer.cpp | 2 -- dScripts/CatapultBaseServer.h | 3 --- dScripts/CatapultBouncerServer.cpp | 1 - dScripts/CatapultBouncerServer.h | 3 --- dScripts/CavePrisonCage.cpp | 2 +- dScripts/CavePrisonCage.h | 3 --- dScripts/ChooseYourDestinationNsToNt.cpp | 2 -- dScripts/ChooseYourDestinationNsToNt.h | 1 - dScripts/ClRing.cpp | 2 -- dScripts/CppScripts.cpp | 2 -- dScripts/CppScripts.h | 8 ++------ dScripts/DLUVanityNPC.cpp | 1 + dScripts/DLUVanityNPC.h | 2 +- dScripts/DamagingPets.h | 1 - dScripts/Darkitect.h | 1 - dScripts/EnemySpiderSpawner.cpp | 2 -- dScripts/ExplodingAsset.cpp | 2 +- dScripts/FallingTile.cpp | 1 - dScripts/FlameJetServer.cpp | 1 - dScripts/ForceVolumeServer.cpp | 8 +------- dScripts/FountainOfImagination.cpp | 2 ++ dScripts/FvBounceOverWall.cpp | 1 + dScripts/FvCandle.cpp | 1 + dScripts/FvCandle.h | 1 - dScripts/FvConsoleLeftQuickbuild.cpp | 3 --- dScripts/FvConsoleRightQuickbuild.cpp | 3 --- dScripts/FvFacilityBrick.cpp | 4 ---- dScripts/FvFong.cpp | 2 +- dScripts/FvFreeGfNinjas.cpp | 1 + dScripts/FvHorsemenTrigger.cpp | 5 ----- dScripts/FvMaelstromCavalry.cpp | 8 -------- dScripts/FvMaelstromCavalry.h | 1 - dScripts/FvMaelstromDragon.cpp | 1 - dScripts/FvMaelstromDragon.h | 1 - dScripts/FvPassThroughWall.cpp | 1 + dScripts/FvRaceSmashEggImagineServer.cpp | 3 ++- dScripts/GfBanana.cpp | 5 ----- dScripts/GfBananaCluster.cpp | 1 + dScripts/GfCampfire.cpp | 3 --- dScripts/GfJailWalls.cpp | 1 - dScripts/GfTikiTorch.cpp | 2 +- dScripts/ImaginationBackpackHealServer.cpp | 1 + dScripts/ImaginationShrineServer.cpp | 1 - dScripts/ImgBrickConsoleQB.cpp | 8 -------- dScripts/ImgBrickConsoleQB.h | 1 - ...tanceExitTransferPlayerToLastNonInstance.cpp | 3 --- dScripts/LegoDieRoll.cpp | 3 +-- dScripts/MastTeleport.cpp | 1 - dScripts/MinigameTreasureChestServer.cpp | 3 +-- dScripts/MissionConsoleServer.cpp | 1 - dScripts/MissionConsoleServer.h | 6 ------ dScripts/MonCoreNookDoors.cpp | 2 -- dScripts/MonCoreSmashableDoors.cpp | 2 -- dScripts/NjEarthDragonPetServer.cpp | 1 + dScripts/NjEarthDragonPetServer.h | 1 - dScripts/NjJayMissionItems.h | 2 ++ dScripts/NjMonastryBossInstance.cpp | 5 ++--- dScripts/NjNPCMissionSpinjitzuServer.h | 1 + dScripts/NjNyaMissionitems.h | 2 ++ dScripts/NjPetSpawnerServer.cpp | 5 ----- dScripts/NjPetSpawnerServer.h | 6 ------ dScripts/NjhubLavaPlayerDeathTrigger.cpp | 1 + dScripts/NjhubLavaPlayerDeathTrigger.h | 1 - dScripts/NpcAgCourseStarter.cpp | 11 +---------- dScripts/NpcCowboyServer.cpp | 2 +- dScripts/NpcNjAssistantServer.cpp | 1 + dScripts/NpcNpSpacemanBob.cpp | 6 +----- dScripts/NpcWispServer.cpp | 2 -- dScripts/NsConcertChoiceBuildManager.cpp | 1 - dScripts/NsConcertInstrument.cpp | 1 + dScripts/NsConcertQuickBuild.cpp | 2 +- dScripts/NsJohnnyMissionServer.cpp | 1 + dScripts/NsLegoClubDoor.cpp | 3 +-- dScripts/NsLegoClubDoor.h | 1 - dScripts/NsLupTeleport.cpp | 3 +-- dScripts/NsLupTeleport.h | 1 - dScripts/NsModularBuild.cpp | 3 +-- dScripts/NsQbImaginationStatue.cpp | 3 --- dScripts/NsTokenConsoleServer.cpp | 1 - dScripts/NtAssemblyTubeServer.cpp | 6 +----- dScripts/NtCombatChallengeDummy.cpp | 1 - dScripts/NtCombatChallengeExplodingDummy.cpp | 1 - dScripts/NtCombatChallengeServer.cpp | 17 ----------------- dScripts/NtConsoleTeleportServer.cpp | 3 ++- dScripts/NtConsoleTeleportServer.h | 1 - dScripts/NtDirtCloudServer.cpp | 1 - dScripts/NtDukeServer.cpp | 1 + dScripts/NtFactionSpyServer.cpp | 1 + dScripts/NtHaelServer.cpp | 1 + dScripts/NtParadoxTeleServer.cpp | 6 +----- dScripts/NtSentinelWalkwayServer.cpp | 6 +----- dScripts/NtVentureCannonServer.cpp | 1 - dScripts/NtVentureSpeedPadServer.cpp | 1 - dScripts/NtXRayServer.cpp | 2 -- dScripts/PetDigBuild.cpp | 1 + dScripts/PetDigServer.cpp | 3 +-- dScripts/PrSeagullFly.cpp | 1 + dScripts/PrWhistle.cpp | 2 +- dScripts/PropertyDeathPlane.cpp | 4 ---- dScripts/PropertyDevice.cpp | 1 + dScripts/QbEnemyStunner.cpp | 2 -- dScripts/RaceImagineCrateServer.cpp | 2 +- dScripts/RaceImaginePowerup.cpp | 4 +--- dScripts/RaceMaelstromGeiser.cpp | 8 -------- dScripts/RaceSmashServer.cpp | 1 + dScripts/SGCannon.cpp | 2 +- dScripts/ScriptComponent.cpp | 1 - dScripts/ScriptComponent.h | 1 - dScripts/ScriptedPowerupSpawner.cpp | 1 - dScripts/SpawnGryphonServer.cpp | 1 + dScripts/SpawnLionServer.cpp | 1 + dScripts/SpawnSaberCatServer.cpp | 1 + dScripts/SpawnShrakeServer.cpp | 1 + dScripts/SpawnStegoServer.cpp | 1 + dScripts/SpecialImaginePowerupSpawner.cpp | 1 - dScripts/SsModularBuildServer.cpp | 3 +-- dScripts/StoryBoxInteractServer.cpp | 1 - dScripts/Sunflower.cpp | 1 + dScripts/TokenConsoleServer.cpp | 2 -- dScripts/TreasureChestDragonServer.cpp | 1 - dScripts/TriggerAmbush.cpp | 7 ------- dScripts/VeBricksampleServer.cpp | 1 + dScripts/WaveBossApe.cpp | 1 + dScripts/WaveBossHammerling.cpp | 1 + dScripts/WaveBossHorsemen.cpp | 1 + dScripts/WaveBossSpiderling.cpp | 1 + dScripts/WhFans.cpp | 3 +++ dScripts/WhFans.h | 4 ---- dScripts/WildAmbients.cpp | 2 -- dScripts/WishingWellServer.cpp | 2 -- dScripts/ZoneAgMedProperty.cpp | 2 +- dScripts/ZoneAgProperty.cpp | 4 +--- dScripts/ZoneAgProperty.h | 1 - dScripts/ZoneAgSpiderQueen.cpp | 2 -- dScripts/ZoneAgSurvival.h | 1 + dScripts/ZoneFvProperty.cpp | 1 + dScripts/ZoneGfProperty.cpp | 1 + dScripts/ZoneNsMedProperty.cpp | 1 + dScripts/ZoneNsProperty.cpp | 1 + 192 files changed, 135 insertions(+), 371 deletions(-) delete mode 100644 dScripts/MissionConsoleServer.cpp delete mode 100644 dScripts/MissionConsoleServer.h delete mode 100644 dScripts/NjPetSpawnerServer.cpp delete mode 100644 dScripts/NjPetSpawnerServer.h diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 7faf9394..04e2f633 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -2,6 +2,7 @@ #include <sstream> +#include "MissionComponent.h" #include "EntityManager.h" #include "PropertyDataMessage.h" #include "UserManager.h" diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 5e313a7a..603a18cc 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -6,6 +6,8 @@ #include "Game.h" #include "dLogger.h" #include "CharacterComponent.h" +#include "MissionComponent.h" +#include "MissionTaskType.h" #include "dServer.h" #include "PacketUtils.h" diff --git a/dGame/dMission/MissionState.h b/dGame/dMission/MissionState.h index 161a4021..c189c708 100644 --- a/dGame/dMission/MissionState.h +++ b/dGame/dMission/MissionState.h @@ -1,5 +1,8 @@ #pragma once +#ifndef __MISSIONSTATE__H__ +#define __MISSIONSTATE__H__ + /** * Represents the possible states a mission can be in */ @@ -49,3 +52,5 @@ enum class MissionState : int { */ MISSION_STATE_COMPLETE_READY_TO_COMPLETE = 12 }; + +#endif //!__MISSIONSTATE__H__ diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index e8fd4cf0..c3f8f6b4 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -11,6 +11,8 @@ #include "dConfig.h" #include "dServer.h" #include "tinyxml2.h" +#include "Game.h" +#include "dLogger.h" #include <fstream> diff --git a/dScripts/ActNinjaTurret.cpp b/dScripts/ActNinjaTurret.cpp index 4aecd327..8c361ad7 100644 --- a/dScripts/ActNinjaTurret.cpp +++ b/dScripts/ActNinjaTurret.cpp @@ -2,18 +2,12 @@ void ActNinjaTurret::OnRebuildNotifyState(Entity* self, eRebuildState state) { - Game::logger->Log("ActNinjaTurret", "Rebuild state: %i\n", state); - if (state == eRebuildState::REBUILD_COMPLETED) { - Game::logger->Log("ActNinjaTurret", "I am build\n"); - self->SetVar(u"AmBuilt", true); } else if (state == eRebuildState::REBUILD_RESETTING) { - Game::logger->Log("ActNinjaTurret", "I am not build\n"); - self->SetVar(u"AmBuilt", false); } } @@ -22,8 +16,6 @@ void ActNinjaTurret::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { - Game::logger->Log("ActNinjaTurret", "Got server side event %s\n", args.c_str()); - if (args == "ISpawned" && self->GetVar<bool>(u"AmBuilt")) { sender->Smash(); diff --git a/dScripts/ActSharkPlayerDeathTrigger.cpp b/dScripts/ActSharkPlayerDeathTrigger.cpp index 4185496c..a8aaac8b 100644 --- a/dScripts/ActSharkPlayerDeathTrigger.cpp +++ b/dScripts/ActSharkPlayerDeathTrigger.cpp @@ -1,24 +1,17 @@ #include "ActSharkPlayerDeathTrigger.h" +#include "MissionComponent.h" +#include "MissionTaskType.h" #include "Entity.h" -#include "GameMessages.h" -#include "Game.h" -#include "dLogger.h" - -void ActSharkPlayerDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { - -} void ActSharkPlayerDeathTrigger::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args == "achieve") { - MissionComponent* mis = static_cast<MissionComponent*>(sender->GetComponent(COMPONENT_TYPE_MISSION)); - if (!mis) return; + auto missionComponent = sender->GetComponent<MissionComponent>(); + if (!missionComponent) return; - mis->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, 8419); + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, 8419); if (sender->GetIsDead() || !sender->GetPlayerReadyForUpdates()) return; //Don't kill already dead players or players not ready - - Game::logger->Log("ActSharkPlayerDeathTrigger", "%i\n", self->GetLOT()); if (sender->GetCharacter()) { sender->Smash(self->GetObjectID(), eKillType::VIOLENT, u"big-shark-death"); diff --git a/dScripts/ActSharkPlayerDeathTrigger.h b/dScripts/ActSharkPlayerDeathTrigger.h index 6f00fd00..cbd3c960 100644 --- a/dScripts/ActSharkPlayerDeathTrigger.h +++ b/dScripts/ActSharkPlayerDeathTrigger.h @@ -4,8 +4,7 @@ class ActSharkPlayerDeathTrigger : public CppScripts::Script { public: - void OnCollisionPhantom(Entity* self, Entity* target); void OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, - int32_t param3); + int32_t param3) override; }; diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index f84963df..e464b20d 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -4,6 +4,7 @@ #include "LeaderboardManager.h" #include "GameMessages.h" #include <algorithm> +#include "dLogger.h" bool ActivityManager::IsPlayerInActivity(Entity *self, LWOOBJID playerID) { const auto* sac = self->GetComponent<ScriptedActivityComponent>(); diff --git a/dScripts/AgBugsprayer.cpp b/dScripts/AgBugsprayer.cpp index 26e2880c..cfea5cf4 100644 --- a/dScripts/AgBugsprayer.cpp +++ b/dScripts/AgBugsprayer.cpp @@ -1,7 +1,6 @@ #include "AgBugsprayer.h" #include "SkillComponent.h" - void AgBugsprayer::OnRebuildComplete(Entity* self, Entity* target) { self->AddTimer("castSkill", 1); diff --git a/dScripts/AgBusDoor.cpp b/dScripts/AgBusDoor.cpp index 8c22dc8c..4453fcad 100644 --- a/dScripts/AgBusDoor.cpp +++ b/dScripts/AgBusDoor.cpp @@ -1,8 +1,6 @@ #include "AgBusDoor.h" #include "Entity.h" #include "GameMessages.h" -#include "Game.h" -#include "dLogger.h" #include "ProximityMonitorComponent.h" void AgBusDoor::OnStartup(Entity* self) { diff --git a/dScripts/AgCagedBricksServer.cpp b/dScripts/AgCagedBricksServer.cpp index 7ad6858c..ec9f5306 100644 --- a/dScripts/AgCagedBricksServer.cpp +++ b/dScripts/AgCagedBricksServer.cpp @@ -12,7 +12,11 @@ void AgCagedBricksServer::OnUse(Entity* self, Entity* user) { } //Set the flag & mission status: - user->GetCharacter()->SetPlayerFlag(74, true); + auto character = user->GetCharacter(); + + if (!character) return; + + character->SetPlayerFlag(74, true); //Remove the maelstrom cube: auto inv = static_cast<InventoryComponent*>(user->GetComponent(COMPONENT_TYPE_INVENTORY)); diff --git a/dScripts/AgFans.cpp b/dScripts/AgFans.cpp index 996a58e7..dbc09547 100644 --- a/dScripts/AgFans.cpp +++ b/dScripts/AgFans.cpp @@ -1,5 +1,8 @@ #include "AgFans.h" +#include "EntityManager.h" +#include "GameMessages.h" +#include "PhantomPhysicsComponent.h" #include "RenderComponent.h" void AgFans::OnStartup(Entity* self) { diff --git a/dScripts/AgFans.h b/dScripts/AgFans.h index 09cc89d9..800267af 100644 --- a/dScripts/AgFans.h +++ b/dScripts/AgFans.h @@ -1,8 +1,5 @@ #pragma once #include "CppScripts.h" -#include "GameMessages.h" -#include "EntityManager.h" -#include "PhantomPhysicsComponent.h" class AgFans : public CppScripts::Script { diff --git a/dScripts/AgImagSmashable.h b/dScripts/AgImagSmashable.h index 88efe3fe..fd047c34 100644 --- a/dScripts/AgImagSmashable.h +++ b/dScripts/AgImagSmashable.h @@ -4,7 +4,6 @@ class AgImagSmashable : public CppScripts::Script { public: void OnDie(Entity* self, Entity* killer); - private: void CrateAnimal(Entity* self); }; \ No newline at end of file diff --git a/dScripts/AgJetEffectServer.cpp b/dScripts/AgJetEffectServer.cpp index 0572fb46..599f4d01 100644 --- a/dScripts/AgJetEffectServer.cpp +++ b/dScripts/AgJetEffectServer.cpp @@ -1,15 +1,8 @@ #include "AgJetEffectServer.h" - #include "GameMessages.h" #include "EntityManager.h" -#include "PhantomPhysicsComponent.h" #include "SkillComponent.h" - -void AgJetEffectServer::OnStartup(Entity* self) -{ -} - void AgJetEffectServer::OnUse(Entity* self, Entity* user) { if (inUse) @@ -41,7 +34,6 @@ void AgJetEffectServer::OnUse(Entity* self, Entity* user) GameMessages::SendPlayFXEffect(effect, 641, u"create", "radarDish", LWOOBJID_EMPTY, 1, 1, true); self->AddTimer("radarDish", 2); - //self->AddTimer("PlayEffect", 2.5f); self->AddTimer("CineDone", 9); } diff --git a/dScripts/AgJetEffectServer.h b/dScripts/AgJetEffectServer.h index 0069d0bb..094c73d2 100644 --- a/dScripts/AgJetEffectServer.h +++ b/dScripts/AgJetEffectServer.h @@ -4,16 +4,12 @@ class AgJetEffectServer final : public CppScripts::Script { public: - void OnStartup(Entity* self) override; - void OnUse(Entity* self, Entity* user) override; void OnRebuildComplete(Entity* self, Entity* target) override; void OnTimerDone(Entity* self, std::string timerName) override; - private: LWOOBJID builder; - bool inUse; }; diff --git a/dScripts/AgLaserSensorServer.cpp b/dScripts/AgLaserSensorServer.cpp index f1d87468..342cc7e1 100644 --- a/dScripts/AgLaserSensorServer.cpp +++ b/dScripts/AgLaserSensorServer.cpp @@ -1,5 +1,9 @@ #include "AgLaserSensorServer.h" +#include "PhantomPhysicsComponent.h" +#include "SkillComponent.h" +#include "EntityManager.h" +#include "AgMonumentLaserServer.h" #include "EntityManager.h" void AgLaserSensorServer::OnStartup(Entity* self) { diff --git a/dScripts/AgLaserSensorServer.h b/dScripts/AgLaserSensorServer.h index 92d33efb..72e09dd8 100644 --- a/dScripts/AgLaserSensorServer.h +++ b/dScripts/AgLaserSensorServer.h @@ -1,9 +1,7 @@ #pragma once #include "CppScripts.h" -#include "PhantomPhysicsComponent.h" -#include "SkillComponent.h" -#include "EntityManager.h" -#include "AgMonumentLaserServer.h" + +class SkillComponent; class AgLaserSensorServer : public CppScripts::Script { public: diff --git a/dScripts/AgMonumentBirds.cpp b/dScripts/AgMonumentBirds.cpp index 212a0631..5870cfff 100644 --- a/dScripts/AgMonumentBirds.cpp +++ b/dScripts/AgMonumentBirds.cpp @@ -1,6 +1,5 @@ #include "AgMonumentBirds.h" #include "GameMessages.h" -#include "DestroyableComponent.h" //-------------------------------------------------------------- //Makes the ag birds fly away when you get close and smashes them. diff --git a/dScripts/AgPropGuard.cpp b/dScripts/AgPropGuard.cpp index 18fcd7c2..b05eef4f 100644 --- a/dScripts/AgPropGuard.cpp +++ b/dScripts/AgPropGuard.cpp @@ -1,9 +1,9 @@ #include "AgPropGuard.h" #include "Entity.h" #include "Character.h" -#include "GameMessages.h" #include "EntityManager.h" #include "InventoryComponent.h" +#include "MissionComponent.h" #include "Item.h" void AgPropGuard::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) diff --git a/dScripts/AgSalutingNpcs.cpp b/dScripts/AgSalutingNpcs.cpp index 6a39f06f..618dc631 100644 --- a/dScripts/AgSalutingNpcs.cpp +++ b/dScripts/AgSalutingNpcs.cpp @@ -1,5 +1,4 @@ #include "AgSalutingNpcs.h" - #include "GameMessages.h" diff --git a/dScripts/AgShipPlayerDeathTrigger.cpp b/dScripts/AgShipPlayerDeathTrigger.cpp index 6ba2d193..d20edee7 100644 --- a/dScripts/AgShipPlayerDeathTrigger.cpp +++ b/dScripts/AgShipPlayerDeathTrigger.cpp @@ -1,12 +1,8 @@ #include "AgShipPlayerDeathTrigger.h" #include "Entity.h" -#include "GameMessages.h" -#include "Game.h" -#include "dLogger.h" void AgShipPlayerDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { if (target->GetLOT() == 1 && !target->GetIsDead()) { - Game::logger->Log("CppScripts::AgShipPlayerDeathTrigger", "Attempting to kill %llu\n", target->GetObjectID()); target->Smash(self->GetObjectID(), eKillType::VIOLENT, u"electro-shock-death"); } } \ No newline at end of file diff --git a/dScripts/AgSpaceStuff.cpp b/dScripts/AgSpaceStuff.cpp index 507b908f..18e4eb47 100644 --- a/dScripts/AgSpaceStuff.cpp +++ b/dScripts/AgSpaceStuff.cpp @@ -1,9 +1,7 @@ #include "AgSpaceStuff.h" #include "GeneralUtils.h" #include "GameMessages.h" -#include "dZoneManager.h" #include "EntityManager.h" -#include "Game.h" void AgSpaceStuff::OnStartup(Entity* self) { self->AddTimer("FloaterScale", 5.0f); diff --git a/dScripts/AgSurvivalBuffStation.cpp b/dScripts/AgSurvivalBuffStation.cpp index 86a2f653..8a6cfb05 100644 --- a/dScripts/AgSurvivalBuffStation.cpp +++ b/dScripts/AgSurvivalBuffStation.cpp @@ -3,7 +3,6 @@ #include "EntityManager.h" #include "GameMessages.h" #include "SkillComponent.h" -#include "dLogger.h" #include "TeamManager.h" void AgSurvivalBuffStation::OnRebuildComplete(Entity* self, Entity* target) { diff --git a/dScripts/AgSurvivalSpiderling.cpp b/dScripts/AgSurvivalSpiderling.cpp index ebb0395b..d44455d8 100644 --- a/dScripts/AgSurvivalSpiderling.cpp +++ b/dScripts/AgSurvivalSpiderling.cpp @@ -1,6 +1,5 @@ #include "AgSurvivalSpiderling.h" #include "BaseCombatAIComponent.h" -#include "GameMessages.h" void AgSurvivalSpiderling::OnStartup(Entity *self) { BaseWavesGenericEnemy::OnStartup(self); diff --git a/dScripts/AgTurret.cpp b/dScripts/AgTurret.cpp index a439ecf1..6db493d5 100644 --- a/dScripts/AgTurret.cpp +++ b/dScripts/AgTurret.cpp @@ -1,6 +1,4 @@ #include "AgTurret.h" -#include "EntityManager.h" -#include "RebuildComponent.h" #include "GameMessages.h" void AgTurret::OnStartup(Entity* self) { diff --git a/dScripts/AllCrateChicken.cpp b/dScripts/AllCrateChicken.cpp index c4aeec80..1a368a80 100644 --- a/dScripts/AllCrateChicken.cpp +++ b/dScripts/AllCrateChicken.cpp @@ -1,6 +1,4 @@ #include "AllCrateChicken.h" -#include "dCommonVars.h" -#include "EntityManager.h" #include "Entity.h" void AllCrateChicken::OnStartup(Entity* self) { diff --git a/dScripts/AmConsoleTeleportServer.cpp b/dScripts/AmConsoleTeleportServer.cpp index 5c60e827..5087aae2 100644 --- a/dScripts/AmConsoleTeleportServer.cpp +++ b/dScripts/AmConsoleTeleportServer.cpp @@ -1,5 +1,6 @@ #include "AmConsoleTeleportServer.h" - +#include "ChooseYourDestinationNsToNt.h" +#include "AMFFormat.h" void AmConsoleTeleportServer::OnStartup(Entity* self) { diff --git a/dScripts/AmConsoleTeleportServer.h b/dScripts/AmConsoleTeleportServer.h index ac241ee5..8236e67e 100644 --- a/dScripts/AmConsoleTeleportServer.h +++ b/dScripts/AmConsoleTeleportServer.h @@ -1,8 +1,6 @@ #pragma once #include "CppScripts.h" -#include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" class AmConsoleTeleportServer : public CppScripts::Script, BaseConsoleTeleportServer { diff --git a/dScripts/AmDarklingDragon.cpp b/dScripts/AmDarklingDragon.cpp index be87f466..94066167 100644 --- a/dScripts/AmDarklingDragon.cpp +++ b/dScripts/AmDarklingDragon.cpp @@ -6,7 +6,6 @@ #include "SkillComponent.h" #include "BaseCombatAIComponent.h" - void AmDarklingDragon::OnStartup(Entity* self) { self->SetVar<int32_t>(u"weakspot", 0); @@ -48,15 +47,11 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t auto* destroyableComponent = self->GetComponent<DestroyableComponent>(); if (destroyableComponent != nullptr) { - Game::logger->Log("AmDarklingDragon", "Armor is %i\n", destroyableComponent->GetArmor()); - if (destroyableComponent->GetArmor() > 0) return; auto weakpoint = self->GetVar<int32_t>(u"weakpoint"); if (weakpoint == 0) { - Game::logger->Log("AmDarklingDragon", "Activating weakpoint\n"); - self->AddTimer("ReviveTimer", 12); auto* baseCombatAIComponent = self->GetComponent<BaseCombatAIComponent>(); diff --git a/dScripts/AmDarklingMech.cpp b/dScripts/AmDarklingMech.cpp index 59eb6b45..33c3fcbf 100644 --- a/dScripts/AmDarklingMech.cpp +++ b/dScripts/AmDarklingMech.cpp @@ -1,5 +1,4 @@ #include "AmDarklingMech.h" -#include "DestroyableComponent.h" void AmDarklingMech::OnStartup(Entity* self) { diff --git a/dScripts/AmDarklingMech.h b/dScripts/AmDarklingMech.h index 363e4db8..cc179795 100644 --- a/dScripts/AmDarklingMech.h +++ b/dScripts/AmDarklingMech.h @@ -1,8 +1,5 @@ #pragma once #include "CppScripts.h" -#include "ChooseYourDestinationNsToNt.h" -#include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" #include "BaseEnemyMech.h" class AmDarklingMech : public BaseEnemyMech diff --git a/dScripts/AmDrawBridge.cpp b/dScripts/AmDrawBridge.cpp index 2c774ca1..8e52e3e4 100644 --- a/dScripts/AmDrawBridge.cpp +++ b/dScripts/AmDrawBridge.cpp @@ -3,7 +3,6 @@ #include "GameMessages.h" #include "SimplePhysicsComponent.h" - void AmDrawBridge::OnStartup(Entity* self) { self->SetNetworkVar(u"InUse", false); diff --git a/dScripts/AmDropshipComputer.cpp b/dScripts/AmDropshipComputer.cpp index dfc17474..d25bd4f2 100644 --- a/dScripts/AmDropshipComputer.cpp +++ b/dScripts/AmDropshipComputer.cpp @@ -2,7 +2,6 @@ #include "MissionComponent.h" #include "RebuildComponent.h" #include "InventoryComponent.h" -#include "GameMessages.h" #include "dZoneManager.h" void AmDropshipComputer::OnStartup(Entity* self) diff --git a/dScripts/AmShieldGenerator.cpp b/dScripts/AmShieldGenerator.cpp index 1f9b5f9c..0e942612 100644 --- a/dScripts/AmShieldGenerator.cpp +++ b/dScripts/AmShieldGenerator.cpp @@ -6,7 +6,6 @@ #include "BaseCombatAIComponent.h" #include "SkillComponent.h" - void AmShieldGenerator::OnStartup(Entity* self) { self->SetProximityRadius(20, "shield"); diff --git a/dScripts/AmShieldGeneratorQuickbuild.cpp b/dScripts/AmShieldGeneratorQuickbuild.cpp index a2d99ad2..aa80148c 100644 --- a/dScripts/AmShieldGeneratorQuickbuild.cpp +++ b/dScripts/AmShieldGeneratorQuickbuild.cpp @@ -8,7 +8,6 @@ #include "RebuildComponent.h" #include "MissionComponent.h" - void AmShieldGeneratorQuickbuild::OnStartup(Entity* self) { self->SetProximityRadius(20, "shield"); diff --git a/dScripts/AmSkullkinDrill.cpp b/dScripts/AmSkullkinDrill.cpp index 8b4986d0..d5b7e7e6 100644 --- a/dScripts/AmSkullkinDrill.cpp +++ b/dScripts/AmSkullkinDrill.cpp @@ -87,8 +87,6 @@ void AmSkullkinDrill::TriggerDrill(Entity* self) if (standObj != nullptr) { - Game::logger->Log("AmSkullkinDrill", "Disabling knockback\n"); - standObj->SetVar(u"bActive", false); } @@ -213,8 +211,6 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) if (standObj != nullptr) { - Game::logger->Log("AmSkullkinDrill", "Disabling knockback\n"); - standObj->SetVar(u"bActive", false); } @@ -302,8 +298,6 @@ void AmSkullkinDrill::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { - Game::logger->Log("AmSkullkinDrill", "Timer: %s\n", timerName.c_str()); - if (timerName == "killDrill") { const auto childID = self->GetVar<LWOOBJID>(u"ChildSmash"); @@ -323,8 +317,6 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) if (standObj != nullptr) { - Game::logger->Log("AmSkullkinDrill", "Enabling knockback\n"); - standObj->SetVar(u"bActive", true); } @@ -351,8 +343,6 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { const auto& animName = data[1]; - Game::logger->Log("AmSkullkinDrill", "Anim done: %s\n", animName.c_str()); - const auto playerID = self->GetVar<LWOOBJID>(u"userID"); auto* player = EntityManager::Instance()->GetEntity(playerID); @@ -364,8 +354,6 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) if (animName == "spinjitzu-staff-windup") { - Game::logger->Log("AmSkullkinDrill", "Triggering drill\n"); - TriggerDrill(self); GameMessages::SendPlayAnimation(player, u"spinjitzu-staff-loop"); diff --git a/dScripts/AmSkullkinTower.cpp b/dScripts/AmSkullkinTower.cpp index 6869b94b..1b9e8c6d 100644 --- a/dScripts/AmSkullkinTower.cpp +++ b/dScripts/AmSkullkinTower.cpp @@ -2,7 +2,6 @@ #include "EntityManager.h" #include "DestroyableComponent.h" #include "MovingPlatformComponent.h" -#include "dCommonVars.h" #include "GameMessages.h" #include "MissionComponent.h" diff --git a/dScripts/BaseConsoleTeleportServer.cpp b/dScripts/BaseConsoleTeleportServer.cpp index ef2d00e0..6475e025 100644 --- a/dScripts/BaseConsoleTeleportServer.cpp +++ b/dScripts/BaseConsoleTeleportServer.cpp @@ -1,8 +1,6 @@ #include "BaseConsoleTeleportServer.h" #include "GameMessages.h" #include "Player.h" -#include "RocketLaunchpadControlComponent.h" - void BaseConsoleTeleportServer::BaseOnUse(Entity* self, Entity* user) { diff --git a/dScripts/BaseEnemyMech.cpp b/dScripts/BaseEnemyMech.cpp index eb95095a..17c7a347 100644 --- a/dScripts/BaseEnemyMech.cpp +++ b/dScripts/BaseEnemyMech.cpp @@ -1,8 +1,5 @@ #include "BaseEnemyMech.h" #include "Entity.h" -#include "GameMessages.h" -#include "Game.h" -#include "dLogger.h" #include "ControllablePhysicsComponent.h" #include "EntityManager.h" #include "dpWorld.h" @@ -21,7 +18,6 @@ void BaseEnemyMech::OnDie(Entity* self, Entity* killer) { if (!controlPhys) return; NiPoint3 newLoc = {controlPhys->GetPosition().x, dpWorld::Instance().GetHeightAtPoint(controlPhys->GetPosition()), controlPhys->GetPosition().z }; - //NiPoint3 newLoc = { controlPhys->GetPosition().x, controlPhys->GetPosition().y, controlPhys->GetPosition().z }; EntityInfo info = EntityInfo(); std::vector<LDFBaseData*> cfg; diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 27e3767b..e7a95844 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -1,6 +1,4 @@ #include "BasePropertyServer.h" -#include <utility> -#include "dCommonVars.h" #include "GameMessages.h" #include "EntityManager.h" #include "dZoneManager.h" @@ -8,7 +6,8 @@ #include "DestroyableComponent.h" #include "Entity.h" #include "RenderComponent.h" -#include "dServer.h" +#include "PropertyManagementComponent.h" +#include "MissionComponent.h" void BasePropertyServer::SetGameVariables(Entity *self) { self->SetVar<std::string>(ClaimMarkerGroup, ""); @@ -337,7 +336,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); // No guard for the spider instance fight - if (Game::server->GetZoneID() == 1150) + if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1150) return; const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar<std::string>(GuardGroup)); diff --git a/dScripts/BasePropertyServer.h b/dScripts/BasePropertyServer.h index 8d9a2d7e..79a52f54 100644 --- a/dScripts/BasePropertyServer.h +++ b/dScripts/BasePropertyServer.h @@ -1,7 +1,5 @@ #pragma once #include "CppScripts.h" -#include "PropertyManagementComponent.h" -#include "PropertyVendorComponent.h" class BasePropertyServer : public CppScripts::Script { public: diff --git a/dScripts/BaseRandomServer.cpp b/dScripts/BaseRandomServer.cpp index 182544be..7026178c 100644 --- a/dScripts/BaseRandomServer.cpp +++ b/dScripts/BaseRandomServer.cpp @@ -1,8 +1,8 @@ #include "BaseRandomServer.h" -#include "EntityManager.h" #include "dZoneManager.h" -#include "DestroyableComponent.h" #include "Spawner.h" +#include "dLogger.h" +#include "Entity.h" void BaseRandomServer::BaseStartup(Entity* self) { diff --git a/dScripts/BaseRandomServer.h b/dScripts/BaseRandomServer.h index d04414f1..68aadf30 100644 --- a/dScripts/BaseRandomServer.h +++ b/dScripts/BaseRandomServer.h @@ -1,8 +1,8 @@ #pragma once -#include "CppScripts.h" -#include "Entity.h" -#include "dCommonVars.h" +#include <map> + +class Spawner; class BaseRandomServer { public: diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index dd9b9365..f6a326e8 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -4,6 +4,8 @@ #include "EntityManager.h" #include "dZoneManager.h" #include "Player.h" +#include "MissionTaskType.h" +#include "MissionComponent.h" #include "Character.h" void BaseSurvivalServer::SetGameVariables(Entity *self) { diff --git a/dScripts/BaseSurvivalServer.h b/dScripts/BaseSurvivalServer.h index 55e1f8f9..c85f1bbf 100644 --- a/dScripts/BaseSurvivalServer.h +++ b/dScripts/BaseSurvivalServer.h @@ -1,6 +1,5 @@ #pragma once #include "ActivityManager.h" -#include "CppScripts.h" /** * State for each active game diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 29706f52..2c8a2edd 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -4,6 +4,8 @@ #include "EntityManager.h" #include "dZoneManager.h" #include "Player.h" +#include "MissionTaskType.h" +#include "MissionComponent.h" #include "Character.h" // Done diff --git a/dScripts/BaseWavesServer.h b/dScripts/BaseWavesServer.h index cb04f50b..3dc90da8 100644 --- a/dScripts/BaseWavesServer.h +++ b/dScripts/BaseWavesServer.h @@ -1,6 +1,5 @@ #pragma once #include "ActivityManager.h" -#include "CppScripts.h" /** * State for each active game diff --git a/dScripts/BootyDigServer.cpp b/dScripts/BootyDigServer.cpp index eeb3bfd4..50d873e0 100644 --- a/dScripts/BootyDigServer.cpp +++ b/dScripts/BootyDigServer.cpp @@ -1,6 +1,8 @@ #include "BootyDigServer.h" #include "EntityManager.h" #include "RenderComponent.h" +#include "MissionComponent.h" +#include "MissionTaskType.h" void BootyDigServer::OnStartup(Entity *self) { auto* zoneControlObject = EntityManager::Instance()->GetZoneControlEntity(); diff --git a/dScripts/BossSpiderQueenEnemyServer.cpp b/dScripts/BossSpiderQueenEnemyServer.cpp index 9896fd45..dd0b80c8 100644 --- a/dScripts/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/BossSpiderQueenEnemyServer.cpp @@ -6,7 +6,10 @@ #include "EntityManager.h" #include "Entity.h" #include "dZoneManager.h" -#include "dServer.h" + +#include "DestroyableComponent.h" +#include "ControllablePhysicsComponent.h" +#include "BaseCombatAIComponent.h" #include "GameMessages.h" #include "SkillComponent.h" @@ -49,7 +52,7 @@ void BossSpiderQueenEnemyServer::OnStartup(Entity* self) { } void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { - if (Game::server->GetZoneID() == instanceZoneID) { + if (dZoneManager::Instance()->GetZoneID().GetMapID() == instanceZoneID) { auto* missionComponent = killer->GetComponent<MissionComponent>(); if (missionComponent == nullptr) return; diff --git a/dScripts/BossSpiderQueenEnemyServer.h b/dScripts/BossSpiderQueenEnemyServer.h index 34faf055..f3219cf7 100644 --- a/dScripts/BossSpiderQueenEnemyServer.h +++ b/dScripts/BossSpiderQueenEnemyServer.h @@ -1,10 +1,6 @@ #pragma once #include "CppScripts.h" -#include "DestroyableComponent.h" -#include "ControllablePhysicsComponent.h" -#include "BaseCombatAIComponent.h" - /* -------------------------------------------------------------- @@ -17,7 +13,9 @@ -------------------------------------------------------------- */ - +class DestroyableComponent; +class ControllablePhysicsComponent; +class BaseCombatAIComponent; class BossSpiderQueenEnemyServer final : public CppScripts::Script { public: void OnStartup(Entity* self) override; diff --git a/dScripts/BuccaneerValiantShip.cpp b/dScripts/BuccaneerValiantShip.cpp index 1cc1e633..710a0d1a 100644 --- a/dScripts/BuccaneerValiantShip.cpp +++ b/dScripts/BuccaneerValiantShip.cpp @@ -1,6 +1,5 @@ #include "BuccaneerValiantShip.h" #include "SkillComponent.h" -#include "dLogger.h" void BuccaneerValiantShip::OnStartup(Entity* self) { self->AddCallbackTimer(1.0F, [self]() { diff --git a/dScripts/BurningTile.cpp b/dScripts/BurningTile.cpp index 95a0bf17..b9a05391 100644 --- a/dScripts/BurningTile.cpp +++ b/dScripts/BurningTile.cpp @@ -1,7 +1,5 @@ #include "BurningTile.h" - #include "SkillComponent.h" -#include "GameMessages.h" void BurningTile::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { diff --git a/dScripts/CatapultBaseServer.cpp b/dScripts/CatapultBaseServer.cpp index 81db8abd..33539de8 100644 --- a/dScripts/CatapultBaseServer.cpp +++ b/dScripts/CatapultBaseServer.cpp @@ -1,8 +1,6 @@ #include "CatapultBaseServer.h" #include "GameMessages.h" #include "EntityManager.h" -#include "dZoneManager.h" - void CatapultBaseServer::OnNotifyObject(Entity *self, Entity *sender, const std::string& name, int32_t param1, int32_t param2) { diff --git a/dScripts/CatapultBaseServer.h b/dScripts/CatapultBaseServer.h index ad949022..a174fcaf 100644 --- a/dScripts/CatapultBaseServer.h +++ b/dScripts/CatapultBaseServer.h @@ -1,8 +1,5 @@ #pragma once #include "CppScripts.h" -#include "Spawner.h" -#include "dZoneManager.h" -#include "dCommonVars.h" class CatapultBaseServer : public CppScripts::Script { public: diff --git a/dScripts/CatapultBouncerServer.cpp b/dScripts/CatapultBouncerServer.cpp index 0952a7ff..098f38ac 100644 --- a/dScripts/CatapultBouncerServer.cpp +++ b/dScripts/CatapultBouncerServer.cpp @@ -1,7 +1,6 @@ #include "CatapultBouncerServer.h" #include "GameMessages.h" #include "EntityManager.h" -#include "dZoneManager.h" void CatapultBouncerServer::OnRebuildComplete(Entity* self, Entity* target) { diff --git a/dScripts/CatapultBouncerServer.h b/dScripts/CatapultBouncerServer.h index 1178a46f..06f03bf4 100644 --- a/dScripts/CatapultBouncerServer.h +++ b/dScripts/CatapultBouncerServer.h @@ -1,8 +1,5 @@ #pragma once #include "CppScripts.h" -#include "Spawner.h" -#include "dZoneManager.h" -#include "dCommonVars.h" class CatapultBouncerServer : public CppScripts::Script { public: diff --git a/dScripts/CavePrisonCage.cpp b/dScripts/CavePrisonCage.cpp index 793050b3..5fe47f2d 100644 --- a/dScripts/CavePrisonCage.cpp +++ b/dScripts/CavePrisonCage.cpp @@ -1,9 +1,9 @@ #include "CavePrisonCage.h" #include "EntityManager.h" #include "RebuildComponent.h" -#include "MovingPlatformComponent.h" #include "GameMessages.h" #include "Character.h" +#include "dZoneManager.h" void CavePrisonCage::OnStartup(Entity *self) { diff --git a/dScripts/CavePrisonCage.h b/dScripts/CavePrisonCage.h index 47f95a98..5ae357d5 100644 --- a/dScripts/CavePrisonCage.h +++ b/dScripts/CavePrisonCage.h @@ -1,8 +1,5 @@ #pragma once #include "CppScripts.h" -#include "Spawner.h" -#include "dZoneManager.h" -#include "dCommonVars.h" class CavePrisonCage : public CppScripts::Script { public: diff --git a/dScripts/ChooseYourDestinationNsToNt.cpp b/dScripts/ChooseYourDestinationNsToNt.cpp index 2ed8ebdc..823d7c85 100644 --- a/dScripts/ChooseYourDestinationNsToNt.cpp +++ b/dScripts/ChooseYourDestinationNsToNt.cpp @@ -1,8 +1,6 @@ #include "ChooseYourDestinationNsToNt.h" #include "Character.h" #include "GameMessages.h" -#include "dZoneManager.h" -#include "EntityManager.h" bool ChooseYourDestinationNsToNt::CheckChoice(Entity* self, Entity* player) { diff --git a/dScripts/ChooseYourDestinationNsToNt.h b/dScripts/ChooseYourDestinationNsToNt.h index 7a02b38b..cbf3709e 100644 --- a/dScripts/ChooseYourDestinationNsToNt.h +++ b/dScripts/ChooseYourDestinationNsToNt.h @@ -1,5 +1,4 @@ #pragma once -#include "CppScripts.h" class ChooseYourDestinationNsToNt { diff --git a/dScripts/ClRing.cpp b/dScripts/ClRing.cpp index 5b2910d3..5de3e683 100644 --- a/dScripts/ClRing.cpp +++ b/dScripts/ClRing.cpp @@ -1,6 +1,4 @@ #include "ClRing.h" -#include "EntityManager.h" -#include "Character.h" void ClRing::OnCollisionPhantom(Entity* self, Entity* target) { diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 26bde33e..420394bb 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -4,10 +4,8 @@ #include "CppScripts.h" #include "GameMessages.h" -#include "dpWorld.h" #include "Entity.h" #include "ScriptComponent.h" -#include "EntityManager.h" #include "Game.h" #include "dLogger.h" #include "InvalidScript.h" diff --git a/dScripts/CppScripts.h b/dScripts/CppScripts.h index 9cd014b5..bf30017c 100644 --- a/dScripts/CppScripts.h +++ b/dScripts/CppScripts.h @@ -1,12 +1,8 @@ #pragma once #include "dCommonVars.h" -#include "RakNetTypes.h" -#include <string> -#include "MissionComponent.h" #include "MissionState.h" -#include "Game.h" -#include "dLogger.h" -#include "Loot.h" +#include <string> +#include <vector> class User; class Entity; diff --git a/dScripts/DLUVanityNPC.cpp b/dScripts/DLUVanityNPC.cpp index ec8a0574..c219a5f9 100644 --- a/dScripts/DLUVanityNPC.cpp +++ b/dScripts/DLUVanityNPC.cpp @@ -1,6 +1,7 @@ #include "DLUVanityNPC.h" #include "GameMessages.h" #include "dServer.h" +#include "VanityUtilities.h" void DLUVanityNPC::OnStartup(Entity* self) { diff --git a/dScripts/DLUVanityNPC.h b/dScripts/DLUVanityNPC.h index baacf5dd..4eba3554 100644 --- a/dScripts/DLUVanityNPC.h +++ b/dScripts/DLUVanityNPC.h @@ -1,7 +1,7 @@ #pragma once #include "CppScripts.h" -#include "VanityUtilities.h" +class VanityNPC; class DLUVanityNPC : public CppScripts::Script { public: diff --git a/dScripts/DamagingPets.h b/dScripts/DamagingPets.h index d0044fb5..04c4e6bf 100644 --- a/dScripts/DamagingPets.h +++ b/dScripts/DamagingPets.h @@ -1,5 +1,4 @@ #pragma once - #include "CppScripts.h" /** diff --git a/dScripts/Darkitect.h b/dScripts/Darkitect.h index f0d19648..56b1c832 100644 --- a/dScripts/Darkitect.h +++ b/dScripts/Darkitect.h @@ -1,5 +1,4 @@ #pragma once - class Entity; class Darkitect diff --git a/dScripts/EnemySpiderSpawner.cpp b/dScripts/EnemySpiderSpawner.cpp index 96f5e6c8..98524ae1 100644 --- a/dScripts/EnemySpiderSpawner.cpp +++ b/dScripts/EnemySpiderSpawner.cpp @@ -1,9 +1,7 @@ #include "EnemySpiderSpawner.h" #include "GameMessages.h" -#include "SimplePhysicsComponent.h" #include "EntityManager.h" #include "DestroyableComponent.h" -#include "MovementAIComponent.h" //---------------------------------------------- //--Initiate egg hatching on call diff --git a/dScripts/ExplodingAsset.cpp b/dScripts/ExplodingAsset.cpp index 929d2082..b4bd6913 100644 --- a/dScripts/ExplodingAsset.cpp +++ b/dScripts/ExplodingAsset.cpp @@ -1,7 +1,7 @@ #include "ExplodingAsset.h" - #include "DestroyableComponent.h" #include "GameMessages.h" +#include "MissionComponent.h" #include "SkillComponent.h" //TODO: this has to be updated so that you only get killed if you're in a certain radius. diff --git a/dScripts/FallingTile.cpp b/dScripts/FallingTile.cpp index 5bd8adc6..2dd8c7bc 100644 --- a/dScripts/FallingTile.cpp +++ b/dScripts/FallingTile.cpp @@ -2,7 +2,6 @@ #include "MovingPlatformComponent.h" #include "GameMessages.h" - void FallingTile::OnStartup(Entity* self) { auto* movingPlatfromComponent = self->GetComponent<MovingPlatformComponent>(); diff --git a/dScripts/FlameJetServer.cpp b/dScripts/FlameJetServer.cpp index 9ecf4fa2..0e6d91cc 100644 --- a/dScripts/FlameJetServer.cpp +++ b/dScripts/FlameJetServer.cpp @@ -1,5 +1,4 @@ #include "FlameJetServer.h" - #include "SkillComponent.h" #include "GameMessages.h" diff --git a/dScripts/ForceVolumeServer.cpp b/dScripts/ForceVolumeServer.cpp index ce3e0bd6..e9320527 100644 --- a/dScripts/ForceVolumeServer.cpp +++ b/dScripts/ForceVolumeServer.cpp @@ -2,17 +2,11 @@ #include "PhantomPhysicsComponent.h" #include "EntityManager.h" - void ForceVolumeServer::OnStartup(Entity* self) { auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); - if (phantomPhysicsComponent == nullptr) - { - Game::logger->Log("ForceVolumeServer", "Failed to find PhantomPhysicsComponent\n"); - - return; - } + if (phantomPhysicsComponent == nullptr) return; const auto forceAmount = self->GetVar<float>(u"ForceAmt"); const auto forceX = self->GetVar<float>(u"ForceX"); diff --git a/dScripts/FountainOfImagination.cpp b/dScripts/FountainOfImagination.cpp index 2d752db4..43351e18 100644 --- a/dScripts/FountainOfImagination.cpp +++ b/dScripts/FountainOfImagination.cpp @@ -1,4 +1,6 @@ #include "FountainOfImagination.h" +#include "dCommonVars.h" +#include "Entity.h" void FountainOfImagination::OnStartup(Entity *self) { self->SetVar<uint32_t>(u"numCycles", 6); diff --git a/dScripts/FvBounceOverWall.cpp b/dScripts/FvBounceOverWall.cpp index 348bc36c..1c85ffbd 100644 --- a/dScripts/FvBounceOverWall.cpp +++ b/dScripts/FvBounceOverWall.cpp @@ -1,4 +1,5 @@ #include "FvBounceOverWall.h" +#include "MissionComponent.h" void FvBounceOverWall::OnCollisionPhantom(Entity* self, Entity* target) { auto missionComponent = target->GetComponent<MissionComponent>(); diff --git a/dScripts/FvCandle.cpp b/dScripts/FvCandle.cpp index 2081faf3..63f90f0b 100644 --- a/dScripts/FvCandle.cpp +++ b/dScripts/FvCandle.cpp @@ -1,5 +1,6 @@ #include "FvCandle.h" #include "MissionComponent.h" +#include "RenderComponent.h" std::vector<int32_t> FvCandle::m_Missions = {850, 1431, 1529, 1566, 1603}; diff --git a/dScripts/FvCandle.h b/dScripts/FvCandle.h index 1df63675..362d2a05 100644 --- a/dScripts/FvCandle.h +++ b/dScripts/FvCandle.h @@ -1,6 +1,5 @@ #pragma once #include "CppScripts.h" -#include "RenderComponent.h" class FvCandle : public CppScripts::Script { diff --git a/dScripts/FvConsoleLeftQuickbuild.cpp b/dScripts/FvConsoleLeftQuickbuild.cpp index 4b0a4f6c..ef281f15 100644 --- a/dScripts/FvConsoleLeftQuickbuild.cpp +++ b/dScripts/FvConsoleLeftQuickbuild.cpp @@ -1,7 +1,4 @@ #include "FvConsoleLeftQuickbuild.h" -#include "RebuildComponent.h" -#include "GeneralUtils.h" -#include "dZoneManager.h" #include "EntityManager.h" #include "GameMessages.h" diff --git a/dScripts/FvConsoleRightQuickbuild.cpp b/dScripts/FvConsoleRightQuickbuild.cpp index d72658b0..0bf9849a 100644 --- a/dScripts/FvConsoleRightQuickbuild.cpp +++ b/dScripts/FvConsoleRightQuickbuild.cpp @@ -1,7 +1,4 @@ #include "FvConsoleRightQuickbuild.h" -#include "RebuildComponent.h" -#include "GeneralUtils.h" -#include "dZoneManager.h" #include "EntityManager.h" #include "GameMessages.h" diff --git a/dScripts/FvFacilityBrick.cpp b/dScripts/FvFacilityBrick.cpp index 639265a7..fce9e630 100644 --- a/dScripts/FvFacilityBrick.cpp +++ b/dScripts/FvFacilityBrick.cpp @@ -1,10 +1,8 @@ #include "FvFacilityBrick.h" #include "GameMessages.h" -#include "GeneralUtils.h" #include "dZoneManager.h" #include "EntityManager.h" - void FvFacilityBrick::OnStartup(Entity* self) { self->SetVar(u"ConsoleLEFTActive", false); @@ -13,8 +11,6 @@ void FvFacilityBrick::OnStartup(Entity* self) void FvFacilityBrick::OnNotifyObject(Entity *self, Entity *sender, const std::string& name, int32_t param1, int32_t param2) { - Game::logger->Log("FvFacilityBrick", "Notify: %s\n", name.c_str()); - auto* brickSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationBrick")[0]; auto* bugSpawner = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug")[0]; auto* canisterSpawner = dZoneManager::Instance()->GetSpawnersByName("BrickCanister")[0]; diff --git a/dScripts/FvFong.cpp b/dScripts/FvFong.cpp index 890bf0ff..9a3de0b2 100644 --- a/dScripts/FvFong.cpp +++ b/dScripts/FvFong.cpp @@ -1,6 +1,6 @@ #include "FvFong.h" #include "Darkitect.h" -#include "MissionComponent.h" +#include "MissionState.h" void FvFong::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { diff --git a/dScripts/FvFreeGfNinjas.cpp b/dScripts/FvFreeGfNinjas.cpp index 0d749b01..8022b32f 100644 --- a/dScripts/FvFreeGfNinjas.cpp +++ b/dScripts/FvFreeGfNinjas.cpp @@ -1,5 +1,6 @@ #include "FvFreeGfNinjas.h" #include "Character.h" +#include "MissionComponent.h" void FvFreeGfNinjas::OnMissionDialogueOK(Entity *self, Entity *target, int missionID, MissionState missionState) { if (missionID == 705 && missionState == MissionState::MISSION_STATE_AVAILABLE) { diff --git a/dScripts/FvHorsemenTrigger.cpp b/dScripts/FvHorsemenTrigger.cpp index e984ab99..541c11e0 100644 --- a/dScripts/FvHorsemenTrigger.cpp +++ b/dScripts/FvHorsemenTrigger.cpp @@ -11,8 +11,6 @@ void FvHorsemenTrigger::OnStartup(Entity* self) void FvHorsemenTrigger::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - Game::logger->Log("FvHorsemenTrigger", "Proximity update\n"); - if (name != "horsemenTrigger" || !entering->IsPlayer()) { return; @@ -24,12 +22,10 @@ void FvHorsemenTrigger::OnProximityUpdate(Entity* self, Entity* entering, std::s if (status == "ENTER" && iter == players.end()) { - Game::logger->Log("FvHorsemenTrigger", "Proximity enter\n"); players.push_back(entering->GetObjectID()); } else if (status == "LEAVE" && iter != players.end()) { - Game::logger->Log("FvHorsemenTrigger", "Proximity leave\n"); players.erase(iter); } @@ -42,7 +38,6 @@ FvHorsemenTrigger::OnFireEventServerSide(Entity *self, Entity *sender, std::stri { auto players = self->GetVar<std::vector<LWOOBJID>>(u"players"); - Game::logger->Log("FvHorsemenTrigger", "Got event %s with %i players\n", args.c_str(), players.size()); if (args == "HorsemenDeath") { for (const auto& playerId : self->GetVar<std::vector<LWOOBJID>>(u"players")) diff --git a/dScripts/FvMaelstromCavalry.cpp b/dScripts/FvMaelstromCavalry.cpp index d4d93645..b4a32991 100644 --- a/dScripts/FvMaelstromCavalry.cpp +++ b/dScripts/FvMaelstromCavalry.cpp @@ -5,16 +5,12 @@ void FvMaelstromCavalry::OnStartup(Entity* self) { for (const auto& group : self->GetGroups()) { - Game::logger->Log("FvMaelstromCavalry", "Got group: %s\n", group.c_str()); - const auto& objects = EntityManager::Instance()->GetEntitiesInGroup(group); for (auto* obj : objects) { if (obj->GetLOT() != 8551) continue; - Game::logger->Log("FvMaelstromCavalry", "Trigger in group: %s\n", group.c_str()); - obj->OnFireEventServerSide(self, "ISpawned"); } } @@ -27,8 +23,6 @@ void FvMaelstromCavalry::OnDie(Entity* self, Entity* killer) return; } - Game::logger->Log("FvMaelstromCavalry", "Killer: %i\n", killer->GetLOT()); - if (killer->GetLOT() != 8665) { return; @@ -38,8 +32,6 @@ void FvMaelstromCavalry::OnDie(Entity* self, Entity* killer) for (auto* trigger : triggers) { - Game::logger->Log("FvMaelstromCavalry", "Trigger for: %i\n", killer->GetLOT()); - trigger->OnFireEventServerSide(self, "HorsemenDeath"); } } diff --git a/dScripts/FvMaelstromCavalry.h b/dScripts/FvMaelstromCavalry.h index cfa9ff4b..0fc3e840 100644 --- a/dScripts/FvMaelstromCavalry.h +++ b/dScripts/FvMaelstromCavalry.h @@ -1,6 +1,5 @@ #pragma once #include "CppScripts.h" -#include "RenderComponent.h" class FvMaelstromCavalry : public CppScripts::Script { diff --git a/dScripts/FvMaelstromDragon.cpp b/dScripts/FvMaelstromDragon.cpp index e67ce815..afdfa4ae 100644 --- a/dScripts/FvMaelstromDragon.cpp +++ b/dScripts/FvMaelstromDragon.cpp @@ -2,7 +2,6 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "BaseCombatAIComponent.h" -#include "RenderComponent.h" #include "DestroyableComponent.h" void FvMaelstromDragon::OnStartup(Entity* self) diff --git a/dScripts/FvMaelstromDragon.h b/dScripts/FvMaelstromDragon.h index 993306d3..52af80c4 100644 --- a/dScripts/FvMaelstromDragon.h +++ b/dScripts/FvMaelstromDragon.h @@ -1,6 +1,5 @@ #pragma once #include "CppScripts.h" -#include "RenderComponent.h" class FvMaelstromDragon : public CppScripts::Script { diff --git a/dScripts/FvPassThroughWall.cpp b/dScripts/FvPassThroughWall.cpp index 66130a9f..e894f923 100644 --- a/dScripts/FvPassThroughWall.cpp +++ b/dScripts/FvPassThroughWall.cpp @@ -1,5 +1,6 @@ #include "FvPassThroughWall.h" #include "InventoryComponent.h" +#include "MissionComponent.h" void FvPassThroughWall::OnCollisionPhantom(Entity* self, Entity* target) { auto missionComponent = target->GetComponent<MissionComponent>(); diff --git a/dScripts/FvRaceSmashEggImagineServer.cpp b/dScripts/FvRaceSmashEggImagineServer.cpp index 8e0d0897..696504e2 100644 --- a/dScripts/FvRaceSmashEggImagineServer.cpp +++ b/dScripts/FvRaceSmashEggImagineServer.cpp @@ -1,9 +1,10 @@ +#include "FvRaceSmashEggImagineServer.h" #include "CharacterComponent.h" #include "DestroyableComponent.h" #include "EntityManager.h" -#include "FvRaceSmashEggImagineServer.h" #include "PossessableComponent.h" #include "RacingTaskParam.h" +#include "MissionComponent.h" void FvRaceSmashEggImagineServer::OnDie(Entity *self, Entity *killer) { if (killer != nullptr) { diff --git a/dScripts/GfBanana.cpp b/dScripts/GfBanana.cpp index 65c434ba..346c9ad7 100644 --- a/dScripts/GfBanana.cpp +++ b/dScripts/GfBanana.cpp @@ -3,12 +3,9 @@ #include "Entity.h" #include "DestroyableComponent.h" #include "EntityManager.h" -#include "dLogger.h" void GfBanana::SpawnBanana(Entity* self) { - Game::logger->Log("GfBanana", "Spawning banana\n"); - auto position = self->GetPosition(); const auto rotation = self->GetRotation(); @@ -44,8 +41,6 @@ void GfBanana::OnStartup(Entity* self) void GfBanana::OnHit(Entity* self, Entity* attacker) { - Game::logger->Log("GfBanana", "Spawning cluster\n"); - auto* destroyable = self->GetComponent<DestroyableComponent>(); destroyable->SetHealth(9999); diff --git a/dScripts/GfBananaCluster.cpp b/dScripts/GfBananaCluster.cpp index 8ccc3be6..aacba224 100644 --- a/dScripts/GfBananaCluster.cpp +++ b/dScripts/GfBananaCluster.cpp @@ -1,4 +1,5 @@ #include "GfBananaCluster.h" +#include "Entity.h" void GfBananaCluster::OnStartup(Entity* self) { diff --git a/dScripts/GfCampfire.cpp b/dScripts/GfCampfire.cpp index caeaa6da..48170c66 100644 --- a/dScripts/GfCampfire.cpp +++ b/dScripts/GfCampfire.cpp @@ -1,11 +1,8 @@ #include "GfCampfire.h" -#include "GameMessages.h" - #include "RenderComponent.h" #include "SkillComponent.h" #include "MissionComponent.h" #include "RenderComponent.h" -#include "ProximityMonitorComponent.h" #include "EntityManager.h" void GfCampfire::OnStartup(Entity* self) { diff --git a/dScripts/GfJailWalls.cpp b/dScripts/GfJailWalls.cpp index 184fbd69..da547d0b 100644 --- a/dScripts/GfJailWalls.cpp +++ b/dScripts/GfJailWalls.cpp @@ -1,5 +1,4 @@ #include "GfJailWalls.h" -#include "EntityManager.h" #include "dZoneManager.h" #include "GeneralUtils.h" diff --git a/dScripts/GfTikiTorch.cpp b/dScripts/GfTikiTorch.cpp index d0e5d58d..dd1c14a7 100644 --- a/dScripts/GfTikiTorch.cpp +++ b/dScripts/GfTikiTorch.cpp @@ -1,7 +1,7 @@ #include "GfTikiTorch.h" #include "GameMessages.h" #include "EntityManager.h" - +#include "MissionComponent.h" #include "RenderComponent.h" void GfTikiTorch::OnStartup(Entity* self) { diff --git a/dScripts/ImaginationBackpackHealServer.cpp b/dScripts/ImaginationBackpackHealServer.cpp index 3f572a8f..1d7da2c5 100644 --- a/dScripts/ImaginationBackpackHealServer.cpp +++ b/dScripts/ImaginationBackpackHealServer.cpp @@ -1,5 +1,6 @@ #include "ImaginationBackpackHealServer.h" #include "GameMessages.h" +#include "MissionComponent.h" void ImaginationBackpackHealServer::OnSkillEventFired(Entity *self, Entity *caster, const std::string &message) { if (message == "CastImaginationBackpack") { diff --git a/dScripts/ImaginationShrineServer.cpp b/dScripts/ImaginationShrineServer.cpp index 0b40b44f..54c02614 100644 --- a/dScripts/ImaginationShrineServer.cpp +++ b/dScripts/ImaginationShrineServer.cpp @@ -1,7 +1,6 @@ #include "ImaginationShrineServer.h" #include "RebuildComponent.h" - void ImaginationShrineServer::OnUse(Entity* self, Entity* user) { // If the rebuild component is complete, use the shrine diff --git a/dScripts/ImgBrickConsoleQB.cpp b/dScripts/ImgBrickConsoleQB.cpp index 4d2d1e96..0dfb6288 100644 --- a/dScripts/ImgBrickConsoleQB.cpp +++ b/dScripts/ImgBrickConsoleQB.cpp @@ -197,8 +197,6 @@ void ImgBrickConsoleQB::OnDie(Entity* self, Entity* killer) self->SetVar(u"Died", true); - Game::logger->Log("ImgBrickConsoleQB", "On Die...\n"); - auto* rebuildComponent = self->GetComponent<RebuildComponent>(); if (rebuildComponent->GetState() == REBUILD_COMPLETED) @@ -266,16 +264,12 @@ void ImgBrickConsoleQB::OnDie(Entity* self, Entity* killer) } self->SetNetworkVar(u"used", false); - - Game::logger->Log("ImgBrickConsoleQB", "Died...\n"); } void ImgBrickConsoleQB::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "reset") { - Game::logger->Log("ImgBrickConsoleQB", "Resetting...\n"); - auto* rebuildComponent = self->GetComponent<RebuildComponent>(); if (rebuildComponent->GetState() == REBUILD_OPEN) @@ -285,8 +279,6 @@ void ImgBrickConsoleQB::OnTimerDone(Entity* self, std::string timerName) } else if (timerName == "Die") { - Game::logger->Log("ImgBrickConsoleQB", "Die...\n"); - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); for (auto* console : consoles) diff --git a/dScripts/ImgBrickConsoleQB.h b/dScripts/ImgBrickConsoleQB.h index 1fdcf84a..f51f8e6c 100644 --- a/dScripts/ImgBrickConsoleQB.h +++ b/dScripts/ImgBrickConsoleQB.h @@ -1,6 +1,5 @@ #pragma once #include "CppScripts.h" -#include <map> class ImgBrickConsoleQB : public CppScripts::Script { diff --git a/dScripts/InstanceExitTransferPlayerToLastNonInstance.cpp b/dScripts/InstanceExitTransferPlayerToLastNonInstance.cpp index 4bd99f7f..307c6c73 100644 --- a/dScripts/InstanceExitTransferPlayerToLastNonInstance.cpp +++ b/dScripts/InstanceExitTransferPlayerToLastNonInstance.cpp @@ -2,13 +2,10 @@ #include "GameMessages.h" #include "Player.h" #include "Character.h" -#include "Game.h" #include "dServer.h" void InstanceExitTransferPlayerToLastNonInstance::OnUse(Entity* self, Entity* user) { - Game::logger->Log("Instance", "OnUse\n"); - auto transferText = self->GetVar<std::u16string>(u"transferText"); if (transferText.empty()) transferText = u"DRAGON_EXIT_QUESTION"; diff --git a/dScripts/LegoDieRoll.cpp b/dScripts/LegoDieRoll.cpp index 4b375a38..386313be 100644 --- a/dScripts/LegoDieRoll.cpp +++ b/dScripts/LegoDieRoll.cpp @@ -1,7 +1,7 @@ #include "LegoDieRoll.h" #include "Entity.h" -#include "dLogger.h" #include "GameMessages.h" +#include "MissionComponent.h" void LegoDieRoll::OnStartup(Entity* self) { self->AddTimer("DoneRolling", 10.0f); @@ -48,7 +48,6 @@ void LegoDieRoll::OnTimerDone(Entity* self, std::string timerName) { break; } default: - Game::logger->LogDebug("LegoDieRoll", "Invalid animation: roll-die-%i\n", dieRoll); break; } } diff --git a/dScripts/MastTeleport.cpp b/dScripts/MastTeleport.cpp index 601f7dbf..94d5f552 100644 --- a/dScripts/MastTeleport.cpp +++ b/dScripts/MastTeleport.cpp @@ -1,7 +1,6 @@ #include "MastTeleport.h" #include "EntityManager.h" #include "GameMessages.h" -#include "Game.h" #include "Preconditions.h" #ifdef _WIN32 diff --git a/dScripts/MinigameTreasureChestServer.cpp b/dScripts/MinigameTreasureChestServer.cpp index ff32b527..fc3f14c0 100644 --- a/dScripts/MinigameTreasureChestServer.cpp +++ b/dScripts/MinigameTreasureChestServer.cpp @@ -3,7 +3,6 @@ #include "TeamManager.h" #include "EntityManager.h" #include "dZoneManager.h" -#include "dServer.h" void MinigameTreasureChestServer::OnUse(Entity *self, Entity *user) { auto* sac = self->GetComponent<ScriptedActivityComponent>(); @@ -56,7 +55,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 (Game::server->GetZoneID() == 1204) { + if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1204) { auto* sac = self->GetComponent<ScriptedActivityComponent>(); if (sac != nullptr) { sac->SetInstanceMapID(1204); diff --git a/dScripts/MissionConsoleServer.cpp b/dScripts/MissionConsoleServer.cpp deleted file mode 100644 index 136f2cb6..00000000 --- a/dScripts/MissionConsoleServer.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "MissionConsoleServer.h" diff --git a/dScripts/MissionConsoleServer.h b/dScripts/MissionConsoleServer.h deleted file mode 100644 index c502fc00..00000000 --- a/dScripts/MissionConsoleServer.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "CppScripts.h" - -class MissionConsoleServer : public CppScripts::Script { -}; - diff --git a/dScripts/MonCoreNookDoors.cpp b/dScripts/MonCoreNookDoors.cpp index c038c1dd..c3fcf9be 100644 --- a/dScripts/MonCoreNookDoors.cpp +++ b/dScripts/MonCoreNookDoors.cpp @@ -1,6 +1,4 @@ #include "MonCoreNookDoors.h" -#include "GameMessages.h" -#include "EntityManager.h" #include "dZoneManager.h" void MonCoreNookDoors::OnStartup(Entity* self) diff --git a/dScripts/MonCoreSmashableDoors.cpp b/dScripts/MonCoreSmashableDoors.cpp index 1ea1bef9..0e7950f5 100644 --- a/dScripts/MonCoreSmashableDoors.cpp +++ b/dScripts/MonCoreSmashableDoors.cpp @@ -1,7 +1,5 @@ #include "MonCoreSmashableDoors.h" -#include "GameMessages.h" #include "EntityManager.h" -#include "dZoneManager.h" void MonCoreSmashableDoors::OnDie(Entity* self, Entity* killer) { diff --git a/dScripts/NjEarthDragonPetServer.cpp b/dScripts/NjEarthDragonPetServer.cpp index 3be5c63a..2b91f33c 100644 --- a/dScripts/NjEarthDragonPetServer.cpp +++ b/dScripts/NjEarthDragonPetServer.cpp @@ -1,4 +1,5 @@ #include "NjEarthDragonPetServer.h" +#include "Entity.h" void NjEarthDragonPetServer::SetVariables(Entity *self) { self->SetVar<LOT>(u"petLOT", 16210); diff --git a/dScripts/NjEarthDragonPetServer.h b/dScripts/NjEarthDragonPetServer.h index 41c068f4..2227bbb6 100644 --- a/dScripts/NjEarthDragonPetServer.h +++ b/dScripts/NjEarthDragonPetServer.h @@ -1,5 +1,4 @@ #pragma once -//#include "NjPetSpawnerServer.h" #include "SpawnPetBaseServer.h" class NjEarthDragonPetServer : public SpawnPetBaseServer { diff --git a/dScripts/NjJayMissionItems.h b/dScripts/NjJayMissionItems.h index 7f30d7f0..19cb4f40 100644 --- a/dScripts/NjJayMissionItems.h +++ b/dScripts/NjJayMissionItems.h @@ -1,6 +1,8 @@ #pragma once #include "NjNPCMissionSpinjitzuServer.h" #include "NPCAddRemoveItem.h" +#include <vector> +#include <map> class NjJayMissionItems : public NjNPCMissionSpinjitzuServer, NPCAddRemoveItem { void OnMissionDialogueOK(Entity *self, Entity *target, int missionID, MissionState missionState) override; diff --git a/dScripts/NjMonastryBossInstance.cpp b/dScripts/NjMonastryBossInstance.cpp index 27de7439..cd34ea2c 100644 --- a/dScripts/NjMonastryBossInstance.cpp +++ b/dScripts/NjMonastryBossInstance.cpp @@ -1,15 +1,14 @@ -#include <algorithm> -#include "RebuildComponent.h" #include "NjMonastryBossInstance.h" +#include "RebuildComponent.h" #include "DestroyableComponent.h" #include "EntityManager.h" -#include "GameMessages.h" #include "dZoneManager.h" #include "GameMessages.h" #include "BaseCombatAIComponent.h" #include "BuffComponent.h" #include "SkillComponent.h" #include "TeamManager.h" +#include <algorithm> // // // // // // // // Event handling // diff --git a/dScripts/NjNPCMissionSpinjitzuServer.h b/dScripts/NjNPCMissionSpinjitzuServer.h index 51150373..5b346ee7 100644 --- a/dScripts/NjNPCMissionSpinjitzuServer.h +++ b/dScripts/NjNPCMissionSpinjitzuServer.h @@ -1,5 +1,6 @@ #pragma once #include "CppScripts.h" +#include <map> static std::map<std::u16string, uint32_t> ElementFlags = { {u"earth", ePlayerFlags::NJ_EARTH_SPINJITZU}, diff --git a/dScripts/NjNyaMissionitems.h b/dScripts/NjNyaMissionitems.h index 91681126..5e2bbc7b 100644 --- a/dScripts/NjNyaMissionitems.h +++ b/dScripts/NjNyaMissionitems.h @@ -1,5 +1,7 @@ #pragma once #include "NPCAddRemoveItem.h" +#include <map> +#include <vector> class NjNyaMissionitems : public NPCAddRemoveItem { std::map<uint32_t, std::vector<ItemSetting>> GetSettings() override; diff --git a/dScripts/NjPetSpawnerServer.cpp b/dScripts/NjPetSpawnerServer.cpp deleted file mode 100644 index d09e5f01..00000000 --- a/dScripts/NjPetSpawnerServer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by Mick Vermeulen on 23/08/2021. -// - -#include "NjPetSpawnerServer.h" diff --git a/dScripts/NjPetSpawnerServer.h b/dScripts/NjPetSpawnerServer.h deleted file mode 100644 index 56b6c147..00000000 --- a/dScripts/NjPetSpawnerServer.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "SpawnPetBaseServer.h" - -class NjPetSpawnerServer : public SpawnPetBaseServer { - -}; diff --git a/dScripts/NjhubLavaPlayerDeathTrigger.cpp b/dScripts/NjhubLavaPlayerDeathTrigger.cpp index ff31df2c..af47f99b 100644 --- a/dScripts/NjhubLavaPlayerDeathTrigger.cpp +++ b/dScripts/NjhubLavaPlayerDeathTrigger.cpp @@ -1,4 +1,5 @@ #include "NjhubLavaPlayerDeathTrigger.h" +#include "Entity.h" void NjhubLavaPlayerDeathTrigger::OnCollisionPhantom(Entity *self, Entity *target) { diff --git a/dScripts/NjhubLavaPlayerDeathTrigger.h b/dScripts/NjhubLavaPlayerDeathTrigger.h index d7e78604..48ff85d0 100644 --- a/dScripts/NjhubLavaPlayerDeathTrigger.h +++ b/dScripts/NjhubLavaPlayerDeathTrigger.h @@ -1,7 +1,6 @@ #pragma once #include "CppScripts.h" - class NjhubLavaPlayerDeathTrigger : public CppScripts::Script { void OnCollisionPhantom(Entity *self, Entity *target) override; }; diff --git a/dScripts/NpcAgCourseStarter.cpp b/dScripts/NpcAgCourseStarter.cpp index 4e6dd5c5..188186fb 100644 --- a/dScripts/NpcAgCourseStarter.cpp +++ b/dScripts/NpcAgCourseStarter.cpp @@ -1,11 +1,9 @@ #include "NpcAgCourseStarter.h" #include "EntityManager.h" -#include "GeneralUtils.h" #include "ScriptedActivityComponent.h" #include "GameMessages.h" #include "LeaderboardManager.h" -#include "Game.h" -#include "dLogger.h" +#include "MissionComponent.h" #include <ctime> void NpcAgCourseStarter::OnStartup(Entity* self) { @@ -35,8 +33,6 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 } if (identifier == u"player_dialog_cancel_course" && button == 1) { - Game::logger->Log("OnMessageBoxResponse", "Removing player %llu\n", sender->GetObjectID()); - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"cancel_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); @@ -58,8 +54,6 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 data->values[1] = *(float*)&startTime; - Game::logger->Log("NpcAgCourseStarter", "Start time: %llu / %f\n", startTime, data->values[1]); - EntityManager::Instance()->SerializeEntity(self); } else if (identifier == u"FootRaceCancel") { @@ -94,9 +88,6 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity *self, Entity *sender, std time_t endTime = std::time(0); time_t finish = (endTime - *(time_t *) &data->values[1]); - Game::logger->Log("NpcAgCourseStarter", "End time: %llu, start time %llu, finish: %llu\n", endTime, - *(time_t *) &data->values[1], finish); - data->values[2] = *(float *) &finish; auto *missionComponent = sender->GetComponent<MissionComponent>(); diff --git a/dScripts/NpcCowboyServer.cpp b/dScripts/NpcCowboyServer.cpp index 9223dcd4..f4986045 100644 --- a/dScripts/NpcCowboyServer.cpp +++ b/dScripts/NpcCowboyServer.cpp @@ -1,5 +1,5 @@ #include "NpcCowboyServer.h" -#include "MissionComponent.h" +#include "MissionState.h" #include "InventoryComponent.h" void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) diff --git a/dScripts/NpcNjAssistantServer.cpp b/dScripts/NpcNjAssistantServer.cpp index 7ff21c8e..b9743756 100644 --- a/dScripts/NpcNjAssistantServer.cpp +++ b/dScripts/NpcNjAssistantServer.cpp @@ -1,6 +1,7 @@ #include "NpcNjAssistantServer.h" #include "GameMessages.h" #include "InventoryComponent.h" +#include "MissionComponent.h" #include "Item.h" void NpcNjAssistantServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { diff --git a/dScripts/NpcNpSpacemanBob.cpp b/dScripts/NpcNpSpacemanBob.cpp index 2893e039..91fe0f95 100644 --- a/dScripts/NpcNpSpacemanBob.cpp +++ b/dScripts/NpcNpSpacemanBob.cpp @@ -1,10 +1,6 @@ #include "NpcNpSpacemanBob.h" #include "DestroyableComponent.h" -#include "Entity.h" -#include "GameMessages.h" -#include "MissionState.h" -#include "Game.h" -#include "dLogger.h" +#include "MissionComponent.h" void NpcNpSpacemanBob::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { diff --git a/dScripts/NpcWispServer.cpp b/dScripts/NpcWispServer.cpp index 03c8f071..0f573d65 100644 --- a/dScripts/NpcWispServer.cpp +++ b/dScripts/NpcWispServer.cpp @@ -1,10 +1,8 @@ #include "NpcWispServer.h" #include "InventoryComponent.h" - #include "EntityManager.h" #include "Entity.h" #include "GameMessages.h" -#include "Item.h" void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { if (missionID != 1849 && missionID != 1883) diff --git a/dScripts/NsConcertChoiceBuildManager.cpp b/dScripts/NsConcertChoiceBuildManager.cpp index 562ff61a..8875beed 100644 --- a/dScripts/NsConcertChoiceBuildManager.cpp +++ b/dScripts/NsConcertChoiceBuildManager.cpp @@ -1,6 +1,5 @@ #include "NsConcertChoiceBuildManager.h" #include "EntityManager.h" -#include "Player.h" const std::vector<Crate> NsConcertChoiceBuildManager::crates { { "laser", 11203, 5.0, "Concert_Laser_QB_" }, diff --git a/dScripts/NsConcertInstrument.cpp b/dScripts/NsConcertInstrument.cpp index bfd35083..a449a6a4 100644 --- a/dScripts/NsConcertInstrument.cpp +++ b/dScripts/NsConcertInstrument.cpp @@ -5,6 +5,7 @@ #include "EntityManager.h" #include "RebuildComponent.h" #include "SoundTriggerComponent.h" +#include "MissionComponent.h" // Constants are at the bottom diff --git a/dScripts/NsConcertQuickBuild.cpp b/dScripts/NsConcertQuickBuild.cpp index 6bf501c4..ba7b4010 100644 --- a/dScripts/NsConcertQuickBuild.cpp +++ b/dScripts/NsConcertQuickBuild.cpp @@ -2,9 +2,9 @@ #include "EntityManager.h" #include "NsConcertChoiceBuildManager.h" #include "DestroyableComponent.h" -#include "RenderComponent.h" #include "GameMessages.h" #include "MovingPlatformComponent.h" +#include "MissionComponent.h" const float NsConcertQuickBuild::resetTime = 40.0f; const float NsConcertQuickBuild::resetBlinkTime = 6.0f; diff --git a/dScripts/NsJohnnyMissionServer.cpp b/dScripts/NsJohnnyMissionServer.cpp index 435f50c8..6fc73a82 100644 --- a/dScripts/NsJohnnyMissionServer.cpp +++ b/dScripts/NsJohnnyMissionServer.cpp @@ -1,4 +1,5 @@ #include "NsJohnnyMissionServer.h" +#include "MissionComponent.h" void NsJohnnyMissionServer::OnMissionDialogueOK(Entity *self, Entity *target, int missionID, MissionState missionState) { if (missionID == 773 && missionState <= MissionState::MISSION_STATE_ACTIVE) { diff --git a/dScripts/NsLegoClubDoor.cpp b/dScripts/NsLegoClubDoor.cpp index 1e575c54..0b773b09 100644 --- a/dScripts/NsLegoClubDoor.cpp +++ b/dScripts/NsLegoClubDoor.cpp @@ -1,8 +1,7 @@ #include "NsLegoClubDoor.h" #include "dZoneManager.h" -#include "EntityManager.h" -#include "GeneralUtils.h" #include "GameMessages.h" +#include "AMFFormat.h" void NsLegoClubDoor::OnStartup(Entity* self) { diff --git a/dScripts/NsLegoClubDoor.h b/dScripts/NsLegoClubDoor.h index 480c9250..7f17692d 100644 --- a/dScripts/NsLegoClubDoor.h +++ b/dScripts/NsLegoClubDoor.h @@ -2,7 +2,6 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" class NsLegoClubDoor : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/NsLupTeleport.cpp b/dScripts/NsLupTeleport.cpp index 28f598a4..4c196d01 100644 --- a/dScripts/NsLupTeleport.cpp +++ b/dScripts/NsLupTeleport.cpp @@ -1,8 +1,7 @@ #include "NsLupTeleport.h" #include "dZoneManager.h" -#include "EntityManager.h" -#include "GeneralUtils.h" #include "GameMessages.h" +#include "AMFFormat.h" void NsLupTeleport::OnStartup(Entity* self) { diff --git a/dScripts/NsLupTeleport.h b/dScripts/NsLupTeleport.h index 3ace6698..833f5f0a 100644 --- a/dScripts/NsLupTeleport.h +++ b/dScripts/NsLupTeleport.h @@ -2,7 +2,6 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" class NsLupTeleport : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/NsModularBuild.cpp b/dScripts/NsModularBuild.cpp index 09d3d695..065d061e 100644 --- a/dScripts/NsModularBuild.cpp +++ b/dScripts/NsModularBuild.cpp @@ -1,6 +1,5 @@ #include "NsModularBuild.h" -#include "EntityManager.h" -#include "Character.h" +#include "MissionComponent.h" void NsModularBuild::OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) { if (bCompleted) { diff --git a/dScripts/NsQbImaginationStatue.cpp b/dScripts/NsQbImaginationStatue.cpp index 6b512119..4404ba5f 100644 --- a/dScripts/NsQbImaginationStatue.cpp +++ b/dScripts/NsQbImaginationStatue.cpp @@ -1,9 +1,6 @@ #include "NsQbImaginationStatue.h" #include "EntityManager.h" -#include "Loot.h" #include "GameMessages.h" -#include "ScriptedActivityComponent.h" -#include "RebuildComponent.h" void NsQbImaginationStatue::OnStartup(Entity* self) { diff --git a/dScripts/NsTokenConsoleServer.cpp b/dScripts/NsTokenConsoleServer.cpp index 0e9ac09e..976b9bc8 100644 --- a/dScripts/NsTokenConsoleServer.cpp +++ b/dScripts/NsTokenConsoleServer.cpp @@ -1,6 +1,5 @@ #include "NsTokenConsoleServer.h" #include "InventoryComponent.h" -#include "EntityManager.h" #include "GameMessages.h" #include "Character.h" #include "MissionComponent.h" diff --git a/dScripts/NtAssemblyTubeServer.cpp b/dScripts/NtAssemblyTubeServer.cpp index 5f05f54e..935993f4 100644 --- a/dScripts/NtAssemblyTubeServer.cpp +++ b/dScripts/NtAssemblyTubeServer.cpp @@ -1,9 +1,7 @@ #include "NtAssemblyTubeServer.h" #include "GameMessages.h" -#include "dZoneManager.h" #include "EntityManager.h" -#include "SkillComponent.h" -#include "DestroyableComponent.h" +#include "MissionComponent.h" void NtAssemblyTubeServer::OnStartup(Entity* self) { @@ -17,8 +15,6 @@ void NtAssemblyTubeServer::OnPlayerLoaded(Entity* self, Entity* player) void NtAssemblyTubeServer::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - Game::logger->Log("NtAssemblyTubeServer", "Entering\n"); - if (status != "ENTER" || !entering->IsPlayer() || name != "teleport") return; auto* player = entering; diff --git a/dScripts/NtCombatChallengeDummy.cpp b/dScripts/NtCombatChallengeDummy.cpp index 76f8576f..a391e00f 100644 --- a/dScripts/NtCombatChallengeDummy.cpp +++ b/dScripts/NtCombatChallengeDummy.cpp @@ -1,7 +1,6 @@ #include "NtCombatChallengeDummy.h" #include "EntityManager.h" - void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) { const auto challengeObjectID = self->GetVar<LWOOBJID>(u"challengeObjectID"); diff --git a/dScripts/NtCombatChallengeExplodingDummy.cpp b/dScripts/NtCombatChallengeExplodingDummy.cpp index dd61817d..24494939 100644 --- a/dScripts/NtCombatChallengeExplodingDummy.cpp +++ b/dScripts/NtCombatChallengeExplodingDummy.cpp @@ -1,5 +1,4 @@ #include "NtCombatChallengeExplodingDummy.h" -#include "NtCombatChallengeDummy.h" #include "EntityManager.h" #include "SkillComponent.h" diff --git a/dScripts/NtCombatChallengeServer.cpp b/dScripts/NtCombatChallengeServer.cpp index 2c6a5426..4bf5dffc 100644 --- a/dScripts/NtCombatChallengeServer.cpp +++ b/dScripts/NtCombatChallengeServer.cpp @@ -1,27 +1,16 @@ #include "NtCombatChallengeServer.h" -#include "Character.h" #include "GameMessages.h" #include "EntityManager.h" #include "InventoryComponent.h" #include "MissionComponent.h" - void NtCombatChallengeServer::OnUse(Entity* self, Entity* user) { - auto* character = user->GetCharacter(); - - if (character == nullptr) - { - return; - } - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"UI_Open", 0, 0, user->GetObjectID(), "", user->GetSystemAddress()); } void NtCombatChallengeServer::OnDie(Entity* self, Entity* killer) { - Game::logger->Log("NtCombatChallengeServer", "Smashed\n"); - if (killer != self && killer != nullptr) { SpawnTargetDummy(self); @@ -47,8 +36,6 @@ void NtCombatChallengeServer::OnHitOrHealResult(Entity* self, Entity* attacker, self->SetVar(u"totalDmg", totalDmg); self->SetNetworkVar(u"totalDmg", totalDmg); - Game::logger->Log("NtCombatChallengeServer", "Damage %i -> %i\n", damage, totalDmg); - GameMessages::SendPlayNDAudioEmitter(self, attacker->GetSystemAddress(), scoreSound); } @@ -169,12 +156,8 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { for (const auto& mission : tMissions) { - Game::logger->Log("NtCombatChallengeServer", "Mission %i, %i\n", mission.mission, mission.damage); - if (totalDmg >= mission.damage) { - Game::logger->Log("NtCombatChallengeServer", "Progressing Mission %i, %i\n", mission.mission, mission.damage); - missionComponent->ForceProgressTaskType(mission.mission, 1, 1); } } diff --git a/dScripts/NtConsoleTeleportServer.cpp b/dScripts/NtConsoleTeleportServer.cpp index 91354c0b..b03ae34e 100644 --- a/dScripts/NtConsoleTeleportServer.cpp +++ b/dScripts/NtConsoleTeleportServer.cpp @@ -1,5 +1,6 @@ #include "NtConsoleTeleportServer.h" - +#include "Entity.h" +#include "AMFFormat.h" void NtConsoleTeleportServer::OnStartup(Entity* self) { diff --git a/dScripts/NtConsoleTeleportServer.h b/dScripts/NtConsoleTeleportServer.h index 0d834cd6..7bba7ee1 100644 --- a/dScripts/NtConsoleTeleportServer.h +++ b/dScripts/NtConsoleTeleportServer.h @@ -2,7 +2,6 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" class NtConsoleTeleportServer : public CppScripts::Script, BaseConsoleTeleportServer { diff --git a/dScripts/NtDirtCloudServer.cpp b/dScripts/NtDirtCloudServer.cpp index ee011dd8..82572703 100644 --- a/dScripts/NtDirtCloudServer.cpp +++ b/dScripts/NtDirtCloudServer.cpp @@ -1,5 +1,4 @@ #include "NtDirtCloudServer.h" -#include "dZoneManager.h" #include "MissionComponent.h" std::map<std::string, std::vector<int32_t>> NtDirtCloudServer::m_Missions = diff --git a/dScripts/NtDukeServer.cpp b/dScripts/NtDukeServer.cpp index fe196811..df3f39d6 100644 --- a/dScripts/NtDukeServer.cpp +++ b/dScripts/NtDukeServer.cpp @@ -1,5 +1,6 @@ #include "NtDukeServer.h" #include "InventoryComponent.h" +#include "MissionComponent.h" void NtDukeServer::SetVariables(Entity *self) { self->SetVar<float_t>(m_SpyProximityVariable, 35.0f); diff --git a/dScripts/NtFactionSpyServer.cpp b/dScripts/NtFactionSpyServer.cpp index b99990c0..f1104e34 100644 --- a/dScripts/NtFactionSpyServer.cpp +++ b/dScripts/NtFactionSpyServer.cpp @@ -3,6 +3,7 @@ #include "ProximityMonitorComponent.h" #include "InventoryComponent.h" #include "GameMessages.h" +#include "MissionComponent.h" void NtFactionSpyServer::OnStartup(Entity *self) { SetVariables(self); diff --git a/dScripts/NtHaelServer.cpp b/dScripts/NtHaelServer.cpp index 2e2643fe..a4c16e1f 100644 --- a/dScripts/NtHaelServer.cpp +++ b/dScripts/NtHaelServer.cpp @@ -1,4 +1,5 @@ #include "NtHaelServer.h" +#include "Entity.h" void NtHaelServer::SetVariables(Entity *self) { self->SetVar<float_t>(m_SpyProximityVariable, 25.0f); diff --git a/dScripts/NtParadoxTeleServer.cpp b/dScripts/NtParadoxTeleServer.cpp index 41d21cb7..84222374 100644 --- a/dScripts/NtParadoxTeleServer.cpp +++ b/dScripts/NtParadoxTeleServer.cpp @@ -1,9 +1,7 @@ #include "NtParadoxTeleServer.h" #include "GameMessages.h" -#include "dZoneManager.h" #include "EntityManager.h" -#include "SkillComponent.h" -#include "DestroyableComponent.h" +#include "MissionComponent.h" void NtParadoxTeleServer::OnStartup(Entity* self) { @@ -17,8 +15,6 @@ void NtParadoxTeleServer::OnPlayerLoaded(Entity* self, Entity* player) void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - Game::logger->Log("NtParadoxTeleServer", "Entering\n"); - if (status != "ENTER" || !entering->IsPlayer() || name != "teleport") return; auto* player = entering; diff --git a/dScripts/NtSentinelWalkwayServer.cpp b/dScripts/NtSentinelWalkwayServer.cpp index 5f4b50e2..3d7c75a3 100644 --- a/dScripts/NtSentinelWalkwayServer.cpp +++ b/dScripts/NtSentinelWalkwayServer.cpp @@ -1,7 +1,7 @@ #include "NtSentinelWalkwayServer.h" #include "PhantomPhysicsComponent.h" #include "EntityManager.h" - +#include "MissionComponent.h" void NtSentinelWalkwayServer::OnStartup(Entity* self) { @@ -9,8 +9,6 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) if (phantomPhysicsComponent == nullptr) { - Game::logger->Log("NtSentinelWalkwayServer", "Failed to find PhantomPhysicsComponent\n"); - return; } @@ -21,8 +19,6 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) force = 115; } - Game::logger->Log("NtSentinelWalkwayServer", "Setting force to %i\n", force); - const auto forward = self->GetRotation().GetRightVector() * -1; phantomPhysicsComponent->SetEffectType(0); // PUSH diff --git a/dScripts/NtVentureCannonServer.cpp b/dScripts/NtVentureCannonServer.cpp index 0b72c8b7..66172733 100644 --- a/dScripts/NtVentureCannonServer.cpp +++ b/dScripts/NtVentureCannonServer.cpp @@ -2,7 +2,6 @@ #include "GameMessages.h" #include "EntityManager.h" - void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { auto* player = user; diff --git a/dScripts/NtVentureSpeedPadServer.cpp b/dScripts/NtVentureSpeedPadServer.cpp index 1f44ec04..19a752d2 100644 --- a/dScripts/NtVentureSpeedPadServer.cpp +++ b/dScripts/NtVentureSpeedPadServer.cpp @@ -2,7 +2,6 @@ #include "SkillComponent.h" #include "MissionComponent.h" - void NtVentureSpeedPadServer::OnStartup(Entity* self) { self->SetProximityRadius(3, "speedboost"); diff --git a/dScripts/NtXRayServer.cpp b/dScripts/NtXRayServer.cpp index 7fae01c6..b65cf65b 100644 --- a/dScripts/NtXRayServer.cpp +++ b/dScripts/NtXRayServer.cpp @@ -1,6 +1,4 @@ #include "NtXRayServer.h" -#include "PhantomPhysicsComponent.h" -#include "EntityManager.h" #include "SkillComponent.h" void NtXRayServer::OnCollisionPhantom(Entity* self, Entity* target) diff --git a/dScripts/PetDigBuild.cpp b/dScripts/PetDigBuild.cpp index 31b3db06..7ff88fff 100644 --- a/dScripts/PetDigBuild.cpp +++ b/dScripts/PetDigBuild.cpp @@ -1,5 +1,6 @@ #include "PetDigBuild.h" #include "EntityManager.h" +#include "MissionComponent.h" void PetDigBuild::OnRebuildComplete(Entity* self, Entity* target) { auto flagNumber = self->GetVar<std::u16string>(u"flagNum"); diff --git a/dScripts/PetDigServer.cpp b/dScripts/PetDigServer.cpp index a78c0881..dc7e85dd 100644 --- a/dScripts/PetDigServer.cpp +++ b/dScripts/PetDigServer.cpp @@ -1,7 +1,6 @@ -#include <dZoneManager.h> +#include "dZoneManager.h" #include "PetDigServer.h" #include "MissionComponent.h" -#include "InventoryComponent.h" #include "EntityManager.h" #include "Character.h" #include "PetComponent.h" diff --git a/dScripts/PrSeagullFly.cpp b/dScripts/PrSeagullFly.cpp index 728b245f..a4dd5fcd 100644 --- a/dScripts/PrSeagullFly.cpp +++ b/dScripts/PrSeagullFly.cpp @@ -1,4 +1,5 @@ #include "PrSeagullFly.h" +#include "Entity.h" void PrSeagullFly::OnStartup(Entity* self) { diff --git a/dScripts/PrWhistle.cpp b/dScripts/PrWhistle.cpp index 850059d2..4d4d0708 100644 --- a/dScripts/PrWhistle.cpp +++ b/dScripts/PrWhistle.cpp @@ -1,6 +1,6 @@ #include "PrWhistle.h" #include "Character.h" -#include "CharacterComponent.h" +#include "Entity.h" void PrWhistle::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, int32_t param3) diff --git a/dScripts/PropertyDeathPlane.cpp b/dScripts/PropertyDeathPlane.cpp index b682be67..93981dac 100644 --- a/dScripts/PropertyDeathPlane.cpp +++ b/dScripts/PropertyDeathPlane.cpp @@ -1,8 +1,6 @@ #include "PropertyDeathPlane.h" #include "Entity.h" #include "GameMessages.h" -#include "Game.h" -#include "dLogger.h" #include "EntityManager.h" void PropertyDeathPlane::OnCollisionPhantom(Entity* self, Entity* target) @@ -16,7 +14,5 @@ void PropertyDeathPlane::OnCollisionPhantom(Entity* self, Entity* target) auto* teleport = teleportGroup[0]; - Game::logger->Log("PropertyDeathPlane", "Teleporting!\n"); - GameMessages::SendTeleport(target->GetObjectID(), teleport->GetPosition(), teleport->GetRotation(), target->GetSystemAddress()); } diff --git a/dScripts/PropertyDevice.cpp b/dScripts/PropertyDevice.cpp index 6d8e2c0a..ed0d7b81 100644 --- a/dScripts/PropertyDevice.cpp +++ b/dScripts/PropertyDevice.cpp @@ -1,6 +1,7 @@ #include "PropertyDevice.h" #include "GameMessages.h" #include "EntityManager.h" +#include "MissionComponent.h" void PropertyDevice::OnStartup(Entity *self) { auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); diff --git a/dScripts/QbEnemyStunner.cpp b/dScripts/QbEnemyStunner.cpp index 9f0cb8fc..a3dfa94b 100644 --- a/dScripts/QbEnemyStunner.cpp +++ b/dScripts/QbEnemyStunner.cpp @@ -1,7 +1,5 @@ #include "QbEnemyStunner.h" -#include "EntityManager.h" #include "SkillComponent.h" -#include "GameMessages.h" #include "DestroyableComponent.h" void QbEnemyStunner::OnRebuildComplete(Entity* self, Entity* target) diff --git a/dScripts/RaceImagineCrateServer.cpp b/dScripts/RaceImagineCrateServer.cpp index 166b3363..3729004a 100644 --- a/dScripts/RaceImagineCrateServer.cpp +++ b/dScripts/RaceImagineCrateServer.cpp @@ -1,10 +1,10 @@ #include "CharacterComponent.h" #include "DestroyableComponent.h" #include "EntityManager.h" -#include "GameMessages.h" #include "PossessableComponent.h" #include "RaceImagineCrateServer.h" #include "RacingTaskParam.h" +#include "MissionComponent.h" #include "SkillComponent.h" void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) diff --git a/dScripts/RaceImaginePowerup.cpp b/dScripts/RaceImaginePowerup.cpp index 43e20e9d..a940b88d 100644 --- a/dScripts/RaceImaginePowerup.cpp +++ b/dScripts/RaceImaginePowerup.cpp @@ -1,11 +1,9 @@ -#include "CharacterComponent.h" #include "DestroyableComponent.h" #include "EntityManager.h" -#include "PossessableComponent.h" #include "PossessorComponent.h" #include "RaceImaginePowerup.h" #include "RacingTaskParam.h" - +#include "MissionComponent.h" void RaceImaginePowerup::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, int32_t param3) diff --git a/dScripts/RaceMaelstromGeiser.cpp b/dScripts/RaceMaelstromGeiser.cpp index 8e91c5fe..88a45bbd 100644 --- a/dScripts/RaceMaelstromGeiser.cpp +++ b/dScripts/RaceMaelstromGeiser.cpp @@ -1,14 +1,10 @@ #include "RaceMaelstromGeiser.h" -#include "DestroyableComponent.h" #include "GameMessages.h" #include "PossessableComponent.h" #include "PossessorComponent.h" #include "EntityManager.h" #include "RacingControlComponent.h" #include "dZoneManager.h" -#include "Game.h" -#include "dLogger.h" - void RaceMaelstromGeiser::OnStartup(Entity* self) { @@ -26,15 +22,11 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: return; } - Game::logger->Log("RaceMaelstromGeiser", "Entered\n"); - if (!self->GetVar<bool>(u"AmFiring")) { return; } - Game::logger->Log("RaceMaelstromGeiser", "Smashing!\n"); - auto* possessableComponent = entering->GetComponent<PossessableComponent>(); Entity* vehicle; diff --git a/dScripts/RaceSmashServer.cpp b/dScripts/RaceSmashServer.cpp index 582a8ed3..8c8b3f79 100644 --- a/dScripts/RaceSmashServer.cpp +++ b/dScripts/RaceSmashServer.cpp @@ -3,6 +3,7 @@ #include "PossessableComponent.h" #include "RaceSmashServer.h" #include "RacingTaskParam.h" +#include "MissionComponent.h" void RaceSmashServer::OnDie(Entity *self, Entity *killer) { // Crate is smashed by the car diff --git a/dScripts/SGCannon.cpp b/dScripts/SGCannon.cpp index 2deacdde..b1f64b64 100644 --- a/dScripts/SGCannon.cpp +++ b/dScripts/SGCannon.cpp @@ -9,8 +9,8 @@ #include "CharacterComponent.h" #include "SimplePhysicsComponent.h" #include "MovementAIComponent.h" -#include "ControllablePhysicsComponent.h" #include "../dWorldServer/ObjectIDManager.h" +#include "MissionComponent.h" void SGCannon::OnStartup(Entity *self) { Game::logger->Log("SGCannon", "OnStartup\n"); diff --git a/dScripts/ScriptComponent.cpp b/dScripts/ScriptComponent.cpp index 6b3304a3..3c5c2584 100644 --- a/dScripts/ScriptComponent.cpp +++ b/dScripts/ScriptComponent.cpp @@ -5,7 +5,6 @@ #include "Entity.h" #include "ScriptComponent.h" -#include "InvalidScript.h" ScriptComponent::ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client) : Component(parent) { m_Serialized = serialized; diff --git a/dScripts/ScriptComponent.h b/dScripts/ScriptComponent.h index 3c8597ed..82d1f648 100644 --- a/dScripts/ScriptComponent.h +++ b/dScripts/ScriptComponent.h @@ -6,7 +6,6 @@ #ifndef SCRIPTCOMPONENT_H #define SCRIPTCOMPONENT_H -#include "BitStream.h" #include "CppScripts.h" #include "Component.h" #include <string> diff --git a/dScripts/ScriptedPowerupSpawner.cpp b/dScripts/ScriptedPowerupSpawner.cpp index fe35dfed..91c25856 100644 --- a/dScripts/ScriptedPowerupSpawner.cpp +++ b/dScripts/ScriptedPowerupSpawner.cpp @@ -1,6 +1,5 @@ #include "ScriptedPowerupSpawner.h" #include "RenderComponent.h" -#include "GameMessages.h" #include "EntityManager.h" void ScriptedPowerupSpawner::OnTemplateStartup(Entity *self) { diff --git a/dScripts/SpawnGryphonServer.cpp b/dScripts/SpawnGryphonServer.cpp index 93cbbac9..d411569c 100644 --- a/dScripts/SpawnGryphonServer.cpp +++ b/dScripts/SpawnGryphonServer.cpp @@ -1,6 +1,7 @@ #include "SpawnGryphonServer.h" #include "InventoryComponent.h" #include "GameMessages.h" +#include "MissionComponent.h" void SpawnGryphonServer::SetVariables(Entity *self) { self->SetVar<LOT>(u"petLOT", 12433); diff --git a/dScripts/SpawnLionServer.cpp b/dScripts/SpawnLionServer.cpp index 5c6b79d3..b19531a4 100644 --- a/dScripts/SpawnLionServer.cpp +++ b/dScripts/SpawnLionServer.cpp @@ -1,4 +1,5 @@ #include "SpawnLionServer.h" +#include "Entity.h" void SpawnLionServer::SetVariables(Entity *self) { self->SetVar<LOT>(u"petLOT", 3520); diff --git a/dScripts/SpawnSaberCatServer.cpp b/dScripts/SpawnSaberCatServer.cpp index 1d3a5df8..e89d9df7 100644 --- a/dScripts/SpawnSaberCatServer.cpp +++ b/dScripts/SpawnSaberCatServer.cpp @@ -1,4 +1,5 @@ #include "SpawnSaberCatServer.h" +#include "Entity.h" void SpawnSaberCatServer::SetVariables(Entity *self) { self->SetVar<LOT>(u"petLOT", 12432); diff --git a/dScripts/SpawnShrakeServer.cpp b/dScripts/SpawnShrakeServer.cpp index 954cbc3f..5be55ebc 100644 --- a/dScripts/SpawnShrakeServer.cpp +++ b/dScripts/SpawnShrakeServer.cpp @@ -1,4 +1,5 @@ #include "SpawnShrakeServer.h" +#include "Entity.h" void SpawnShrakeServer::SetVariables(Entity *self) { self->SetVar<LOT>(u"petLOT", 12434); diff --git a/dScripts/SpawnStegoServer.cpp b/dScripts/SpawnStegoServer.cpp index ef79d889..d845ff45 100644 --- a/dScripts/SpawnStegoServer.cpp +++ b/dScripts/SpawnStegoServer.cpp @@ -1,4 +1,5 @@ #include "SpawnStegoServer.h" +#include "Entity.h" void SpawnStegoServer::SetVariables(Entity *self) { self->SetVar<LOT>(u"petLOT", 12431); diff --git a/dScripts/SpecialImaginePowerupSpawner.cpp b/dScripts/SpecialImaginePowerupSpawner.cpp index f19b8d28..8417efa2 100644 --- a/dScripts/SpecialImaginePowerupSpawner.cpp +++ b/dScripts/SpecialImaginePowerupSpawner.cpp @@ -5,7 +5,6 @@ #include "DestroyableComponent.h" #include "EntityManager.h" - void SpecialImaginePowerupSpawner::OnStartup(Entity* self) { self->SetProximityRadius(1.5f, "powerupEnter"); diff --git a/dScripts/SsModularBuildServer.cpp b/dScripts/SsModularBuildServer.cpp index ff05d0e4..33f8db47 100644 --- a/dScripts/SsModularBuildServer.cpp +++ b/dScripts/SsModularBuildServer.cpp @@ -1,6 +1,5 @@ #include "SsModularBuildServer.h" -#include "EntityManager.h" -#include "Character.h" +#include "MissionComponent.h" void SsModularBuildServer::OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) { int missionNum = 1732; diff --git a/dScripts/StoryBoxInteractServer.cpp b/dScripts/StoryBoxInteractServer.cpp index 12cb6815..e5899f5d 100644 --- a/dScripts/StoryBoxInteractServer.cpp +++ b/dScripts/StoryBoxInteractServer.cpp @@ -1,7 +1,6 @@ #include "StoryBoxInteractServer.h" #include "Character.h" #include "GameMessages.h" -#include "Game.h" #include "dServer.h" #include "AMFFormat.h" diff --git a/dScripts/Sunflower.cpp b/dScripts/Sunflower.cpp index ac3134d5..436ca5f4 100644 --- a/dScripts/Sunflower.cpp +++ b/dScripts/Sunflower.cpp @@ -1,4 +1,5 @@ #include "Sunflower.h" +#include "Entity.h" void Sunflower::OnStartup(Entity *self) { self->SetVar<uint32_t>(u"numCycles", 6); diff --git a/dScripts/TokenConsoleServer.cpp b/dScripts/TokenConsoleServer.cpp index 58565869..378cc17f 100644 --- a/dScripts/TokenConsoleServer.cpp +++ b/dScripts/TokenConsoleServer.cpp @@ -1,9 +1,7 @@ #include "TokenConsoleServer.h" #include "InventoryComponent.h" -#include "Item.h" #include "GameMessages.h" #include "Character.h" -#include "dCommonVars.h" //2021-05-03 - max - added script, omitted some parts related to inheritance in lua which we don't need diff --git a/dScripts/TreasureChestDragonServer.cpp b/dScripts/TreasureChestDragonServer.cpp index d0e8eaec..80f8aa48 100644 --- a/dScripts/TreasureChestDragonServer.cpp +++ b/dScripts/TreasureChestDragonServer.cpp @@ -1,7 +1,6 @@ #include "TreasureChestDragonServer.h" #include "ScriptedActivityComponent.h" #include "TeamManager.h" -#include "Loot.h" #include "EntityManager.h" void TreasureChestDragonServer::OnStartup(Entity* self) diff --git a/dScripts/TriggerAmbush.cpp b/dScripts/TriggerAmbush.cpp index 42b1ea8f..f9fb8cf7 100644 --- a/dScripts/TriggerAmbush.cpp +++ b/dScripts/TriggerAmbush.cpp @@ -1,7 +1,6 @@ #include "TriggerAmbush.h" #include "dZoneManager.h" -#include "EntityManager.h" void TriggerAmbush::OnStartup(Entity* self) { @@ -11,21 +10,15 @@ void TriggerAmbush::OnStartup(Entity* self) void TriggerAmbush::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { if (name != "ambush" || status != "ENTER" || !entering->IsPlayer()) return; - - Game::logger->Log("TriggerAmbush", "Got ambush collision!\n"); if (self->GetVar<bool>(u"triggered")) return; self->SetVar(u"triggered", true); - Game::logger->Log("TriggerAmbush", "Triggering ambush!\n"); - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("Ambush"); for (auto* spawner : spawners) { - Game::logger->Log("TriggerAmbush", "Triggering ambush on spawner!\n"); - spawner->Activate(); } diff --git a/dScripts/VeBricksampleServer.cpp b/dScripts/VeBricksampleServer.cpp index f42cd9a4..76486d78 100644 --- a/dScripts/VeBricksampleServer.cpp +++ b/dScripts/VeBricksampleServer.cpp @@ -1,6 +1,7 @@ #include "VeBricksampleServer.h" #include "InventoryComponent.h" #include "EntityManager.h" +#include "MissionComponent.h" #include "GameMessages.h" void VeBricksampleServer::OnUse(Entity *self, Entity *user) { diff --git a/dScripts/WaveBossApe.cpp b/dScripts/WaveBossApe.cpp index c7fdccf2..f4d8a132 100644 --- a/dScripts/WaveBossApe.cpp +++ b/dScripts/WaveBossApe.cpp @@ -1,5 +1,6 @@ #include "WaveBossApe.h" #include "BaseCombatAIComponent.h" +#include "Entity.h" void WaveBossApe::OnStartup(Entity *self) { BaseWavesGenericEnemy::OnStartup(self); diff --git a/dScripts/WaveBossHammerling.cpp b/dScripts/WaveBossHammerling.cpp index 6dce0ae3..4775bf42 100644 --- a/dScripts/WaveBossHammerling.cpp +++ b/dScripts/WaveBossHammerling.cpp @@ -1,5 +1,6 @@ #include "WaveBossHammerling.h" #include "BaseCombatAIComponent.h" +#include "Entity.h" void WaveBossHammerling::OnStartup(Entity *self) { BaseWavesGenericEnemy::OnStartup(self); diff --git a/dScripts/WaveBossHorsemen.cpp b/dScripts/WaveBossHorsemen.cpp index 75bffa5b..c129d654 100644 --- a/dScripts/WaveBossHorsemen.cpp +++ b/dScripts/WaveBossHorsemen.cpp @@ -1,5 +1,6 @@ #include "WaveBossHorsemen.h" #include "BaseCombatAIComponent.h" +#include "Entity.h" void WaveBossHorsemen::OnStartup(Entity *self) { BaseWavesGenericEnemy::OnStartup(self); diff --git a/dScripts/WaveBossSpiderling.cpp b/dScripts/WaveBossSpiderling.cpp index f168cb7b..5c8f8766 100644 --- a/dScripts/WaveBossSpiderling.cpp +++ b/dScripts/WaveBossSpiderling.cpp @@ -1,5 +1,6 @@ #include "WaveBossSpiderling.h" #include "BaseCombatAIComponent.h" +#include "Entity.h" void WaveBossSpiderling::OnStartup(Entity *self) { BaseWavesGenericEnemy::OnStartup(self); diff --git a/dScripts/WhFans.cpp b/dScripts/WhFans.cpp index 3a594a4c..f71383cf 100644 --- a/dScripts/WhFans.cpp +++ b/dScripts/WhFans.cpp @@ -1,6 +1,9 @@ #include "WhFans.h" #include "RenderComponent.h" +#include "GameMessages.h" +#include "EntityManager.h" +#include "PhantomPhysicsComponent.h" void WhFans::OnStartup(Entity* self) { self->SetVar<bool>(u"alive", true); diff --git a/dScripts/WhFans.h b/dScripts/WhFans.h index 91aaa9d8..d41eed5b 100644 --- a/dScripts/WhFans.h +++ b/dScripts/WhFans.h @@ -1,9 +1,5 @@ #pragma once #include "CppScripts.h" -#include "GameMessages.h" -#include "EntityManager.h" -#include "PhantomPhysicsComponent.h" - class WhFans : public CppScripts::Script { public: diff --git a/dScripts/WildAmbients.cpp b/dScripts/WildAmbients.cpp index 8ad0f04a..f6414ee8 100644 --- a/dScripts/WildAmbients.cpp +++ b/dScripts/WildAmbients.cpp @@ -1,6 +1,4 @@ #include "WildAmbients.h" -#include "EntityManager.h" -#include "Character.h" #include "GameMessages.h" void WildAmbients::OnUse(Entity* self, Entity* user) diff --git a/dScripts/WishingWellServer.cpp b/dScripts/WishingWellServer.cpp index 36bca973..09e953ac 100644 --- a/dScripts/WishingWellServer.cpp +++ b/dScripts/WishingWellServer.cpp @@ -1,8 +1,6 @@ #include "WishingWellServer.h" -#include "Loot.h" #include "ScriptedActivityComponent.h" #include "GameMessages.h" -#include "Game.h" void WishingWellServer::OnStartup(Entity* self) { diff --git a/dScripts/ZoneAgMedProperty.cpp b/dScripts/ZoneAgMedProperty.cpp index 7fdca69b..da8214b1 100644 --- a/dScripts/ZoneAgMedProperty.cpp +++ b/dScripts/ZoneAgMedProperty.cpp @@ -1,7 +1,7 @@ #include "ZoneAgMedProperty.h" +#include "Entity.h" void ZoneAgMedProperty::SetGameVariables(Entity *self) { - Game::logger->Log("Properties", "Setting variables in instance\n"); self->SetVar<std::string>(ClaimMarkerGroup, "ClaimMarker"); self->SetVar<std::string>(GeneratorGroup, "Generator"); diff --git a/dScripts/ZoneAgProperty.cpp b/dScripts/ZoneAgProperty.cpp index ce30af68..44650a35 100644 --- a/dScripts/ZoneAgProperty.cpp +++ b/dScripts/ZoneAgProperty.cpp @@ -1,12 +1,11 @@ #include "ZoneAgProperty.h" #include "EntityManager.h" -#include "BasePropertyServer.h" #include "Character.h" #include "Entity.h" #include "GameMessages.h" #include "dZoneManager.h" -#include "LDFFormat.h" #include "RenderComponent.h" +#include "MissionComponent.h" void ZoneAgProperty::SetGameVariables(Entity *self) { self->SetVar<std::string>(GuardGroup, "Guard"); @@ -340,7 +339,6 @@ void ZoneAgProperty::OnZonePropertyModelPickedUp(Entity* self, Entity* player) { } void ZoneAgProperty::OnZonePropertyModelRemoved(Entity* self, Entity* player) { - Game::logger->Log("OnZonePropertyModelRemoved", "Removed flag updated!\n"); auto* character = player->GetCharacter(); character->SetPlayerFlag(111, true); } diff --git a/dScripts/ZoneAgProperty.h b/dScripts/ZoneAgProperty.h index 3d88215b..4044be57 100644 --- a/dScripts/ZoneAgProperty.h +++ b/dScripts/ZoneAgProperty.h @@ -1,5 +1,4 @@ #pragma once -#include "CppScripts.h" #include "BasePropertyServer.h" class ZoneAgProperty : public BasePropertyServer { diff --git a/dScripts/ZoneAgSpiderQueen.cpp b/dScripts/ZoneAgSpiderQueen.cpp index 57f93698..27c11aa7 100644 --- a/dScripts/ZoneAgSpiderQueen.cpp +++ b/dScripts/ZoneAgSpiderQueen.cpp @@ -1,10 +1,8 @@ #include "ZoneAgSpiderQueen.h" #include "GameMessages.h" #include "EntityManager.h" -#include "Character.h" #include "ZoneAgProperty.h" #include "DestroyableComponent.h" -#include "dZoneManager.h" void ZoneAgSpiderQueen::SetGameVariables(Entity *self) { ZoneAgProperty::SetGameVariables(self); diff --git a/dScripts/ZoneAgSurvival.h b/dScripts/ZoneAgSurvival.h index 3f84c6d0..c5d803ae 100644 --- a/dScripts/ZoneAgSurvival.h +++ b/dScripts/ZoneAgSurvival.h @@ -1,6 +1,7 @@ #pragma once #include "CppScripts.h" #include "BaseSurvivalServer.h" +#include <map> class ZoneAgSurvival : public BaseSurvivalServer { Constants GetConstants() override; diff --git a/dScripts/ZoneFvProperty.cpp b/dScripts/ZoneFvProperty.cpp index bc573667..64aaad9e 100644 --- a/dScripts/ZoneFvProperty.cpp +++ b/dScripts/ZoneFvProperty.cpp @@ -1,4 +1,5 @@ #include "ZoneFvProperty.h" +#include "Entity.h" void ZoneFvProperty::SetGameVariables(Entity *self) { self->SetVar<std::string>(ClaimMarkerGroup, "Platform"); diff --git a/dScripts/ZoneGfProperty.cpp b/dScripts/ZoneGfProperty.cpp index 630e915a..925320c3 100644 --- a/dScripts/ZoneGfProperty.cpp +++ b/dScripts/ZoneGfProperty.cpp @@ -1,4 +1,5 @@ #include "ZoneGfProperty.h" +#include "Entity.h" void ZoneGfProperty::SetGameVariables(Entity *self) { self->SetVar<std::string>(ClaimMarkerGroup, "BehavQB"); diff --git a/dScripts/ZoneNsMedProperty.cpp b/dScripts/ZoneNsMedProperty.cpp index 92675815..feaadf31 100644 --- a/dScripts/ZoneNsMedProperty.cpp +++ b/dScripts/ZoneNsMedProperty.cpp @@ -1,4 +1,5 @@ #include "ZoneNsMedProperty.h" +#include "Entity.h" void ZoneNsMedProperty::SetGameVariables(Entity *self) { self->SetVar<std::string>(ClaimMarkerGroup, "ClaimMarker"); diff --git a/dScripts/ZoneNsProperty.cpp b/dScripts/ZoneNsProperty.cpp index eec62aa5..72eb1ead 100644 --- a/dScripts/ZoneNsProperty.cpp +++ b/dScripts/ZoneNsProperty.cpp @@ -1,4 +1,5 @@ #include "ZoneNsProperty.h" +#include "Entity.h" void ZoneNsProperty::SetGameVariables(Entity *self) { self->SetVar<std::string>(ClaimMarkerGroup, "Rhino"); From 3cf243b1d7267e75747f620b8a942c35e73a0f8e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 5 Jul 2022 23:18:04 -0700 Subject: [PATCH 73/98] Address modular build not returning parts upon switching some out (#614) --- dGame/dGameMessages/GameMessages.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 6e6236a6..4f5cb1f4 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5514,13 +5514,15 @@ void GameMessages::HandleMoveItemBetweenInventoryTypes(RakNet::BitStream* inStre auto* item = inv->FindItemById(objectID); - if (item == nullptr) - { - item = inv->FindItemByLot(templateID); - - if (item == nullptr) - { - return; + if (!item) { + // Attempt to find the item by lot in inventory A since A is the source inventory. + item = inv->FindItemByLot(templateID, static_cast<eInventoryType>(inventoryTypeA)); + if (!item) { + // As a final resort, try to find the item in its default inventory based on type. + item = inv->FindItemByLot(templateID); + if (!item) { + return; + } } } From de5d9182eb8daeb69c9e2a4a7dff907a06a1c7d2 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 6 Jul 2022 01:30:13 -0700 Subject: [PATCH 74/98] Address items not re-equipping upon exiting build mode (#615) * Implement Precompiled Headers * fix cmake * Fix modular builds not returning parts Modular builds would not search inventory A for their corresponding item and by default would only look in the models bag. This PR forces the item to be looked for in the inventory its coming from (inventoryA) as a second resort before doing the final search in the default inventory of the item. Tested modular building a car and a rocket and when replacing parts the part that was already placed was returned to the inventory correctly. * Push equipped items upon entering build mode Fixes an issue where leaving build mode anywhere would not re-equip your items. This also implements the feature to set your stats back to full, as was done in the live game. Tested exiting build mode on a property with full venture gear and all gear was re-equipped and stats were set to the expected values. --- dGame/dComponents/BuildBorderComponent.cpp | 2 ++ dGame/dComponents/InventoryComponent.cpp | 12 ++++++++++++ dGame/dComponents/PropertyManagementComponent.cpp | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/dGame/dComponents/BuildBorderComponent.cpp b/dGame/dComponents/BuildBorderComponent.cpp index ed2fe2d2..1747f0ed 100644 --- a/dGame/dComponents/BuildBorderComponent.cpp +++ b/dGame/dComponents/BuildBorderComponent.cpp @@ -42,6 +42,8 @@ void BuildBorderComponent::OnUse(Entity* originator) { return; } + inventoryComponent->PushEquippedItems(); + Game::logger->Log("BuildBorderComponent", "Starting with %llu\n", buildArea); if (PropertyManagementComponent::Instance() != nullptr) { diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 950536ab..8ae6e93f 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1158,6 +1158,18 @@ void InventoryComponent::PopEquippedItems() item->Equip(); } + m_Pushed.clear(); + + auto destroyableComponent = m_Parent->GetComponent<DestroyableComponent>(); + + // Reset stats to full + if (destroyableComponent) { + destroyableComponent->SetHealth(static_cast<int32_t>(destroyableComponent->GetMaxHealth())); + destroyableComponent->SetArmor(static_cast<int32_t>(destroyableComponent->GetMaxArmor())); + destroyableComponent->SetImagination(static_cast<int32_t>(destroyableComponent->GetMaxImagination())); + EntityManager::Instance()->SerializeEntity(m_Parent); + } + m_Dirty = true; } diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 04e2f633..f27ea283 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -286,6 +286,10 @@ void PropertyManagementComponent::OnStartBuilding() player->SendToZone(zoneId); } + auto inventoryComponent = ownerEntity->GetComponent<InventoryComponent>(); + + // Push equipped items + if (inventoryComponent) inventoryComponent->PushEquippedItems(); } void PropertyManagementComponent::OnFinishBuilding() From 138fffda2ce51559621b3e5d48fdb0884cdb8f05 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 6 Jul 2022 08:54:41 -0700 Subject: [PATCH 75/98] Fix item collection missions (#617) * Implement Precompiled Headers * fix cmake * Fix modular builds not returning parts Modular builds would not search inventory A for their corresponding item and by default would only look in the models bag. This PR forces the item to be looked for in the inventory its coming from (inventoryA) as a second resort before doing the final search in the default inventory of the item. Tested modular building a car and a rocket and when replacing parts the part that was already placed was returned to the inventory correctly. * Push equipped items upon entering build mode Fixes an issue where leaving build mode anywhere would not re-equip your items. This also implements the feature to set your stats back to full, as was done in the live game. Tested exiting build mode on a property with full venture gear and all gear was re-equipped and stats were set to the expected values. * Fix item collection missions Item collection missions are only supposed to take items should they be in the items inventory or the hidden inventory and no others. This change removes the global inventory find of items and only removes it from the two inventories that items get taken from in live, ITEMS and HIDDEN Tested completing mission 470 and 477 as well as 622 and the correct items were taken or not taken, based on the inventory the target item was in. --- dGame/dMission/Mission.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 31987505..aeb26838 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -421,7 +421,9 @@ void Mission::YieldRewards() { if (param.empty() || (param[0] & 1) == 0) // Should items be removed? { for (const auto target : task->GetAllTargets()) { - inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue); + // This is how live did it. ONLY remove item collection items from the items and hidden inventories and none of the others. + inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::ITEMS); + inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::HIDDEN); missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, target, LWOOBJID_EMPTY, "", -task->GetClientInfo().targetValue); } From 0734760d42282dd27d1b7ac754ae00f34e39f223 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 6 Jul 2022 12:05:42 -0700 Subject: [PATCH 76/98] Add openssl to list of package requirements I forgot to add this to the list of needed packages. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79a1f27c..6b82e1b0 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ This was done make sure that older and incomplete clients wouldn't produce false If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number. ### Linux builds -Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required. +Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`. CMake must be version 3.14 or higher! From 22b2516107d9b0e6f6b4ccf6f9d19771d067b37b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 6 Jul 2022 19:29:15 -0700 Subject: [PATCH 77/98] Fix nested preconditions not evaluating costs (#618) Fixed an issue with some builds that had preconditions not taking items from the players due to the evaluate costs parameter not being passed to nested conditions. Tested the build in Avant Gardens and it now correctly takes items from the player upon completion. --- dGame/dUtilities/Preconditions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index 6921343b..bd10b814 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -317,7 +317,7 @@ bool PreconditionExpression::Check(Entity* player, bool evaluateCosts) const GameMessages::SendNotifyClientFailedPrecondition(player->GetObjectID(), player->GetSystemAddress(), u"", condition); } - const auto b = next == nullptr ? true : next->Check(player); + const auto b = next == nullptr ? true : next->Check(player, evaluateCosts); return m_or ? a || b : a && b; } From 3865a186a7ee5b774f06df8c126afdc93ef76992 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 8 Jul 2022 22:25:15 -0500 Subject: [PATCH 78/98] Possessor and possessable additions (#619) * possessor-fixup and possessable additions * comment and docstring fixes * fix possessable initialization * split animation flags into it's own header remove unnecessary checks --- dCommon/dCommonVars.h | 1 - dCommon/eAninmationFlags.h | 44 ++++++++ dGame/Entity.cpp | 5 +- dGame/dComponents/PossessableComponent.cpp | 72 ++++++------- dGame/dComponents/PossessableComponent.h | 108 ++++++++++++++----- dGame/dComponents/PossessorComponent.h | 26 +++-- dGame/dComponents/RacingControlComponent.cpp | 1 + dScripts/SGCannon.cpp | 10 +- 8 files changed, 178 insertions(+), 89 deletions(-) create mode 100644 dCommon/eAninmationFlags.h diff --git a/dCommon/dCommonVars.h b/dCommon/dCommonVars.h index 4cbdb61c..e941413b 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dCommonVars.h @@ -664,7 +664,6 @@ enum ePlayerFlags { NJ_WU_SHOW_DAILY_CHEST = 2099 }; - //======== FUNC =========== template<typename T> diff --git a/dCommon/eAninmationFlags.h b/dCommon/eAninmationFlags.h new file mode 100644 index 00000000..09cfde22 --- /dev/null +++ b/dCommon/eAninmationFlags.h @@ -0,0 +1,44 @@ +#pragma once + +#ifndef __EANINMATIONFLAGS__H__ +#define __EANINMATIONFLAGS__H__ + +#include <cstdint> + +enum class eAnimationFlags : uint32_t { + IDLE_INVALID = 0, // made up, for internal use!!! + IDLE_BASIC, + IDLE_SWIM, + IDLE_CARRY, + IDLE_SWORD, + IDLE_HAMMER, + IDLE_SPEAR, + IDLE_PISTOL, + IDLE_BOW, + IDLE_COMBAT, + IDLE_JETPACK, + IDLE_HORSE, + IDLE_SG, + IDLE_ORGAN, + IDLE_SKATEBOARD, + IDLE_DAREDEVIL, + IDLE_SAMURAI, + IDLE_SUMMONER, + IDLE_BUCCANEER, + IDLE_MISC, + IDLE_NINJA, + IDLE_MISC1, + IDLE_MISC2, + IDLE_MISC3, + IDLE_MISC4, + IDLE_MISC5, + IDLE_MISC6, + IDLE_MISC7, + IDLE_MISC8, + IDLE_MISC9, + IDLE_MISC10, + IDLE_MISC11, + IDLE_MISC12 +}; + +#endif //!__EANINMATIONFLAGS__H__ \ No newline at end of file diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index bb7e0335..68277cd8 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -208,8 +208,9 @@ void Entity::Initialize() m_Components.insert(std::make_pair(COMPONENT_TYPE_ZONE_CONTROL, nullptr)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_POSSESSABLE) > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_POSSESSABLE, new PossessableComponent(this))); + uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_POSSESSABLE); + if (possessableComponentId > 0) { + m_Components.insert(std::make_pair(COMPONENT_TYPE_POSSESSABLE, new PossessableComponent(this, possessableComponentId))); } if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MODULE_ASSEMBLY) > 0) { diff --git a/dGame/dComponents/PossessableComponent.cpp b/dGame/dComponents/PossessableComponent.cpp index d4fd0d62..1d721466 100644 --- a/dGame/dComponents/PossessableComponent.cpp +++ b/dGame/dComponents/PossessableComponent.cpp @@ -1,51 +1,43 @@ #include "PossessableComponent.h" - #include "PossessorComponent.h" #include "EntityManager.h" +#include "Item.h" -PossessableComponent::PossessableComponent(Entity* parent) : Component(parent) -{ - m_Possessor = LWOOBJID_EMPTY; +PossessableComponent::PossessableComponent(Entity* parent, uint32_t componentId) : Component(parent){ + m_Possessor = LWOOBJID_EMPTY; + + // Get the possession Type from the CDClient + auto query = CDClientDatabase::CreatePreppedStmt("SELECT possessionType, depossessOnHit FROM PossessableComponent WHERE id = ?;"); + + query.bind(1, static_cast<int>(componentId)); + + auto result = query.execQuery(); + + // Should a result not exist for this default to attached visible + if (!result.eof()) { + m_PossessionType = static_cast<ePossessionType>(result.getIntField(0, 0)); + m_DepossessOnHit = static_cast<bool>(result.getIntField(1, 0)); + } else { + m_PossessionType = ePossessionType::ATTACHED_VISIBLE; + m_DepossessOnHit = false; + } + result.finalize(); } -PossessableComponent::~PossessableComponent() -{ - -} +void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { + outBitStream->Write(m_DirtyPossessable || bIsInitialUpdate); + if (m_DirtyPossessable || bIsInitialUpdate) { + m_DirtyPossessable = false; + outBitStream->Write(m_Possessor != LWOOBJID_EMPTY); + if (m_Possessor != LWOOBJID_EMPTY) outBitStream->Write(m_Possessor); -void PossessableComponent::SetPossessor(LWOOBJID value) -{ - m_Possessor = value; -} + outBitStream->Write(m_AnimationFlag != eAnimationFlags::IDLE_INVALID); + if(m_AnimationFlag != eAnimationFlags::IDLE_INVALID) outBitStream->Write(m_AnimationFlag); -LWOOBJID PossessableComponent::GetPossessor() const -{ - return m_Possessor; -} - -void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) -{ - outBitStream->Write(m_Possessor != LWOOBJID_EMPTY); - if (m_Possessor != LWOOBJID_EMPTY) - { - outBitStream->Write1(); - outBitStream->Write(m_Possessor); - outBitStream->Write0(); - outBitStream->Write0(); - } -} - -void PossessableComponent::Update(float deltaTime) -{ - + outBitStream->Write(m_ImmediatelyDepossess); + } } void PossessableComponent::OnUse(Entity* originator) { - PossessorComponent* possessorComponent; - if (originator->TryGetComponent(COMPONENT_TYPE_POSSESSOR, possessorComponent)) { - SetPossessor(originator->GetObjectID()); - possessorComponent->SetPossessable(m_Parent->GetObjectID()); - EntityManager::Instance()->SerializeEntity(m_Parent); - EntityManager::Instance()->SerializeEntity(originator); - } -} + // TODO: Implement this +} \ No newline at end of file diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index 744ebfc5..5eefaaf4 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -3,44 +3,96 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "Item.h" +#include "PossessorComponent.h" +#include "eAninmationFlags.h" /** * Represents an entity that can be controlled by some other entity, generally used by cars to indicate that some * player is controlling it. */ class PossessableComponent : public Component { -public: - static const uint32_t ComponentType = COMPONENT_TYPE_POSSESSABLE; - - PossessableComponent(Entity* parentEntity); - ~PossessableComponent() override; + public: + static const uint32_t ComponentType = COMPONENT_TYPE_POSSESSABLE; - void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - void Update(float deltaTime) override; + PossessableComponent(Entity* parentEntity, uint32_t componentId); - /** - * Sets the possessor of this entity - * @param value the ID of the possessor to set - */ - void SetPossessor(LWOOBJID value); + void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); - /** - * Returns the possessor of this entity - * @return the possessor of this entitythe - */ - LWOOBJID GetPossessor() const; + /** + * Sets the possessor of this entity + * @param value the ID of the possessor to set + */ + void SetPossessor(LWOOBJID value) { m_Possessor = value; m_DirtyPossessable = true;}; - /** - * Handles an OnUsed event by some other entity, if said entity has a PossessorComponent it becomes the possessor - * of this entity - * @param originator the entity that caused the event to trigger - */ - void OnUse(Entity* originator) override; + /** + * Returns the possessor of this entity + * @return the possessor of this entity + */ + LWOOBJID GetPossessor() const { return m_Possessor; }; -private: + /** + * Sets the animation Flag of the possessable + * @param value the animation flag to set to + */ + void SetAnimationFlag(eAnimationFlags value) { m_AnimationFlag = value; m_DirtyPossessable = true;}; + + /** + * Returns the possession type of this entity + * @return the possession type of this entity + */ + ePossessionType GetPossessionType() const { return m_PossessionType; }; + + /** + * Returns if the entity should deposses on hit + * @return if the entity should deposses on hit + */ + bool GetDepossessOnHit() const { return m_DepossessOnHit; }; + + /** + * Forcibly depossess the entity + */ + void ForceDepossess() { m_ImmediatelyDepossess = true; m_DirtyPossessable = true;}; + + /** + * Handles an OnUsed event by some other entity, if said entity has a Possessor it becomes the possessor + * of this entity + * @param originator the entity that caused the event to trigger + */ + void OnUse(Entity* originator) override; + + private: + + /** + * @brief Whether the possessor is dirty + */ + bool m_DirtyPossessable = true; + + /** + * @brief The possessor of this entity, e.g. the entity that controls this entity + */ + LWOOBJID m_Possessor = LWOOBJID_EMPTY; + + /** + * @brief The type of possesstion to use on this entity + */ + ePossessionType m_PossessionType = ePossessionType::NO_POSSESSION; + + /** + * @brief Should the possessable be dismount on hit + */ + bool m_DepossessOnHit = false; + + /** + * @brief What animaiton flag to use + * + */ + eAnimationFlags m_AnimationFlag = eAnimationFlags::IDLE_INVALID; + + /** + * @brief Should this be immediately depossessed + * + */ + bool m_ImmediatelyDepossess = false; - /** - * The possessor of this entity, e.g. the entity that controls this entity - */ - LWOOBJID m_Possessor; }; diff --git a/dGame/dComponents/PossessorComponent.h b/dGame/dComponents/PossessorComponent.h index f3389274..f202b907 100644 --- a/dGame/dComponents/PossessorComponent.h +++ b/dGame/dComponents/PossessorComponent.h @@ -4,6 +4,14 @@ #include "Entity.h" #include "Component.h" +// possession types +enum class ePossessionType : uint8_t { + NO_POSSESSION = 0, + ATTACHED_VISIBLE, + NOT_ATTACHED_VISIBLE, + NOT_ATTACHED_NOT_VISIBLE, +}; + /** * Represents an entity that can posess other entities. Generally used by players to drive a car. */ @@ -22,34 +30,34 @@ class PossessorComponent : public Component { */ void SetPossessable(LWOOBJID value) { m_Possessable = value; m_DirtyPossesor = true; } - /** - * Sets the possesible type that's currently used, merely used by the shooting gallery if it's 0 - * @param value the possesible type to set - */ - void SetPossessableType(uint8_t value) { m_PossessableType = value; m_DirtyPossesor = true; } - /** * Returns the entity that this entity is currently posessing * @return the entity that this entity is currently posessing */ LWOOBJID GetPossessable() const { return m_Possessable; } + /** + * Sets the possesible type that's currently used, merely used by the shooting gallery if it's 0 + * @param value the possesible type to set + */ + void SetPossessableType(ePossessionType value) { m_PossessableType = value; m_DirtyPossesor = true; } + private: /** * The ID of the entity this entity is possessing (e.g. the ID of a car) */ - LWOOBJID m_Possessable; + LWOOBJID m_Possessable = LWOOBJID_EMPTY; /** * @brief possessable type * */ - uint8_t m_PossessableType; + ePossessionType m_PossessableType = ePossessionType::NO_POSSESSION; /** * @brief if the possessor is dirty * */ - bool m_DirtyPossesor; + bool m_DirtyPossesor = false; }; diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index d8794114..7bea03f6 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -212,6 +212,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity *player, if (possessorComponent != nullptr) { possessorComponent->SetPossessable(carEntity->GetObjectID()); + possessorComponent->SetPossessableType(ePossessionType::ATTACHED_VISIBLE); // for racing it's always Attached_Visible } // Set the player's current activity as racing. diff --git a/dScripts/SGCannon.cpp b/dScripts/SGCannon.cpp index b1f64b64..ab179226 100644 --- a/dScripts/SGCannon.cpp +++ b/dScripts/SGCannon.cpp @@ -95,14 +95,6 @@ void SGCannon::OnActivityStateChangeRequest(Entity *self, LWOOBJID senderID, int Game::logger->Log("SGCannon", "Shooting gallery component is null\n"); } - auto* possessorComponent = player->GetComponent<PossessorComponent>(); - - /*if (possessorComponent != nullptr) { - possessorComponent->SetPossessable(self->GetObjectID()); - - EntityManager::Instance()->SerializeEntity(player); - }*/ - auto* characterComponent = player->GetComponent<CharacterComponent>(); if (characterComponent != nullptr) { @@ -111,7 +103,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity *self, LWOOBJID senderID, int auto possessor = player->GetComponent<PossessorComponent>(); if(possessor) { possessor->SetPossessable(self->GetObjectID()); - possessor->SetPossessableType(0); + possessor->SetPossessableType(ePossessionType::NO_POSSESSION); } EntityManager::Instance()->SerializeEntity(player); From dddc33607b32e93341c61c723252471af8e18d6b Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 8 Jul 2022 22:25:44 -0500 Subject: [PATCH 79/98] remove unused code and callbacktimers in testmap (#620) --- dGame/dUtilities/SlashCommandHandler.cpp | 79 ++++++++---------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 8631f760..ae8e7969 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1362,13 +1362,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (requestedPlayerToSetLevelOf != "") { ChatPackets::SendSystemMessage( - sysAddr, u"Set " + GeneralUtils::ASCIIToUTF16(requestedPlayerToSetLevelOf) + u"'s level to " + GeneralUtils::to_u16string(requestedLevel) + - u" and UScore to " + GeneralUtils::to_u16string(characterComponent->GetUScore()) + + sysAddr, u"Set " + GeneralUtils::ASCIIToUTF16(requestedPlayerToSetLevelOf) + u"'s level to " + GeneralUtils::to_u16string(requestedLevel) + + u" and UScore to " + GeneralUtils::to_u16string(characterComponent->GetUScore()) + u". Relog to see changes."); } else { ChatPackets::SendSystemMessage( - sysAddr, u"Set your level to " + GeneralUtils::to_u16string(requestedLevel) + - u" and UScore to " + GeneralUtils::to_u16string(characterComponent->GetUScore()) + + sysAddr, u"Set your level to " + GeneralUtils::to_u16string(requestedLevel) + + u" and UScore to " + GeneralUtils::to_u16string(characterComponent->GetUScore()) + u". Relog to see changes."); } return; @@ -1518,61 +1518,36 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto objid = entity->GetObjectID(); - if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery - bool darwin = true; //Putting this on true, as I'm sick of having to wait 3-4 seconds on a transfer while trying to quickly moderate properties + if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery - Character* character = entity->GetCharacter(); - if (character) { - std::string lowerName = character->GetName(); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); - // feel free to add your name to the list - if (lowerName.find("max") != std::string::npos || lowerName.find("darwin") != std::string::npos || lowerName.find("gie") != std::string::npos) { - darwin = true; - } - } + 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) { - if (!darwin) { - GameMessages::SendPlayAnimation(entity, u"lup-teleport"); - GameMessages::SendSetStunned(objid, PUSH, user->GetSystemAddress(), - LWOOBJID_EMPTY, true, true, true, true, true, true, true, true - ); - } - - ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, reqZone, cloneId, false, [objid, darwin](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { auto* entity = EntityManager::Instance()->GetEntity(objid); + if (!entity) return; - if (entity == nullptr) { - return; + const auto sysAddr = entity->GetSystemAddress(); + + ChatPackets::SendSystemMessage(sysAddr, u"Transfering map..."); + + Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort); + if (entity->GetCharacter()) { + entity->GetCharacter()->SetZoneID(zoneID); + entity->GetCharacter()->SetZoneInstance(zoneInstance); + entity->GetCharacter()->SetZoneClone(zoneClone); + entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u""); } - float transferTime = 3.32999992370605f; - if (darwin) transferTime = 0.0f; + entity->GetCharacter()->SaveXMLToDatabase(); - entity->AddCallbackTimer(transferTime, [=] { - const auto sysAddr = entity->GetSystemAddress(); - - ChatPackets::SendSystemMessage(sysAddr, u"Transfering map..."); - - Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort); - if (entity->GetCharacter()) { - entity->GetCharacter()->SetZoneID(zoneID); - entity->GetCharacter()->SetZoneInstance(zoneInstance); - entity->GetCharacter()->SetZoneClone(zoneClone); - entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u""); - } - - entity->GetCharacter()->SaveXMLToDatabase(); - - WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); - }); - return; - }); - } else { - std::string msg = "ZoneID not found or allowed: "; - msg.append(args[0]); - ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(msg, msg.size())); - } - } + WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); + return; + }); + } else { + std::string msg = "ZoneID not found or allowed: "; + msg.append(args[0]); + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(msg, msg.size())); + } + } if (chatCommand == "createprivate" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { From 485de6173aa8f36173a82f7c56ce179269e82167 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 8 Jul 2022 23:07:52 -0700 Subject: [PATCH 80/98] Added caching for behavior parameter table (#621) * Added caching for table Added caching for table Add more caching Update MasterServer.cpp grds Update CDBehaviorParameterTable.cpp Update CDBehaviorParameterTable.h Update CDBehaviorTemplateTable.cpp Update Behavior.cpp Update Behavior.cpp change to map Remove redundant query * Remove include * change to enum * Update Behavior.cpp * Use already cached table * Update Behavior.cpp --- dDatabase/CDClientManager.cpp | 2 +- dDatabase/Tables/CDBehaviorParameterTable.cpp | 84 ++++++---------- dDatabase/Tables/CDBehaviorParameterTable.h | 11 ++- dDatabase/Tables/CDBehaviorTemplateTable.cpp | 15 ++- dDatabase/Tables/CDBehaviorTemplateTable.h | 6 +- dGame/dBehaviors/Behavior.cpp | 99 +++++++------------ dGame/dBehaviors/Behavior.h | 2 +- 7 files changed, 93 insertions(+), 126 deletions(-) diff --git a/dDatabase/CDClientManager.cpp b/dDatabase/CDClientManager.cpp index 7ad852bc..75ada1ea 100644 --- a/dDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientManager.cpp @@ -8,7 +8,7 @@ void CDClientManager::Initialize(void) { tables.insert(std::make_pair("ActivityRewards", new CDActivityRewardsTable())); UNUSED(tables.insert(std::make_pair("Animations", new CDAnimationsTable()))); tables.insert(std::make_pair("BehaviorParameter", new CDBehaviorParameterTable())); - UNUSED(tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable()))); + tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable())); tables.insert(std::make_pair("ComponentsRegistry", new CDComponentsRegistryTable())); tables.insert(std::make_pair("CurrencyTable", new CDCurrencyTableTable())); tables.insert(std::make_pair("DestructibleComponent", new CDDestructibleComponentTable())); diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index 4991ac82..bbbdb2b6 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -3,33 +3,25 @@ //! Constructor CDBehaviorParameterTable::CDBehaviorParameterTable(void) { -#ifdef CDCLIENT_CACHE_ALL auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); + size_t hash = 0; while (!tableData.eof()) { + hash = 0; CDBehaviorParameter entry; entry.behaviorID = tableData.getIntField(0, -1); entry.parameterID = tableData.getStringField(1, ""); entry.value = tableData.getFloatField(2, -1.0f); - //Check if we have an entry with this ID: - auto it = m_entries.find(entry.behaviorID); - if (it != m_entries.end()) { - it->second.insert(std::make_pair(entry.parameterID, entry.value)); - } - else { - //Otherwise, insert it: - m_entries.insert(std::make_pair(entry.behaviorID, std::map<std::string, float>())); - auto jit = m_entries.find(entry.behaviorID); + GeneralUtils::hash_combine(hash, entry.behaviorID); + GeneralUtils::hash_combine(hash, entry.parameterID); - //Add our value as well: - jit->second.insert(std::make_pair(entry.parameterID, entry.value)); - } + auto it = m_Entries.find(entry.behaviorID); + m_ParametersList.insert(entry.parameterID); + m_Entries.insert(std::make_pair(hash, entry)); tableData.nextRow(); } - tableData.finalize(); -#endif } //! Destructor @@ -40,51 +32,33 @@ std::string CDBehaviorParameterTable::GetName(void) const { return "BehaviorParameter"; } -float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) +CDBehaviorParameter CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) { + CDBehaviorParameter returnValue; + returnValue.behaviorID = 0; + returnValue.parameterID = ""; + returnValue.value = defaultValue; + size_t hash = 0; GeneralUtils::hash_combine(hash, behaviorID); GeneralUtils::hash_combine(hash, name); // Search for specific parameter const auto& it = m_Entries.find(hash); - if (it != m_Entries.end()) { - return it->second; - } - - // Check if this behavior has already been checked - const auto& itChecked = m_Entries.find(behaviorID); - if (itChecked != m_Entries.end()) { - return defaultValue; - } - -#ifndef CDCLIENT_CACHE_ALL - auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); - query.bind(1, (int) behaviorID); - - auto tableData = query.execQuery(); - - m_Entries.insert_or_assign(behaviorID, 0); - - while (!tableData.eof()) { - const std::string parameterID = tableData.getStringField(0, ""); - const float value = tableData.getFloatField(1, 0); - - size_t parameterHash = 0; - GeneralUtils::hash_combine(parameterHash, behaviorID); - GeneralUtils::hash_combine(parameterHash, parameterID); - - m_Entries.insert_or_assign(parameterHash, value); - - tableData.nextRow(); - } - - const auto& it2 = m_Entries.find(hash); - if (it2 != m_Entries.end()) { - return it2->second; - } -#endif - - return defaultValue; + return it != m_Entries.end() ? it->second : returnValue; +} + +std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) { + size_t hash; + std::map<std::string, float> returnInfo; + for (auto parameterCandidate : m_ParametersList) { + hash = 0; + GeneralUtils::hash_combine(hash, behaviorID); + GeneralUtils::hash_combine(hash, parameterCandidate); + auto infoCandidate = m_Entries.find(hash); + if (infoCandidate != m_Entries.end()) { + returnInfo.insert(std::make_pair(infoCandidate->second.parameterID, infoCandidate->second.value)); + } + } + return returnInfo; } diff --git a/dDatabase/Tables/CDBehaviorParameterTable.h b/dDatabase/Tables/CDBehaviorParameterTable.h index 3d14d66d..17605636 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.h +++ b/dDatabase/Tables/CDBehaviorParameterTable.h @@ -2,7 +2,8 @@ // Custom Classes #include "CDTable.h" -#include <map> +#include <unordered_map> +#include <unordered_set> /*! \file CDBehaviorParameterTable.hpp @@ -19,8 +20,8 @@ struct CDBehaviorParameter { //! BehaviorParameter table class CDBehaviorParameterTable : public CDTable { private: - std::map<size_t, float> m_Entries; - + std::unordered_map<size_t, CDBehaviorParameter> m_Entries; + std::unordered_set<std::string> m_ParametersList; public: //! Constructor @@ -35,5 +36,7 @@ public: */ std::string GetName(void) const override; - float GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); + CDBehaviorParameter GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); + + std::map<std::string, float> GetParametersByBehaviorID(uint32_t behaviorID); }; diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.cpp b/dDatabase/Tables/CDBehaviorTemplateTable.cpp index f9830317..c79f4177 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.cpp +++ b/dDatabase/Tables/CDBehaviorTemplateTable.cpp @@ -16,7 +16,7 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { // Reserve the size this->entries.reserve(size); - + // Now get the data auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate"); while (!tableData.eof()) { @@ -27,6 +27,7 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { entry.effectHandle = tableData.getStringField(3, ""); this->entries.push_back(entry); + this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry)); tableData.nextRow(); } @@ -55,3 +56,15 @@ std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<boo std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::GetEntries(void) const { return this->entries; } + +const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behaviorID) { + auto entry = this->entriesMappedByBehaviorID.find(behaviorID); + if (entry == this->entriesMappedByBehaviorID.end()) { + CDBehaviorTemplate entryToReturn; + entryToReturn.behaviorID = 0; + entryToReturn.effectHandle = ""; + return entryToReturn; + } else { + return entry->second; + } +} diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.h b/dDatabase/Tables/CDBehaviorTemplateTable.h index a63c2160..36424c12 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.h +++ b/dDatabase/Tables/CDBehaviorTemplateTable.h @@ -2,6 +2,7 @@ // Custom Classes #include "CDTable.h" +#include <unordered_map> /*! \file CDBehaviorTemplateTable.hpp @@ -21,7 +22,7 @@ struct CDBehaviorTemplate { class CDBehaviorTemplateTable : public CDTable { private: std::vector<CDBehaviorTemplate> entries; - + std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID; public: //! Constructor @@ -47,5 +48,6 @@ public: \return The entries */ std::vector<CDBehaviorTemplate> GetEntries(void) const; - + + const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID); }; diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 7305ed2d..ac1ab7de 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -7,6 +7,7 @@ #include "dLogger.h" #include "BehaviorTemplates.h" #include "BehaviorBranchContext.h" +#include <unordered_map> /* * Behavior includes @@ -69,7 +70,7 @@ #include "RenderComponent.h" #include "DestroyableComponent.h" -std::map<uint32_t, Behavior*> Behavior::Cache = {}; +std::unordered_map<uint32_t, Behavior*> Behavior::Cache = {}; CDBehaviorParameterTable* Behavior::BehaviorParameterTable = nullptr; Behavior* Behavior::GetBehavior(const uint32_t behaviorId) @@ -285,28 +286,22 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) } BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { - auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;"); - query.bind(1, (int) behaviorId); + auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate"); - auto result = query.execQuery(); - - // Make sure we do not proceed if we are trying to load an invalid behavior - if (result.eof()) - { - if (behaviorId != 0) - { - Game::logger->Log("Behavior::GetBehaviorTemplate", "Failed to load behavior template with id (%i)!\n", behaviorId); + BehaviorTemplates templateID = BehaviorTemplates::BEHAVIOR_EMPTY; + // Find behavior template by its behavior id. Default to 0. + if (behaviorTemplateTable) { + auto templateEntry = behaviorTemplateTable->GetByBehaviorID(behaviorId); + if (templateEntry.behaviorID == behaviorId) { + templateID = static_cast<BehaviorTemplates>(templateEntry.templateID); } - - return BehaviorTemplates::BEHAVIOR_EMPTY; } - const auto id = static_cast<BehaviorTemplates>(result.getIntField(0)); + if (templateID == BehaviorTemplates::BEHAVIOR_EMPTY && behaviorId != 0) { + Game::logger->Log("Behavior", "Failed to load behavior template with id (%i)!\n", behaviorId); + } - result.finalize(); - - return id; + return templateID; } // For use with enemies, to display the correct damage animations on the players @@ -412,6 +407,17 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID Behavior::Behavior(const uint32_t behaviorId) { + auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate"); + + CDBehaviorTemplate templateInDatabase; + + if (behaviorTemplateTable) { + auto templateEntry = behaviorTemplateTable->GetByBehaviorID(behaviorId); + if (templateEntry.behaviorID == behaviorId) { + templateInDatabase = templateEntry; + } + } + this->m_behaviorId = behaviorId; // Add to cache @@ -423,14 +429,8 @@ Behavior::Behavior(const uint32_t behaviorId) this->m_templateId = BehaviorTemplates::BEHAVIOR_EMPTY; } - auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = ?;"); - query.bind(1, (int) behaviorId); - - auto result = query.execQuery(); - // Make sure we do not proceed if we are trying to load an invalid behavior - if (result.eof()) + if (templateInDatabase.behaviorID == 0) { Game::logger->Log("Behavior", "Failed to load behavior with id (%i)!\n", behaviorId); @@ -441,34 +441,19 @@ Behavior::Behavior(const uint32_t behaviorId) return; } - this->m_templateId = static_cast<BehaviorTemplates>(result.getIntField(0)); + this->m_templateId = static_cast<BehaviorTemplates>(templateInDatabase.templateID); - this->m_effectId = result.getIntField(1); + this->m_effectId = templateInDatabase.effectID; - if (!result.fieldIsNull(2)) - { - const std::string effectHandle = result.getStringField(2); - if (effectHandle == "") - { - this->m_effectHandle = nullptr; - } - else - { - this->m_effectHandle = new std::string(effectHandle); - } - } - else - { - this->m_effectHandle = nullptr; - } - - result.finalize(); + this->m_effectHandle = templateInDatabase.effectHandle != "" ? new std::string(templateInDatabase.effectHandle) : nullptr; } float Behavior::GetFloat(const std::string& name, const float defaultValue) const { - return BehaviorParameterTable->GetEntry(this->m_behaviorId, name, defaultValue); + // Get the behavior parameter entry and return its value. + if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter"); + return BehaviorParameterTable->GetEntry(this->m_behaviorId, name, defaultValue).value; } @@ -498,24 +483,14 @@ Behavior* Behavior::GetAction(float value) const std::map<std::string, float> Behavior::GetParameterNames() const { - std::map<std::string, float> parameters; - - auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); - query.bind(1, (int) this->m_behaviorId); - - auto tableData = query.execQuery(); - - while (!tableData.eof()) - { - parameters.insert_or_assign(tableData.getStringField(0, ""), tableData.getFloatField(1, 0)); - - tableData.nextRow(); + std::map<std::string, float> templatesInDatabase; + // Find behavior template by its behavior id. + if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter"); + if (BehaviorParameterTable) { + templatesInDatabase = BehaviorParameterTable->GetParametersByBehaviorID(this->m_behaviorId); } - tableData.finalize(); - - return parameters; + return templatesInDatabase; } void Behavior::Load() diff --git a/dGame/dBehaviors/Behavior.h b/dGame/dBehaviors/Behavior.h index e8700f48..34ba469b 100644 --- a/dGame/dBehaviors/Behavior.h +++ b/dGame/dBehaviors/Behavior.h @@ -19,7 +19,7 @@ public: /* * Static */ - static std::map<uint32_t, Behavior*> Cache; + static std::unordered_map<uint32_t, Behavior*> Cache; static CDBehaviorParameterTable* BehaviorParameterTable; static Behavior* GetBehavior(uint32_t behaviorId); From 66edf57b025196b31fc89906f3cc616f827ecb0f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:27:20 -0700 Subject: [PATCH 81/98] Wait for world to shutdown (#624) We need to wait for the message that the world has shutdown before shutting it down. --- dMasterServer/MasterServer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index ac49b1a1..94e0d5b6 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -303,7 +303,6 @@ int main(int argc, char** argv) { if (affirmTimeout == 1000) { instance->Shutdown(); - instance->SetShutdownComplete(true); Game::im->RedirectPendingRequests(instance); } From 325dc5a5711fbd5bbff66024820fb392d9e0a599 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 9 Jul 2022 15:57:45 -0700 Subject: [PATCH 82/98] Revert "Wait for world to shutdown (#624)" (#626) This reverts commit 66edf57b025196b31fc89906f3cc616f827ecb0f. --- dMasterServer/MasterServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 94e0d5b6..ac49b1a1 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -303,6 +303,7 @@ int main(int argc, char** argv) { if (affirmTimeout == 1000) { instance->Shutdown(); + instance->SetShutdownComplete(true); Game::im->RedirectPendingRequests(instance); } From 06217ad5e30981a3e8b94093dca2c0bbc4d28b80 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:59:07 -0700 Subject: [PATCH 83/98] Address friends list IDs and removal of friends (#628) * Add friends list migration * Change friends to use charID Update friends table to use charID and not LWOOBJID variant. * Fix remove friend Fix remove friend and make the query more readable at a glance. * Add and remove friends in the container Properly add and remove friends in the player container --- dChatServer/ChatPacketHandler.cpp | 145 +++++++++++--------- migrations/dlu/4_friends_list_objectids.sql | 1 + 2 files changed, 84 insertions(+), 62 deletions(-) create mode 100644 migrations/dlu/4_friends_list_objectids.sql diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 899fd355..82f24ffa 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -21,10 +21,17 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { auto player = playerContainer.GetPlayerData(playerID); if (!player) return; - //Get our friends list from the Db: - auto stmt = Database::CreatePreppedStmt("SELECT * FROM friends WHERE player_id = ? OR friend_id = ?"); - stmt->setUInt64(1, playerID); - stmt->setUInt64(2, playerID); + //Get our friends list from the Db. Using a derived table since the friend of a player can be in either column. + auto stmt = Database::CreatePreppedStmt( + "SELECT fr.requested_player, best_friend, ci.name FROM " + "(SELECT CASE " + "WHEN player_id = ? THEN friend_id " + "WHEN friend_id = ? THEN player_id " + "END AS requested_player, best_friend FROM friends) AS fr " + "JOIN charinfo AS ci ON ci.id = fr.requested_player " + "WHERE fr.requested_player IS NOT NULL;"); + stmt->setUInt(1, static_cast<uint32_t>(playerID)); + stmt->setUInt(2, static_cast<uint32_t>(playerID)); std::vector<FriendData> friends; @@ -32,27 +39,16 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { while (res->next()) { FriendData fd; fd.isFTP = false; // not a thing in DLU - fd.friendID = res->getInt64(1); - if (fd.friendID == playerID) fd.friendID = res->getUInt64(2); + fd.friendID = res->getUInt(1); + GeneralUtils::SetBit(fd.friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_PERSISTENT)); + GeneralUtils::SetBit(fd.friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_CHARACTER)); - fd.isBestFriend = res->getInt(3) == 2; //0 = friends, 1 = requested, 2 = bffs - - //We need to find their name as well: - { - auto stmt = Database::CreatePreppedStmt("SELECT name FROM charinfo WHERE id=? limit 1"); - stmt->setInt(1, fd.friendID); - - auto res = stmt->executeQuery(); - while (res->next()) { - fd.friendName = res->getString(1); - } - - delete res; - delete stmt; - } + fd.isBestFriend = res->getInt(2) == 2; //0 = friends, 1 = requested, 2 = bffs + fd.friendName = res->getString(3); //Now check if they're online: auto fr = playerContainer.GetPlayerData(fd.friendID); + Game::logger->Log("ChatPacketHandler", "friend is %llu\n", fd.friendID); if (fr) { fd.isOnline = true; fd.zoneID = fr->zoneID; @@ -69,7 +65,9 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { } delete res; + res = nullptr; delete stmt; + stmt = nullptr; //Now, we need to send the friendlist to the server they came from: CBITSTREAM; @@ -100,8 +98,6 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { std::string playerName = PacketUtils::ReadString(0x14, packet, true); //There's another bool here to determine if it's a best friend request, but we're not handling it right now. - //PacketUtils::SavePacket("FriendRequest.bin", (char*)inStream.GetData(), inStream.GetNumberOfBytesUsed()); - //We need to check to see if the player is actually online or not: auto targetData = playerContainer.GetPlayerData(playerName); if (targetData) { @@ -118,23 +114,46 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { uint8_t responseCode = packet->data[0x14]; std::string friendName = PacketUtils::ReadString(0x15, packet, true); - Game::logger->Log("ChatPacketHandler", "Friend response code: %i\n", responseCode); - - if (responseCode != 0) return; //If we're not accepting the request, end here, do not insert to friends table. - - PacketUtils::SavePacket("HandleFriendResponse.bin", (char*)inStream.GetData(), inStream.GetNumberOfBytesUsed()); - //Now to try and find both of these: auto goonA = playerContainer.GetPlayerData(playerID); auto goonB = playerContainer.GetPlayerData(friendName); if (!goonA || !goonB) return; + if (responseCode != 0) return; //If we're not accepting the request, end here, do not insert to friends table. + + for (auto friendData : goonA->friends) { + if (friendData.friendID == goonB->playerID) return; + } + + for (auto friendData : goonB->friends) { + if (friendData.friendID == goonA->playerID) return; + } + + // Add the goons to their friends list + FriendData goonAData; + goonAData.zoneID = goonA->zoneID; + goonAData.friendID = goonA->playerID; + goonAData.friendName = goonA->playerName; + goonAData.isBestFriend = false; + goonAData.isFTP = false; + goonAData.isOnline = true; + goonB->friends.push_back(goonAData); + + FriendData goonBData; + goonBData.zoneID = goonB->zoneID; + goonBData.friendID = goonB->playerID; + goonBData.friendName = goonB->playerName; + goonBData.isBestFriend = false; + goonBData.isFTP = false; + goonBData.isOnline = true; + goonA->friends.push_back(goonBData); + SendFriendResponse(goonB, goonA, responseCode); SendFriendResponse(goonA, goonB, responseCode); //Do we need to send it to both? I think so so both get the updated friendlist but... idk. - auto stmt = Database::CreatePreppedStmt("INSERT INTO `friends`(`player_id`, `friend_id`, `best_friend`) VALUES (?,?,?)"); - stmt->setUInt64(1, goonA->playerID); - stmt->setUInt64(2, goonB->playerID); + auto stmt = Database::CreatePreppedStmt("INSERT IGNORE INTO `friends` (`player_id`, `friend_id`, `best_friend`) VALUES (?,?,?)"); + stmt->setUInt(1, static_cast<uint32_t>(goonA->playerID)); + stmt->setUInt(2, static_cast<uint32_t>(goonB->playerID)); stmt->setInt(3, 0); stmt->execute(); delete stmt; @@ -145,50 +164,61 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { LWOOBJID playerID; inStream.Read(playerID); inStream.Read(playerID); - std::string friendName = PacketUtils::ReadString(16, packet, true); + std::string friendName = PacketUtils::ReadString(0x14, packet, true); //we'll have to query the db here to find the user, since you can delete them while they're offline. //First, we need to find their ID: - auto stmt = Database::CreatePreppedStmt("select id from charinfo where name=? limit 1;"); + auto stmt = Database::CreatePreppedStmt("SELECT id FROM charinfo WHERE name=? LIMIT 1;"); stmt->setString(1, friendName.c_str()); LWOOBJID friendID = 0; auto res = stmt->executeQuery(); while (res->next()) { - friendID = res->getUInt64(1); + friendID = res->getUInt(1); } + // Convert friendID to LWOOBJID + GeneralUtils::SetBit(friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_PERSISTENT)); + GeneralUtils::SetBit(friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_CHARACTER)); + delete res; + res = nullptr; delete stmt; + stmt = nullptr; - //Set our bits to convert to the BIG BOY objectID. - friendID = GeneralUtils::ClearBit(friendID, OBJECT_BIT_CHARACTER); - friendID = GeneralUtils::ClearBit(friendID, OBJECT_BIT_PERSISTENT); - - //YEET: - auto deletestmt = Database::CreatePreppedStmt("DELETE FROM `friends` WHERE player_id=? AND friend_id=? LIMIT 1"); - deletestmt->setUInt64(1, playerID); - deletestmt->setUInt64(2, friendID); + auto deletestmt = Database::CreatePreppedStmt("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;"); + deletestmt->setUInt(1, static_cast<uint32_t>(playerID)); + deletestmt->setUInt(2, static_cast<uint32_t>(friendID)); + deletestmt->setUInt(3, static_cast<uint32_t>(friendID)); + deletestmt->setUInt(4, static_cast<uint32_t>(playerID)); deletestmt->execute(); - delete deletestmt; - //because I'm lazy and they can be reversed: - { - auto deletestmt = Database::CreatePreppedStmt("DELETE FROM `friends` WHERE player_id=? AND friend_id=? LIMIT 1"); - deletestmt->setUInt64(1, friendID); - deletestmt->setUInt64(2, playerID); - deletestmt->execute(); - delete deletestmt; - } + delete deletestmt; + deletestmt = nullptr; //Now, we need to send an update to notify the sender (and possibly, receiver) that their friendship has been ended: auto goonA = playerContainer.GetPlayerData(playerID); if (goonA) { + // Remove the friend from our list of friends + for (auto friendData = goonA->friends.begin(); friendData != goonA->friends.end(); friendData++) { + if ((*friendData).friendID == friendID) { + goonA->friends.erase(friendData); + break; + } + } SendRemoveFriend(goonA, friendName, true); } - + auto goonB = playerContainer.GetPlayerData(friendID); if (!goonB) return; + // Do it again for other person + for (auto friendData = goonB->friends.begin(); friendData != goonB->friends.end(); friendData++) { + if ((*friendData).friendID == playerID) { + goonB->friends.erase(friendData); + break; + } + } + std::string goonAName = GeneralUtils::UTF16ToWTF8(playerContainer.GetName(playerID)); SendRemoveFriend(goonB, goonAName, true); } @@ -217,8 +247,6 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) Game::logger->Log("ChatPacketHandler", "Got a message from (%s) [%d]: %s\n", senderName.c_str(), channel, message.c_str()); - //PacketUtils::SavePacket("chat.bin", reinterpret_cast<char*>(packet->data), packet->length); - if (channel != 8) return; auto* team = playerContainer.GetTeam(playerID); @@ -454,8 +482,6 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) playerContainer.RemoveMember(team, kickedId, false, true, false); } - - //PacketUtils::SavePacket("kick.bin", reinterpret_cast<char*>(packet->data), packet->length); } void ChatPacketHandler::HandleTeamPromote(Packet* packet) @@ -481,8 +507,6 @@ void ChatPacketHandler::HandleTeamPromote(Packet* packet) playerContainer.PromoteMember(team, promoted->playerID); } - - //PacketUtils::SavePacket("promote.bin", reinterpret_cast<char*>(packet->data), packet->length); } void ChatPacketHandler::HandleTeamLootOption(Packet* packet) @@ -509,8 +533,6 @@ void ChatPacketHandler::HandleTeamLootOption(Packet* packet) playerContainer.UpdateTeamsOnWorld(team, false); } - - //PacketUtils::SavePacket("option.bin", reinterpret_cast<char*>(packet->data), packet->length); } void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) @@ -560,7 +582,6 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) const auto memberName = playerContainer.GetName(memberId); - //ChatPacketHandler::SendTeamAddPlayer(otherMember, false, false, false, data->playerID, leaderName, data->zoneID); if (otherMember != nullptr) { ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, data->playerID, data->zoneID); diff --git a/migrations/dlu/4_friends_list_objectids.sql b/migrations/dlu/4_friends_list_objectids.sql new file mode 100644 index 00000000..efb3a7ae --- /dev/null +++ b/migrations/dlu/4_friends_list_objectids.sql @@ -0,0 +1 @@ +UPDATE friends SET player_id = player_id % 0x100000000, friend_id = friend_id % 0x100000000; \ No newline at end of file From d642de9462127a10bd83885610adebd34f9c69ec Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sun, 10 Jul 2022 20:40:26 +0100 Subject: [PATCH 84/98] Implement a migration runner --- CMakeLists.txt | 17 ++++- README.md | 2 +- dCommon/GeneralUtils.cpp | 50 +++++++++++++++ dCommon/GeneralUtils.h | 2 + dDatabase/Database.cpp | 45 +++++++------ dDatabase/Database.h | 11 +++- dDatabase/MigrationRunner.cpp | 78 +++++++++++++++++++++++ dDatabase/MigrationRunner.h | 19 ++++++ dMasterServer/MasterServer.cpp | 8 +++ migrations/cdserver/3_plunger_gun_fix.sql | 1 - migrations/dlu/2_reporter_id.sql | 2 +- 11 files changed, 208 insertions(+), 27 deletions(-) create mode 100644 dDatabase/MigrationRunner.cpp create mode 100644 dDatabase/MigrationRunner.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cf311d2..5373dfe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.14) project(Darkflame) include(CTest) +set (CMAKE_CXX_STANDARD 17) + # Read variables from file FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables) @@ -88,8 +90,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}") # Echo the version message(STATUS "Version: ${PROJECT_VERSION}") -set(CMAKE_CXX_STANDARD 17) - if(WIN32) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif(WIN32) @@ -138,6 +138,19 @@ configure_file("${CMAKE_SOURCE_DIR}/vanity/INFO.md" "${CMAKE_BINARY_DIR}/vanity/ configure_file("${CMAKE_SOURCE_DIR}/vanity/TESTAMENT.md" "${CMAKE_BINARY_DIR}/vanity/TESTAMENT.md" COPYONLY) configure_file("${CMAKE_SOURCE_DIR}/vanity/NPC.xml" "${CMAKE_BINARY_DIR}/vanity/NPC.xml" COPYONLY) +# Move our migrations for MasterServer to run +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/migrations/) +file(GLOB SQL_FILES ${CMAKE_SOURCE_DIR}/migrations/dlu/*.sql) +foreach (file ${SQL_FILES}) + get_filename_component(file ${file} NAME) + if (NOT EXISTS ${PROJECT_BINARY_DIR}/migrations/${file}) + configure_file( + ${CMAKE_SOURCE_DIR}/migrations/dlu/${file} ${PROJECT_BINARY_DIR}/migrations/${file} + COPYONLY + ) + endif() +endforeach() + # 3rdparty includes include_directories(${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/) if(APPLE) diff --git a/README.md b/README.md index 6b82e1b0..d029ed93 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ Darkflame Universe utilizes a MySQL/MariaDB database for account and character i Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running. * Create a database for Darkflame Universe to use -* Run each SQL file in the order at which they appear [here](migrations/dlu/) on the database +* Run the migrations by running `./MasterServer -m` to automatically run them ### Resources diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index b3461e8a..01306226 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -188,3 +188,53 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream *inStream) { return string; } + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> + +std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) +{ + std::vector<std::string> names; + std::string search_path = folder + "/*.*"; + WIN32_FIND_DATA fd; + HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + do { + if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + names.push_back(fd.cFileName); + } + } while (::FindNextFile(hFind, &fd)); + ::FindClose(hFind); + } + return names; +} +#else +#include <stdio.h> +#include <dirent.h> +#include <sys/types.h> +#include <iostream> +#include <vector> +#include <cstring> + +std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) { + std::vector<std::string> names; + struct dirent* entry; + DIR* dir = opendir(folder.c_str()); + if (dir == NULL) { + return names; + } + + while ((entry = readdir(dir)) != NULL) { + std::string value(entry->d_name, strlen(entry->d_name)); + if (value == "." || value == "..") { + continue; + } + names.push_back(value); + } + + closedir(dir); + + return names; +} +#endif \ No newline at end of file diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 58b9e962..4973201e 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -128,6 +128,8 @@ namespace GeneralUtils { std::vector<std::string> SplitString(const std::string& str, char delimiter); + std::vector<std::string> GetFileNamesFromFolder(const std::string& folder); + template <typename T> T Parse(const char* value); diff --git a/dDatabase/Database.cpp b/dDatabase/Database.cpp index ef4faa52..26a45359 100644 --- a/dDatabase/Database.cpp +++ b/dDatabase/Database.cpp @@ -8,6 +8,8 @@ using namespace std; sql::Driver * Database::driver; sql::Connection * Database::con; +sql::Properties Database::props; +std::string Database::database; void Database::Connect(const string& host, const string& database, const string& username, const string& password) { @@ -25,14 +27,26 @@ void Database::Connect(const string& host, const string& database, const string& properties["user"] = szUsername; properties["password"] = szPassword; properties["autoReconnect"] = "true"; - con = driver->connect(properties); - con->setSchema(szDatabase); -} //Connect -void Database::Destroy(std::string source) { + Database::props = properties; + Database::database = database; + + Database::Connect(); +} + +void Database::Connect() { + con = driver->connect(Database::props); + con->setSchema(Database::database); +} + +void Database::Destroy(std::string source, bool log) { if (!con) return; - if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!\n", source.c_str()); - else Game::logger->Log("Database", "Destroying MySQL connection!\n"); + + if (log) { + if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!\n", source.c_str()); + else Game::logger->Log("Database", "Destroying MySQL connection!\n"); + } + con->close(); delete con; } //Destroy @@ -48,13 +62,7 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) { sql::SQLString str(test, size); if (!con) { - //Connect to the MySQL Database - std::string mysql_host = Game::config->GetValue("mysql_host"); - std::string mysql_database = Game::config->GetValue("mysql_database"); - std::string mysql_username = Game::config->GetValue("mysql_username"); - std::string mysql_password = Game::config->GetValue("mysql_password"); - - Connect(mysql_host, mysql_database, mysql_username, mysql_password); + Connect(); Game::logger->Log("Database", "Trying to reconnect to MySQL\n"); } @@ -64,13 +72,7 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) { con = nullptr; - //Connect to the MySQL Database - std::string mysql_host = Game::config->GetValue("mysql_host"); - std::string mysql_database = Game::config->GetValue("mysql_database"); - std::string mysql_username = Game::config->GetValue("mysql_username"); - std::string mysql_password = Game::config->GetValue("mysql_password"); - - Connect(mysql_host, mysql_database, mysql_username, mysql_password); + Connect(); Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection\n"); } @@ -79,3 +81,6 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) { return stmt; } //CreatePreppedStmt +void Database::Commit() { + Database::con->commit(); +} \ No newline at end of file diff --git a/dDatabase/Database.h b/dDatabase/Database.h index e972b0ca..ece62a95 100644 --- a/dDatabase/Database.h +++ b/dDatabase/Database.h @@ -13,10 +13,17 @@ class Database { private: static sql::Driver *driver; static sql::Connection *con; - + static sql::Properties props; + static std::string database; public: static void Connect(const std::string& host, const std::string& database, const std::string& username, const std::string& password); - static void Destroy(std::string source=""); + static void Connect(); + static void Destroy(std::string source = "", bool log = true); + static sql::Statement* CreateStmt(); static sql::PreparedStatement* CreatePreppedStmt(const std::string& query); + static void Commit(); + + static std::string GetDatabase() { return database; } + static sql::Properties GetProperties() { return props; } }; diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp new file mode 100644 index 00000000..a058b85e --- /dev/null +++ b/dDatabase/MigrationRunner.cpp @@ -0,0 +1,78 @@ +#include "MigrationRunner.h" + +#include "GeneralUtils.h" + +#include <fstream> +#include <algorithm> +#include <thread> + +void MigrationRunner::RunMigrations() { + auto stmt = Database::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP());"); + stmt->executeQuery(); + delete stmt; + + sql::SQLString finalSQL = ""; + Migration checkMigration{}; + + for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/")) { + auto migration = LoadMigration(entry); + + if (migration.data.empty()) { + continue; + } + + checkMigration = migration; + + stmt = Database::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;"); + stmt->setString(1, migration.name); + auto res = stmt->executeQuery(); + bool doExit = res->next(); + delete res; + delete stmt; + if (doExit) continue; + + Game::logger->Log("MigrationRunner", "Running migration: " + migration.name + "\n"); + + finalSQL.append(migration.data); + finalSQL.append('\n'); + + stmt = Database::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); + stmt->setString(1, entry); + stmt->execute(); + delete stmt; + } + + if (!finalSQL.empty()) { + try { + auto simpleStatement = Database::CreateStmt(); + simpleStatement->execute(finalSQL); + delete simpleStatement; + } + catch (sql::SQLException e) { + Game::logger->Log("MigrationRunner", std::string("Encountered error running migration: ") + e.what() + "\n"); + } + } +} + +Migration MigrationRunner::LoadMigration(std::string path) { + Migration migration{}; + std::ifstream file("./migrations/" + path); + + if (file.is_open()) { + std::hash<std::string> hash; + + std::string line; + std::string total = ""; + + while (std::getline(file, line)) { + total += line; + } + + file.close(); + + migration.name = path; + migration.data = total; + } + + return migration; +} diff --git a/dDatabase/MigrationRunner.h b/dDatabase/MigrationRunner.h new file mode 100644 index 00000000..343b252d --- /dev/null +++ b/dDatabase/MigrationRunner.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Database.h" + +#include "dCommonVars.h" +#include "Game.h" +#include "dCommonVars.h" +#include "dLogger.h" + +struct Migration { + std::string data; + std::string name; +}; + +class MigrationRunner { +public: + static void RunMigrations(); + static Migration LoadMigration(std::string path); +}; \ No newline at end of file diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index ac49b1a1..1cfd7d4a 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -19,6 +19,7 @@ #include "CDClientDatabase.h" #include "CDClientManager.h" #include "Database.h" +#include "MigrationRunner.h" #include "Diagnostics.h" #include "dCommonVars.h" #include "dConfig.h" @@ -127,6 +128,13 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + if (argc > 1 && (strcmp(argv[1], "-m") == 0 || strcmp(argv[1], "--migrations") == 0)) { + MigrationRunner::RunMigrations(); + Game::logger->Log("MigrationRunner", "Finished running migrations\n"); + + return EXIT_SUCCESS; + } + //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/cdserver/3_plunger_gun_fix.sql b/migrations/cdserver/3_plunger_gun_fix.sql index 35654e8b..3d33592e 100644 --- a/migrations/cdserver/3_plunger_gun_fix.sql +++ b/migrations/cdserver/3_plunger_gun_fix.sql @@ -1,2 +1 @@ --- File added April 9th, 2022 UPDATE ItemComponent SET itemType = 5 where id = 7082; diff --git a/migrations/dlu/2_reporter_id.sql b/migrations/dlu/2_reporter_id.sql index 26103342..dc2a9a7e 100644 --- a/migrations/dlu/2_reporter_id.sql +++ b/migrations/dlu/2_reporter_id.sql @@ -1 +1 @@ -ALTER TABLE bug_reports ADD reporter_id INT NOT NULL DEFAULT 0; +ALTER TABLE bug_reports ADD (reporter_id) INT NOT NULL DEFAULT 0; From bfa1f57158f7b16f73f3cdf3702610fe5b7eff93 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 12 Jul 2022 03:06:54 +0100 Subject: [PATCH 85/98] Improve cpplinq checks On certain Windows header versions defining NOMINMAX doesn't work for some odd reason. --- thirdparty/cpplinq/cpplinq.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/thirdparty/cpplinq/cpplinq.hpp b/thirdparty/cpplinq/cpplinq.hpp index d25cde85..ae9169d9 100644 --- a/thirdparty/cpplinq/cpplinq.hpp +++ b/thirdparty/cpplinq/cpplinq.hpp @@ -14,6 +14,8 @@ #ifndef CPPLINQ__HEADER_GUARD # define CPPLINQ__HEADER_GUARD +#undef min +#undef max #define NOMINMAX // ---------------------------------------------------------------------------- From b7497a47e4c0aa6b3605f6b09706a7e06f62d428 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 11 Jul 2022 20:43:09 -0700 Subject: [PATCH 86/98] Lower memory usage of Behavior Parameter Table by 10MB (#627) * Added caching for table Added caching for table Add more caching Update MasterServer.cpp grds Update CDBehaviorParameterTable.cpp Update CDBehaviorParameterTable.h Update CDBehaviorTemplateTable.cpp Update Behavior.cpp Update Behavior.cpp change to map Remove redundant query * Remove include * change to enum * Update Behavior.cpp * Use already cached table * Update Behavior.cpp * Reduce memory usage Reduces the memory usage for the BehaviorParameter table by 10MB in memory. * Update CDBehaviorTemplateTable.cpp --- dDatabase/Tables/CDBehaviorParameterTable.cpp | 16 +++++++++++----- dDatabase/Tables/CDBehaviorParameterTable.h | 6 +++--- dDatabase/Tables/CDBehaviorTemplateTable.cpp | 11 +++++++++-- dDatabase/Tables/CDBehaviorTemplateTable.h | 10 ++++++---- dGame/dBehaviors/Behavior.cpp | 2 +- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index bbbdb2b6..05f39016 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -9,14 +9,20 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { hash = 0; CDBehaviorParameter entry; entry.behaviorID = tableData.getIntField(0, -1); - entry.parameterID = tableData.getStringField(1, ""); + auto candidateStringToAdd = std::string(tableData.getStringField(1, "")); + auto parameter = m_ParametersList.find(candidateStringToAdd); + if (parameter != m_ParametersList.end()) { + entry.parameterID = parameter; + } else { + entry.parameterID = m_ParametersList.insert(candidateStringToAdd).first; + } entry.value = tableData.getFloatField(2, -1.0f); GeneralUtils::hash_combine(hash, entry.behaviorID); - GeneralUtils::hash_combine(hash, entry.parameterID); + GeneralUtils::hash_combine(hash, *entry.parameterID); auto it = m_Entries.find(entry.behaviorID); - m_ParametersList.insert(entry.parameterID); + m_ParametersList.insert(*entry.parameterID); m_Entries.insert(std::make_pair(hash, entry)); tableData.nextRow(); @@ -36,7 +42,7 @@ CDBehaviorParameter CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID { CDBehaviorParameter returnValue; returnValue.behaviorID = 0; - returnValue.parameterID = ""; + returnValue.parameterID = m_ParametersList.end(); returnValue.value = defaultValue; size_t hash = 0; @@ -57,7 +63,7 @@ std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID GeneralUtils::hash_combine(hash, parameterCandidate); auto infoCandidate = m_Entries.find(hash); if (infoCandidate != m_Entries.end()) { - returnInfo.insert(std::make_pair(infoCandidate->second.parameterID, infoCandidate->second.value)); + returnInfo.insert(std::make_pair(*(infoCandidate->second.parameterID), infoCandidate->second.value)); } } return returnInfo; diff --git a/dDatabase/Tables/CDBehaviorParameterTable.h b/dDatabase/Tables/CDBehaviorParameterTable.h index 17605636..c45d287b 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.h +++ b/dDatabase/Tables/CDBehaviorParameterTable.h @@ -12,9 +12,9 @@ //! BehaviorParameter Entry Struct struct CDBehaviorParameter { - unsigned int behaviorID; //!< The Behavior ID - std::string parameterID; //!< The Parameter ID - float value; //!< The value of the behavior template + unsigned int behaviorID; //!< The Behavior ID + std::unordered_set<std::string>::iterator parameterID; //!< The Parameter ID + float value; //!< The value of the behavior template }; //! BehaviorParameter table diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.cpp b/dDatabase/Tables/CDBehaviorTemplateTable.cpp index c79f4177..b832400d 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.cpp +++ b/dDatabase/Tables/CDBehaviorTemplateTable.cpp @@ -24,7 +24,13 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { entry.behaviorID = tableData.getIntField(0, -1); entry.templateID = tableData.getIntField(1, -1); entry.effectID = tableData.getIntField(2, -1); - entry.effectHandle = tableData.getStringField(3, ""); + auto candidateToAdd = tableData.getStringField(3, ""); + auto parameter = m_EffectHandles.find(candidateToAdd); + if (parameter != m_EffectHandles.end()) { + entry.effectHandle = parameter; + } else { + entry.effectHandle = m_EffectHandles.insert(candidateToAdd).first; + } this->entries.push_back(entry); this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry)); @@ -62,7 +68,8 @@ const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behav if (entry == this->entriesMappedByBehaviorID.end()) { CDBehaviorTemplate entryToReturn; entryToReturn.behaviorID = 0; - entryToReturn.effectHandle = ""; + entryToReturn.effectHandle = m_EffectHandles.end(); + entryToReturn.effectID = 0; return entryToReturn; } else { return entry->second; diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.h b/dDatabase/Tables/CDBehaviorTemplateTable.h index 36424c12..170da854 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.h +++ b/dDatabase/Tables/CDBehaviorTemplateTable.h @@ -3,6 +3,7 @@ // Custom Classes #include "CDTable.h" #include <unordered_map> +#include <unordered_set> /*! \file CDBehaviorTemplateTable.hpp @@ -11,10 +12,10 @@ //! BehaviorTemplate Entry Struct struct CDBehaviorTemplate { - unsigned int behaviorID; //!< The Behavior ID - unsigned int templateID; //!< The Template ID (LOT) - unsigned int effectID; //!< The Effect ID attached - std::string effectHandle; //!< The effect handle + unsigned int behaviorID; //!< The Behavior ID + unsigned int templateID; //!< The Template ID (LOT) + unsigned int effectID; //!< The Effect ID attached + std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle }; @@ -23,6 +24,7 @@ class CDBehaviorTemplateTable : public CDTable { private: std::vector<CDBehaviorTemplate> entries; std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID; + std::unordered_set<std::string> m_EffectHandles; public: //! Constructor diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index ac1ab7de..a2329f96 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -445,7 +445,7 @@ Behavior::Behavior(const uint32_t behaviorId) this->m_effectId = templateInDatabase.effectID; - this->m_effectHandle = templateInDatabase.effectHandle != "" ? new std::string(templateInDatabase.effectHandle) : nullptr; + this->m_effectHandle = *templateInDatabase.effectHandle != "" ? new std::string(*templateInDatabase.effectHandle) : nullptr; } From 24dbd3944da07590ac6b7508c403fdc5251609af Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 12 Jul 2022 20:36:06 -0700 Subject: [PATCH 87/98] Friends List Overhaul (#630) v103 * Add friends list migration * Change friends to use charID Update friends table to use charID and not LWOOBJID variant. * Fix remove friend Fix remove friend and make the query more readable at a glance. * Add and remove friends in the container Properly add and remove friends in the player container * add enums * Add best friends and basic GM support V1 * Add more features * not online / doesnt exist implementation Implements the not online and invalid character response codes * Address players not being removed Fix an issue where players would not be marked as offline in the friends list due to the message not being sent in all circumstances. Tested changes on 3 clients, switching characters, logging out from character select, switching characters, world transfer and my friends list looked as it was supposed to. * Implement proper friends system Remove debug logs Track count of best friends Add best friends list cap of 5 Add config option and best friend update Add a config option and implement the last missing best friend serialization Added comments and fixed remove best friend bug Added some comments and addressed an issue where removing best friends would not remove them from your internal count of friends. properties and logs fixes whoops, had an issue send reply if already BFFs Send the correct objectID I really need to rename these Fix white space goon * Replace queries with unique ptrs * remove user from player container on deletion Remove the user from the player container when they delete their character. --- CMakeVariables.txt | 2 +- dChatServer/ChatPacketHandler.cpp | 315 +++++++++++++----- dChatServer/ChatPacketHandler.h | 8 +- dChatServer/PlayerContainer.cpp | 2 +- dChatServer/PlayerContainer.h | 1 + dCommon/AddFriendResponseCode.h | 15 + dCommon/AddFriendResponseType.h | 24 ++ dGame/EntityManager.cpp | 2 +- dGame/UserManager.cpp | 14 +- .../dComponents/PropertyEntranceComponent.cpp | 24 +- dGame/dComponents/PropertyEntranceComponent.h | 2 +- dWorldServer/WorldServer.cpp | 17 +- resources/worldconfig.ini | 4 + 13 files changed, 321 insertions(+), 109 deletions(-) create mode 100644 dCommon/AddFriendResponseCode.h create mode 100644 dCommon/AddFriendResponseType.h diff --git a/CMakeVariables.txt b/CMakeVariables.txt index ed0cfce8..db89fef7 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -1,6 +1,6 @@ PROJECT_VERSION_MAJOR=1 PROJECT_VERSION_MINOR=0 -PROJECT_VERSION_PATCH=2 +PROJECT_VERSION_PATCH=3 # LICENSE LICENSE=AGPL-3.0 # The network version. diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 82f24ffa..b84c3eef 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -8,6 +8,10 @@ #include "dServer.h" #include "GeneralUtils.h" #include "dLogger.h" +#include "AddFriendResponseCode.h" +#include "AddFriendResponseType.h" +#include "RakString.h" +#include "dConfig.h" extern PlayerContainer playerContainer; @@ -22,20 +26,20 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { if (!player) return; //Get our friends list from the Db. Using a derived table since the friend of a player can be in either column. - auto stmt = Database::CreatePreppedStmt( + std::unique_ptr<sql::PreparedStatement> stmt(Database::CreatePreppedStmt( "SELECT fr.requested_player, best_friend, ci.name FROM " "(SELECT CASE " "WHEN player_id = ? THEN friend_id " "WHEN friend_id = ? THEN player_id " "END AS requested_player, best_friend FROM friends) AS fr " "JOIN charinfo AS ci ON ci.id = fr.requested_player " - "WHERE fr.requested_player IS NOT NULL;"); + "WHERE fr.requested_player IS NOT NULL;")); stmt->setUInt(1, static_cast<uint32_t>(playerID)); stmt->setUInt(2, static_cast<uint32_t>(playerID)); std::vector<FriendData> friends; - auto res = stmt->executeQuery(); + std::unique_ptr<sql::ResultSet> res(stmt->executeQuery()); while (res->next()) { FriendData fd; fd.isFTP = false; // not a thing in DLU @@ -43,18 +47,19 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { GeneralUtils::SetBit(fd.friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_PERSISTENT)); GeneralUtils::SetBit(fd.friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_CHARACTER)); - fd.isBestFriend = res->getInt(2) == 2; //0 = friends, 1 = requested, 2 = bffs + fd.isBestFriend = res->getInt(2) == 3; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs + if (fd.isBestFriend) player->countOfBestFriends+=1; fd.friendName = res->getString(3); //Now check if they're online: auto fr = playerContainer.GetPlayerData(fd.friendID); - Game::logger->Log("ChatPacketHandler", "friend is %llu\n", fd.friendID); + if (fr) { fd.isOnline = true; fd.zoneID = fr->zoneID; //Since this friend is online, we need to update them on the fact that we've just logged in: - SendFriendUpdate(fr, player, 1); + SendFriendUpdate(fr, player, 1, fd.isBestFriend); } else { fd.isOnline = false; @@ -64,11 +69,6 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { friends.push_back(fd); } - delete res; - res = nullptr; - delete stmt; - stmt = nullptr; - //Now, we need to send the friendlist to the server they came from: CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ROUTE_TO_PLAYER); @@ -91,18 +91,150 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { } void ChatPacketHandler::HandleFriendRequest(Packet* packet) { + auto maxNumberOfBestFriendsAsString = Game::config->GetValue("max_number_of_best_friends"); + // If this config option doesn't exist, default to 5 which is what live used. + auto maxNumberOfBestFriends = maxNumberOfBestFriendsAsString != "" ? std::stoi(maxNumberOfBestFriendsAsString) : 5U; CINSTREAM; - LWOOBJID playerID; - inStream.Read(playerID); - inStream.Read(playerID); - std::string playerName = PacketUtils::ReadString(0x14, packet, true); - //There's another bool here to determine if it's a best friend request, but we're not handling it right now. + LWOOBJID requestorPlayerID; + inStream.Read(requestorPlayerID); + inStream.Read(requestorPlayerID); + uint32_t spacing{}; + inStream.Read(spacing); + std::string playerName = ""; + uint16_t character; + bool noMoreLettersInName = false; - //We need to check to see if the player is actually online or not: - auto targetData = playerContainer.GetPlayerData(playerName); - if (targetData) { - SendFriendRequest(targetData, playerContainer.GetPlayerData(playerID)); + for (uint32_t j = 0; j < 33; j++) { + inStream.Read(character); + if (character == '\0') noMoreLettersInName = true; + if (!noMoreLettersInName) playerName.push_back(static_cast<char>(character)); } + + char isBestFriendRequest{}; + inStream.Read(isBestFriendRequest); + + auto requestor = playerContainer.GetPlayerData(requestorPlayerID); + std::unique_ptr<PlayerData> requestee(playerContainer.GetPlayerData(playerName)); + + // Check if player is online first + if (isBestFriendRequest && !requestee) { + for (auto friendDataCandidate : requestor->friends) { + if (friendDataCandidate.friendName == playerName) { + requestee.reset(new PlayerData()); + // Setup the needed info since you can add a best friend offline. + requestee->playerID = friendDataCandidate.friendID; + requestee->playerName = RakNet::RakString(friendDataCandidate.friendName.c_str()); + requestee->zoneID = LWOZONEID(); + + FriendData requesteeFriendData{}; + requesteeFriendData.friendID = requestor->playerID; + requesteeFriendData.friendName = requestor->playerName; + requesteeFriendData.isFTP = false; + requesteeFriendData.isOnline = false; + requesteeFriendData.zoneID = requestor->zoneID; + requestee->friends.push_back(requesteeFriendData); + requestee->sysAddr = UNASSIGNED_SYSTEM_ADDRESS; + break; + } + } + } + + // If at this point we dont have a target, then they arent online and we cant send the request. + // Send the response code that corresponds to what the error is. + if (!requestee) { + std::unique_ptr<sql::PreparedStatement> nameQuery(Database::CreatePreppedStmt("SELECT name from charinfo where name = ?;")); + nameQuery->setString(1, playerName); + std::unique_ptr<sql::ResultSet> result(nameQuery->executeQuery()); + + requestee.reset(new PlayerData()); + requestee->playerName = RakNet::RakString(playerName.c_str()); + + SendFriendResponse(requestor, requestee.get(), result->next() ? AddFriendResponseType::NOTONLINE : AddFriendResponseType::INVALIDCHARACTER); + return; + } + + if (isBestFriendRequest) { + std::unique_ptr<sql::PreparedStatement> friendUpdate(Database::CreatePreppedStmt("SELECT * FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;")); + friendUpdate->setUInt(1, static_cast<uint32_t>(requestorPlayerID)); + friendUpdate->setUInt(2, static_cast<uint32_t>(requestee->playerID)); + friendUpdate->setUInt(3, static_cast<uint32_t>(requestee->playerID)); + friendUpdate->setUInt(4, static_cast<uint32_t>(requestorPlayerID)); + std::unique_ptr<sql::ResultSet> result(friendUpdate->executeQuery()); + + LWOOBJID queryPlayerID = LWOOBJID_EMPTY; + LWOOBJID queryFriendID = LWOOBJID_EMPTY; + uint8_t oldBestFriendStatus{}; + uint8_t bestFriendStatus{}; + + if (result->next()) { + // Get the IDs + queryPlayerID = result->getInt(1); + queryFriendID = result->getInt(2); + oldBestFriendStatus = result->getInt(3); + bestFriendStatus = oldBestFriendStatus; + + // Set the bits + GeneralUtils::SetBit(queryPlayerID, static_cast<size_t>(eObjectBits::OBJECT_BIT_CHARACTER)); + GeneralUtils::SetBit(queryPlayerID, static_cast<size_t>(eObjectBits::OBJECT_BIT_PERSISTENT)); + GeneralUtils::SetBit(queryFriendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_CHARACTER)); + GeneralUtils::SetBit(queryFriendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_PERSISTENT)); + + // Since this player can either be the friend of someone else or be friends with someone else + // their column in the database determines what bit gets set. When the value hits 3, they + // are now best friends with the other player. + if (queryPlayerID == requestorPlayerID) { + bestFriendStatus |= 1ULL << 0; + } else { + bestFriendStatus |= 1ULL << 1; + } + } + + // Only do updates if there was a change in the bff status. + if (oldBestFriendStatus != bestFriendStatus) { + if (requestee->countOfBestFriends >= maxNumberOfBestFriends || requestor->countOfBestFriends >= maxNumberOfBestFriends) { + if (requestee->countOfBestFriends >= maxNumberOfBestFriends) { + SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::THEIRFRIENDLISTFULL, false); + } + if (requestor->countOfBestFriends >= maxNumberOfBestFriends) { + SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::YOURFRIENDSLISTFULL, false); + } + } else { + // Then update the database with this new info. + std::unique_ptr<sql::PreparedStatement> updateQuery(Database::CreatePreppedStmt("UPDATE friends SET best_friend = ? WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;")); + updateQuery->setUInt(1, bestFriendStatus); + updateQuery->setUInt(2, static_cast<uint32_t>(requestorPlayerID)); + updateQuery->setUInt(3, static_cast<uint32_t>(requestee->playerID)); + updateQuery->setUInt(4, static_cast<uint32_t>(requestee->playerID)); + updateQuery->setUInt(5, static_cast<uint32_t>(requestorPlayerID)); + updateQuery->executeUpdate(); + // Sent the best friend update here if the value is 3 + if (bestFriendStatus == 3U) { + requestee->countOfBestFriends+=1; + requestor->countOfBestFriends+=1; + if (requestee->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestee.get(), requestor, AddFriendResponseType::ACCEPTED, false, true); + if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::ACCEPTED, false, true); + for (auto& friendData : requestor->friends) { + if (friendData.friendID == requestee->playerID) { + friendData.isBestFriend = true; + } + } + for (auto& friendData : requestee->friends) { + if (friendData.friendID == requestor->playerID) { + friendData.isBestFriend = true; + } + } + } + } + } else { + if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::WAITINGAPPROVAL, true, true); + } + } else { + // Do not send this if we are requesting to be a best friend. + SendFriendRequest(requestee.get(), requestor); + } + + // If the player is actually a player and not a ghost one defined above, release it from being deleted. + if (requestee->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) requestee.release(); } void ChatPacketHandler::HandleFriendResponse(Packet* packet) { @@ -110,53 +242,75 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { LWOOBJID playerID; inStream.Read(playerID); inStream.Read(playerID); - - uint8_t responseCode = packet->data[0x14]; + + AddFriendResponseCode clientResponseCode = static_cast<AddFriendResponseCode>(packet->data[0x14]); std::string friendName = PacketUtils::ReadString(0x15, packet, true); //Now to try and find both of these: - auto goonA = playerContainer.GetPlayerData(playerID); - auto goonB = playerContainer.GetPlayerData(friendName); - if (!goonA || !goonB) return; + auto requestor = playerContainer.GetPlayerData(playerID); + auto requestee = playerContainer.GetPlayerData(friendName); + if (!requestor || !requestee) return; - if (responseCode != 0) return; //If we're not accepting the request, end here, do not insert to friends table. - - for (auto friendData : goonA->friends) { - if (friendData.friendID == goonB->playerID) return; + AddFriendResponseType serverResponseCode{}; + uint8_t isAlreadyBestFriends = 0U; + // We need to convert this response code to one we can actually send back to the client. + switch (clientResponseCode) { + case AddFriendResponseCode::ACCEPTED: + serverResponseCode = AddFriendResponseType::ACCEPTED; + break; + case AddFriendResponseCode::BUSY: + serverResponseCode = AddFriendResponseType::BUSY; + break; + case AddFriendResponseCode::CANCELLED: + serverResponseCode = AddFriendResponseType::CANCELLED; + break; + case AddFriendResponseCode::REJECTED: + serverResponseCode = AddFriendResponseType::DECLINED; + break; } - for (auto friendData : goonB->friends) { - if (friendData.friendID == goonA->playerID) return; + // Now that we have handled the base cases, we need to check the other cases. + if (serverResponseCode == AddFriendResponseType::ACCEPTED) { + for (auto friendData : requestor->friends) { + if (friendData.friendID == requestee->playerID) { + serverResponseCode = AddFriendResponseType::ALREADYFRIEND; + if (friendData.isBestFriend) { + isAlreadyBestFriends = 1U; + } + } + } } - // Add the goons to their friends list - FriendData goonAData; - goonAData.zoneID = goonA->zoneID; - goonAData.friendID = goonA->playerID; - goonAData.friendName = goonA->playerName; - goonAData.isBestFriend = false; - goonAData.isFTP = false; - goonAData.isOnline = true; - goonB->friends.push_back(goonAData); + // This message is NOT sent for best friends and is handled differently for those requests. + if (serverResponseCode == AddFriendResponseType::ACCEPTED) { + // Add the each player to the others friend list. + FriendData requestorData; + requestorData.zoneID = requestor->zoneID; + requestorData.friendID = requestor->playerID; + requestorData.friendName = requestor->playerName; + requestorData.isBestFriend = false; + requestorData.isFTP = false; + requestorData.isOnline = true; + requestee->friends.push_back(requestorData); - FriendData goonBData; - goonBData.zoneID = goonB->zoneID; - goonBData.friendID = goonB->playerID; - goonBData.friendName = goonB->playerName; - goonBData.isBestFriend = false; - goonBData.isFTP = false; - goonBData.isOnline = true; - goonA->friends.push_back(goonBData); + FriendData requesteeData; + requesteeData.zoneID = requestee->zoneID; + requesteeData.friendID = requestee->playerID; + requesteeData.friendName = requestee->playerName; + requesteeData.isBestFriend = false; + requesteeData.isFTP = false; + requesteeData.isOnline = true; + requestor->friends.push_back(requesteeData); + + std::unique_ptr<sql::PreparedStatement> statement(Database::CreatePreppedStmt("INSERT IGNORE INTO `friends` (`player_id`, `friend_id`, `best_friend`) VALUES (?,?,?);")); + statement->setUInt(1, static_cast<uint32_t>(requestor->playerID)); + statement->setUInt(2, static_cast<uint32_t>(requestee->playerID)); + statement->setInt(3, 0); + statement->execute(); + } - SendFriendResponse(goonB, goonA, responseCode); - SendFriendResponse(goonA, goonB, responseCode); //Do we need to send it to both? I think so so both get the updated friendlist but... idk. - - auto stmt = Database::CreatePreppedStmt("INSERT IGNORE INTO `friends` (`player_id`, `friend_id`, `best_friend`) VALUES (?,?,?)"); - stmt->setUInt(1, static_cast<uint32_t>(goonA->playerID)); - stmt->setUInt(2, static_cast<uint32_t>(goonB->playerID)); - stmt->setInt(3, 0); - stmt->execute(); - delete stmt; + if (serverResponseCode != AddFriendResponseType::DECLINED) SendFriendResponse(requestor, requestee, serverResponseCode, isAlreadyBestFriends); + if (serverResponseCode != AddFriendResponseType::ALREADYFRIEND) SendFriendResponse(requestee, requestor, serverResponseCode, isAlreadyBestFriends); } void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { @@ -168,11 +322,11 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { //we'll have to query the db here to find the user, since you can delete them while they're offline. //First, we need to find their ID: - auto stmt = Database::CreatePreppedStmt("SELECT id FROM charinfo WHERE name=? LIMIT 1;"); + std::unique_ptr<sql::PreparedStatement> stmt(Database::CreatePreppedStmt("SELECT id FROM charinfo WHERE name=? LIMIT 1;")); stmt->setString(1, friendName.c_str()); LWOOBJID friendID = 0; - auto res = stmt->executeQuery(); + std::unique_ptr<sql::ResultSet> res(stmt->executeQuery()); while (res->next()) { friendID = res->getUInt(1); } @@ -181,27 +335,20 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { GeneralUtils::SetBit(friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_PERSISTENT)); GeneralUtils::SetBit(friendID, static_cast<size_t>(eObjectBits::OBJECT_BIT_CHARACTER)); - delete res; - res = nullptr; - delete stmt; - stmt = nullptr; - - auto deletestmt = Database::CreatePreppedStmt("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;"); + std::unique_ptr<sql::PreparedStatement> deletestmt(Database::CreatePreppedStmt("DELETE FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?) LIMIT 1;")); deletestmt->setUInt(1, static_cast<uint32_t>(playerID)); deletestmt->setUInt(2, static_cast<uint32_t>(friendID)); deletestmt->setUInt(3, static_cast<uint32_t>(friendID)); deletestmt->setUInt(4, static_cast<uint32_t>(playerID)); deletestmt->execute(); - delete deletestmt; - deletestmt = nullptr; - //Now, we need to send an update to notify the sender (and possibly, receiver) that their friendship has been ended: auto goonA = playerContainer.GetPlayerData(playerID); if (goonA) { // Remove the friend from our list of friends for (auto friendData = goonA->friends.begin(); friendData != goonA->friends.end(); friendData++) { if ((*friendData).friendID == friendID) { + if ((*friendData).isBestFriend) --goonA->countOfBestFriends; goonA->friends.erase(friendData); break; } @@ -214,6 +361,7 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { // Do it again for other person for (auto friendData = goonB->friends.begin(); friendData != goonB->friends.end(); friendData++) { if ((*friendData).friendID == playerID) { + if ((*friendData).isBestFriend) --goonB->countOfBestFriends; goonB->friends.erase(friendData); break; } @@ -766,7 +914,7 @@ void ChatPacketHandler::SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i SEND_PACKET; } -void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType) { +void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend) { /*chat notification is displayed if log in / out and friend is updated in friends list [u8] - update type Update types @@ -804,19 +952,20 @@ void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* pla bitStream.Write(playerData->zoneID.GetCloneID()); } - bitStream.Write<uint8_t>(0); //isBFF + bitStream.Write<uint8_t>(isBestFriend); //isBFF bitStream.Write<uint8_t>(0); //isFTP SystemAddress sysAddr = friendData->sysAddr; SEND_PACKET; } -void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* sender, bool isBFFReq) { +void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* sender) { if (!receiver || !sender) return; //Make sure people aren't requesting people that they're already friends with: for (auto fr : receiver->friends) { if (fr.friendID == sender->playerID) { + SendFriendResponse(sender, receiver, AddFriendResponseType::ALREADYFRIEND, fr.isBestFriend); return; //we have this player as a friend, yeet this function so it doesn't send another request. } } @@ -828,29 +977,33 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send //portion that will get routed: PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_ADD_FRIEND_REQUEST); PacketUtils::WritePacketWString(sender->playerName.C_String(), 33, &bitStream); - bitStream.Write<uint8_t>(0); + bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side. SystemAddress sysAddr = receiver->sysAddr; SEND_PACKET; } -void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sender, uint8_t responseCode) { +void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sender, AddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) { if (!receiver || !sender) return; CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); - //portion that will get routed: + // Portion that will get routed: PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_ADD_FRIEND_RESPONSE); - bitStream.Write<uint8_t>(responseCode); - bitStream.Write<uint8_t>(1); //isOnline + 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<uint8_t>(responseCode != AddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); + // Then write the player name PacketUtils::WritePacketWString(sender->playerName.C_String(), 33, &bitStream); - bitStream.Write(sender->playerID); - bitStream.Write(sender->zoneID); - bitStream.Write<uint8_t>(0); //isBFF - bitStream.Write<uint8_t>(0); //isFTP - + // Then if this is an acceptance code, write the following extra info. + if (responseCode == AddFriendResponseType::ACCEPTED) { + bitStream.Write(sender->playerID); + bitStream.Write(sender->zoneID); + bitStream.Write(isBestFriendRequest); //isBFF + bitStream.Write<uint8_t>(0); //isFTP + } SystemAddress sysAddr = receiver->sysAddr; SEND_PACKET; } diff --git a/dChatServer/ChatPacketHandler.h b/dChatServer/ChatPacketHandler.h index e38a65c1..fffd1ca4 100644 --- a/dChatServer/ChatPacketHandler.h +++ b/dChatServer/ChatPacketHandler.h @@ -4,6 +4,7 @@ #include "BitStream.h" struct PlayerData; +enum class AddFriendResponseType : uint8_t; namespace ChatPacketHandler { void HandleFriendlistRequest(Packet* packet); @@ -31,10 +32,9 @@ namespace ChatPacketHandler { void SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID); //FriendData is the player we're SENDING this stuff to. Player is the friend that changed state. - void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType); + void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend); - void SendFriendRequest(PlayerData* receiver, PlayerData* sender, bool isBFFReq = false); - void SendFriendResponse(PlayerData* receiver, PlayerData* sender, uint8_t responseCode = 3); + void SendFriendRequest(PlayerData* receiver, PlayerData* sender); + void SendFriendResponse(PlayerData* receiver, PlayerData* sender, AddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U); void SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful); }; - diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index d261b32f..b40e8386 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -59,7 +59,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) { //if (!fr.isOnline) continue; auto fd = this->GetPlayerData(fr.friendID); - if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0); + if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0, fr.isBestFriend); } auto* team = GetTeam(playerID); diff --git a/dChatServer/PlayerContainer.h b/dChatServer/PlayerContainer.h index dc78d3b0..b1e1defd 100644 --- a/dChatServer/PlayerContainer.h +++ b/dChatServer/PlayerContainer.h @@ -14,6 +14,7 @@ struct PlayerData { LWOZONEID zoneID; std::vector<FriendData> friends; time_t muteExpire; + uint8_t countOfBestFriends = 0; }; struct TeamData { diff --git a/dCommon/AddFriendResponseCode.h b/dCommon/AddFriendResponseCode.h new file mode 100644 index 00000000..bb2faff7 --- /dev/null +++ b/dCommon/AddFriendResponseCode.h @@ -0,0 +1,15 @@ +#pragma once + +#ifndef __ADDFRIENDRESPONSECODE__H__ +#define __ADDFRIENDRESPONSECODE__H__ + +#include <cstdint> + +enum class AddFriendResponseCode : uint8_t { + ACCEPTED = 0, + REJECTED, + BUSY, + CANCELLED +}; + +#endif //!__ADDFRIENDRESPONSECODE__H__ diff --git a/dCommon/AddFriendResponseType.h b/dCommon/AddFriendResponseType.h new file mode 100644 index 00000000..305796e8 --- /dev/null +++ b/dCommon/AddFriendResponseType.h @@ -0,0 +1,24 @@ +#pragma once + +#ifndef __ADDFRIENDRESPONSETYPE__H__ +#define __ADDFRIENDRESPONSETYPE__H__ + +#include <cstdint> + +enum class AddFriendResponseType : uint8_t { + ACCEPTED = 0, + ALREADYFRIEND, + INVALIDCHARACTER, + GENERALERROR, + YOURFRIENDSLISTFULL, + THEIRFRIENDLISTFULL, + DECLINED, + BUSY, + NOTONLINE, + WAITINGAPPROVAL, + MYTHRAN, + CANCELLED, + FRIENDISFREETRIAL +}; + +#endif //!__ADDFRIENDRESPONSETYPE__H__ diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index db60a1d1..da0cf685 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -401,7 +401,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr Game::server->Send(&stream, sysAddr, false); } - PacketUtils::SavePacket("[24]_"+std::to_string(entity->GetObjectID()) + "_" + std::to_string(m_SerializationCounter) + ".bin", (char*)stream.GetData(), stream.GetNumberOfBytesUsed()); + // PacketUtils::SavePacket("[24]_"+std::to_string(entity->GetObjectID()) + "_" + std::to_string(m_SerializationCounter) + ".bin", (char*)stream.GetData(), stream.GetNumberOfBytesUsed()); if (entity->IsPlayer()) { diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 1d14cb0a..3956942a 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -369,10 +369,8 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) } LWOOBJID objectID = PacketUtils::ReadPacketS64(8, packet); - objectID = GeneralUtils::ClearBit(objectID, OBJECT_BIT_CHARACTER); - objectID = GeneralUtils::ClearBit(objectID, OBJECT_BIT_PERSISTENT); - - uint32_t charID = static_cast<uint32_t>(objectID); + uint32_t charID = static_cast<uint32_t>(objectID); + Game::logger->Log("UserManager", "Received char delete req for ID: %llu (%u)\n", objectID, charID); //Check if this user has this character: @@ -402,10 +400,14 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) } { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("DELETE FROM friends WHERE player_id=? OR friend_id=?;"); - stmt->setUInt64(1, charID); - stmt->setUInt64(2, charID); + stmt->setUInt(1, charID); + stmt->setUInt(2, charID); stmt->execute(); delete stmt; + CBITSTREAM; + PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_PLAYER_REMOVED_NOTIFICATION); + bitStream.Write(objectID); + Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("DELETE FROM leaderboard WHERE character_id=?;"); diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 1d631e88..87e0c7ed 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -102,7 +102,7 @@ PropertySelectQueryProperty PropertyEntranceComponent::SetPropertyValues(Propert return property; } -std::string PropertyEntranceComponent::BuildQuery(Entity* entity, int32_t sortMethod, std::string customQuery, bool wantLimits) { +std::string PropertyEntranceComponent::BuildQuery(Entity* entity, int32_t sortMethod, Character* character, std::string customQuery, bool wantLimits) { std::string base; if (customQuery == "") { base = baseQueryForProperties; @@ -115,15 +115,13 @@ std::string PropertyEntranceComponent::BuildQuery(Entity* entity, int32_t sortMe auto friendsListQuery = Database::CreatePreppedStmt("SELECT * FROM (SELECT CASE WHEN player_id = ? THEN friend_id WHEN friend_id = ? THEN player_id END AS requested_player FROM friends ) AS fr WHERE requested_player IS NOT NULL ORDER BY requested_player DESC;"); - friendsListQuery->setInt64(1, entity->GetObjectID()); - friendsListQuery->setInt64(2, entity->GetObjectID()); + friendsListQuery->setUInt(1, character->GetID()); + friendsListQuery->setUInt(2, character->GetID()); auto friendsListQueryResult = friendsListQuery->executeQuery(); while (friendsListQueryResult->next()) { - auto playerIDToConvert = friendsListQueryResult->getInt64(1); - playerIDToConvert = GeneralUtils::ClearBit(playerIDToConvert, OBJECT_BIT_CHARACTER); - playerIDToConvert = GeneralUtils::ClearBit(playerIDToConvert, OBJECT_BIT_PERSISTENT); + auto playerIDToConvert = friendsListQueryResult->getInt(1); friendsList = friendsList + std::to_string(playerIDToConvert) + ","; } // Replace trailing comma with the closing parenthesis. @@ -193,7 +191,7 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl entries.push_back(playerEntry); - const auto query = BuildQuery(entity, sortMethod); + const auto query = BuildQuery(entity, sortMethod, character); auto propertyLookup = Database::CreatePreppedStmt(query); @@ -262,17 +260,17 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl // Query to get friend and best friend fields auto friendCheck = Database::CreatePreppedStmt("SELECT best_friend FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?)"); - friendCheck->setInt64(1, entity->GetObjectID()); - friendCheck->setInt64(2, ownerObjId); - friendCheck->setInt64(3, ownerObjId); - friendCheck->setInt64(4, entity->GetObjectID()); + friendCheck->setUInt(1, character->GetID()); + friendCheck->setUInt(2, ownerObjId); + friendCheck->setUInt(3, ownerObjId); + friendCheck->setUInt(4, character->GetID()); auto friendResult = friendCheck->executeQuery(); // If we got a result than the two players are friends. if (friendResult->next()) { isFriend = true; - if (friendResult->getInt(1) == 2) { + if (friendResult->getInt(1) == 3) { isBestFriend = true; } } @@ -326,7 +324,7 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl // Query here is to figure out whether or not to display the button to go to the next page or not. int32_t numberOfProperties = 0; - auto buttonQuery = BuildQuery(entity, sortMethod, "SELECT COUNT(*) FROM properties as p JOIN charinfo as ci ON ci.prop_clone_id = p.clone_id where p.zone_id = ? AND (p.description LIKE ? OR p.name LIKE ? OR ci.name LIKE ?) AND p.privacy_option >= ? ", false); + auto buttonQuery = BuildQuery(entity, sortMethod, character, "SELECT COUNT(*) FROM properties as p JOIN charinfo as ci ON ci.prop_clone_id = p.clone_id where p.zone_id = ? AND (p.description LIKE ? OR p.name LIKE ? OR ci.name LIKE ?) AND p.privacy_option >= ? ", false); auto propertiesLeft = Database::CreatePreppedStmt(buttonQuery); propertiesLeft->setUInt(1, this->m_MapID); diff --git a/dGame/dComponents/PropertyEntranceComponent.h b/dGame/dComponents/PropertyEntranceComponent.h index a3be38a6..fe583e92 100644 --- a/dGame/dComponents/PropertyEntranceComponent.h +++ b/dGame/dComponents/PropertyEntranceComponent.h @@ -60,7 +60,7 @@ class PropertyEntranceComponent : public Component { PropertySelectQueryProperty SetPropertyValues(PropertySelectQueryProperty property, LWOCLONEID cloneId = LWOCLONEID_INVALID, std::string ownerName = "", std::string propertyName = "", std::string propertyDescription = "", float reputation = 0, bool isBFF = false, bool isFriend = false, bool isModeratorApproved = false, bool isAlt = false, bool isOwned = false, uint32_t privacyOption = 0, uint32_t timeLastUpdated = 0, float performanceCost = 0.0f); - std::string BuildQuery(Entity* entity, int32_t sortMethod, std::string customQuery = "", bool wantLimits = true); + std::string BuildQuery(Entity* entity, int32_t sortMethod, Character* character, std::string customQuery = "", bool wantLimits = true); private: /** diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 4f1ec400..330263ed 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -669,10 +669,12 @@ void HandlePacket(Packet* packet) { Game::logger->Log("WorldServer", "Deleting player %llu\n", entity->GetObjectID()); EntityManager::Instance()->DestroyEntity(entity); + } + { CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_PLAYER_REMOVED_NOTIFICATION); - bitStream.Write(c->GetObjectID()); + bitStream.Write(user->GetLoggedInChar()); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -930,6 +932,19 @@ void HandlePacket(Packet* packet) { playerID = GeneralUtils::ClearBit(playerID, OBJECT_BIT_CHARACTER); playerID = GeneralUtils::ClearBit(playerID, OBJECT_BIT_PERSISTENT); + auto user = UserManager::Instance()->GetUser(packet->systemAddress); + + if (user) { + auto lastCharacter = user->GetLoggedInChar(); + // This means we swapped characters and we need to remove the previous player from the container. + if (static_cast<uint32_t>(lastCharacter) != playerID) { + CBITSTREAM; + PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_PLAYER_REMOVED_NOTIFICATION); + bitStream.Write(lastCharacter); + Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); + } + } + UserManager::Instance()->LoginCharacter(packet->systemAddress, static_cast<uint32_t>(playerID)); break; } diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index a665f059..931da28c 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -60,3 +60,7 @@ classic_survival_scoring=0 # If this value is 1, pets will consume imagination as they did in live. if 0 they will not consume imagination at all. pets_take_imagination=1 + +# If you would like to increase the maximum number of best friends a player can have on the server +# Change the value below to what you would like this to be (5 is live accurate) +max_number_of_best_friends=5 \ No newline at end of file From ccb9f7c499a4ea3b054e5b172b5bfc39c0bb7b60 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 12 Jul 2022 20:45:25 -0700 Subject: [PATCH 88/98] Move instruction for database Move the instruction for running the MasterServer migration down to where the command will actually work as well as use a more syntactically correct statement --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d029ed93..5781c7b8 100644 --- a/README.md +++ b/README.md @@ -152,13 +152,6 @@ now follow the build section for your system ## Setting up the environment -### Database -Darkflame Universe utilizes a MySQL/MariaDB database for account and character information. - -Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running. -* Create a database for Darkflame Universe to use -* Run the migrations by running `./MasterServer -m` to automatically run them - ### Resources **LEGO® Universe 1.10.64** @@ -202,6 +195,13 @@ certutil -hashfile <file> SHA256 * Move and rename `cdclient.sqlite` into `build/res/CDServer.sqlite` * Run each SQL file in the order at which they appear [here](migrations/cdserver/) on the SQLite database +### Database +Darkflame Universe utilizes a MySQL/MariaDB database for account and character information. + +Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running. +* Create a database for Darkflame Universe to use +* Use the command `./MasterServer -m` to automatically run them. + **Configuration** After the server has been built there should be four `ini` files in the build director: `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`. Go through them and fill in the database credentials and configure other settings if necessary. From 9ba297dd2e2a6814646fa755ebaac780d60f6a0e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 13 Jul 2022 09:10:02 -0700 Subject: [PATCH 89/98] Add code to complete hidden property mission (#641) --- dScripts/BasePropertyServer.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index e7a95844..ce36caa9 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -169,11 +169,10 @@ void BasePropertyServer::BaseZonePropertyRented(Entity* self, Entity* player) co EntityManager::Instance()->DestructEntity(plaque); } - if (self->GetVar<int32_t>(brickLinkMissionIDFlag) != 0) { - auto plaques = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar<std::string>(PropertyPlaqueGroup)); - for (auto* plaque : plaques) { - EntityManager::Instance()->DestructEntity(plaque); - } + auto brickLinkMissionID = self->GetVar<uint32_t>(brickLinkMissionIDFlag); + if (brickLinkMissionID != 0) { + auto missionComponent = player->GetComponent<MissionComponent>(); + if (missionComponent) missionComponent->CompleteMission(brickLinkMissionID, true); } ActivateSpawner(self->GetVar<std::string>(PropObjsSpawner)); From 3d46d703b2c10cd8673f518a44054753db7723dc Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 13 Jul 2022 09:11:24 -0700 Subject: [PATCH 90/98] Remove memory leak in player container and warning in Behavior (#640) * Add friends list migration * Change friends to use charID Update friends table to use charID and not LWOOBJID variant. * Fix remove friend Fix remove friend and make the query more readable at a glance. * Add and remove friends in the container Properly add and remove friends in the player container * add enums * Add best friends and basic GM support V1 * Add more features * not online / doesnt exist implementation Implements the not online and invalid character response codes * Address players not being removed Fix an issue where players would not be marked as offline in the friends list due to the message not being sent in all circumstances. Tested changes on 3 clients, switching characters, logging out from character select, switching characters, world transfer and my friends list looked as it was supposed to. * Implement proper friends system Remove debug logs Track count of best friends Add best friends list cap of 5 Add config option and best friend update Add a config option and implement the last missing best friend serialization Added comments and fixed remove best friend bug Added some comments and addressed an issue where removing best friends would not remove them from your internal count of friends. properties and logs fixes whoops, had an issue send reply if already BFFs Send the correct objectID I really need to rename these Fix white space goon * Replace queries with unique ptrs * remove user from player container on deletion Remove the user from the player container when they delete their character. * Bump patch version * Improvements to PlayerContainer Resolved a memory leak in the player container, removed commented out code and resolved a warning in Behavior.cpp * Make it a unique ptr * Improvements to PlayerContainer Resolved a memory leak in the player container, removed commented out code and resolved a warning in Behavior.cpp Make it a unique ptr * Update PlayerContainer.cpp --- dChatServer/PlayerContainer.cpp | 19 ++----------------- dGame/dBehaviors/Behavior.cpp | 2 +- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index b40e8386..c5da3a7f 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -49,25 +49,21 @@ void PlayerContainer::RemovePlayer(Packet* packet) { inStream.Read(playerID); //Before they get kicked, we need to also send a message to their friends saying that they disconnected. - auto player = this->GetPlayerData(playerID); + std::unique_ptr<PlayerData> player(this->GetPlayerData(playerID)); if (player == nullptr) { return; } for (auto& fr : player->friends) { - //if (!fr.isOnline) continue; - auto fd = this->GetPlayerData(fr.friendID); - if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0, fr.isBestFriend); + if (fd) ChatPacketHandler::SendFriendUpdate(fd, player.get(), 0, fr.isBestFriend); } auto* team = GetTeam(playerID); if (team != nullptr) { - //TeamStatusUpdate(team); - const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(player->playerName.C_String())); for (const auto memberId : team->memberIDs) @@ -77,7 +73,6 @@ void PlayerContainer::RemovePlayer(Packet* packet) { if (otherMember == nullptr) continue; ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, {0, 0, 0}); - //ChatPacketHandler::SendTeamRemovePlayer(otherMember, false, false, true, false, team->leaderID, player->playerID, memberName); } } @@ -241,12 +236,6 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(member->playerName.C_String())); ChatPacketHandler::SendTeamInviteConfirm(member, false, leader->playerID, leader->zoneID, team->lootFlag, 0, 0, leaderName); - - /* - ChatPacketHandler::SendTeamAddPlayer(member, false, false, false, leader->playerID, leaderName, leader->zoneID); - - Game::logger->Log("PlayerContainer", "Team invite successfully accepted, leader: %s, member: %s\n", leader->playerName.C_String(), member->playerName.C_String()); - */ if (!team->local) { @@ -383,10 +372,6 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) { ChatPacketHandler::SendTeamStatus(otherMember, team->leaderID, leader->zoneID, team->lootFlag, 0, leaderName); } - else - { - //ChatPacketHandler::SendTeamStatus(otherMember, LWOOBJID_EMPTY, LWOZONEID(0, 0, 0), 1, 0, u""); - } } UpdateTeamsOnWorld(team, false); diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index a2329f96..489bd1a7 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -409,7 +409,7 @@ Behavior::Behavior(const uint32_t behaviorId) { auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate"); - CDBehaviorTemplate templateInDatabase; + CDBehaviorTemplate templateInDatabase{}; if (behaviorTemplateTable) { auto templateEntry = behaviorTemplateTable->GetByBehaviorID(behaviorId); From 9c0819de4fded129dc17713b5630b382e74093f8 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 16 Jul 2022 22:55:54 +0100 Subject: [PATCH 91/98] Add MacOS building to the Github Actions (#643) * Add MacOS to CMakePresets.json * Update workflow to run MacOS builds * Update test and build presets * Add libssl install to integration * Update workflow to install libssl and openssl * Prevent brew running as super user --- .github/workflows/build-and-test.yml | 7 +++++-- CMakePresets.json | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 0e7785d9..5a36df4b 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -12,18 +12,21 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ windows-2022, ubuntu-20.04 ] + os: [ windows-2022, ubuntu-20.04, macos-11 ] steps: - uses: actions/checkout@v2 with: submodules: true - - name: Add msbuild to PATH (windows only) + - name: Add msbuild to PATH (Windows only) if: ${{ matrix.os == 'windows-2022' }} uses: microsoft/setup-msbuild@v1.1 with: vs-version: '[17,18)' msbuild-architecture: x64 + - name: Install libssl (Mac Only) + if: ${{ matrix.os == 'macos-11' }} + run: brew install openssl@3 - name: cmake uses: lukka/run-cmake@v10 with: diff --git a/CMakePresets.json b/CMakePresets.json index 241220e0..133d6a3c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -19,6 +19,15 @@ "description": "Same as default, Used in GitHub actions workflow", "inherits": "default" }, + { + "name": "ci-macos-11", + "displayName": "CI configure step for MacOS", + "description": "Same as default, Used in GitHub actions workflow", + "inherits": "default", + "cacheVariables": { + "OPENSSL_ROOT_DIR": "/usr/local/Cellar/openssl@3/3.0.5/" + } + }, { "name": "ci-windows-2022", "displayName": "CI configure step for Windows", @@ -66,6 +75,13 @@ "displayName": "Linux CI Build", "description": "This preset is used by the CI build on linux", "jobs": 2 + }, + { + "name": "ci-macos-11", + "configurePreset": "ci-macos-11", + "displayName": "MacOS CI Build", + "description": "This preset is used by the CI build on MacOS", + "jobs": 2 } ], "testPresets": [ @@ -81,6 +97,18 @@ "outputOnFailure": true } }, + { + "name": "ci-macos-11", + "configurePreset": "ci-macos-11", + "displayName": "CI Tests on MacOS", + "description": "Runs all tests on a Mac configuration", + "execution": { + "jobs": 2 + }, + "output": { + "outputOnFailure": true + } + }, { "name": "ci-windows-2022", "configurePreset": "ci-windows-2022", From df0f11c95b76c6f5869776272189b6fb81b22e74 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sun, 17 Jul 2022 00:24:16 +0100 Subject: [PATCH 92/98] Update CMake configuration for easier maintenance (#642) * Update CMake configuration for easier maintenance * Incorrect casing fix * Move package requirement * Update CTest linking * Add logs to the CMake * Add linking for common libraries Added linking for common libraries in tests subdirectory. * Move test subdirectory higher up for some reason * Whitespace a log removal Missed new line * Add dCommon to dChatFilter * Update library output dir * Correct libBcrypt * Further refactor CMake behaviour * Repair bad comments and update library defines * Revert to old include directory method * Implement platform defines * Add missing include Mac needs a specific include for defining platform. Does not compile without this. Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> --- CMakeLists.txt | 546 +++++++++-------------------- dAuthServer/CMakeLists.txt | 4 + dChatFilter/CMakeLists.txt | 4 + dChatServer/CMakeLists.txt | 6 + dCommon/CMakeLists.txt | 26 ++ dCommon/ZCompression.cpp | 6 +- dCommon/ZCompression.h | 6 + dCommon/dPlatforms.h | 29 ++ dDatabase/CMakeLists.txt | 13 + dDatabase/Tables/CMakeLists.txt | 38 ++ dGame/CMakeLists.txt | 59 ++++ dGame/dBehaviors/CMakeLists.txt | 51 +++ dGame/dComponents/CMakeLists.txt | 40 +++ dGame/dEntity/CMakeLists.txt | 2 + dGame/dGameMessages/CMakeLists.txt | 4 + dGame/dInventory/CMakeLists.txt | 5 + dGame/dMission/CMakeLists.txt | 3 + dGame/dUtilities/CMakeLists.txt | 9 + dMasterServer/CMakeLists.txt | 10 + dNet/CMakeLists.txt | 11 + dPhysics/CMakeLists.txt | 9 + dScripts/CMakeLists.txt | 253 +++++++++++++ dWorldServer/CMakeLists.txt | 6 + dZoneManager/CMakeLists.txt | 6 + tests/CMakeLists.txt | 20 +- thirdparty/CMakeLists.txt | 102 ++++-- 26 files changed, 839 insertions(+), 429 deletions(-) create mode 100644 dAuthServer/CMakeLists.txt create mode 100644 dChatFilter/CMakeLists.txt create mode 100644 dChatServer/CMakeLists.txt create mode 100644 dCommon/CMakeLists.txt create mode 100644 dCommon/dPlatforms.h create mode 100644 dDatabase/CMakeLists.txt create mode 100644 dDatabase/Tables/CMakeLists.txt create mode 100644 dGame/CMakeLists.txt create mode 100644 dGame/dBehaviors/CMakeLists.txt create mode 100644 dGame/dComponents/CMakeLists.txt create mode 100644 dGame/dEntity/CMakeLists.txt create mode 100644 dGame/dGameMessages/CMakeLists.txt create mode 100644 dGame/dInventory/CMakeLists.txt create mode 100644 dGame/dMission/CMakeLists.txt create mode 100644 dGame/dUtilities/CMakeLists.txt create mode 100644 dMasterServer/CMakeLists.txt create mode 100644 dNet/CMakeLists.txt create mode 100644 dPhysics/CMakeLists.txt create mode 100644 dScripts/CMakeLists.txt create mode 100644 dWorldServer/CMakeLists.txt create mode 100644 dZoneManager/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 5373dfe4..0817412b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,90 +12,67 @@ string(REPLACE "\n" ";" variables ${variables}) # Set the cmake variables, formatted as "VARIABLE #" in variables foreach(variable ${variables}) - # If the string contains a #, skip it - if(NOT "${variable}" MATCHES "#") - - # Split the variable into name and value - string(REPLACE "=" ";" variable ${variable}) + # If the string contains a #, skip it + if(NOT "${variable}" MATCHES "#") + + # Split the variable into name and value + string(REPLACE "=" ";" variable ${variable}) - # Check that the length of the variable is 2 (name and value) - list(LENGTH variable length) - if(${length} EQUAL 2) + # Check that the length of the variable is 2 (name and value) + list(LENGTH variable length) + if(${length} EQUAL 2) - list(GET variable 0 variable_name) - list(GET variable 1 variable_value) + list(GET variable 0 variable_name) + list(GET variable 1 variable_value) - # Set the variable - set(${variable_name} ${variable_value}) + # Set the variable + set(${variable_name} ${variable_value}) - # Add compiler definition - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}") + # Add compiler definition + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}") - message(STATUS "Variable: ${variable_name} = ${variable_value}") + message(STATUS "Variable: ${variable_name} = ${variable_value}") endif() endif() endforeach() -# On windows it's better to build this from source, as there's no way FindZLIB is gonna find it -if(NOT WIN32) -find_package(ZLIB REQUIRED) -endif() - -# Fetch External (Non-Submodule) Libraries -if(WIN32) -include(FetchContent) - -FetchContent_Declare( - zlib - URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip - URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1 -) - -FetchContent_MakeAvailable(zlib) - -set(ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR}) -set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") # Why? -add_library(ZLIB::ZLIB ALIAS zlib) # You're welcome - -endif(WIN32) - -if(UNIX AND NOT APPLE) - include(FetchContent) - if (__include_backtrace__ AND __compile_backtrace__) - FetchContent_Declare( - backtrace - GIT_REPOSITORY https://github.com/ianlancetaylor/libbacktrace.git - ) - - FetchContent_MakeAvailable(backtrace) - - if (NOT EXISTS ${backtrace_SOURCE_DIR}/.libs) - set(backtrace_make_cmd "${backtrace_SOURCE_DIR}/configure --prefix=\"/usr\" --enable-shared --with-system-libunwind") - - execute_process( - COMMAND bash -c "cd ${backtrace_SOURCE_DIR} && ${backtrace_make_cmd} && make && cd ${CMAKE_SOURCE_DIR}" - ) - endif() - - link_directories(${backtrace_SOURCE_DIR}/.libs/) - include_directories(${backtrace_SOURCE_DIR}) - endif() -endif() - # Set the version set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}") - # Echo the version message(STATUS "Version: ${PROJECT_VERSION}") -if(WIN32) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) -endif(WIN32) +# Compiler flags: +# Disabled deprecated warnings as the MySQL includes have deprecated code in them. +# Disabled misleading indentation as DL_LinkedList from RakNet has a weird indent. +# Disabled no-register +# Disabled unknown pragmas because Linux doesn't understand Windows pragmas. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}") +if(UNIX) + if(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC") + endif() + if (__dynamic) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") + endif() + if (__ggdb) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb") + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC") +elseif(MSVC) + # Skip warning for invalid conversion from size_t to uint32_t for all targets below for now + add_compile_options("/wd4267") +elseif(WIN32) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +endif() # Our output dir set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) # Create a /res directory make_directory(${CMAKE_BINARY_DIR}/res) @@ -107,363 +84,172 @@ make_directory(${CMAKE_BINARY_DIR}/locale) make_directory(${CMAKE_BINARY_DIR}/logs) # Copy ini files on first build -if (NOT EXISTS ${PROJECT_BINARY_DIR}/authconfig.ini) - configure_file( - ${CMAKE_SOURCE_DIR}/resources/authconfig.ini ${PROJECT_BINARY_DIR}/authconfig.ini - COPYONLY - ) -endif() -if (NOT EXISTS ${PROJECT_BINARY_DIR}/chatconfig.ini) - configure_file( - ${CMAKE_SOURCE_DIR}/resources/chatconfig.ini ${PROJECT_BINARY_DIR}/chatconfig.ini - COPYONLY - ) -endif() -if (NOT EXISTS ${PROJECT_BINARY_DIR}/worldconfig.ini) - configure_file( - ${CMAKE_SOURCE_DIR}/resources/worldconfig.ini ${PROJECT_BINARY_DIR}/worldconfig.ini - COPYONLY - ) -endif() -if (NOT EXISTS ${PROJECT_BINARY_DIR}/masterconfig.ini) - configure_file( - ${CMAKE_SOURCE_DIR}/resources/masterconfig.ini ${PROJECT_BINARY_DIR}/masterconfig.ini - COPYONLY - ) -endif() +set(INI_FILES "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini") +foreach(ini ${INI_FILES}) + if (NOT EXISTS ${PROJECT_BINARY_DIR}/${ini}) + configure_file( + ${CMAKE_SOURCE_DIR}/resources/${ini} ${PROJECT_BINARY_DIR}/${ini} + COPYONLY + ) + endif() +endforeach() -# Copy files to output -configure_file("${CMAKE_SOURCE_DIR}/vanity/CREDITS.md" "${CMAKE_BINARY_DIR}/vanity/CREDITS.md" COPYONLY) -configure_file("${CMAKE_SOURCE_DIR}/vanity/INFO.md" "${CMAKE_BINARY_DIR}/vanity/INFO.md" COPYONLY) -configure_file("${CMAKE_SOURCE_DIR}/vanity/TESTAMENT.md" "${CMAKE_BINARY_DIR}/vanity/TESTAMENT.md" COPYONLY) -configure_file("${CMAKE_SOURCE_DIR}/vanity/NPC.xml" "${CMAKE_BINARY_DIR}/vanity/NPC.xml" COPYONLY) +# Copy vanity files on first build +set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml") +foreach(file ${VANITY_FILES}) + configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY) +endforeach() # Move our migrations for MasterServer to run file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/migrations/) file(GLOB SQL_FILES ${CMAKE_SOURCE_DIR}/migrations/dlu/*.sql) -foreach (file ${SQL_FILES}) - get_filename_component(file ${file} NAME) - if (NOT EXISTS ${PROJECT_BINARY_DIR}/migrations/${file}) - configure_file( - ${CMAKE_SOURCE_DIR}/migrations/dlu/${file} ${PROJECT_BINARY_DIR}/migrations/${file} - COPYONLY - ) - endif() +foreach(file ${SQL_FILES}) + get_filename_component(file ${file} NAME) + if (NOT EXISTS ${PROJECT_BINARY_DIR}/migrations/${file}) + configure_file( + ${CMAKE_SOURCE_DIR}/migrations/dlu/${file} ${PROJECT_BINARY_DIR}/migrations/${file} + COPYONLY + ) + endif() endforeach() -# 3rdparty includes -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/) -if(APPLE) - include_directories(/usr/local/include/) -endif(APPLE) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include) +# Create our list of include directories +set(INCLUDED_DIRECTORIES + "dCommon" + "dChatFilter" + "dGame" + "dGame/dBehaviors" + "dGame/dComponents" + "dGame/dGameMessages" + "dGame/dInventory" + "dGame/dMission" + "dGame/dEntity" + "dGame/dUtilities" + "dPhysics" + "dZoneManager" + "dDatabase" + "dDatabase/Tables" + "dNet" + "dScripts" + + "thirdparty/raknet/Source" + "thirdparty/tinyxml2" + "thirdparty/recastnavigation/Recast/Include" + "thirdparty/recastnavigation/Detour/Include" + "thirdparty/SQLite" + "thirdparty/cpplinq" + ) + +# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux) +if (APPLE) + include_directories("/usr/local/include/") +endif() + +if (WIN32) + set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include") +elseif (UNIX) + set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt") + set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include/bcrypt") +endif() + include_directories(${ZLIB_INCLUDE_DIRS}) - -# Bcrypt -if (NOT WIN32) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include/bcrypt) -else () -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include) -endif () - -# Our includes +# Add binary directory as an include directory include_directories(${PROJECT_BINARY_DIR}) -include_directories(${PROJECT_SOURCE_DIR}/dChatFilter/) -include_directories(${PROJECT_SOURCE_DIR}/dCommon/) -include_directories(${PROJECT_SOURCE_DIR}/dGame/) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dBehaviors) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dComponents) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dGameMessages) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dInventory) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dMission) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dEntity) -include_directories(${PROJECT_SOURCE_DIR}/dGame/dUtilities) -include_directories(${PROJECT_SOURCE_DIR}/dPhysics/) -include_directories(${PROJECT_SOURCE_DIR}/dZoneManager/) -include_directories(${PROJECT_SOURCE_DIR}/dDatabase/) -include_directories(${PROJECT_SOURCE_DIR}/dDatabase/Tables/) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/SQLite/) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/cpplinq/) -include_directories(${PROJECT_SOURCE_DIR}/dNet/) -include_directories(${PROJECT_SOURCE_DIR}/dScripts/) -# Lib folders: +# Actually include the directories from our list +foreach (dir ${INCLUDED_DIRECTORIES}) + include_directories(${PROJECT_SOURCE_DIR}/${dir}) +endforeach() + +# Add linking directories: link_directories(${PROJECT_BINARY_DIR}) -# Third-Party libraries +# Load all of our third party directories add_subdirectory(thirdparty) -# Source Code +# Glob together all headers that need to be precompiled file( -GLOB SOURCES -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dWorldServer/*.cpp -) - -# Source Code for AuthServer -file( -GLOB SOURCES_AUTH -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dAuthServer/*.cpp -) - -# Source Code for MasterServer -file( -GLOB SOURCES_MASTER -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dMasterServer/*.cpp -) - -# Source Code for ChatServer -file( -GLOB SOURCES_CHAT -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dChatServer/*.cpp -) - -# Source Code for dCommon -file( -GLOB SOURCES_DCOMMON -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dCommon/*.cpp -) - -# Source Code for dChatFilter -file( -GLOB SOURCES_DCHATFILTER -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dChatFilter/*.cpp -) - -# Source Code for dDatabase -file( -GLOB SOURCES_DDATABASE -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dDatabase/*.cpp -${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.cpp + GLOB HEADERS_DDATABASE + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dDatabase/*.h + ${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.h + ${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h ) file( - GLOB HEADERS_DDATABASE - LIST_DIRECTORIES false - ${PROJECT_SOURCE_DIR}/dDatabase/*.h - ${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.h - ${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h + GLOB HEADERS_DZONEMANAGER + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dZoneManager/*.h ) file( - GLOB HEADERS_DZONEMANAGER - LIST_DIRECTORIES false - ${PROJECT_SOURCE_DIR}/dZoneManager/*.h + GLOB HEADERS_DCOMMON + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dCommon/*.h ) file( - GLOB HEADERS_DCOMMON - LIST_DIRECTORIES false - ${PROJECT_SOURCE_DIR}/dCommon/*.h + GLOB HEADERS_DGAME + LIST_DIRECTORIES false + ${PROJECT_SOURCE_DIR}/dGame/Entity.h + ${PROJECT_SOURCE_DIR}/dGame/dGameMessages/GameMessages.h + ${PROJECT_SOURCE_DIR}/dGame/EntityManager.h + ${PROJECT_SOURCE_DIR}/dScripts/CppScripts.h ) -file( - GLOB HEADERS_DGAME - LIST_DIRECTORIES false - ${PROJECT_SOURCE_DIR}/dGame/Entity.h - ${PROJECT_SOURCE_DIR}/dGame/dGameMessages/GameMessages.h - ${PROJECT_SOURCE_DIR}/dGame/EntityManager.h - ${PROJECT_SOURCE_DIR}/dScripts/CppScripts.h -) +# Add our library subdirectories for creation of the library object +add_subdirectory(dCommon) +add_subdirectory(dDatabase) +add_subdirectory(dChatFilter) +add_subdirectory(dNet) +add_subdirectory(dScripts) # Add for dGame to use +add_subdirectory(dGame) +add_subdirectory(dZoneManager) +add_subdirectory(dPhysics) -# Source Code for dNet -file( -GLOB SOURCES_DNET -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dNet/*.cpp -) +# Create a list of common libraries shared between all binaries +set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp") -# Source Code for dGame -file( -GLOB SOURCES_DGAME -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dGame/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dBehaviors/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dComponents/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dGameMessages/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dInventory/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dMission/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dEntity/*.cpp -${PROJECT_SOURCE_DIR}/dGame/dUtilities/*.cpp -${PROJECT_SOURCE_DIR}/dScripts/*.cpp -) +# Add platform specific common libraries +if (UNIX) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "dl" "pthread") -# Source Code for dZoneManager -file( -GLOB SOURCES_DZM -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dZoneManager/*.cpp -) + if (NOT APPLE AND __include_backtrace__) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "backtrace") + endif() +endif() -# Source Code for dPhysics -file( -GLOB SOURCES_DPHYSICS -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${PROJECT_SOURCE_DIR}/dPhysics/*.cpp -) +add_subdirectory(tests) -if(MSVC) - # Skip warning for invalid conversion from size_t to uint32_t for all targets below for now - add_compile_options("/wd4267") -endif(MSVC) +# Include all of our binary directories +add_subdirectory(dWorldServer) +add_subdirectory(dAuthServer) +add_subdirectory(dChatServer) +add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries -# Our static libraries: -add_library(dCommon ${SOURCES_DCOMMON}) -add_library(dChatFilter ${SOURCES_DCHATFILTER}) -add_library(dDatabase ${SOURCES_DDATABASE}) -add_library(dNet ${SOURCES_DNET}) -add_library(dGame ${SOURCES_DGAME}) -add_library(dZoneManager ${SOURCES_DZM}) -add_library(dPhysics ${SOURCES_DPHYSICS}) -target_link_libraries(dDatabase sqlite3) -target_link_libraries(dNet dCommon) #Needed because otherwise linker errors occur. -target_link_libraries(dCommon ZLIB::ZLIB) -target_link_libraries(dCommon libbcrypt) -target_link_libraries(dDatabase mariadbConnCpp) -target_link_libraries(dNet dDatabase) -target_link_libraries(dGame dDatabase) -target_link_libraries(dChatFilter dDatabase) - -if(WIN32) -target_link_libraries(raknet ws2_32) -endif(WIN32) - -# Our executables: -add_executable(WorldServer ${SOURCES}) -add_executable(AuthServer ${SOURCES_AUTH}) -add_executable(MasterServer ${SOURCES_MASTER}) -add_executable(ChatServer ${SOURCES_CHAT}) - -# Add out precompiled headers +# Add our precompiled headers target_precompile_headers( - dGame PRIVATE - ${HEADERS_DGAME} + dGame PRIVATE + ${HEADERS_DGAME} ) target_precompile_headers( - dZoneManager PRIVATE - ${HEADERS_DZONEMANAGER} + dZoneManager PRIVATE + ${HEADERS_DZONEMANAGER} ) # Need to specify to use the CXX compiler language here or else we get errors including <string>. target_precompile_headers( - dDatabase PRIVATE - "$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>" + dDatabase PRIVATE + "$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>" ) target_precompile_headers( - dCommon PRIVATE - ${HEADERS_DCOMMON} + dCommon PRIVATE + ${HEADERS_DCOMMON} ) target_precompile_headers( - tinyxml2 PRIVATE - "$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>" -) - -# Target libraries to link to: -target_link_libraries(WorldServer dCommon) -target_link_libraries(WorldServer dChatFilter) -target_link_libraries(WorldServer dDatabase) -target_link_libraries(WorldServer dNet) -target_link_libraries(WorldServer dGame) -target_link_libraries(WorldServer dZoneManager) -target_link_libraries(WorldServer dPhysics) -target_link_libraries(WorldServer detour) -target_link_libraries(WorldServer recast) -target_link_libraries(WorldServer raknet) -target_link_libraries(WorldServer mariadbConnCpp) -if(UNIX) -if(NOT APPLE AND __include_backtrace__) -target_link_libraries(WorldServer backtrace) -target_link_libraries(MasterServer backtrace) -target_link_libraries(AuthServer backtrace) -target_link_libraries(ChatServer backtrace) -endif() - -endif(UNIX) -target_link_libraries(WorldServer tinyxml2) - -# Target libraries for Auth: -target_link_libraries(AuthServer dCommon) -target_link_libraries(AuthServer dDatabase) -target_link_libraries(AuthServer dNet) -target_link_libraries(AuthServer raknet) -target_link_libraries(AuthServer mariadbConnCpp) -if(UNIX) -target_link_libraries(AuthServer pthread) -target_link_libraries(AuthServer dl) -endif(UNIX) - -# Target libraries for Master: -target_link_libraries(MasterServer dCommon) -target_link_libraries(MasterServer dDatabase) -target_link_libraries(MasterServer dNet) -target_link_libraries(MasterServer raknet) -target_link_libraries(MasterServer mariadbConnCpp) -if(UNIX) -target_link_libraries(MasterServer pthread) -target_link_libraries(MasterServer dl) -endif(UNIX) - -# Target libraries for Chat: -target_link_libraries(ChatServer dCommon) -target_link_libraries(ChatServer dChatFilter) -target_link_libraries(ChatServer dDatabase) -target_link_libraries(ChatServer dNet) -target_link_libraries(ChatServer raknet) -target_link_libraries(ChatServer mariadbConnCpp) -if(UNIX) -target_link_libraries(ChatServer pthread) -target_link_libraries(ChatServer dl) -endif(UNIX) - -# Compiler flags: -# Disabled deprecated warnings as the MySQL includes have deprecated code in them. -# Disabled misleading indentation as DL_LinkedList from RakNet has a weird indent. -# Disabled no-register -# Disabled unknown pragmas because Linux doesn't understand Windows pragmas. -if(UNIX) - if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC") - endif() - if (__dynamic) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") - endif() - if (__ggdb) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb") - endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC") -endif(UNIX) - -if(WIN32) -add_dependencies(MasterServer WorldServer) -add_dependencies(MasterServer AuthServer) -add_dependencies(MasterServer ChatServer) -endif() - -# Finally, add the tests -add_subdirectory(tests) - + tinyxml2 PRIVATE + "$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>" +) \ No newline at end of file diff --git a/dAuthServer/CMakeLists.txt b/dAuthServer/CMakeLists.txt new file mode 100644 index 00000000..353f2a54 --- /dev/null +++ b/dAuthServer/CMakeLists.txt @@ -0,0 +1,4 @@ +set(DAUTHSERVER_SOURCES "AuthServer.cpp") + +add_executable(AuthServer ${DAUTHSERVER_SOURCES}) +target_link_libraries(AuthServer ${COMMON_LIBRARIES}) diff --git a/dChatFilter/CMakeLists.txt b/dChatFilter/CMakeLists.txt new file mode 100644 index 00000000..24b5e428 --- /dev/null +++ b/dChatFilter/CMakeLists.txt @@ -0,0 +1,4 @@ +set(DCHATFILTER_SOURCES "dChatFilter.cpp") + +add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES}) +target_link_libraries(dChatFilter dDatabase) diff --git a/dChatServer/CMakeLists.txt b/dChatServer/CMakeLists.txt new file mode 100644 index 00000000..948593fb --- /dev/null +++ b/dChatServer/CMakeLists.txt @@ -0,0 +1,6 @@ +set(DCHATSERVER_SOURCES "ChatPacketHandler.cpp" + "ChatServer.cpp" + "PlayerContainer.cpp") + +add_executable(ChatServer ${DCHATSERVER_SOURCES}) +target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter) diff --git a/dCommon/CMakeLists.txt b/dCommon/CMakeLists.txt new file mode 100644 index 00000000..7e047a9c --- /dev/null +++ b/dCommon/CMakeLists.txt @@ -0,0 +1,26 @@ +set(DCOMMON_SOURCES "AMFFormat.cpp" + "AMFFormat_BitStream.cpp" + "BinaryIO.cpp" + "dConfig.cpp" + "Diagnostics.cpp" + "dLogger.cpp" + "GeneralUtils.cpp" + "LDFFormat.cpp" + "MD5.cpp" + "Metrics.cpp" + "NiPoint3.cpp" + "NiQuaternion.cpp" + "SHA512.cpp" + "Type.cpp" + "ZCompression.cpp") + +include_directories(${PROJECT_SOURCE_DIR}/dCommon/) + +add_library(dCommon STATIC ${DCOMMON_SOURCES}) + +target_link_libraries(dCommon libbcrypt) + +if (UNIX) + find_package(ZLIB REQUIRED) + target_link_libraries(dCommon ZLIB::ZLIB) +endif() diff --git a/dCommon/ZCompression.cpp b/dCommon/ZCompression.cpp index 3a66323d..28588bb8 100644 --- a/dCommon/ZCompression.cpp +++ b/dCommon/ZCompression.cpp @@ -1,5 +1,7 @@ #include "ZCompression.h" +#ifndef _WIN32 + #include <zlib.h> namespace ZCompression @@ -70,4 +72,6 @@ namespace ZCompression return(nRet); // -1 or len of output */ } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/dCommon/ZCompression.h b/dCommon/ZCompression.h index ec870fb8..6db2a600 100644 --- a/dCommon/ZCompression.h +++ b/dCommon/ZCompression.h @@ -2,6 +2,10 @@ #include <cstdint> +#include "dPlatforms.h" + +#ifndef DARKFLAME_PLATFORM_WIN32 + namespace ZCompression { int32_t GetMaxCompressedLength(int32_t nLenSrc); @@ -10,3 +14,5 @@ namespace ZCompression int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr); } + +#endif diff --git a/dCommon/dPlatforms.h b/dCommon/dPlatforms.h new file mode 100644 index 00000000..d19e8121 --- /dev/null +++ b/dCommon/dPlatforms.h @@ -0,0 +1,29 @@ +#pragma once + +#if defined(_WIN32) + #define DARKFLAME_PLATFORM_WIN32 +#elif defined(__APPLE__) && defined(__MACH__) + #include <TargetConditionals.h> + #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + #define DARKFLAME_PLATFORM_IOS + #elif TARGET_OS_MAC + #define DARKFLAME_PLATFORM_MACOS + #else + #error unknown Apple operating system + #endif +#elif defined(__unix__) + #define DARKFLAME_PLATFORM_UNIX + #if defined(__ANDROID__) + #define DARKFLAME_PLATFORM_ANDROID + #elif defined(__linux__) + #define DARKFLAME_PLATFORM_LINUX + #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + #define DARKFLAME_PLATFORM_FREEBSD + #elif defined(__CYGWIN__) + #define DARKFLAME_PLATFORM_CYGWIN + #else + #error unknown unix operating system + #endif +#else + #error unknown operating system +#endif \ No newline at end of file diff --git a/dDatabase/CMakeLists.txt b/dDatabase/CMakeLists.txt new file mode 100644 index 00000000..9e55fbe2 --- /dev/null +++ b/dDatabase/CMakeLists.txt @@ -0,0 +1,13 @@ +set(DDATABASE_SOURCES "CDClientDatabase.cpp" + "CDClientManager.cpp" + "Database.cpp" + "MigrationRunner.cpp") + +add_subdirectory(Tables) + +foreach(file ${DDATABASE_TABLES_SOURCES}) + set(DDATABASE_SOURCES ${DDATABASE_SOURCES} "Tables/${file}") +endforeach() + +add_library(dDatabase STATIC ${DDATABASE_SOURCES}) +target_link_libraries(dDatabase sqlite3 mariadbConnCpp) diff --git a/dDatabase/Tables/CMakeLists.txt b/dDatabase/Tables/CMakeLists.txt new file mode 100644 index 00000000..b6a02b02 --- /dev/null +++ b/dDatabase/Tables/CMakeLists.txt @@ -0,0 +1,38 @@ +set(DDATABASE_TABLES_SOURCES "CDActivitiesTable.cpp" + "CDActivityRewardsTable.cpp" + "CDAnimationsTable.cpp" + "CDBehaviorParameterTable.cpp" + "CDBehaviorTemplateTable.cpp" + "CDBrickIDTableTable.cpp" + "CDComponentsRegistryTable.cpp" + "CDCurrencyTableTable.cpp" + "CDDestructibleComponentTable.cpp" + "CDEmoteTable.cpp" + "CDFeatureGatingTable.cpp" + "CDInventoryComponentTable.cpp" + "CDItemComponentTable.cpp" + "CDItemSetSkillsTable.cpp" + "CDItemSetsTable.cpp" + "CDLevelProgressionLookupTable.cpp" + "CDLootMatrixTable.cpp" + "CDLootTableTable.cpp" + "CDMissionEmailTable.cpp" + "CDMissionNPCComponentTable.cpp" + "CDMissionsTable.cpp" + "CDMissionTasksTable.cpp" + "CDMovementAIComponentTable.cpp" + "CDObjectSkillsTable.cpp" + "CDObjectsTable.cpp" + "CDPackageComponentTable.cpp" + "CDPhysicsComponentTable.cpp" + "CDPropertyEntranceComponentTable.cpp" + "CDPropertyTemplateTable.cpp" + "CDProximityMonitorComponentTable.cpp" + "CDRailActivatorComponent.cpp" + "CDRarityTableTable.cpp" + "CDRebuildComponentTable.cpp" + "CDRewardsTable.cpp" + "CDScriptComponentTable.cpp" + "CDSkillBehaviorTable.cpp" + "CDVendorComponentTable.cpp" + "CDZoneTableTable.cpp" PARENT_SCOPE) diff --git a/dGame/CMakeLists.txt b/dGame/CMakeLists.txt new file mode 100644 index 00000000..5acdba31 --- /dev/null +++ b/dGame/CMakeLists.txt @@ -0,0 +1,59 @@ +set(DGAME_SOURCES "Character.cpp" + "Entity.cpp" + "EntityManager.cpp" + "LeaderboardManager.cpp" + "Player.cpp" + "TeamManager.cpp" + "TradingManager.cpp" + "User.cpp" + "UserManager.cpp") + +add_subdirectory(dBehaviors) + +foreach(file ${DGAME_DBEHAVIORS_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dBehaviors/${file}") +endforeach() + +add_subdirectory(dComponents) + +foreach(file ${DGAME_DCOMPONENTS_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dComponents/${file}") +endforeach() + +add_subdirectory(dEntity) + +foreach(file ${DGAME_DENTITY_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dEntity/${file}") +endforeach() + +add_subdirectory(dGameMessages) + +foreach(file ${DGAME_DGAMEMESSAGES_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dGameMessages/${file}") +endforeach() + +add_subdirectory(dInventory) + +foreach(file ${DGAME_DINVENTORY_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dInventory/${file}") +endforeach() + +add_subdirectory(dMission) + +foreach(file ${DGAME_DMISSION_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dMission/${file}") +endforeach() + +add_subdirectory(dUtilities) + +foreach(file ${DGAME_DUTILITIES_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "dUtilities/${file}") +endforeach() + +foreach(file ${DSCRIPT_SOURCES}) + set(DGAME_SOURCES ${DGAME_SOURCES} "${PROJECT_SOURCE_DIR}/dScripts/${file}") +endforeach() + +add_library(dGame STATIC ${DGAME_SOURCES}) + +target_link_libraries(dGame dDatabase) diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt new file mode 100644 index 00000000..fe8e89b8 --- /dev/null +++ b/dGame/dBehaviors/CMakeLists.txt @@ -0,0 +1,51 @@ +set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" + "AndBehavior.cpp" + "ApplyBuffBehavior.cpp" + "AreaOfEffectBehavior.cpp" + "AttackDelayBehavior.cpp" + "BasicAttackBehavior.cpp" + "Behavior.cpp" + "BehaviorBranchContext.cpp" + "BehaviorContext.cpp" + "BehaviorTemplates.cpp" + "BlockBehavior.cpp" + "BuffBehavior.cpp" + "CarBoostBehavior.cpp" + "ChainBehavior.cpp" + "ChangeOrientationBehavior.cpp" + "ChargeUpBehavior.cpp" + "ClearTargetBehavior.cpp" + "DamageAbsorptionBehavior.cpp" + "DamageReductionBehavior.cpp" + "DurationBehavior.cpp" + "EmptyBehavior.cpp" + "EndBehavior.cpp" + "ForceMovementBehavior.cpp" + "HealBehavior.cpp" + "ImaginationBehavior.cpp" + "ImmunityBehavior.cpp" + "InterruptBehavior.cpp" + "JetPackBehavior.cpp" + "KnockbackBehavior.cpp" + "LootBuffBehavior.cpp" + "MovementSwitchBehavior.cpp" + "NpcCombatSkillBehavior.cpp" + "OverTimeBehavior.cpp" + "PlayEffectBehavior.cpp" + "ProjectileAttackBehavior.cpp" + "PullToPointBehavior.cpp" + "RepairBehavior.cpp" + "SkillCastFailedBehavior.cpp" + "SkillEventBehavior.cpp" + "SpawnBehavior.cpp" + "SpawnQuickbuildBehavior.cpp" + "SpeedBehavior.cpp" + "StartBehavior.cpp" + "StunBehavior.cpp" + "SwitchBehavior.cpp" + "SwitchMultipleBehavior.cpp" + "TacArcBehavior.cpp" + "TargetCasterBehavior.cpp" + "TauntBehavior.cpp" + "VentureVisionBehavior.cpp" + "VerifyBehavior.cpp" PARENT_SCOPE) diff --git a/dGame/dComponents/CMakeLists.txt b/dGame/dComponents/CMakeLists.txt new file mode 100644 index 00000000..706395ea --- /dev/null +++ b/dGame/dComponents/CMakeLists.txt @@ -0,0 +1,40 @@ +set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" + "BouncerComponent.cpp" + "BuffComponent.cpp" + "BuildBorderComponent.cpp" + "CharacterComponent.cpp" + "Component.cpp" + "ControllablePhysicsComponent.cpp" + "DestroyableComponent.cpp" + "InventoryComponent.cpp" + "LUPExhibitComponent.cpp" + "MissionComponent.cpp" + "MissionOfferComponent.cpp" + "ModelComponent.cpp" + "ModuleAssemblyComponent.cpp" + "MovementAIComponent.cpp" + "MovingPlatformComponent.cpp" + "PetComponent.cpp" + "PhantomPhysicsComponent.cpp" + "PossessableComponent.cpp" + "PossessorComponent.cpp" + "PropertyComponent.cpp" + "PropertyEntranceComponent.cpp" + "PropertyManagementComponent.cpp" + "PropertyVendorComponent.cpp" + "ProximityMonitorComponent.cpp" + "RacingControlComponent.cpp" + "RailActivatorComponent.cpp" + "RebuildComponent.cpp" + "RenderComponent.cpp" + "RigidbodyPhantomPhysicsComponent.cpp" + "RocketLaunchLupComponent.cpp" + "RocketLaunchpadControlComponent.cpp" + "ScriptedActivityComponent.cpp" + "ShootingGalleryComponent.cpp" + "SimplePhysicsComponent.cpp" + "SkillComponent.cpp" + "SoundTriggerComponent.cpp" + "SwitchComponent.cpp" + "VehiclePhysicsComponent.cpp" + "VendorComponent.cpp" PARENT_SCOPE) diff --git a/dGame/dEntity/CMakeLists.txt b/dGame/dEntity/CMakeLists.txt new file mode 100644 index 00000000..4bb49799 --- /dev/null +++ b/dGame/dEntity/CMakeLists.txt @@ -0,0 +1,2 @@ +set(DGAME_DENTITY_SOURCES "EntityCallbackTimer.cpp" + "EntityTimer.cpp" PARENT_SCOPE) diff --git a/dGame/dGameMessages/CMakeLists.txt b/dGame/dGameMessages/CMakeLists.txt new file mode 100644 index 00000000..3c3cb53f --- /dev/null +++ b/dGame/dGameMessages/CMakeLists.txt @@ -0,0 +1,4 @@ +set(DGAME_DGAMEMESSAGES_SOURCES "GameMessageHandler.cpp" + "GameMessages.cpp" + "PropertyDataMessage.cpp" + "PropertySelectQueryProperty.cpp" PARENT_SCOPE) diff --git a/dGame/dInventory/CMakeLists.txt b/dGame/dInventory/CMakeLists.txt new file mode 100644 index 00000000..60cfca75 --- /dev/null +++ b/dGame/dInventory/CMakeLists.txt @@ -0,0 +1,5 @@ +set(DGAME_DINVENTORY_SOURCES "EquippedItem.cpp" + "Inventory.cpp" + "Item.cpp" + "ItemSet.cpp" + "ItemSetPassiveAbility.cpp" PARENT_SCOPE) diff --git a/dGame/dMission/CMakeLists.txt b/dGame/dMission/CMakeLists.txt new file mode 100644 index 00000000..652c3cb2 --- /dev/null +++ b/dGame/dMission/CMakeLists.txt @@ -0,0 +1,3 @@ +set(DGAME_DMISSION_SOURCES "Mission.cpp" + "MissionPrerequisites.cpp" + "MissionTask.cpp" PARENT_SCOPE) diff --git a/dGame/dUtilities/CMakeLists.txt b/dGame/dUtilities/CMakeLists.txt new file mode 100644 index 00000000..0c848bf4 --- /dev/null +++ b/dGame/dUtilities/CMakeLists.txt @@ -0,0 +1,9 @@ +set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp" + "dLocale.cpp" + "GameConfig.cpp" + "GUID.cpp" + "Loot.cpp" + "Mail.cpp" + "Preconditions.cpp" + "SlashCommandHandler.cpp" + "VanityUtilities.cpp" PARENT_SCOPE) diff --git a/dMasterServer/CMakeLists.txt b/dMasterServer/CMakeLists.txt new file mode 100644 index 00000000..08fc63db --- /dev/null +++ b/dMasterServer/CMakeLists.txt @@ -0,0 +1,10 @@ +set(DMASTERSERVER_SOURCES "InstanceManager.cpp" + "MasterServer.cpp" + "ObjectIDManager.cpp") + +add_executable(MasterServer ${DMASTERSERVER_SOURCES}) +target_link_libraries(MasterServer ${COMMON_LIBRARIES}) + +if(WIN32) + add_dependencies(MasterServer WorldServer AuthServer ChatServer) +endif() diff --git a/dNet/CMakeLists.txt b/dNet/CMakeLists.txt new file mode 100644 index 00000000..938c0449 --- /dev/null +++ b/dNet/CMakeLists.txt @@ -0,0 +1,11 @@ +set(DNET_SOURCES "AuthPackets.cpp" + "ChatPackets.cpp" + "ClientPackets.cpp" + "dServer.cpp" + "MasterPackets.cpp" + "PacketUtils.cpp" + "WorldPackets.cpp" + "ZoneInstanceManager.cpp") + +add_library(dNet STATIC ${DNET_SOURCES}) +target_link_libraries(dNet dCommon dDatabase) diff --git a/dPhysics/CMakeLists.txt b/dPhysics/CMakeLists.txt new file mode 100644 index 00000000..383393cc --- /dev/null +++ b/dPhysics/CMakeLists.txt @@ -0,0 +1,9 @@ +set(DPHYSICS_SOURCES "dpCollisionChecks.cpp" + "dpEntity.cpp" + "dpGrid.cpp" + "dpShapeBase.cpp" + "dpShapeBox.cpp" + "dpShapeSphere.cpp" + "dpWorld.cpp") + +add_library(dPhysics STATIC ${DPHYSICS_SOURCES}) diff --git a/dScripts/CMakeLists.txt b/dScripts/CMakeLists.txt new file mode 100644 index 00000000..1fa177ba --- /dev/null +++ b/dScripts/CMakeLists.txt @@ -0,0 +1,253 @@ +set(DSCRIPT_SOURCES "ActivityManager.cpp" + "ActMine.cpp" + "ActNinjaTurret.cpp" + "ActParadoxPipeFix.cpp" + "ActPlayerDeathTrigger.cpp" + "ActSharkPlayerDeathTrigger.cpp" + "ActVehicleDeathTrigger.cpp" + "AgBugsprayer.cpp" + "AgBusDoor.cpp" + "AgCagedBricksServer.cpp" + "AgDarkSpiderling.cpp" + "AgFans.cpp" + "AgImagSmashable.cpp" + "AgJetEffectServer.cpp" + "AgLaserSensorServer.cpp" + "AgMonumentBirds.cpp" + "AgMonumentLaserServer.cpp" + "AgMonumentRaceCancel.cpp" + "AgMonumentRaceGoal.cpp" + "AgPicnicBlanket.cpp" + "AgPropGuard.cpp" + "AgPropguards.cpp" + "AgQbElevator.cpp" + "AgSalutingNpcs.cpp" + "AgShipPlayerDeathTrigger.cpp" + "AgShipPlayerShockServer.cpp" + "AgSpaceStuff.cpp" + "AgStagePlatforms.cpp" + "AgStromlingProperty.cpp" + "AgSurvivalBuffStation.cpp" + "AgSurvivalMech.cpp" + "AgSurvivalSpiderling.cpp" + "AgSurvivalStromling.cpp" + "AgTurret.cpp" + "AllCrateChicken.cpp" + "AmBlueX.cpp" + "AmBridge.cpp" + "AmConsoleTeleportServer.cpp" + "AmDarklingDragon.cpp" + "AmDarklingMech.cpp" + "AmDrawBridge.cpp" + "AmDropshipComputer.cpp" + "AmScrollReaderServer.cpp" + "AmShieldGenerator.cpp" + "AmShieldGeneratorQuickbuild.cpp" + "AmSkeletonEngineer.cpp" + "AmSkullkinDrill.cpp" + "AmSkullkinDrillStand.cpp" + "AmSkullkinTower.cpp" + "AmTeapotServer.cpp" + "AmTemplateSkillVolume.cpp" + "AnvilOfArmor.cpp" + "BankInteractServer.cpp" + "BaseConsoleTeleportServer.cpp" + "BaseEnemyApe.cpp" + "BaseEnemyMech.cpp" + "BaseFootRaceManager.cpp" + "BaseInteractDropLootServer.cpp" + "BasePropertyServer.cpp" + "BaseRandomServer.cpp" + "BaseSurvivalServer.cpp" + "BaseWavesGenericEnemy.cpp" + "BaseWavesServer.cpp" + "Binoculars.cpp" + "BootyDigServer.cpp" + "BossSpiderQueenEnemyServer.cpp" + "BuccaneerValiantShip.cpp" + "BurningTile.cpp" + "CatapultBaseServer.cpp" + "CatapultBouncerServer.cpp" + "CauldronOfLife.cpp" + "CavePrisonCage.cpp" + "ChooseYourDestinationNsToNt.cpp" + "ClRing.cpp" + "CppScripts.cpp" + "CrabServer.cpp" + "DamagingPets.cpp" + "Darkitect.cpp" + "DLUVanityNPC.cpp" + "EnemyNjBuff.cpp" + "EnemyRoninSpawner.cpp" + "EnemySkeletonSpawner.cpp" + "EnemySpiderSpawner.cpp" + "ExplodingAsset.cpp" + "FallingTile.cpp" + "FireFirstSkillonStartup.cpp" + "FlameJetServer.cpp" + "ForceVolumeServer.cpp" + "FountainOfImagination.cpp" + "FvBounceOverWall.cpp" + "FvBrickPuzzleServer.cpp" + "FvCandle.cpp" + "FvConsoleLeftQuickbuild.cpp" + "FvConsoleRightQuickbuild.cpp" + "FvDragonSmashingGolemQb.cpp" + "FvFacilityBrick.cpp" + "FvFlyingCreviceDragon.cpp" + "FvFong.cpp" + "FvFreeGfNinjas.cpp" + "FvHorsemenTrigger.cpp" + "FvMaelstromCavalry.cpp" + "FvMaelstromDragon.cpp" + "FvNinjaGuard.cpp" + "FvPandaServer.cpp" + "FvPandaSpawnerServer.cpp" + "FvPassThroughWall.cpp" + "FvRaceSmashEggImagineServer.cpp" + "GfApeSmashingQB.cpp" + "GfBanana.cpp" + "GfBananaCluster.cpp" + "GfCampfire.cpp" + "GfCaptainsCannon.cpp" + "GfJailkeepMission.cpp" + "GfJailWalls.cpp" + "GfOrgan.cpp" + "GfTikiTorch.cpp" + "GrowingFlower.cpp" + "HydrantBroken.cpp" + "HydrantSmashable.cpp" + "ImaginationBackpackHealServer.cpp" + "ImaginationShrineServer.cpp" + "ImgBrickConsoleQB.cpp" + "InstanceExitTransferPlayerToLastNonInstance.cpp" + "InvalidScript.cpp" + "LegoDieRoll.cpp" + "Lieutenant.cpp" + "MaestromExtracticatorServer.cpp" + "MailBoxServer.cpp" + "MastTeleport.cpp" + "MinigameTreasureChestServer.cpp" + "MonCoreNookDoors.cpp" + "MonCoreSmashableDoors.cpp" + "NjColeNPC.cpp" + "NjDragonEmblemChestServer.cpp" + "NjEarthDragonPetServer.cpp" + "NjEarthPetServer.cpp" + "NjGarmadonCelebration.cpp" + "NjhubLavaPlayerDeathTrigger.cpp" + "NjIceRailActivator.cpp" + "NjJayMissionItems.cpp" + "NjMonastryBossInstance.cpp" + "NjNPCMissionSpinjitzuServer.cpp" + "NjNyaMissionitems.cpp" + "NjRailActivatorsServer.cpp" + "NjRailPostServer.cpp" + "NjRailSwitch.cpp" + "NjScrollChestServer.cpp" + "NjWuNPC.cpp" + "NPCAddRemoveItem.cpp" + "NpcAgCourseStarter.cpp" + "NpcCowboyServer.cpp" + "NpcEpsilonServer.cpp" + "NpcNjAssistantServer.cpp" + "NpcNpSpacemanBob.cpp" + "NpcPirateServer.cpp" + "NpcWispServer.cpp" + "NsConcertChoiceBuild.cpp" + "NsConcertChoiceBuildManager.cpp" + "NsConcertInstrument.cpp" + "NsConcertQuickBuild.cpp" + "NsGetFactionMissionServer.cpp" + "NsJohnnyMissionServer.cpp" + "NsLegoClubDoor.cpp" + "NsLupTeleport.cpp" + "NsModularBuild.cpp" + "NsQbImaginationStatue.cpp" + "NsTokenConsoleServer.cpp" + "NtAssemblyTubeServer.cpp" + "NtBeamImaginationCollectors.cpp" + "NtCombatChallengeDummy.cpp" + "NtCombatChallengeExplodingDummy.cpp" + "NtCombatChallengeServer.cpp" + "NtConsoleTeleportServer.cpp" + "NtDarkitectRevealServer.cpp" + "NtDirtCloudServer.cpp" + "NtDukeServer.cpp" + "NtFactionSpyServer.cpp" + "NtHaelServer.cpp" + "NtImagBeamBuffer.cpp" + "NtOverbuildServer.cpp" + "NtParadoxPanelServer.cpp" + "NtParadoxTeleServer.cpp" + "NtSentinelWalkwayServer.cpp" + "NtSleepingGuard.cpp" + "NtVandaServer.cpp" + "NtVentureCannonServer.cpp" + "NtVentureSpeedPadServer.cpp" + "NtXRayServer.cpp" + "PersonalFortress.cpp" + "PetDigBuild.cpp" + "PetDigServer.cpp" + "PetFromDigServer.cpp" + "PetFromObjectServer.cpp" + "PropertyBankInteract.cpp" + "PropertyDeathPlane.cpp" + "PropertyDevice.cpp" + "PropertyFXDamage.cpp" + "PropertyPlatform.cpp" + "PrSeagullFly.cpp" + "PrWhistle.cpp" + "QbEnemyStunner.cpp" + "RaceImagineCrateServer.cpp" + "RaceImaginePowerup.cpp" + "RaceMaelstromGeiser.cpp" + "RaceSmashServer.cpp" + "RainOfArrows.cpp" + "RandomSpawnerFin.cpp" + "RandomSpawnerPit.cpp" + "RandomSpawnerStr.cpp" + "RandomSpawnerZip.cpp" + "RemoveRentalGear.cpp" + "RockHydrantBroken.cpp" + "RockHydrantSmashable.cpp" + "ScriptComponent.cpp" + "ScriptedPowerupSpawner.cpp" + "SGCannon.cpp" + "SpawnGryphonServer.cpp" + "SpawnLionServer.cpp" + "SpawnPetBaseServer.cpp" + "SpawnSaberCatServer.cpp" + "SpawnShrakeServer.cpp" + "SpawnStegoServer.cpp" + "SpecialImaginePowerupSpawner.cpp" + "SpiderBossTreasureChestServer.cpp" + "SsModularBuildServer.cpp" + "StinkyFishTarget.cpp" + "StoryBoxInteractServer.cpp" + "Sunflower.cpp" + "TokenConsoleServer.cpp" + "TouchMissionUpdateServer.cpp" + "TreasureChestDragonServer.cpp" + "TriggerAmbush.cpp" + "VeBricksampleServer.cpp" + "VeEpsilonServer.cpp" + "VeMech.cpp" + "VeMissionConsole.cpp" + "WaveBossApe.cpp" + "WaveBossHammerling.cpp" + "WaveBossHorsemen.cpp" + "WaveBossSpiderling.cpp" + "WhFans.cpp" + "WildAmbients.cpp" + "WishingWellServer.cpp" + "ZoneAgMedProperty.cpp" + "ZoneAgProperty.cpp" + "ZoneAgSpiderQueen.cpp" + "ZoneAgSurvival.cpp" + "ZoneFvProperty.cpp" + "ZoneGfProperty.cpp" + "ZoneNsMedProperty.cpp" + "ZoneNsProperty.cpp" + "ZoneNsWaves.cpp" + "ZoneSGServer.cpp" PARENT_SCOPE) diff --git a/dWorldServer/CMakeLists.txt b/dWorldServer/CMakeLists.txt new file mode 100644 index 00000000..3df808a2 --- /dev/null +++ b/dWorldServer/CMakeLists.txt @@ -0,0 +1,6 @@ +set(DWORLDSERVER_SOURCES "ObjectIDManager.cpp" + "PerformanceManager.cpp" + "WorldServer.cpp") + +add_executable(WorldServer ${DWORLDSERVER_SOURCES}) +target_link_libraries(WorldServer ${COMMON_LIBRARIES} dChatFilter dGame dZoneManager dPhysics detour recast tinyxml2) diff --git a/dZoneManager/CMakeLists.txt b/dZoneManager/CMakeLists.txt new file mode 100644 index 00000000..1dd3841b --- /dev/null +++ b/dZoneManager/CMakeLists.txt @@ -0,0 +1,6 @@ +set(DZONEMANAGER_SOURCES "dZoneManager.cpp" + "Level.cpp" + "Spawner.cpp" + "Zone.cpp") + +add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 85f4bda4..b0e2c28d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,17 +1,13 @@ # create the testing file and list of tests create_test_sourcelist (Tests - CommonCxxTests.cpp - TestNiPoint3.cpp - TestLDFFormat.cpp + CommonCxxTests.cpp + TestNiPoint3.cpp + TestLDFFormat.cpp ) - + # add the executable add_executable (CommonCxxTests ${Tests}) -target_link_libraries(CommonCxxTests dCommon raknet) - -if(WIN32) - target_link_libraries(CommonCxxTests ws2_32) -endif(WIN32) +target_link_libraries(CommonCxxTests ${COMMON_LIBRARIES}) # remove the test driver source file set (TestsToRun ${Tests}) @@ -19,7 +15,7 @@ remove (TestsToRun CommonCxxTests.cpp) # Add all the ADD_TEST for each test foreach (test ${TestsToRun}) - get_filename_component (TName ${test} NAME_WE) - add_test (NAME ${TName} COMMAND CommonCxxTests ${TName}) - set_property(TEST ${TName} PROPERTY ENVIRONMENT CTEST_OUTPUT_ON_FAILURE=1) + get_filename_component (TName ${test} NAME_WE) + add_test (NAME ${TName} COMMAND CommonCxxTests ${TName}) + set_property(TEST ${TName} PROPERTY ENVIRONMENT CTEST_OUTPUT_ON_FAILURE=1) endforeach () diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index ce24ecd3..119ce4fd 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -1,50 +1,50 @@ # Source Code for raknet file( -GLOB SOURCES_RAKNET -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${CMAKE_CURRENT_SOURCE_DIR}/raknet/Source/*.cpp + GLOB SOURCES_RAKNET + LIST_DIRECTORIES false + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR}/raknet/Source/*.cpp ) # Source Code for recast file( -GLOB SOURCES_RECAST -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${CMAKE_CURRENT_SOURCE_DIR}/recastnavigation/Recast/Source/*.cpp + GLOB SOURCES_RECAST + LIST_DIRECTORIES false + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR}/recastnavigation/Recast/Source/*.cpp ) # Source Code for detour file( -GLOB SOURCES_DETOUR -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${CMAKE_CURRENT_SOURCE_DIR}/recastnavigation/Detour/Source/*.cpp + GLOB SOURCES_DETOUR + LIST_DIRECTORIES false + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR}/recastnavigation/Detour/Source/*.cpp ) # Source Code for tinyxml2 file( -GLOB SOURCES_TINYXML2 -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${CMAKE_CURRENT_SOURCE_DIR}/tinyxml2/tinyxml2.cpp + GLOB SOURCES_TINYXML2 + LIST_DIRECTORIES false + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR}/tinyxml2/tinyxml2.cpp ) # Source Code for libbcrypt file( -GLOB SOURCES_LIBBCRYPT -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/*.c -${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/src/*.c + GLOB SOURCES_LIBBCRYPT + LIST_DIRECTORIES false + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/src/*.c ) file( -GLOB SOURCES_SQLITE3 -LIST_DIRECTORIES false -RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" -${CMAKE_CURRENT_SOURCE_DIR}/SQLite/*.cpp -${CMAKE_CURRENT_SOURCE_DIR}/SQLite/*.c + GLOB SOURCES_SQLITE3 + LIST_DIRECTORIES false + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR}/SQLite/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/SQLite/*.c ) # mariadb connector cpp @@ -147,7 +147,6 @@ else() # Build from source set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/RelWithDebInfo/${MARIADB_SHARED_LIBRARY_NAME}") set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}/$<CONFIG>") set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb/RelWithDebInfo") - message(STATUS "1 ${CMAKE_SOURCE_DIR}") else() set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}") set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}") @@ -179,16 +178,19 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists. file(REMOVE "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt") endif() +# Create mariadb connector library object add_library(mariadbConnCpp SHARED IMPORTED GLOBAL) set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_LOCATION ${MARIADB_SHARED_LIBRARY_LOCATION}) + if(WIN32) set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_IMPLIB ${MARIADB_IMPLIB_LOCATION}) endif() + +# Add directories to include lists target_include_directories(mariadbConnCpp INTERFACE ${MARIADB_INCLUDE_DIR}) add_dependencies(mariadbConnCpp mariadb_connector_cpp) -# 3rdparty static libraries: -#add_library(zlib ${SOURCES_ZLIB}) +# Create our third party library objects add_library(raknet ${SOURCES_RAKNET}) add_library(tinyxml2 ${SOURCES_TINYXML2}) add_library(detour ${SOURCES_DETOUR}) @@ -196,11 +198,39 @@ add_library(recast ${SOURCES_RECAST}) add_library(libbcrypt ${SOURCES_LIBBCRYPT}) add_library(sqlite3 ${SOURCES_SQLITE3}) -if(UNIX) -target_link_libraries(sqlite3 pthread dl m) +if(WIN32) + # Link Win Sockets 2 to RakNet + target_link_libraries(raknet ws2_32) +elseif(UNIX) + # Add warning disable flags and link Unix libraries to sqlite3 + target_link_libraries(sqlite3 pthread dl m) -# -Wno-unused-result -Wno-unknown-pragmas -fpermissive -target_compile_options(sqlite3 PRIVATE "-Wno-return-local-addr" "-Wno-maybe-uninitialized") -target_compile_options(raknet PRIVATE "-Wno-write-strings" "-Wformat-overflow=0" "-Wformat=0") -target_compile_options(libbcrypt PRIVATE "-Wno-implicit-function-declaration" "-Wno-int-conversion") -endif(UNIX) \ No newline at end of file + # -Wno-unused-result -Wno-unknown-pragmas -fpermissive + target_compile_options(sqlite3 PRIVATE "-Wno-return-local-addr" "-Wno-maybe-uninitialized") + target_compile_options(raknet PRIVATE "-Wno-write-strings" "-Wformat-overflow=0" "-Wformat=0") + target_compile_options(libbcrypt PRIVATE "-Wno-implicit-function-declaration" "-Wno-int-conversion") +endif() + +# Download Backtrace if configured +if(UNIX AND NOT APPLE) + include(FetchContent) + if (__include_backtrace__ AND __compile_backtrace__) + FetchContent_Declare( + backtrace + GIT_REPOSITORY https://github.com/ianlancetaylor/libbacktrace.git + ) + + FetchContent_MakeAvailable(backtrace) + + if (NOT EXISTS ${backtrace_SOURCE_DIR}/.libs) + set(backtrace_make_cmd "${backtrace_SOURCE_DIR}/configure --prefix=\"/usr\" --enable-shared --with-system-libunwind") + + execute_process( + COMMAND bash -c "cd ${backtrace_SOURCE_DIR} && ${backtrace_make_cmd} && make && cd ${CMAKE_SOURCE_DIR}" + ) + endif() + + link_directories(${backtrace_SOURCE_DIR}/.libs/) + include_directories(${backtrace_SOURCE_DIR}) + endif() +endif() \ No newline at end of file From f5ae5aa13e34d2ed879497f9c8cf5592a213476d Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 16 Jul 2022 18:21:35 -0700 Subject: [PATCH 93/98] Address timers being iterated through poorly (#646) * Fix timers * Update Entity.cpp * Fix timers Fix timers Remove debug logs remove _dynamic * I like to move it move it --- dGame/Entity.cpp | 26 +++++++++++++++++++------- dGame/Entity.h | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 68277cd8..93fa0609 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1201,17 +1201,21 @@ void Entity::UpdateXMLDoc(tinyxml2::XMLDocument* doc) { } void Entity::Update(const float deltaTime) { - for (int i = 0; i < m_Timers.size(); i++) { - m_Timers[i]->Update(deltaTime); - if (m_Timers[i]->GetTime() <= 0) { - const auto timerName = m_Timers[i]->GetName(); + uint32_t timerPosition; + timerPosition = 0; + while (timerPosition < m_Timers.size()) { + m_Timers[timerPosition]->Update(deltaTime); + if (m_Timers[timerPosition]->GetTime() <= 0) { + const auto timerName = m_Timers[timerPosition]->GetName(); - delete m_Timers[i]; - m_Timers.erase(m_Timers.begin() + i); + delete m_Timers[timerPosition]; + m_Timers.erase(m_Timers.begin() + timerPosition); for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { script->OnTimerDone(this, timerName); } + } else { + timerPosition++; } } @@ -1223,6 +1227,14 @@ void Entity::Update(const float deltaTime) { m_CallbackTimers.erase(m_CallbackTimers.begin() + i); } } + + // Add pending timers to the list of timers so they start next tick. + if (m_PendingTimers.size() > 0) { + for (auto namedTimer : m_PendingTimers) { + m_Timers.push_back(namedTimer); + } + m_PendingTimers.clear(); + } if (IsSleeping()) { @@ -1661,7 +1673,7 @@ void Entity::RemoveChild(Entity* child) { void Entity::AddTimer(std::string name, float time) { EntityTimer* timer = new EntityTimer(name, time); - m_Timers.push_back(timer); + m_PendingTimers.push_back(timer); } void Entity::AddCallbackTimer(float time, std::function<void()> callback) { diff --git a/dGame/Entity.h b/dGame/Entity.h index c804deaa..ca12b355 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -309,6 +309,7 @@ protected: std::unordered_map<int32_t, Component*> m_Components; //The int is the ID of the component std::vector<EntityTimer*> m_Timers; + std::vector<EntityTimer*> m_PendingTimers; std::vector<EntityCallbackTimer*> m_CallbackTimers; bool m_ShouldDestroyAfterUpdate = false; From 9287e5bc4bd61fb469e90ef8c476d754a760df06 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sat, 16 Jul 2022 20:36:09 -0500 Subject: [PATCH 94/98] Split itemType enum into it's own header (#647) * Split itemType enum into it's own header add mount item type * fix whitespace --- dCommon/dCommonVars.h | 27 ------------ dCommon/eItemType.h | 36 ++++++++++++++++ dGame/dComponents/InventoryComponent.cpp | 15 +++---- dGame/dComponents/InventoryComponent.h | 4 +- dGame/dInventory/Inventory.cpp | 52 ++++++++++++------------ 5 files changed, 74 insertions(+), 60 deletions(-) create mode 100644 dCommon/eItemType.h diff --git a/dCommon/dCommonVars.h b/dCommon/dCommonVars.h index e941413b..c458b9fb 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dCommonVars.h @@ -440,33 +440,6 @@ enum eInventoryType : uint32_t { INVALID // made up, for internal use!!! }; -enum eItemType : int32_t { - ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type - ITEM_TYPE_BRICK = 1, //!< A brick - ITEM_TYPE_HAT = 2, //!< A hat / head item - ITEM_TYPE_HAIR = 3, //!< A hair item - ITEM_TYPE_NECK = 4, //!< A neck item - ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item - ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item - ITEM_TYPE_LEGS = 7, //!< A pants item - ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item - ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item - ITEM_TYPE_BEHAVIOR = 10, //!< A behavior - ITEM_TYPE_PROPERTY = 11, //!< A property - ITEM_TYPE_MODEL = 12, //!< A model - ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item - ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item - ITEM_TYPE_CHEST = 15, //!< A chest item - ITEM_TYPE_EGG = 16, //!< An egg - ITEM_TYPE_PET_FOOD = 17, //!< A pet food item - ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item - ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item - ITEM_TYPE_PACKAGE = 20, //!< A package - ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model - ITEM_TYPE_VEHICLE = 22, //!< A vehicle - ITEM_TYPE_CURRENCY = 23 //!< Currency -}; - enum eRebuildState : uint32_t { REBUILD_OPEN, REBUILD_COMPLETED = 2, diff --git a/dCommon/eItemType.h b/dCommon/eItemType.h new file mode 100644 index 00000000..453e8737 --- /dev/null +++ b/dCommon/eItemType.h @@ -0,0 +1,36 @@ +#pragma once + +#ifndef __EITEMTYPE__H__ +#define __EITEMTYPE__H__ + +#include <cstdint> + +enum class eItemType : int32_t { + ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type + ITEM_TYPE_BRICK = 1, //!< A brick + ITEM_TYPE_HAT = 2, //!< A hat / head item + ITEM_TYPE_HAIR = 3, //!< A hair item + ITEM_TYPE_NECK = 4, //!< A neck item + ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item + ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item + ITEM_TYPE_LEGS = 7, //!< A pants item + ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item + ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item + ITEM_TYPE_BEHAVIOR = 10, //!< A behavior + ITEM_TYPE_PROPERTY = 11, //!< A property + ITEM_TYPE_MODEL = 12, //!< A model + ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item + ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item + ITEM_TYPE_CHEST = 15, //!< A chest item + ITEM_TYPE_EGG = 16, //!< An egg + ITEM_TYPE_PET_FOOD = 17, //!< A pet food item + ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item + ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item + ITEM_TYPE_PACKAGE = 20, //!< A package + ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model + ITEM_TYPE_VEHICLE = 22, //!< A vehicle + ITEM_TYPE_CURRENCY = 23, //!< Currency + ITEM_TYPE_MOUNT = 24 //!< A Mount +}; + +#endif //!__EITEMTYPE__H__ \ No newline at end of file diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8ae6e93f..0772482c 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -25,6 +25,7 @@ #include "PropertyManagementComponent.h" #include "DestroyableComponent.h" #include "dConfig.h" +#include "eItemType.h" InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) { @@ -1024,13 +1025,13 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) return; } - if (type == ITEM_TYPE_LOOT_MODEL || type == ITEM_TYPE_VEHICLE) + if (type == eItemType::ITEM_TYPE_LOOT_MODEL || type == eItemType::ITEM_TYPE_VEHICLE) { return; } } - if (type != ITEM_TYPE_LOOT_MODEL && type != ITEM_TYPE_MODEL) + if (type != eItemType::ITEM_TYPE_LOOT_MODEL && type != eItemType::ITEM_TYPE_MODEL) { if (!item->GetBound() && !item->GetPreconditionExpression()->Check(m_Parent)) { @@ -1411,15 +1412,15 @@ void InventoryComponent::RemoveDatabasePet(LWOOBJID id) BehaviorSlot InventoryComponent::FindBehaviorSlot(const eItemType type) { switch (type) { - case ITEM_TYPE_HAT: + case eItemType::ITEM_TYPE_HAT: return BehaviorSlot::Head; - case ITEM_TYPE_NECK: + case eItemType::ITEM_TYPE_NECK: return BehaviorSlot::Neck; - case ITEM_TYPE_LEFT_HAND: + case eItemType::ITEM_TYPE_LEFT_HAND: return BehaviorSlot::Offhand; - case ITEM_TYPE_RIGHT_HAND: + case eItemType::ITEM_TYPE_RIGHT_HAND: return BehaviorSlot::Primary; - case ITEM_TYPE_CONSUMABLE: + case eItemType::ITEM_TYPE_CONSUMABLE: return BehaviorSlot::Consumable; default: return BehaviorSlot::Invalid; diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 1fda5942..a7d3f8ea 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #ifndef INVENTORYCOMPONENT_H #define INVENTORYCOMPONENT_H @@ -25,6 +25,8 @@ class ItemSet; typedef std::map<std::string, EquippedItem> EquipmentMap; +enum class eItemType : int32_t; + /** * Handles the inventory of entity, including the items they possess and have equipped. An entity can have inventories * of different types, each type representing a different group of items, see `eInventoryType` for a list of diff --git a/dGame/dInventory/Inventory.cpp b/dGame/dInventory/Inventory.cpp index 6e8be6aa..53ff37b4 100644 --- a/dGame/dInventory/Inventory.cpp +++ b/dGame/dInventory/Inventory.cpp @@ -1,7 +1,8 @@ -#include "Inventory.h" +#include "Inventory.h" #include "GameMessages.h" #include "Game.h" #include "Item.h" +#include "eItemType.h" std::vector<LOT> Inventory::m_GameMasterRestrictedItems = { 1727, // GM Only - JetPack @@ -274,40 +275,41 @@ eInventoryType Inventory::FindInventoryTypeForLot(const LOT lot) const auto itemType = static_cast<eItemType>(itemComponent.itemType); switch (itemType) { - case ITEM_TYPE_BRICK: + case eItemType::ITEM_TYPE_BRICK: return BRICKS; - case ITEM_TYPE_BEHAVIOR: + case eItemType::ITEM_TYPE_BEHAVIOR: return BEHAVIORS; - case ITEM_TYPE_PROPERTY: + case eItemType::ITEM_TYPE_PROPERTY: return PROPERTY_DEEDS; - case ITEM_TYPE_MODEL: - case ITEM_TYPE_VEHICLE: - case ITEM_TYPE_LOOT_MODEL: + case eItemType::ITEM_TYPE_MODEL: + case eItemType::ITEM_TYPE_VEHICLE: + case eItemType::ITEM_TYPE_LOOT_MODEL: + case eItemType::ITEM_TYPE_MOUNT: return MODELS; - case ITEM_TYPE_HAT: - case ITEM_TYPE_HAIR: - case ITEM_TYPE_NECK: - case ITEM_TYPE_LEFT_HAND: - case ITEM_TYPE_RIGHT_HAND: - case ITEM_TYPE_LEGS: - case ITEM_TYPE_LEFT_TRINKET: - case ITEM_TYPE_RIGHT_TRINKET: - case ITEM_TYPE_COLLECTIBLE: - case ITEM_TYPE_CONSUMABLE: - case ITEM_TYPE_CHEST: - case ITEM_TYPE_EGG: - case ITEM_TYPE_PET_FOOD: - case ITEM_TYPE_PET_INVENTORY_ITEM: - case ITEM_TYPE_PACKAGE: - case ITEM_TYPE_CURRENCY: + case eItemType::ITEM_TYPE_HAT: + case eItemType::ITEM_TYPE_HAIR: + case eItemType::ITEM_TYPE_NECK: + case eItemType::ITEM_TYPE_LEFT_HAND: + case eItemType::ITEM_TYPE_RIGHT_HAND: + case eItemType::ITEM_TYPE_LEGS: + case eItemType::ITEM_TYPE_LEFT_TRINKET: + case eItemType::ITEM_TYPE_RIGHT_TRINKET: + case eItemType::ITEM_TYPE_COLLECTIBLE: + case eItemType::ITEM_TYPE_CONSUMABLE: + case eItemType::ITEM_TYPE_CHEST: + case eItemType::ITEM_TYPE_EGG: + case eItemType::ITEM_TYPE_PET_FOOD: + case eItemType::ITEM_TYPE_PET_INVENTORY_ITEM: + case eItemType::ITEM_TYPE_PACKAGE: + case eItemType::ITEM_TYPE_CURRENCY: return ITEMS; - case ITEM_TYPE_QUEST_OBJECT: - case ITEM_TYPE_UNKNOWN: + case eItemType::ITEM_TYPE_QUEST_OBJECT: + case eItemType::ITEM_TYPE_UNKNOWN: default: return HIDDEN; } From 77d35019cc7258229a99934ed41d2efca48ccb88 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sun, 17 Jul 2022 04:40:46 +0100 Subject: [PATCH 95/98] Replace the usage of RakString (#648) --- dChatServer/ChatPacketHandler.cpp | 22 +++++++-------- dChatServer/PlayerContainer.cpp | 26 +++++++++++------- dChatServer/PlayerContainer.h | 4 +-- dGame/dUtilities/SlashCommandHandler.cpp | 12 ++++++--- dMasterServer/MasterServer.cpp | 34 +++++++++++++++++------- dNet/MasterPackets.cpp | 12 ++++++--- dWorldServer/WorldServer.cpp | 29 +++++++++++++------- 7 files changed, 91 insertions(+), 48 deletions(-) diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index b84c3eef..4f055121 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -123,7 +123,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { requestee.reset(new PlayerData()); // Setup the needed info since you can add a best friend offline. requestee->playerID = friendDataCandidate.friendID; - requestee->playerName = RakNet::RakString(friendDataCandidate.friendName.c_str()); + requestee->playerName = friendDataCandidate.friendName; requestee->zoneID = LWOZONEID(); FriendData requesteeFriendData{}; @@ -147,7 +147,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { std::unique_ptr<sql::ResultSet> result(nameQuery->executeQuery()); requestee.reset(new PlayerData()); - requestee->playerName = RakNet::RakString(playerName.c_str()); + requestee->playerName = playerName; SendFriendResponse(requestor, requestee.get(), result->next() ? AddFriendResponseType::NOTONLINE : AddFriendResponseType::INVALIDCHARACTER); return; @@ -384,7 +384,7 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) if (playerContainer.GetIsMuted(sender)) return; - const auto senderName = std::string(sender->playerName.C_String()); + const auto senderName = std::string(sender->playerName.c_str()); inStream.SetReadOffset(0x14 * 8); @@ -407,7 +407,7 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) if (otherMember == nullptr) return; - const auto otherName = std::string(otherMember->playerName.C_String()); + const auto otherName = std::string(otherMember->playerName.c_str()); CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ROUTE_TO_PLAYER); @@ -443,8 +443,8 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { if (playerContainer.GetIsMuted(goonA)) return; - std::string goonAName = goonA->playerName.C_String(); - std::string goonBName = goonB->playerName.C_String(); + std::string goonAName = goonA->playerName.c_str(); + std::string goonBName = goonB->playerName.c_str(); //To the sender: { @@ -720,7 +720,7 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) playerContainer.TeamStatusUpdate(team); - const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(data->playerName.C_String())); + const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(data->playerName.c_str())); for (const auto memberId : team->memberIDs) { @@ -750,7 +750,7 @@ void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) //portion that will get routed: PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_TEAM_INVITE); - PacketUtils::WritePacketWString(sender->playerName.C_String(), 33, &bitStream); + PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); bitStream.Write(sender->playerID); SystemAddress sysAddr = receiver->sysAddr; @@ -936,7 +936,7 @@ void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* pla PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_UPDATE_FRIEND_NOTIFY); bitStream.Write<uint8_t>(notifyType); - std::string playerName = playerData->playerName.C_String(); + std::string playerName = playerData->playerName.c_str(); PacketUtils::WritePacketWString(playerName, 33, &bitStream); @@ -976,7 +976,7 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send //portion that will get routed: PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_ADD_FRIEND_REQUEST); - PacketUtils::WritePacketWString(sender->playerName.C_String(), 33, &bitStream); + PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side. SystemAddress sysAddr = receiver->sysAddr; @@ -996,7 +996,7 @@ void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sen // For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver. bitStream.Write<uint8_t>(responseCode != AddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); // Then write the player name - PacketUtils::WritePacketWString(sender->playerName.C_String(), 33, &bitStream); + PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); // Then if this is an acceptance code, write the following extra info. if (responseCode == AddFriendResponseType::ACCEPTED) { bitStream.Write(sender->playerID); diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index c5da3a7f..1517153d 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -20,17 +20,25 @@ PlayerContainer::~PlayerContainer() { void PlayerContainer::InsertPlayer(Packet* packet) { CINSTREAM; PlayerData* data = new PlayerData(); + inStream.SetReadOffset(inStream.GetReadOffset() + 64); inStream.Read(data->playerID); - inStream.Read(data->playerID); - inStream.Read(data->playerName); + + uint32_t len; + inStream.Read<uint32_t>(len); + + for (int i = 0; i < len; i++) { + char character; inStream.Read<char>(character); + data->playerName += character; + } + inStream.Read(data->zoneID); inStream.Read(data->muteExpire); data->sysAddr = packet->systemAddress; - mNames[data->playerID] = GeneralUtils::ASCIIToUTF16(std::string(data->playerName.C_String())); + mNames[data->playerID] = GeneralUtils::ASCIIToUTF16(std::string(data->playerName.c_str())); mPlayers.insert(std::make_pair(data->playerID, data)); - Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i\n", data->playerName.C_String(), data->playerID, data->zoneID.GetMapID()); + Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i\n", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID()); auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);"); @@ -64,7 +72,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) { if (team != nullptr) { - const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(player->playerName.C_String())); + const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(player->playerName.c_str())); for (const auto memberId : team->memberIDs) { @@ -232,8 +240,8 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) if (leader == nullptr || member == nullptr) return; - const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.C_String())); - const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(member->playerName.C_String())); + const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.c_str())); + const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(member->playerName.c_str())); ChatPacketHandler::SendTeamInviteConfirm(member, false, leader->playerID, leader->zoneID, team->lootFlag, 0, 0, leaderName); @@ -337,7 +345,7 @@ void PlayerContainer::DisbandTeam(TeamData* team) if (otherMember == nullptr) continue; - const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(otherMember->playerName.C_String())); + const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(otherMember->playerName.c_str())); ChatPacketHandler::SendTeamSetLeader(otherMember, LWOOBJID_EMPTY); ChatPacketHandler::SendTeamRemovePlayer(otherMember, true, false, false, team->local, team->leaderID, otherMember->playerID, memberName); @@ -360,7 +368,7 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) if (leader == nullptr) return; - const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.C_String())); + const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.c_str())); for (const auto memberId : team->memberIDs) { diff --git a/dChatServer/PlayerContainer.h b/dChatServer/PlayerContainer.h index b1e1defd..9216a361 100644 --- a/dChatServer/PlayerContainer.h +++ b/dChatServer/PlayerContainer.h @@ -9,7 +9,7 @@ struct PlayerData { LWOOBJID playerID; - RakNet::RakString playerName; + std::string playerName; SystemAddress sysAddr; LWOZONEID zoneID; std::vector<FriendData> friends; @@ -46,7 +46,7 @@ public: PlayerData* GetPlayerData(const std::string& playerName) { for (auto player : mPlayers) { if (player.second) { - std::string pn = player.second->playerName.C_String(); + std::string pn = player.second->playerName.c_str(); if (pn == playerName) return player.second; } } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index ae8e7969..74d44ce7 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -2017,11 +2017,15 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ANNOUNCEMENT); - RakNet::RakString rsTitle(title.c_str()); - RakNet::RakString rsMsg(message.c_str()); + bitStream.Write<uint32_t>(title.size()); + for (auto character : title) { + bitStream.Write<char>(character); + } - bitStream.Write(rsTitle); - bitStream.Write(rsMsg); + bitStream.Write<uint32_t>(message.size()); + for (auto character : message) { + bitStream.Write<char>(character); + } Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 1cfd7d4a..2e881934 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -497,7 +497,10 @@ void HandlePacket(Packet* packet) { CBITSTREAM; PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_NEW_SESSION_ALERT); bitStream.Write(sessionKey); - bitStream.Write(RakNet::RakString(username.c_str())); + bitStream.Write<uint32_t>(username.size()); + for (auto character : username) { + bitStream.Write(character); + } SEND_PACKET_BROADCAST; break; @@ -572,14 +575,20 @@ void HandlePacket(Packet* packet) { uint32_t mapId; LWOCLONEID cloneId; - RakNet::RakString password; + std::string password; inStream.Read(mapId); inStream.Read(cloneId); - inStream.Read(password); - Game::im->CreatePrivateInstance(mapId, cloneId, - password.C_String()); + uint32_t len; + inStream.Read<uint32_t>(len); + for (int i = 0; len > i; i++) { + char character; + inStream.Read<char>(character); + password += character; + } + + Game::im->CreatePrivateInstance(mapId, cloneId, password.c_str()); break; } @@ -591,15 +600,22 @@ void HandlePacket(Packet* packet) { uint64_t requestID = 0; uint8_t mythranShift = false; - RakNet::RakString password; + std::string password; inStream.Read(requestID); inStream.Read(mythranShift); - inStream.Read(password); + + uint32_t len; + inStream.Read<uint32_t>(len); - auto* instance = Game::im->FindPrivateInstance(password.C_String()); + for (int i = 0; i < len; i++) { + char character; inStream.Read<char>(character); + password += character; + } - Game::logger->Log( "MasterServer", "Join private zone: %llu %d %s %p\n", requestID, mythranShift, password.C_String(), instance); + auto* instance = Game::im->FindPrivateInstance(password.c_str()); + + Game::logger->Log( "MasterServer", "Join private zone: %llu %d %s %p\n", requestID, mythranShift, password.c_str(), instance); if (instance == nullptr) { return; diff --git a/dNet/MasterPackets.cpp b/dNet/MasterPackets.cpp index 96ad1b81..bf58d71c 100644 --- a/dNet/MasterPackets.cpp +++ b/dNet/MasterPackets.cpp @@ -43,8 +43,10 @@ void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint bitStream.Write(zoneID); bitStream.Write(cloneID); - RakNet::RakString passwd(password.c_str()); - bitStream.Write(passwd); + bitStream.Write<uint32_t>(password.size()); + for (auto character : password) { + bitStream.Write<char>(character); + } server->SendToMaster(&bitStream); } @@ -56,8 +58,10 @@ void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, bitStream.Write(requestID); bitStream.Write(static_cast<uint8_t>(mythranShift)); - RakNet::RakString passwd(password.c_str()); - bitStream.Write(passwd); + bitStream.Write<uint32_t>(password.size()); + for (auto character : password) { + bitStream.Write<char>(character); + } server->SendToMaster(&bitStream); } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 330263ed..9e5ff8c1 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -546,18 +546,31 @@ void HandlePacketChat(Packet* packet) { LWOOBJID header; inStream.Read(header); - RakNet::RakString title; - RakNet::RakString msg; + std::string title; + std::string msg; - inStream.Read(title); - inStream.Read(msg); + uint32_t len; + inStream.Read<uint32_t>(len); + for (int i = 0; len > i; i++) { + char character; + inStream.Read<char>(character); + title += character; + } + + len = 0; + inStream.Read<uint32_t>(len); + for (int i = 0; len > i; i++) { + char character; + inStream.Read<char>(character); + msg += character; + } //Send to our clients: AMFArrayValue args; auto* titleValue = new AMFStringValue(); - titleValue->SetStringValue(title.C_String()); + titleValue->SetStringValue(title.c_str()); auto* messageValue = new AMFStringValue(); - messageValue->SetStringValue(msg.C_String()); + messageValue->SetStringValue(msg.c_str()); args.InsertValue("title", titleValue); args.InsertValue("message", messageValue); @@ -1122,14 +1135,12 @@ void HandlePacket(Packet* packet) { CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_PLAYER_ADDED_NOTIFICATION); bitStream.Write(player->GetObjectID()); - bitStream.Write<uint16_t>(playerName.size()); + bitStream.Write<uint32_t>(playerName.size()); for (size_t i = 0; i < playerName.size(); i++) { bitStream.Write(playerName[i]); } - //bitStream.Write(playerName); - auto zone = dZoneManager::Instance()->GetZone()->GetZoneID(); bitStream.Write(zone.GetMapID()); bitStream.Write(zone.GetInstanceID()); From c689b3d3d1a6af247c5c72da25162dc32a23b852 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 16 Jul 2022 21:39:13 -0700 Subject: [PATCH 96/98] Parent and Child Deletion Improvements (#649) * Fix timers * Update Entity.cpp * Fix timers Fix timers Remove debug logs remove _dynamic * I like to move it move it * Child Deletion Improvements * Check bounds --- dGame/Entity.cpp | 19 +++++++++++++++---- dGame/Entity.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 93fa0609..a063b3c6 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -109,6 +109,11 @@ Entity::~Entity() { m_Components.erase(pair.first); } + + for (auto child : m_ChildEntities) { + if (child) child->RemoveParent(); + } + if (m_ParentEntity) { m_ParentEntity->RemoveChild(this); } @@ -1662,15 +1667,21 @@ void Entity::AddChild(Entity* child) { void Entity::RemoveChild(Entity* child) { if (!child) return; - for (auto entity = m_ChildEntities.begin(); entity != m_ChildEntities.end(); entity++) { - if (*entity && (*entity)->GetObjectID() == child->GetObjectID()) { + uint32_t entityPosition = 0; + while (entityPosition < m_ChildEntities.size()) { + if (!m_ChildEntities[entityPosition] || (m_ChildEntities[entityPosition])->GetObjectID() == child->GetObjectID()) { m_IsParentChildDirty = true; - m_ChildEntities.erase(entity); - return; + m_ChildEntities.erase(m_ChildEntities.begin() + entityPosition); + } else { + entityPosition++; } } } +void Entity::RemoveParent() { + this->m_ParentEntity = nullptr; +} + void Entity::AddTimer(std::string name, float time) { EntityTimer* timer = new EntityTimer(name, time); m_PendingTimers.push_back(timer); diff --git a/dGame/Entity.h b/dGame/Entity.h index ca12b355..85f992e8 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -144,6 +144,7 @@ public: void AddChild(Entity* child); void RemoveChild(Entity* child); + void RemoveParent(); void AddTimer(std::string name, float time); void AddCallbackTimer(float time, std::function<void()> callback); bool HasTimer(const std::string& name); From 0d4f86b20b9527028ae0ccfca2b207f4d9fe767a Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sun, 17 Jul 2022 06:57:00 +0100 Subject: [PATCH 97/98] Resolve missing RakNet replacement (#650) Repair issue from PR earlier, crucial fix. --- dWorldServer/WorldServer.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 9e5ff8c1..d7a3b41e 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -817,19 +817,27 @@ void HandlePacket(Packet* packet) { RakNet::BitStream inStream(packet->data, packet->length, false); uint64_t header = inStream.Read(header); uint32_t sessionKey = inStream.Read(sessionKey); - RakNet::RakString username; - inStream.Read(username); + + std::string username; + + uint32_t len; + inStream.Read(len); + + for (int i = 0; i < len; i++) { + char character; inStream.Read<char>(character); + username += character; + } //Find them: - User* user = UserManager::Instance()->GetUser(username.C_String()); + User* user = UserManager::Instance()->GetUser(username.c_str()); if (!user) { - Game::logger->Log("WorldServer", "Got new session alert for user %s, but they're not logged in.\n", username.C_String()); + Game::logger->Log("WorldServer", "Got new session alert for user %s, but they're not logged in.\n", username.c_str()); return; } //Check the key: if (sessionKey != std::atoi(user->GetSessionKey().c_str())) { - Game::logger->Log("WorldServer", "Got new session alert for user %s, but the session key is invalid.\n", username.C_String()); + Game::logger->Log("WorldServer", "Got new session alert for user %s, but the session key is invalid.\n", username.c_str()); Game::server->Disconnect(user->GetSystemAddress(), SERVER_DISCON_INVALID_SESSION_KEY); return; } From ef8c2a40f384973c68c5cc483b2e602e9579fb4f Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sun, 17 Jul 2022 02:35:11 -0500 Subject: [PATCH 98/98] Framework for GM's and helpers for mounts (#651) * Framework for GM's and helpers for mounts * docs and spacing * whitespace --- dGame/dComponents/CharacterComponent.h | 17 + dGame/dComponents/PossessableComponent.cpp | 3 + dGame/dComponents/PossessableComponent.h | 17 + dGame/dComponents/PossessorComponent.h | 18 ++ dGame/dGameMessages/GameMessages.cpp | 359 +++++++++++---------- dGame/dGameMessages/GameMessages.h | 30 +- dNet/dMessageIdentifiers.h | 2 + 7 files changed, 281 insertions(+), 165 deletions(-) diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index c7706325..009530c4 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -179,6 +179,18 @@ public: */ void SetLastRocketItemID(LWOOBJID lastRocketItemID) { m_LastRocketItemID = lastRocketItemID; } + /** + * Gets the object ID of the mount item that is being used + * @return the object ID of the mount item that is being used + */ + LWOOBJID GetMountItemID() const { return m_MountItemID; } + + /** + * Sets the object ID of the mount item that is being used + * @param m_MountItemID the object ID of the mount item that is being used + */ + void SetMountItemID(LWOOBJID mountItemID) { m_MountItemID = mountItemID; } + /** * Gives the player rewards for the last level that they leveled up from */ @@ -579,6 +591,11 @@ private: * ID of the last rocket used */ LWOOBJID m_LastRocketItemID = LWOOBJID_EMPTY; + + /** + * Mount Item ID + */ + LWOOBJID m_MountItemID = LWOOBJID_EMPTY; }; #endif // CHARACTERCOMPONENT_H diff --git a/dGame/dComponents/PossessableComponent.cpp b/dGame/dComponents/PossessableComponent.cpp index 1d721466..8190b9eb 100644 --- a/dGame/dComponents/PossessableComponent.cpp +++ b/dGame/dComponents/PossessableComponent.cpp @@ -1,10 +1,13 @@ #include "PossessableComponent.h" #include "PossessorComponent.h" #include "EntityManager.h" +#include "Inventory.h" #include "Item.h" PossessableComponent::PossessableComponent(Entity* parent, uint32_t componentId) : Component(parent){ m_Possessor = LWOOBJID_EMPTY; + CDItemComponent item = Inventory::FindItemComponent(m_Parent->GetLOT()); + m_AnimationFlag = static_cast<eAnimationFlags>(item.animationFlag); // Get the possession Type from the CDClient auto query = CDClientDatabase::CreatePreppedStmt("SELECT possessionType, depossessOnHit FROM PossessableComponent WHERE id = ?;"); diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index 5eefaaf4..a37b6e34 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -54,6 +54,18 @@ class PossessableComponent : public Component { */ void ForceDepossess() { m_ImmediatelyDepossess = true; m_DirtyPossessable = true;}; + /** + * Set if the parent entity was spawned from an item + * @param value if the parent entity was spawned from an item + */ + void SetItemSpawned(bool value) { m_ItemSpawned = value;}; + + /** + * Returns if the parent entity was spawned from an item + * @return if the parent entity was spawned from an item + */ + LWOOBJID GetItemSpawned() const { return m_ItemSpawned; }; + /** * Handles an OnUsed event by some other entity, if said entity has a Possessor it becomes the possessor * of this entity @@ -95,4 +107,9 @@ class PossessableComponent : public Component { */ bool m_ImmediatelyDepossess = false; + /** + * @brief Whether the parent entity was spawned from an item + * + */ + bool m_ItemSpawned = false; }; diff --git a/dGame/dComponents/PossessorComponent.h b/dGame/dComponents/PossessorComponent.h index f202b907..a81868a5 100644 --- a/dGame/dComponents/PossessorComponent.h +++ b/dGame/dComponents/PossessorComponent.h @@ -36,6 +36,18 @@ class PossessorComponent : public Component { */ LWOOBJID GetPossessable() const { return m_Possessable; } + /** + * Sets if we are busy mounting or dismounting + * @param value if we are busy mounting or dismounting + */ + void SetIsBusy(bool value) { m_IsBusy = value; } + + /** + * Returns if we are busy mounting or dismounting + * @return if we are busy mounting or dismounting + */ + bool GetIsBusy() const { return m_IsBusy; } + /** * Sets the possesible type that's currently used, merely used by the shooting gallery if it's 0 * @param value the possesible type to set @@ -60,4 +72,10 @@ class PossessorComponent : public Component { * */ bool m_DirtyPossesor = false; + + /** + * @brief if the possessor is busy mounting or dismounting + * + */ + bool m_IsBusy = false; }; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 4f5cb1f4..292afc71 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -147,7 +147,7 @@ void GameMessages::SendPlayAnimation(Entity* entity, const std::u16string& anima PacketUtils::WriteWString(bitStream, animationName, animationIDLength); bitStream.Write(bExpectAnimToExist); - + bitStream.Write(bPlayImmediate); bitStream.Write(bTriggerOnCompleteMsg); @@ -427,7 +427,7 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System LWONameValue extraInfo; auto config = item->GetConfig(); - + for (auto* data : config) { extraInfo.name += GeneralUtils::ASCIIToUTF16(data->GetString()) + u","; @@ -435,7 +435,7 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System if (extraInfo.name.length() > 0) extraInfo.name.pop_back(); // remove the last comma - bitStream.Write<uint32_t>(extraInfo.name.size()); + bitStream.Write<uint32_t>(extraInfo.name.size()); if (extraInfo.name.size() > 0) { for (uint32_t i = 0; i < extraInfo.name.size(); ++i) { bitStream.Write(static_cast<uint16_t>(extraInfo.name[i])); @@ -447,10 +447,10 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System bitStream.Write(subKey != LWOOBJID_EMPTY); if (subKey != LWOOBJID_EMPTY) bitStream.Write(subKey); - + auto* inventory = item->GetInventory(); const auto inventoryType = inventory->GetType(); - + bitStream.Write(inventoryType != eInventoryType::ITEMS); if (inventoryType != eInventoryType::ITEMS) bitStream.Write(inventoryType); @@ -458,7 +458,7 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System if (itemCount != 1) bitStream.Write(itemCount); const auto count = item->GetCount(); - + bitStream.Write(count != 0); //items total if (count != 0) bitStream.Write(count); @@ -1008,7 +1008,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, if (GameConfig::GetValue<int32_t>("no_drops") == 1) { return; } - + bool bUsePosition = false; NiPoint3 finalPosition; LWOOBJID lootID = LWOOBJID_EMPTY; @@ -1063,7 +1063,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, if (spawnPos != NiPoint3::ZERO) bitStream.Write(spawnPos); auto* team = TeamManager::Instance()->GetTeam(owner); - + // Currency and powerups should not sync if (team != nullptr && currency == 0) { @@ -1086,7 +1086,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, return; } } - + SystemAddress sysAddr = entity->GetSystemAddress(); SEND_PACKET; } @@ -1097,7 +1097,7 @@ void GameMessages::SendSetPlayerControlScheme(Entity* entity, eControlSceme cont bool bDelayCamSwitchIfInCinematic = true; bool bSwitchCam = true; - + bitStream.Write(entity->GetObjectID()); bitStream.Write(uint16_t(GAME_MSG_SET_PLAYER_CONTROL_SCHEME)); @@ -1265,7 +1265,7 @@ void GameMessages::SendVendorStatusUpdate(Entity* entity, const SystemAddress& s bitStream.Write(entity->GetObjectID()); bitStream.Write(GAME_MSG::GAME_MSG_VENDOR_STATUS_UPDATE); - bitStream.Write(bUpdateOnly); + bitStream.Write(bUpdateOnly); bitStream.Write(static_cast<uint32_t>(vendorItems.size())); for (std::pair<LOT, int> item : vendorItems) { @@ -1282,7 +1282,7 @@ void GameMessages::SendVendorTransactionResult(Entity* entity, const SystemAddre CMSGHEADER int iResult = 0x02; // success, seems to be the only relevant one - + bitStream.Write(entity->GetObjectID()); bitStream.Write(GAME_MSG::GAME_MSG_VENDOR_TRANSACTION_RESULT); bitStream.Write(iResult); @@ -1537,7 +1537,7 @@ void GameMessages::NotifyLevelRewards(LWOOBJID objectID, const SystemAddress& sy bitStream.Write(level); bitStream.Write(sending_rewards); - + SEND_PACKET } @@ -1549,7 +1549,7 @@ void GameMessages::SendSetShootingGalleryParams(LWOOBJID objectId, const SystemA NiPoint3 playerPosOffset, float projectileVelocity, float timeLimit, - bool bUseLeaderboards) + bool bUseLeaderboards) { CBITSTREAM CMSGHEADER @@ -1585,7 +1585,7 @@ void GameMessages::SendNotifyClientShootingGalleryScore(LWOOBJID objectId, const float addTime, int32_t score, LWOOBJID target, - NiPoint3 targetPos) + NiPoint3 targetPos) { CBITSTREAM CMSGHEADER @@ -1602,7 +1602,7 @@ void GameMessages::SendNotifyClientShootingGalleryScore(LWOOBJID objectId, const } -void GameMessages::HandleUpdateShootingGalleryRotation(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleUpdateShootingGalleryRotation(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { float angle = 0.0f; NiPoint3 facing = NiPoint3::ZERO; @@ -1833,13 +1833,13 @@ void GameMessages::SendNotifyClientObject(const LWOOBJID& objectID, std::u16stri for (auto character : name) { bitStream.Write<uint16_t>(character); } - + bitStream.Write(param1); - + bitStream.Write(param2); bitStream.Write(paramObj); - + bitStream.Write(uint32_t(paramStr.size())); for (auto character : paramStr) { bitStream.Write(character); @@ -1988,7 +1988,7 @@ void GameMessages::SendDownloadPropertyData(const LWOOBJID objectId, const Prope data.Serialize(bitStream); Game::logger->Log("SendDownloadPropertyData", "(%llu) sending property data (%d)\n", objectId, sysAddr == UNASSIGNED_SYSTEM_ADDRESS); - + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } @@ -2000,12 +2000,12 @@ void GameMessages::SendPropertyRentalResponse(const LWOOBJID objectId, const LWO bitStream.Write(objectId); bitStream.Write(GAME_MSG::GAME_MSG_PROPERTY_RENTAL_RESPONSE); - + bitStream.Write(cloneId); bitStream.Write(code); bitStream.Write(propertyId); bitStream.Write(rentDue); - + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } @@ -2078,7 +2078,7 @@ void GameMessages::SendZonePropertyModelEquipped(LWOOBJID objectId, LWOOBJID pla bitStream.Write(playerId); bitStream.Write(propertyId); - + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } @@ -2115,7 +2115,7 @@ void GameMessages::SendPlaceModelResponse(LWOOBJID objectId, const SystemAddress { bitStream.Write(response); } - + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; @@ -2131,7 +2131,7 @@ void GameMessages::SendUGCEquipPreCreateBasedOnEditMode(LWOOBJID objectId, const bitStream.Write(modelCount); bitStream.Write(model); - + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } @@ -2250,7 +2250,7 @@ void GameMessages::HandleSetBuildMode(RakNet::BitStream* inStream, Entity* entit NiPoint3 startPosition = NiPoint3::ZERO; inStream->Read(start); - + if (inStream->ReadBit()) inStream->Read(distanceType); @@ -2273,7 +2273,7 @@ void GameMessages::HandleSetBuildMode(RakNet::BitStream* inStream, Entity* entit player->GetCharacter()->SetBuildMode(start); Game::logger->Log("GameMessages", "Sending build mode confirm (%i): (%d) (%i) (%d) (%i) (%llu)\n", entity->GetLOT(), start, distanceType, modePaused, modeValue, playerId); - + SendSetBuildModeConfirmed(entity->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS, start, false, modePaused, modeValue, playerId, startPosition); } @@ -2283,7 +2283,7 @@ void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Enti { return; } - + bool firstTime{}; bool success{}; int32_t sourceBag{}; @@ -2311,11 +2311,11 @@ void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Enti } Game::logger->Log("GameMessages", "Handling start building with item (%i): (%d) (%d) (%i) (%llu) (%i) (%i) (%llu) (%i) (%i)\n", entity->GetLOT(), firstTime, success, sourceBag, sourceId, sourceLot, sourceType, targetId, targetLot, targetType); - + auto* user = UserManager::Instance()->GetUser(sysAddr); auto* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); - + SendStartArrangingWithItem( player, sysAddr, @@ -2336,7 +2336,7 @@ 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(); } @@ -2366,7 +2366,7 @@ void GameMessages::HandlePlacePropertyModel(RakNet::BitStream* inStream, Entity* LWOOBJID model; inStream->Read(model); - + PropertyManagementComponent::Instance()->UpdateModelPosition(model, NiPoint3::ZERO, NiQuaternion::IDENTITY); } @@ -2383,7 +2383,7 @@ void GameMessages::HandleUpdatePropertyModel(RakNet::BitStream* inStream, Entity { inStream->Read(rotation); } - + PropertyManagementComponent::Instance()->UpdateModelPosition(model, position, rotation); } @@ -2422,18 +2422,18 @@ void GameMessages::HandleBBBLoadItemRequest(RakNet::BitStream* inStream, Entity* void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { /* - ___ ___ - /\ /\___ _ __ ___ / __\ ___ / \_ __ __ _ __ _ ___ _ __ ___ + ___ ___ + /\ /\___ _ __ ___ / __\ ___ / \_ __ __ _ __ _ ___ _ __ ___ / /_/ / _ \ '__/ _ \ /__\/// _ \ / /\ / '__/ _` |/ _` |/ _ \| '_ \/ __| / __ / __/ | | __/ / \/ \ __/ / /_//| | | (_| | (_| | (_) | | | \__ \ \/ /_/ \___|_| \___| \_____/\___| /___,' |_| \__,_|\__, |\___/|_| |_|___/ - |___/ - ___ _ - / __\ _____ ____ _ _ __ ___ / \ - /__\/// _ \ \ /\ / / _` | '__/ _ \/ / - / \/ \ __/\ V V / (_| | | | __/\_/ - \_____/\___| \_/\_/ \__,_|_| \___\/ - + |___/ + ___ _ + / __\ _____ ____ _ _ __ ___ / \ + /__\/// _ \ \ /\ / / _` | '__/ _ \/ / + / \/ \ __/\ V V / (_| | | | __/\_/ + \_____/\___| \_/\_/ \__,_|_| \___\/ + <>=======() (/\___ /|\\ ()==========<>_ \_/ | \\ //|\ ______/ \) @@ -2463,7 +2463,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent uint8_t c; inStream->Read(c); } - + uint32_t lxfmlSize; inStream->Read(lxfmlSize); uint8_t* inData = static_cast<uint8_t*>(std::malloc(lxfmlSize)); @@ -2471,13 +2471,13 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent if (inData == nullptr) { return; } - + for (uint32_t i = 0; i < lxfmlSize; ++i) { uint8_t c; inStream->Read(c); inData[i] = c; } - + inStream->Read(timeTaken); /* @@ -2505,7 +2505,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent //Now, the cave of dragons: - //We runs this in async because the http library here is blocking, meaning it'll halt the thread. + //We runs this in async because the http library here is blocking, meaning it'll halt the thread. //But we don't want the server to go unresponsive, because then the client would disconnect. std::async(std::launch::async, [&]() { @@ -2595,7 +2595,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent */ ////Send off to UGC for processing, if enabled: - //if (Game::config->GetValue("ugc_remote") == "1") { + //if (Game::config->GetValue("ugc_remote") == "1") { // std::string ugcIP = Game::config->GetValue("ugc_ip"); // int ugcPort = std::stoi(Game::config->GetValue("ugc_port")); @@ -2750,7 +2750,7 @@ void GameMessages::HandleEnterProperty(RakNet::BitStream* inStream, Entity* enti } } -void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { LOT lot; @@ -2763,10 +2763,10 @@ void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity* inventory->SetConsumable(lot); } -void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, +void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, bool allowGhostUpdates, bool bCloseMultiInteract, bool bSendServerNotify, bool bUseControlledObjectForAudioListener, int endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished, - bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) + bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) { CBITSTREAM; CMSGHEADER; @@ -2806,7 +2806,7 @@ void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, } void GameMessages::SendEndCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, - float leadOut, bool leavePlayerLocked) + float leadOut, bool leavePlayerLocked) { CBITSTREAM; CMSGHEADER; @@ -2880,7 +2880,7 @@ void GameMessages::SendSetStunned(LWOOBJID objectId, eStunState stateChangeType, bool bCantAttackOutChangeWasApplied, bool bCantEquipOutChangeWasApplied, bool bCantInteractOutChangeWasApplied, bool bCantJumpOutChangeWasApplied, bool bCantMoveOutChangeWasApplied, bool bCantTurnOutChangeWasApplied, - bool bCantUseItemOutChangeWasApplied) + bool bCantUseItemOutChangeWasApplied) { CBITSTREAM; CMSGHEADER; @@ -2915,7 +2915,7 @@ void GameMessages::SendSetStunned(LWOOBJID objectId, eStunState stateChangeType, bitStream.Write(bCantUseItemOutChangeWasApplied); bitStream.Write(bDontTerminateInteract); - + bitStream.Write(bIgnoreImmunity); if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; @@ -2923,7 +2923,7 @@ void GameMessages::SendSetStunned(LWOOBJID objectId, eStunState stateChangeType, } -void GameMessages::SendOrientToAngle(LWOOBJID objectId, bool bRelativeToCurrent, float fAngle, const SystemAddress& sysAddr) +void GameMessages::SendOrientToAngle(LWOOBJID objectId, bool bRelativeToCurrent, float fAngle, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -2939,7 +2939,7 @@ void GameMessages::SendOrientToAngle(LWOOBJID objectId, bool bRelativeToCurrent, } -void GameMessages::SendAddRunSpeedModifier(LWOOBJID objectId, LWOOBJID caster, uint32_t modifier, const SystemAddress& sysAddr) +void GameMessages::SendAddRunSpeedModifier(LWOOBJID objectId, LWOOBJID caster, uint32_t modifier, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -2957,7 +2957,7 @@ void GameMessages::SendAddRunSpeedModifier(LWOOBJID objectId, LWOOBJID caster, u SEND_PACKET; } -void GameMessages::SendRemoveRunSpeedModifier(LWOOBJID objectId, uint32_t modifier, const SystemAddress& sysAddr) +void GameMessages::SendRemoveRunSpeedModifier(LWOOBJID objectId, uint32_t modifier, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3009,7 +3009,7 @@ void GameMessages::SendPropertySelectQuery(LWOOBJID objectId, int32_t navOffset, SEND_PACKET; } -void GameMessages::SendNotifyObject(LWOOBJID objectId, LWOOBJID objIDSender, std::u16string name, const SystemAddress& sysAddr, int param1, int param2) +void GameMessages::SendNotifyObject(LWOOBJID objectId, LWOOBJID objIDSender, std::u16string name, const SystemAddress& sysAddr, int param1, int param2) { CBITSTREAM; CMSGHEADER; @@ -3023,7 +3023,7 @@ void GameMessages::SendNotifyObject(LWOOBJID objectId, LWOOBJID objIDSender, std { bitStream.Write(character); } - + bitStream.Write(param1); bitStream.Write(param2); @@ -3031,7 +3031,7 @@ void GameMessages::SendNotifyObject(LWOOBJID objectId, LWOOBJID objIDSender, std SEND_PACKET; } -void GameMessages::HandleVerifyAck(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleVerifyAck(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool bDifferent; std::string sBitStream; @@ -3053,7 +3053,7 @@ void GameMessages::HandleVerifyAck(RakNet::BitStream* inStream, Entity* entity, } } -void GameMessages::SendTeamPickupItem(LWOOBJID objectId, LWOOBJID lootID, LWOOBJID lootOwnerID, const SystemAddress& sysAddr) +void GameMessages::SendTeamPickupItem(LWOOBJID objectId, LWOOBJID lootID, LWOOBJID lootOwnerID, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3063,7 +3063,7 @@ void GameMessages::SendTeamPickupItem(LWOOBJID objectId, LWOOBJID lootID, LWOOBJ bitStream.Write(lootID); bitStream.Write(lootOwnerID); - + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } @@ -3144,7 +3144,7 @@ void GameMessages::SendServerTradeAccept(LWOOBJID objectId, bool bFirst, const S SEND_PACKET; } -void GameMessages::SendServerTradeCancel(LWOOBJID objectId, const SystemAddress& sysAddr) +void GameMessages::SendServerTradeCancel(LWOOBJID objectId, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3156,7 +3156,7 @@ void GameMessages::SendServerTradeCancel(LWOOBJID objectId, const SystemAddress& SEND_PACKET; } -void GameMessages::SendServerTradeUpdate(LWOOBJID objectId, uint64_t coins, const std::vector<TradeItem>& items, const SystemAddress& sysAddr) +void GameMessages::SendServerTradeUpdate(LWOOBJID objectId, uint64_t coins, const std::vector<TradeItem>& items, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3242,7 +3242,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* { TradingManager::Instance()->NewTrade(entity->GetObjectID(), i64Invitee); } - + SendServerTradeInvite( i64Invitee, bNeedInvitePopUp, @@ -3256,7 +3256,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* void GameMessages::HandleClientTradeCancel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { auto* trade = TradingManager::Instance()->GetPlayerTrade(entity->GetObjectID()); - + if (trade == nullptr) return; Game::logger->Log("GameMessages", "Trade canceled from (%llu)\n", entity->GetObjectID()); @@ -3269,9 +3269,9 @@ void GameMessages::HandleClientTradeAccept(RakNet::BitStream* inStream, Entity* bool bFirst = inStream->ReadBit(); Game::logger->Log("GameMessages", "Trade accepted from (%llu) -> (%d)\n", entity->GetObjectID(), bFirst); - + auto* trade = TradingManager::Instance()->GetPlayerTrade(entity->GetObjectID()); - + if (trade == nullptr) return; trade->SetAccepted(entity->GetObjectID(), bFirst); @@ -3343,9 +3343,9 @@ void GameMessages::HandleClientTradeUpdate(RakNet::BitStream* inStream, Entity* Game::logger->Log("GameMessages", "Trade item from (%llu) -> (%llu)/(%llu), (%i), (%llu), (%i), (%i)\n", entity->GetObjectID(), itemId, itemId2, lot, unknown1, unknown2, unknown3); } - + auto* trade = TradingManager::Instance()->GetPlayerTrade(entity->GetObjectID()); - + if (trade == nullptr) return; trade->SetCoins(entity->GetObjectID(), currency); @@ -3355,7 +3355,7 @@ void GameMessages::HandleClientTradeUpdate(RakNet::BitStream* inStream, Entity* //Pets: -void GameMessages::SendNotifyPetTamingMinigame(LWOOBJID objectId, LWOOBJID petId, LWOOBJID playerTamingId, bool bForceTeleport, uint32_t notifyType, NiPoint3 petsDestPos, NiPoint3 telePos, NiQuaternion teleRot, const SystemAddress& sysAddr) +void GameMessages::SendNotifyPetTamingMinigame(LWOOBJID objectId, LWOOBJID petId, LWOOBJID playerTamingId, bool bForceTeleport, uint32_t notifyType, NiPoint3 petsDestPos, NiPoint3 telePos, NiQuaternion teleRot, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3378,7 +3378,7 @@ void GameMessages::SendNotifyPetTamingMinigame(LWOOBJID objectId, LWOOBJID petId SEND_PACKET; } -void GameMessages::SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SystemAddress& sysAddr) +void GameMessages::SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3390,7 +3390,7 @@ void GameMessages::SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SEND_PACKET; } -void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vector<Brick>& bricks, const SystemAddress& sysAddr) +void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vector<Brick>& bricks, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3409,7 +3409,7 @@ void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vec SEND_PACKET; } -void GameMessages::SendPetTamingTryBuildResult(LWOOBJID objectId, bool bSuccess, int32_t iNumCorrect, const SystemAddress& sysAddr) +void GameMessages::SendPetTamingTryBuildResult(LWOOBJID objectId, bool bSuccess, int32_t iNumCorrect, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3425,7 +3425,7 @@ void GameMessages::SendPetTamingTryBuildResult(LWOOBJID objectId, bool bSuccess, SEND_PACKET; } -void GameMessages::SendPetResponse(LWOOBJID objectId, LWOOBJID objIDPet, int32_t iPetCommandType, int32_t iResponse, int32_t iTypeID, const SystemAddress& sysAddr) +void GameMessages::SendPetResponse(LWOOBJID objectId, LWOOBJID objIDPet, int32_t iPetCommandType, int32_t iResponse, int32_t iTypeID, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3442,7 +3442,7 @@ void GameMessages::SendPetResponse(LWOOBJID objectId, LWOOBJID objIDPet, int32_t SEND_PACKET; } -void GameMessages::SendAddPetToPlayer(LWOOBJID objectId, int32_t iElementalType, std::u16string name, LWOOBJID petDBID, LOT petLOT, const SystemAddress& sysAddr) +void GameMessages::SendAddPetToPlayer(LWOOBJID objectId, int32_t iElementalType, std::u16string name, LWOOBJID petDBID, LOT petLOT, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3456,7 +3456,7 @@ void GameMessages::SendAddPetToPlayer(LWOOBJID objectId, int32_t iElementalType, { bitStream.Write(character); } - + bitStream.Write(petDBID); bitStream.Write(petLOT); @@ -3464,7 +3464,7 @@ void GameMessages::SendAddPetToPlayer(LWOOBJID objectId, int32_t iElementalType, SEND_PACKET; } -void GameMessages::SendRegisterPetID(LWOOBJID objectId, LWOOBJID objID, const SystemAddress& sysAddr) +void GameMessages::SendRegisterPetID(LWOOBJID objectId, LWOOBJID objID, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3478,7 +3478,7 @@ void GameMessages::SendRegisterPetID(LWOOBJID objectId, LWOOBJID objID, const Sy SEND_PACKET; } -void GameMessages::SendRegisterPetDBID(LWOOBJID objectId, LWOOBJID petDBID, const SystemAddress& sysAddr) +void GameMessages::SendRegisterPetDBID(LWOOBJID objectId, LWOOBJID petDBID, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3492,7 +3492,7 @@ void GameMessages::SendRegisterPetDBID(LWOOBJID objectId, LWOOBJID petDBID, cons SEND_PACKET; } -void GameMessages::SendMarkInventoryItemAsActive(LWOOBJID objectId, bool bActive, int32_t iType, LWOOBJID itemID, const SystemAddress& sysAddr) +void GameMessages::SendMarkInventoryItemAsActive(LWOOBJID objectId, bool bActive, int32_t iType, LWOOBJID itemID, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3501,7 +3501,7 @@ void GameMessages::SendMarkInventoryItemAsActive(LWOOBJID objectId, bool bActive bitStream.Write(GAME_MSG::GAME_MSG_MARK_INVENTORY_ITEM_AS_ACTIVE); bitStream.Write(bActive); - + bitStream.Write(iType != 0); if (iType != 0) bitStream.Write(iType); @@ -3512,7 +3512,7 @@ void GameMessages::SendMarkInventoryItemAsActive(LWOOBJID objectId, bool bActive SEND_PACKET; } -void GameMessages::SendClientExitTamingMinigame(LWOOBJID objectId, bool bVoluntaryExit, const SystemAddress& sysAddr) +void GameMessages::SendClientExitTamingMinigame(LWOOBJID objectId, bool bVoluntaryExit, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3526,7 +3526,7 @@ void GameMessages::SendClientExitTamingMinigame(LWOOBJID objectId, bool bVolunta SEND_PACKET; } -void GameMessages::SendShowPetActionButton(LWOOBJID objectId, int32_t buttonLabel, bool bShow, const SystemAddress& sysAddr) +void GameMessages::SendShowPetActionButton(LWOOBJID objectId, int32_t buttonLabel, bool bShow, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3557,7 +3557,7 @@ void GameMessages::SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID ta } -void GameMessages::SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, const SystemAddress& sysAddr) +void GameMessages::SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3572,7 +3572,7 @@ void GameMessages::SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, cons } -void GameMessages::SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJID petDBID, const SystemAddress& sysAddr) +void GameMessages::SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJID petDBID, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3585,7 +3585,7 @@ void GameMessages::SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJ { bitStream.Write(character); } - + bitStream.Write(petDBID != LWOOBJID_EMPTY); if (petDBID != LWOOBJID_EMPTY) bitStream.Write(petDBID); @@ -3594,14 +3594,14 @@ void GameMessages::SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJ } -void GameMessages::SendSetPetNameModerated(LWOOBJID objectId, LWOOBJID petDBID, int32_t nModerationStatus, const SystemAddress& sysAddr) +void GameMessages::SendSetPetNameModerated(LWOOBJID objectId, LWOOBJID petDBID, int32_t nModerationStatus, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectId); bitStream.Write(GAME_MSG::GAME_MSG_SET_PET_NAME_MODERATED); - + bitStream.Write(petDBID != LWOOBJID_EMPTY); if (petDBID != LWOOBJID_EMPTY) bitStream.Write(petDBID); @@ -3612,7 +3612,7 @@ void GameMessages::SendSetPetNameModerated(LWOOBJID objectId, LWOOBJID petDBID, } -void GameMessages::SendPetNameChanged(LWOOBJID objectId, int32_t moderationStatus, std::u16string name, std::u16string ownerName, const SystemAddress& sysAddr) +void GameMessages::SendPetNameChanged(LWOOBJID objectId, int32_t moderationStatus, std::u16string name, std::u16string ownerName, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3627,7 +3627,7 @@ void GameMessages::SendPetNameChanged(LWOOBJID objectId, int32_t moderationStatu { bitStream.Write(character); } - + bitStream.Write(static_cast<uint32_t>(ownerName.size())); for (const auto character : ownerName) { @@ -3639,7 +3639,7 @@ void GameMessages::SendPetNameChanged(LWOOBJID objectId, int32_t moderationStatu } -void GameMessages::HandleClientExitTamingMinigame(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleClientExitTamingMinigame(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool bVoluntaryExit = inStream->ReadBit(); @@ -3653,7 +3653,7 @@ void GameMessages::HandleClientExitTamingMinigame(RakNet::BitStream* inStream, E petComponent->ClientExitTamingMinigame(bVoluntaryExit); } -void GameMessages::HandleStartServerPetMinigameTimer(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleStartServerPetMinigameTimer(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { auto* petComponent = PetComponent::GetTamingPet(entity->GetObjectID()); @@ -3665,7 +3665,7 @@ void GameMessages::HandleStartServerPetMinigameTimer(RakNet::BitStream* inStream petComponent->StartTimer(); } -void GameMessages::HandlePetTamingTryBuild(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandlePetTamingTryBuild(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { uint32_t brickCount; std::vector<Brick> bricks; @@ -3696,7 +3696,7 @@ void GameMessages::HandlePetTamingTryBuild(RakNet::BitStream* inStream, Entity* petComponent->TryBuild(bricks.size(), clientFailed); } -void GameMessages::HandleNotifyTamingBuildSuccess(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleNotifyTamingBuildSuccess(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { NiPoint3 position; @@ -3712,7 +3712,7 @@ void GameMessages::HandleNotifyTamingBuildSuccess(RakNet::BitStream* inStream, E petComponent->NotifyTamingBuildSuccess(position); } -void GameMessages::HandleRequestSetPetName(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleRequestSetPetName(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { uint32_t nameLength; std::u16string name; @@ -3725,7 +3725,7 @@ void GameMessages::HandleRequestSetPetName(RakNet::BitStream* inStream, Entity* inStream->Read(character); name.push_back(character); } - + auto* petComponent = PetComponent::GetTamingPet(entity->GetObjectID()); if (petComponent == nullptr) @@ -3741,14 +3741,14 @@ void GameMessages::HandleRequestSetPetName(RakNet::BitStream* inStream, Entity* petComponent->RequestSetPetName(name); } -void GameMessages::HandleCommandPet(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleCommandPet(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { NiPoint3 genericPosInfo; LWOOBJID objIdSource; int32_t iPetCommandType; int32_t iTypeID; bool overrideObey; - + inStream->Read(genericPosInfo); inStream->Read(objIdSource); inStream->Read(iPetCommandType); @@ -3765,7 +3765,7 @@ void GameMessages::HandleCommandPet(RakNet::BitStream* inStream, Entity* entity, petComponent->Command(genericPosInfo, objIdSource, iPetCommandType, iTypeID, overrideObey); } -void GameMessages::HandleDespawnPet(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleDespawnPet(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool bDeletePet; @@ -3788,7 +3788,7 @@ void GameMessages::HandleDespawnPet(RakNet::BitStream* inStream, Entity* entity, } } -void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { int32_t iButton; uint32_t identifierLength; @@ -3813,7 +3813,7 @@ void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* inStream->Read(character); userData.push_back(character); } - + Game::logger->Log("HandleMessageBoxResponse", "Button: " + std::to_string(iButton) + "; LOT: " + std::to_string(entity->GetLOT()) + " identifier: " + GeneralUtils::UTF16ToWTF8(identifier) + "; userData: " + GeneralUtils::UTF16ToWTF8(userData) + "\n"); auto* user = UserManager::Instance()->GetUser(sysAddr); @@ -3852,7 +3852,7 @@ void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* } } -void GameMessages::HandleChoiceBoxRespond(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleChoiceBoxRespond(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { int32_t iButton; uint32_t buttonIdentifierLength; @@ -3877,7 +3877,7 @@ void GameMessages::HandleChoiceBoxRespond(RakNet::BitStream* inStream, Entity* e inStream->Read(character); identifier.push_back(character); } - + Game::logger->Log("HandleChoiceBoxRespond", "Button: " + std::to_string(iButton) + "; LOT: " + std::to_string(entity->GetLOT()) + " buttonIdentifier: " + GeneralUtils::UTF16ToWTF8(buttonIdentifier) + "; userData: " + GeneralUtils::UTF16ToWTF8(identifier) + "\n"); auto* user = UserManager::Instance()->GetUser(sysAddr); @@ -3897,7 +3897,7 @@ void GameMessages::HandleChoiceBoxRespond(RakNet::BitStream* inStream, Entity* e entity->OnChoiceBoxResponse(userEntity, iButton, buttonIdentifier, identifier); } -void GameMessages::SendDisplayZoneSummary(LWOOBJID objectId, const SystemAddress& sysAddr, bool isPropertyMap, bool isZoneStart, LWOOBJID sender) +void GameMessages::SendDisplayZoneSummary(LWOOBJID objectId, const SystemAddress& sysAddr, bool isPropertyMap, bool isZoneStart, LWOOBJID sender) { CBITSTREAM; CMSGHEADER; @@ -3916,7 +3916,7 @@ void GameMessages::SendDisplayZoneSummary(LWOOBJID objectId, const SystemAddress //UI -void GameMessages::SendNotifyNotEnoughInvSpace(LWOOBJID objectId, uint32_t freeSlotsNeeded, eInventoryType inventoryType, const SystemAddress& sysAddr) +void GameMessages::SendNotifyNotEnoughInvSpace(LWOOBJID objectId, uint32_t freeSlotsNeeded, eInventoryType inventoryType, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3932,7 +3932,7 @@ void GameMessages::SendNotifyNotEnoughInvSpace(LWOOBJID objectId, uint32_t freeS SEND_PACKET; } -void GameMessages::SendDisplayMessageBox(LWOOBJID objectId, bool bShow, LWOOBJID callbackClient, const std::u16string& identifier, int32_t imageID, const std::u16string& text, const std::u16string& userData, const SystemAddress& sysAddr) +void GameMessages::SendDisplayMessageBox(LWOOBJID objectId, bool bShow, LWOOBJID callbackClient, const std::u16string& identifier, int32_t imageID, const std::u16string& text, const std::u16string& userData, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3950,7 +3950,7 @@ void GameMessages::SendDisplayMessageBox(LWOOBJID objectId, bool bShow, LWOOBJID } bitStream.Write(imageID); - + bitStream.Write(static_cast<uint32_t>(text.size())); for (const auto character : text) { @@ -3986,6 +3986,47 @@ void GameMessages::SendDisplayChatBubble(LWOOBJID objectId, const std::u16string SEND_PACKET; } +// Mounts + +void GameMessages::SendSetMountInventoryID(Entity* entity, const LWOOBJID& objectID, const SystemAddress& sysAddr){ + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(entity->GetObjectID()); + bitStream.Write(GAME_MSG::GAME_MSG_SET_MOUNT_INVENTORY_ID); + bitStream.Write(objectID); + + SEND_PACKET_BROADCAST; +} + + +void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr){ + LWOOBJID objectId{}; + inStream->Read(objectId); + auto* mount = EntityManager::Instance()->GetEntity(objectId); + + if (objectId != LWOOBJID_EMPTY) { + PossessorComponent* possessor; + if (entity->TryGetComponent(COMPONENT_TYPE_POSSESSOR, possessor)) { + if (mount) { + possessor->SetIsBusy(false); + possessor->SetPossessable(LWOOBJID_EMPTY); + possessor->SetPossessableType(ePossessionType::NO_POSSESSION); + + GameMessages::SendSetStunned(entity->GetObjectID(), eStunState::POP, UNASSIGNED_SYSTEM_ADDRESS, LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); + + EntityManager::Instance()->SerializeEntity(entity); + } + } + } +} + + +void GameMessages::HandleAcknowledgePossession(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { + Game::logger->Log("HandleAcknowledgePossession", "Got AcknowledgePossession from %i\n", entity->GetLOT()); + EntityManager::Instance()->SerializeEntity(entity); +} + //Racing void GameMessages::HandleModuleAssemblyQueryData(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) @@ -3998,12 +4039,12 @@ void GameMessages::HandleModuleAssemblyQueryData(RakNet::BitStream* inStream, En { Game::logger->Log("HandleModuleAssemblyQueryData", "Returning assembly %s\n", GeneralUtils::UTF16ToWTF8(moduleAssemblyComponent->GetAssemblyPartsLOTs()).c_str()); - SendModuleAssemblyDBDataForClient(entity->GetObjectID(), moduleAssemblyComponent->GetSubKey(), moduleAssemblyComponent->GetAssemblyPartsLOTs(), UNASSIGNED_SYSTEM_ADDRESS); + SendModuleAssemblyDBDataForClient(entity->GetObjectID(), moduleAssemblyComponent->GetSubKey(), moduleAssemblyComponent->GetAssemblyPartsLOTs(), UNASSIGNED_SYSTEM_ADDRESS); } } -void GameMessages::HandleModularAssemblyNIFCompleted(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleModularAssemblyNIFCompleted(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { LWOOBJID objectID; @@ -4011,14 +4052,14 @@ void GameMessages::HandleModularAssemblyNIFCompleted(RakNet::BitStream* inStream } -void GameMessages::HandleVehicleSetWheelLockState(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleVehicleSetWheelLockState(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool bExtraFriction = inStream->ReadBit(); bool bLocked = inStream->ReadBit(); } -void GameMessages::HandleRacingClientReady(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleRacingClientReady(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { LWOOBJID playerID; @@ -4042,15 +4083,7 @@ void GameMessages::HandleRacingClientReady(RakNet::BitStream* inStream, Entity* } -void GameMessages::HandleAcknowledgePossession(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) -{ - Game::logger->Log("HandleAcknowledgePossession", "Got AcknowledgePossession from %i\n", entity->GetLOT()); - - EntityManager::Instance()->SerializeEntity(entity); -} - - -void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool bClientDeath; bool bSpawnLoot; @@ -4064,7 +4097,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, bClientDeath = inStream->ReadBit(); bSpawnLoot = inStream->ReadBit(); - + uint32_t deathTypeLength = 0; inStream->Read(deathTypeLength); @@ -4123,13 +4156,13 @@ void GameMessages::HandleVehicleNotifyServerAddPassiveBoostAction(RakNet::BitStr } -void GameMessages::HandleVehicleNotifyServerRemovePassiveBoostAction(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleVehicleNotifyServerRemovePassiveBoostAction(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { //SendVehicleRemovePassiveBoostAction(entity->GetObjectID(), sysAddr); } -void GameMessages::HandleRacingPlayerInfoResetFinished(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleRacingPlayerInfoResetFinished(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { LWOOBJID playerID; @@ -4190,7 +4223,7 @@ void GameMessages::HandleUpdatePropertyPerformanceCost(RakNet::BitStream* inStre updatePerformanceCostQuery = nullptr; } -void GameMessages::HandleVehicleNotifyHitImaginationServer(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleVehicleNotifyHitImaginationServer(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { LWOOBJID pickupObjID = LWOOBJID_EMPTY; LWOOBJID pickupSpawnerID = LWOOBJID_EMPTY; @@ -4350,7 +4383,7 @@ void GameMessages::SendRacingResetPlayerToLastReset(LWOOBJID objectId, LWOOBJID } -void GameMessages::SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType, int32_t param1, LWOOBJID paramObj, std::u16string paramStr, LWOOBJID singleClient, const SystemAddress& sysAddr) +void GameMessages::SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType, int32_t param1, LWOOBJID paramObj, std::u16string paramStr, LWOOBJID singleClient, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4378,7 +4411,7 @@ void GameMessages::SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType, } -void GameMessages::SendActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr) +void GameMessages::SendActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4391,7 +4424,7 @@ void GameMessages::SendActivityEnter(LWOOBJID objectId, const SystemAddress& sys } -void GameMessages::SendActivityStart(LWOOBJID objectId, const SystemAddress& sysAddr) +void GameMessages::SendActivityStart(LWOOBJID objectId, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4404,7 +4437,7 @@ void GameMessages::SendActivityStart(LWOOBJID objectId, const SystemAddress& sys } -void GameMessages::SendActivityExit(LWOOBJID objectId, const SystemAddress& sysAddr) +void GameMessages::SendActivityExit(LWOOBJID objectId, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4417,7 +4450,7 @@ void GameMessages::SendActivityExit(LWOOBJID objectId, const SystemAddress& sysA } -void GameMessages::SendActivityStop(LWOOBJID objectId, bool bExit, bool bUserCancel, const SystemAddress& sysAddr) +void GameMessages::SendActivityStop(LWOOBJID objectId, bool bExit, bool bUserCancel, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4459,7 +4492,7 @@ void GameMessages::SendVehicleRemovePassiveBoostAction(LWOOBJID objectId, const } -void GameMessages::SendVehicleNotifyFinishedRace(LWOOBJID objectId, const SystemAddress& sysAddr) +void GameMessages::SendVehicleNotifyFinishedRace(LWOOBJID objectId, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4561,7 +4594,7 @@ void GameMessages::HandleRequestMoveItemBetweenInventoryTypes(RakNet::BitStream* } -void GameMessages::SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditionalSound, bool bPlayCountdownSound, std::u16string sndName, int32_t stateToPlaySoundOn, const SystemAddress& sysAddr) +void GameMessages::SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditionalSound, bool bPlayCountdownSound, std::u16string sndName, int32_t stateToPlaySoundOn, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -4590,7 +4623,7 @@ void GameMessages::SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditi //------------------------------------------------------------------- Handlers ------------------------------------------------------------------ //----------------------------------------------------------------------------------------------------------------------------------------------- -void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool bOverride = false; @@ -4601,13 +4634,13 @@ void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStrea if (player != nullptr) { player->SetGhostOverride(bOverride); - + EntityManager::Instance()->UpdateGhosting(player); } } -void GameMessages::HandleSetGhostReferencePosition(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) +void GameMessages::HandleSetGhostReferencePosition(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { NiPoint3 position; @@ -4650,7 +4683,7 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti } const auto isCommendationVendor = entity->GetLOT() == 13806; - + VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(COMPONENT_TYPE_VENDOR)); if (!vend && !isCommendationVendor) return; @@ -4923,7 +4956,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity LWOCLONEID cloneId = 0; LWOMAPID mapId = 0; - + auto* rocketPad = entity->GetComponent<RocketLaunchpadControlComponent>(); if (rocketPad == nullptr) return; @@ -4948,7 +4981,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity } Game::logger->Log("FireEventServerSide", "Player %llu has requested zone transfer to (%i, %i).\n", sender->GetObjectID(), (int) mapId, (int) cloneId); - + auto* character = player->GetCharacter(); if (mapId <= 0) { @@ -4957,7 +4990,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, mapId, cloneId, false, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", character->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort); - + if (character) { character->SetZoneID(zoneID); character->SetZoneInstance(zoneInstance); @@ -5011,12 +5044,12 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, return; } - + if (interactedObject->GetLOT() == 9524) { entity->GetCharacter()->SetBuildMode(true); } - + if (bIsMultiInteractUse) { if (multiInteractType == 0) @@ -5039,7 +5072,7 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, //Perform use task if possible: auto missionComponent = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); - + if (missionComponent == nullptr) return; missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MISSION_INTERACTION, interactedObject->GetLOT(), interactedObject->GetObjectID()); @@ -5054,7 +5087,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) inStream->Read(targetID); Game::logger->Log("GameMessages", "Emote (%i) (%llu)\n", emoteID, targetID); - + //TODO: If targetID != 0, and we have one of the "perform emote" missions, complete them. if (emoteID == 0) return; @@ -5064,13 +5097,13 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (mission) { mission->Progress(MissionTaskType::MISSION_TASK_TYPE_EMOTE, emoteID, targetID); } - + if (targetID != LWOOBJID_EMPTY) { auto* targetEntity = EntityManager::Instance()->GetEntity(targetID); Game::logger->Log("GameMessages", "Emote target found (%d)\n", targetEntity != nullptr); - + if (targetEntity != nullptr) { targetEntity->OnEmoteReceived(emoteID, entity); @@ -5222,7 +5255,7 @@ void GameMessages::HandleRequestLinkedMission(RakNet::BitStream* inStream, Entit auto* player = EntityManager::Instance()->GetEntity(playerId); auto* missionOfferComponent = static_cast<MissionOfferComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION_OFFER)); - + if (missionOfferComponent != nullptr) { missionOfferComponent->OfferMissions(player, 0); @@ -5245,7 +5278,7 @@ void GameMessages::HandleHasBeenCollected(RakNet::BitStream* inStream, Entity* e void GameMessages::HandleNotifyServerLevelProcessingComplete(RakNet::BitStream* inStream, Entity* entity) { auto* character = static_cast<CharacterComponent*>(entity->GetComponent(COMPONENT_TYPE_CHARACTER)); if (!character) return; - + //Update our character's level in memory: character->SetLevel(character->GetLevel() + 1); @@ -5281,7 +5314,7 @@ void GameMessages::HandleNotifyServerLevelProcessingComplete(RakNet::BitStream* void GameMessages::HandlePickupCurrency(RakNet::BitStream* inStream, Entity* entity) { unsigned int currency; inStream->Read(currency); - + if (currency == 0) return; auto* ch = entity->GetCharacter(); @@ -5306,7 +5339,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity) inStream->Read(bClientDeath); inStream->Read(bDieAccepted); inStream->Read(bSpawnLoot); - + bool coinSpawnTimeIsDefault{}; inStream->Read(coinSpawnTimeIsDefault); if (coinSpawnTimeIsDefault != 0) inStream->Read(coinSpawnTime); @@ -5343,7 +5376,7 @@ void GameMessages::HandleEquipItem(RakNet::BitStream* inStream, Entity* entity) if (!item) return; item->Equip(); - + EntityManager::Instance()->SerializeEntity(entity); } @@ -5361,9 +5394,9 @@ void GameMessages::HandleUnequipItem(RakNet::BitStream* inStream, Entity* entity auto* item = inv->FindItemById(objectID); if (!item) return; - + item->UnEquip(); - + EntityManager::Instance()->SerializeEntity(entity); } @@ -5439,9 +5472,9 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En { return; } - + iStackCount = std::min<uint32_t>(item->GetCount(), iStackCount); - + if (bConfirmed) { for (auto i = 0; i < iStackCount; ++i) { if (eInvType == eInventoryType::MODELS) @@ -5454,7 +5487,7 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En EntityManager::Instance()->SerializeEntity(entity); auto* missionComponent = entity->GetComponent<MissionComponent>(); - + if (missionComponent != nullptr) { missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, item->GetLot(), LWOOBJID_EMPTY, "", -iStackCount); @@ -5525,7 +5558,7 @@ void GameMessages::HandleMoveItemBetweenInventoryTypes(RakNet::BitStream* inStre } } } - + if (entity->GetCharacter()) { if (entity->GetCharacter()->GetBuildMode()) { showFlyingLoot = false; @@ -5543,7 +5576,7 @@ void GameMessages::HandleBuildModeSet(RakNet::BitStream* inStream, Entity* entit // there's more here but we don't need it (for now?) Game::logger->Log("GameMessages", "Set build mode to (%d) for (%llu)\n", bStart, entity->GetObjectID()); - + if (entity->GetCharacter()) { entity->GetCharacter()->SetBuildMode(bStart); } @@ -5607,7 +5640,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* } auto* missionComponent = character->GetComponent<MissionComponent>(); - + if (entity->GetLOT() != 9980 || Game::server->GetZoneID() != 1200) { if (missionComponent != nullptr) @@ -5686,7 +5719,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti inStream->Read(oldItemTYPE); /* - Game::logger->Log("GameMessages", + Game::logger->Log("GameMessages", "\nnewSourceBAG: %d\nnewSourceID: %llu\nnewSourceLOT: %d\nnewSourceTYPE: %d\nnewTargetID: %llu\nnewTargetLOT: %d\nnewTargetTYPE: %d\nnewTargetPOS: %f, %f, %f\noldItemBAG: %d\noldItemID: %llu\noldItemLOT: %d\noldItemTYPE: %d\n", newSourceBAG, newSourceID, newSourceLOT, newSourceTYPE, newTargetID, newTargetLOT, newTargetTYPE, newTargetPOS.x, newTargetPOS.y, newTargetPOS.z, oldItemBAG, oldItemID, oldItemLOT, oldItemTYPE ); @@ -5694,7 +5727,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti if (PropertyManagementComponent::Instance() != nullptr) { const auto& buildAreas = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_BUILD_BORDER); - + const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque"); Entity* buildArea; @@ -5704,7 +5737,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti } else if (!entities.empty()) { buildArea = entities[0]; - + Game::logger->Log("BuildBorderComponent", "Using PropertyPlaque\n"); } else { @@ -5839,7 +5872,7 @@ void GameMessages::HandleClientItemConsumed(RakNet::BitStream* inStream, Entity* inStream->Read(itemConsumed); auto* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); - + if (inventory == nullptr) { return; @@ -5866,13 +5899,13 @@ void GameMessages::HandleUseNonEquipmentItem(RakNet::BitStream* inStream, Entity LWOOBJID itemConsumed; inStream->Read(itemConsumed); - + auto* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); - + if (!inv) return; auto* item = inv->FindItemById(itemConsumed); - + if (item == nullptr) { return; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 1d42eebc..18e1467e 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -328,6 +328,34 @@ namespace GameMessages { void SendDisplayChatBubble(LWOOBJID objectId, const std::u16string& text, const SystemAddress& sysAddr); + // Mounts + /** + * @brief Set the Inventory LWOOBJID of the mount + * + * @param entity The entity that is mounting + * @param sysAddr the system address to send game message responses to + * @param objectID LWOOBJID of the item in inventory that is being used + */ + void SendSetMountInventoryID(Entity* entity, const LWOOBJID& objectID, const SystemAddress& sysAddr); + + /** + * @brief Handle client dismounting mount + * + * @param inStream Raknet BitStream of incoming data + * @param entity The Entity that is dismounting + * @param sysAddr the system address to send game message responses to + */ + void HandleDismountComplete(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); + + /** + * @brief Handle acknowledging that the client possessed something + * + * @param inStream Raknet BitStream of incoming data + * @param entity The Entity that is possessing + * @param sysAddr the system address to send game message responses to + */ + void HandleAcknowledgePossession(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); + //Racing: void HandleModuleAssemblyQueryData(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); @@ -337,8 +365,6 @@ namespace GameMessages { void HandleRacingClientReady(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); - void HandleAcknowledgePossession(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); - void HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleVehicleNotifyServerAddPassiveBoostAction(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); diff --git a/dNet/dMessageIdentifiers.h b/dNet/dMessageIdentifiers.h index 5b2ff639..5ad3921c 100644 --- a/dNet/dMessageIdentifiers.h +++ b/dNet/dMessageIdentifiers.h @@ -535,8 +535,10 @@ enum GAME_MSG : unsigned short { GAME_MSG_REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1666, GAME_MSG_RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1667, GAME_MSG_PLAYER_SET_CAMERA_CYCLING_MODE = 1676, + GAME_MSG_SET_MOUNT_INVENTORY_ID = 1726, GAME_MSG_NOTIFY_SERVER_LEVEL_PROCESSING_COMPLETE = 1734, GAME_MSG_NOTIFY_LEVEL_REWARDS = 1735, + GAME_MSG_DISMOUNT_COMPLETE = 1756, GAME_MSG_MARK_INVENTORY_ITEM_AS_ACTIVE = 1767, END }; \ No newline at end of file