From 0c1ee0513d1d3fb19709da8c9bb2513290639259 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 10 Feb 2024 05:05:25 -0600 Subject: [PATCH] refactor: Change TryParse implementation (#1442) * Changed how the TryParse function works (and also did some general cleanup along the way) * Update noexcept attributes (verified these are correct) * Add fp overload for MacOS functionality * resolving some feedback * Split out unrelated changes to CleanupRoundup branch * Update in response to feedback * the consequences of emo's member variable renaming request * Revert "the consequences of emo's member variable renaming request" This reverts commit bf318caeda34f4439c1769fd7d5b77d341f7f646. * Fully revert renaming attempt * Revert "the consequences of emo's member variable renaming request" This reverts commit bf318caeda34f4439c1769fd7d5b77d341f7f646. Fully revert renaming attempt * Created ClientVersion.h and moved the client version defaults to it * Fix partial parsing and MacOS floating point errors * attempting fix to MacOS compiler error * syntax pass (should be the last commit unless the CI fails) * ah, wait, forgot to uncomment the preprocessor statements for MacOS. THIS should be the last commit pending CI * Okay, one last thing I noticed: We were including C headers here. Now they're C++ headers. Pinky swear this is it! * typo and I am OCD. please let this be the last * hash is usally but not always noexcept, so the specifier should go * Address MOST of the feedback * address the claim codes issue --- dAuthServer/AuthServer.cpp | 8 +- dChatServer/ChatServer.cpp | 9 +- dChatServer/PlayerContainer.cpp | 6 +- dCommon/GeneralUtils.cpp | 4 - dCommon/GeneralUtils.h | 160 ++++--- dCommon/LDFFormat.cpp | 38 +- dCommon/dClient/CMakeLists.txt | 2 +- dCommon/dClient/ClientVersion.h | 12 + dGame/Entity.cpp | 6 +- dGame/Entity.h | 10 +- dGame/dComponents/ActivityComponent.cpp | 3 +- dGame/dComponents/QuickBuildComponent.cpp | 9 +- dGame/dComponents/QuickBuildComponent.h | 2 +- dGame/dComponents/RenderComponent.cpp | 10 +- dGame/dComponents/TriggerComponent.cpp | 59 ++- dGame/dInventory/Item.cpp | 8 +- dGame/dInventory/ItemSet.cpp | 6 +- dGame/dMission/MissionTask.cpp | 12 +- .../BehaviorMessageBase.cpp | 7 +- dGame/dUtilities/Preconditions.cpp | 6 +- dGame/dUtilities/SlashCommandHandler.cpp | 400 +++++++++--------- dMasterServer/InstanceManager.cpp | 3 +- dMasterServer/InstanceManager.h | 2 +- dMasterServer/MasterServer.cpp | 3 +- dNet/AuthPackets.cpp | 23 +- dPhysics/dpWorld.cpp | 10 +- .../02_server/Map/AM/AmDropshipComputer.cpp | 14 +- dScripts/02_server/Map/AM/AmSkullkinTower.cpp | 9 +- .../Map/AM/AmTemplateSkillVolume.cpp | 9 +- dScripts/ChooseYourDestinationNsToNt.cpp | 10 +- dScripts/ai/FV/FvBrickPuzzleServer.cpp | 16 +- dWorldServer/WorldServer.cpp | 3 +- dZoneManager/Level.cpp | 13 +- 33 files changed, 451 insertions(+), 441 deletions(-) create mode 100644 dCommon/dClient/ClientVersion.h diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 5593f0e19..476e1a689 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -82,11 +82,11 @@ int main(int argc, char** argv) { Game::randomEngine = std::mt19937(time(0)); //It's safe to pass 'localhost' here, as the IP is only used as the external IP. - uint32_t maxClients = 999; - uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. std::string ourIP = "localhost"; - GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients); - GeneralUtils::TryParse(Game::config->GetValue("auth_server_port"), ourPort); + const uint32_t maxClients = GeneralUtils::TryParse(Game::config->GetValue("max_clients")).value_or(999); + + //LU client is hardcoded to use this for auth port, so I'm making it the default. + const uint32_t ourPort = GeneralUtils::TryParse(Game::config->GetValue("auth_server_port")).value_or(1001); const auto externalIPString = Game::config->GetValue("external_ip"); if (!externalIPString.empty()) ourIP = externalIPString; diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index d04cbd010..449570421 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -99,18 +99,15 @@ int main(int argc, char** argv) { masterPort = masterInfo->port; } //It's safe to pass 'localhost' here, as the IP is only used as the external IP. - uint32_t maxClients = 999; - uint32_t ourPort = 1501; std::string ourIP = "localhost"; - GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients); - GeneralUtils::TryParse(Game::config->GetValue("chat_server_port"), ourPort); + const uint32_t maxClients = GeneralUtils::TryParse(Game::config->GetValue("max_clients")).value_or(999); + const uint32_t ourPort = GeneralUtils::TryParse(Game::config->GetValue("chat_server_port")).value_or(1501); const auto externalIPString = Game::config->GetValue("external_ip"); if (!externalIPString.empty()) ourIP = externalIPString; Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal); - bool dontGenerateDCF = false; - GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf"), dontGenerateDCF); + const bool dontGenerateDCF = GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf")).value_or(false); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF); Game::randomEngine = std::mt19937(time(0)); diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index 95bafd8b9..7d8d7d974 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -15,8 +15,10 @@ #include "dConfig.h" void PlayerContainer::Initialize() { - GeneralUtils::TryParse(Game::config->GetValue("max_number_of_best_friends"), m_MaxNumberOfBestFriends); - GeneralUtils::TryParse(Game::config->GetValue("max_number_of_friends"), m_MaxNumberOfFriends); + m_MaxNumberOfBestFriends = + GeneralUtils::TryParse(Game::config->GetValue("max_number_of_best_friends")).value_or(m_MaxNumberOfBestFriends); + m_MaxNumberOfFriends = + GeneralUtils::TryParse(Game::config->GetValue("max_number_of_friends")).value_or(m_MaxNumberOfFriends); } PlayerContainer::~PlayerContainer() { diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index b45165fa2..78cf4f485 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -319,7 +319,3 @@ std::vector GeneralUtils::GetSqlFileNamesFromFolder(const std::stri return sortedFiles; } - -bool GeneralUtils::TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst) { - return TryParse(x.c_str(), dst.x) && TryParse(y.c_str(), dst.y) && TryParse(z.c_str(), dst.z); -} diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 37291ab80..15659912b 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -1,17 +1,20 @@ #pragma once // C++ -#include +#include +#include #include -#include +#include #include -#include +#include +#include #include #include #include #include "BitStream.h" #include "NiPoint3.h" +#include "dPlatforms.h" #include "Game.h" #include "Logger.h" @@ -123,90 +126,125 @@ namespace GeneralUtils { std::vector GetSqlFileNamesFromFolder(const std::string& folder); + // Concept constraining to enum types template - T Parse(const char* value); + concept Enum = std::is_enum_v; - template <> - inline bool Parse(const char* value) { - return std::stoi(value); - } + // Concept constraining to numeric types + template + concept Numeric = std::integral || Enum || std::floating_point; - template <> - inline int32_t Parse(const char* value) { - return std::stoi(value); - } + // Concept trickery to enable parsing underlying numeric types + template + struct numeric_parse { using type = T; }; - template <> - inline int64_t Parse(const char* value) { - return std::stoll(value); - } + // If an enum, present an alias to its underlying type for parsing + template requires Enum + struct numeric_parse { using type = std::underlying_type_t; }; - template <> - inline float Parse(const char* value) { - return std::stof(value); - } + // If a boolean, present an alias to an intermediate integral type for parsing + template requires std::same_as + struct numeric_parse { using type = uint32_t; }; - template <> - inline double Parse(const char* value) { - return std::stod(value); - } + // Shorthand type alias + template + using numeric_parse_t = numeric_parse::type; - template <> - inline uint16_t Parse(const char* value) { - return std::stoul(value); - } + /** + * For numeric values: Parses a string_view and returns an optional variable depending on the result. + * @param str The string_view to be evaluated + * @returns An std::optional containing the desired value if it is equivalent to the string + */ + template + [[nodiscard]] std::optional TryParse(const std::string_view str) { + numeric_parse_t result; - template <> - inline uint32_t Parse(const char* value) { - return std::stoul(value); - } + const char* const strEnd = str.data() + str.size(); + const auto [parseEnd, ec] = std::from_chars(str.data(), strEnd, result); + const bool isParsed = parseEnd == strEnd && ec == std::errc{}; - template <> - inline uint64_t Parse(const char* value) { - return std::stoull(value); + return isParsed ? static_cast(result) : std::optional{}; } - template <> - inline eInventoryType Parse(const char* value) { - return static_cast(std::stoul(value)); - } +#ifdef DARKFLAME_PLATFORM_MACOS - template <> - inline eReplicaComponentType Parse(const char* value) { - return static_cast(std::stoul(value)); - } + // Anonymous namespace containing MacOS floating-point parse function specializations + namespace { + template + [[nodiscard]] T Parse(const std::string_view str, size_t* parseNum); - template - bool TryParse(const char* value, T& dst) { - try { - dst = Parse(value); + template <> + [[nodiscard]] float Parse(const std::string_view str, size_t* parseNum) { + return std::stof(std::string{ str }, parseNum); + } - return true; - } catch (...) { - return false; + template <> + [[nodiscard]] double Parse(const std::string_view str, size_t* parseNum) { + return std::stod(std::string{ str }, parseNum); + } + + template <> + [[nodiscard]] long double Parse(const std::string_view str, size_t* parseNum) { + return std::stold(std::string{ str }, parseNum); } } - template - T Parse(const std::string& value) { - return Parse(value.c_str()); + /** + * For floating-point values: Parses a string_view and returns an optional variable depending on the result. + * Note that this function overload is only included for MacOS, as from_chars will fulfill its purpose otherwise. + * @param str The string_view to be evaluated + * @returns An std::optional containing the desired value if it is equivalent to the string + */ + template + [[nodiscard]] std::optional TryParse(const std::string_view str) noexcept try { + size_t parseNum; + const T result = Parse(str, &parseNum); + const bool isParsed = str.length() == parseNum; + + return isParsed ? result : std::optional{}; + } catch (...) { + return std::nullopt; } +#endif + + /** + * The TryParse overload for handling NiPoint3 by passing 3 seperate string references + * @param strX The string representing the X coordinate + * @param strY The string representing the Y coordinate + * @param strZ The string representing the Z coordinate + * @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters + */ template - bool TryParse(const std::string& value, T& dst) { - return TryParse(value.c_str(), dst); + [[nodiscard]] std::optional TryParse(const std::string& strX, const std::string& strY, const std::string& strZ) { + const auto x = TryParse(strX); + if (!x) return std::nullopt; + + const auto y = TryParse(strY); + if (!y) return std::nullopt; + + const auto z = TryParse(strZ); + return z ? std::make_optional(x.value(), y.value(), z.value()) : std::nullopt; } - bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst); + /** + * The TryParse overload for handling NiPoint3 by passingn a reference to a vector of three strings + * @param str The string vector representing the X, Y, and Xcoordinates + * @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters + */ + template + [[nodiscard]] std::optional TryParse(const std::vector& str) { + return (str.size() == 3) ? TryParse(str[0], str[1], str[2]) : std::nullopt; + } - template + template std::u16string to_u16string(T value) { return GeneralUtils::ASCIIToUTF16(std::to_string(value)); } // From boost::hash_combine template - void hash_combine(std::size_t& s, const T& v) { + constexpr void hash_combine(std::size_t& s, const T& v) { std::hash h; s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2); } @@ -239,10 +277,8 @@ namespace GeneralUtils { * @param entry Enum entry to cast * @returns The enum entry's value in its underlying type */ - template - inline constexpr typename std::underlying_type_t CastUnderlyingType(const eType entry) { - static_assert(std::is_enum_v, "Not an enum"); - + template + constexpr typename std::underlying_type_t CastUnderlyingType(const eType entry) noexcept { return static_cast>(entry); } diff --git a/dCommon/LDFFormat.cpp b/dCommon/LDFFormat.cpp index 67f6a6300..da28ae6e0 100644 --- a/dCommon/LDFFormat.cpp +++ b/dCommon/LDFFormat.cpp @@ -61,33 +61,33 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) { } case LDF_TYPE_S32: { - int32_t data; - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto data = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!data) { LOG("Warning: Attempted to process invalid int32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } - returnValue = new LDFData(key, data); + returnValue = new LDFData(key, data.value()); break; } case LDF_TYPE_FLOAT: { - float data; - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto data = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!data) { LOG("Warning: Attempted to process invalid float value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } - returnValue = new LDFData(key, data); + returnValue = new LDFData(key, data.value()); break; } case LDF_TYPE_DOUBLE: { - double data; - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto data = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!data) { LOG("Warning: Attempted to process invalid double value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } - returnValue = new LDFData(key, data); + returnValue = new LDFData(key, data.value()); break; } @@ -100,10 +100,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) { } else if (ldfTypeAndValue.second == "false") { data = 0; } else { - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto dataOptional = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!dataOptional) { LOG("Warning: Attempted to process invalid uint32 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } + data = dataOptional.value(); } returnValue = new LDFData(key, data); @@ -118,10 +120,12 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) { } else if (ldfTypeAndValue.second == "false") { data = false; } else { - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto dataOptional = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!dataOptional) { LOG("Warning: Attempted to process invalid bool value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } + data = dataOptional.value(); } returnValue = new LDFData(key, data); @@ -129,22 +133,22 @@ LDFBaseData* LDFBaseData::DataFromString(const std::string_view& format) { } case LDF_TYPE_U64: { - uint64_t data; - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto data = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!data) { LOG("Warning: Attempted to process invalid uint64 value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } - returnValue = new LDFData(key, data); + returnValue = new LDFData(key, data.value()); break; } case LDF_TYPE_OBJID: { - LWOOBJID data; - if (!GeneralUtils::TryParse(ldfTypeAndValue.second.data(), data)) { + const auto data = GeneralUtils::TryParse(ldfTypeAndValue.second); + if (!data) { LOG("Warning: Attempted to process invalid LWOOBJID value (%s) from string (%s)", ldfTypeAndValue.second.data(), format.data()); return nullptr; } - returnValue = new LDFData(key, data); + returnValue = new LDFData(key, data.value()); break; } diff --git a/dCommon/dClient/CMakeLists.txt b/dCommon/dClient/CMakeLists.txt index 69bb17127..017a22a52 100644 --- a/dCommon/dClient/CMakeLists.txt +++ b/dCommon/dClient/CMakeLists.txt @@ -1,6 +1,6 @@ set(DCOMMON_DCLIENT_SOURCES + "AssetManager.cpp" "PackIndex.cpp" "Pack.cpp" - "AssetManager.cpp" PARENT_SCOPE ) diff --git a/dCommon/dClient/ClientVersion.h b/dCommon/dClient/ClientVersion.h new file mode 100644 index 000000000..393103ab4 --- /dev/null +++ b/dCommon/dClient/ClientVersion.h @@ -0,0 +1,12 @@ +#ifndef __CLIENTVERSION_H__ +#define __CLIENTVERSION_H__ + +#include + +namespace ClientVersion { + constexpr uint16_t major = 1; + constexpr uint16_t current = 10; + constexpr uint16_t minor = 64; +} + +#endif // !__CLIENTVERSION_H__ diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 84bdca213..161698878 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -452,10 +452,10 @@ void Entity::Initialize() { if (!setFaction.empty()) { // TODO also split on space here however we do not have a general util for splitting on multiple characters yet. std::vector factionsToAdd = GeneralUtils::SplitString(setFaction, ';'); - int32_t factionToAdd; for (const auto faction : factionsToAdd) { - if (GeneralUtils::TryParse(faction, factionToAdd)) { - comp->AddFaction(factionToAdd, true); + const auto factionToAdd = GeneralUtils::TryParse(faction); + if (factionToAdd) { + comp->AddFaction(factionToAdd.value(), true); } } } diff --git a/dGame/Entity.h b/dGame/Entity.h index eb6eb956c..6546e458f 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -395,14 +395,8 @@ const T& Entity::GetVar(const std::u16string& name) const { template T Entity::GetVarAs(const std::u16string& name) const { const auto data = GetVarAsString(name); - - T value; - - if (!GeneralUtils::TryParse(data, value)) { - return LDFData::Default; - } - - return value; + + return GeneralUtils::TryParse(data).value_or(LDFData::Default); } template diff --git a/dGame/dComponents/ActivityComponent.cpp b/dGame/dComponents/ActivityComponent.cpp index 376251d25..49ca4faf1 100644 --- a/dGame/dComponents/ActivityComponent.cpp +++ b/dGame/dComponents/ActivityComponent.cpp @@ -83,7 +83,8 @@ void ActivityComponent::LoadActivityData(const int32_t activityId) { if (m_ActivityInfo.instanceMapID == -1) { const auto& transferOverride = m_Parent->GetVarAsString(u"transferZoneID"); if (!transferOverride.empty()) { - GeneralUtils::TryParse(transferOverride, m_ActivityInfo.instanceMapID); + m_ActivityInfo.instanceMapID = + GeneralUtils::TryParse(transferOverride).value_or(m_ActivityInfo.instanceMapID); } } } diff --git a/dGame/dComponents/QuickBuildComponent.cpp b/dGame/dComponents/QuickBuildComponent.cpp index 1e745d8af..2514f194a 100644 --- a/dGame/dComponents/QuickBuildComponent.cpp +++ b/dGame/dComponents/QuickBuildComponent.cpp @@ -33,10 +33,9 @@ QuickBuildComponent::QuickBuildComponent(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 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)) { + const auto activatorPositionValid = GeneralUtils::TryParse(positionAsVector); + if (positionAsVector.size() == 3 && activatorPositionValid) { + m_ActivatorPosition = activatorPositionValid.value(); } else { LOG("Failed to find activator position for lot %i. Defaulting to parents position.", m_Parent->GetLOT()); m_ActivatorPosition = m_Parent->GetPosition(); @@ -328,7 +327,7 @@ float QuickBuildComponent::GetTimeBeforeSmash() { return m_TimeBeforeSmash; } -eQuickBuildState QuickBuildComponent::GetState() { +eQuickBuildState QuickBuildComponent::GetState() const noexcept { return m_State; } diff --git a/dGame/dComponents/QuickBuildComponent.h b/dGame/dComponents/QuickBuildComponent.h index d989bc510..d9cc41900 100644 --- a/dGame/dComponents/QuickBuildComponent.h +++ b/dGame/dComponents/QuickBuildComponent.h @@ -173,7 +173,7 @@ class QuickBuildComponent final : public Component { * Returns the current quickbuild state * @return the current quickbuild state */ - eQuickBuildState GetState(); + [[nodiscard]] eQuickBuildState GetState() const noexcept; /** * Returns the player that is currently building this quickbuild diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index d3c74f786..118e48478 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -30,13 +30,15 @@ RenderComponent::RenderComponent(Entity* const parentEntity, const int32_t compo auto* animationsTable = CDClientManager::GetTable(); auto groupIdsSplit = GeneralUtils::SplitString(animationGroupIDs, ','); for (auto& groupId : groupIdsSplit) { - int32_t groupIdInt; - if (!GeneralUtils::TryParse(groupId, groupIdInt)) { + const auto groupIdInt = GeneralUtils::TryParse(groupId); + + if (!groupIdInt) { LOG("bad animation group Id %s", groupId.c_str()); continue; } - m_animationGroupIds.push_back(groupIdInt); - animationsTable->CacheAnimationGroup(groupIdInt); + + m_animationGroupIds.push_back(groupIdInt.value()); + animationsTable->CacheAnimationGroup(groupIdInt.value()); } } } diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index bb297dbc2..5d4415f87 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -21,10 +21,8 @@ TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo std::vector tokens = GeneralUtils::SplitString(triggerInfo, ':'); - uint32_t sceneID; - GeneralUtils::TryParse(tokens.at(0), sceneID); - uint32_t triggerID; - GeneralUtils::TryParse(tokens.at(1), triggerID); + const auto sceneID = GeneralUtils::TryParse(tokens.at(0)).value_or(0); + const auto triggerID = GeneralUtils::TryParse(tokens.at(1)).value_or(0); m_Trigger = Game::zoneManager->GetZone()->GetTrigger(sceneID, triggerID); @@ -190,9 +188,8 @@ void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { } void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){ - uint32_t killType; - GeneralUtils::TryParse(args, killType); - targetEntity->Smash(m_Parent->GetObjectID(), static_cast(killType)); + const eKillType killType = GeneralUtils::TryParse(args).value_or(eKillType::VIOLENT); + targetEntity->Smash(m_Parent->GetObjectID(), killType); } void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args){ @@ -216,9 +213,8 @@ void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector argArray){ if (argArray.size() <= 2) return; - auto position = targetEntity->GetPosition(); - NiPoint3 offset = NiPoint3Constant::ZERO; - GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), offset); + NiPoint3 position = targetEntity->GetPosition(); + const NiPoint3 offset = GeneralUtils::TryParse(argArray).value_or(NiPoint3Constant::ZERO); position += offset; targetEntity->SetPosition(position); @@ -227,8 +223,7 @@ void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector argArray){ if (argArray.size() <= 2) return; - NiPoint3 vector = NiPoint3Constant::ZERO; - GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), vector); + const NiPoint3 vector = GeneralUtils::TryParse(argArray).value_or(NiPoint3Constant::ZERO); NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector); targetEntity->SetRotation(rotation); @@ -245,8 +240,7 @@ void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vectorSetPhysicsEffectActive(true); phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); phantomPhysicsComponent->SetDirectionalMultiplier(1); - NiPoint3 direction = NiPoint3Constant::ZERO; - GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction); + const NiPoint3 direction = GeneralUtils::TryParse(argArray).value_or(NiPoint3Constant::ZERO); phantomPhysicsComponent->SetDirection(direction); Game::entityManager->SerializeEntity(m_Parent); @@ -259,8 +253,8 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args) LOG_DEBUG("Phantom Physics component not found!"); return; } - float forceMultiplier; - GeneralUtils::TryParse(args, forceMultiplier); + const float forceMultiplier = GeneralUtils::TryParse(args).value_or(1.0f); + phantomPhysicsComponent->SetPhysicsEffectActive(true); phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE); phantomPhysicsComponent->SetDirectionalMultiplier(forceMultiplier); @@ -279,11 +273,10 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args) void TriggerComponent::HandleSetTimer(Entity* targetEntity, std::vector argArray){ if (argArray.size() != 2) { - LOG_DEBUG("Not ehought variables!"); + LOG_DEBUG("Not enough variables!"); return; } - float time = 0.0; - GeneralUtils::TryParse(argArray.at(1), time); + const float time = GeneralUtils::TryParse(argArray.at(1)).value_or(0.0f); m_Parent->AddTimer(argArray.at(0), time); } @@ -299,7 +292,7 @@ void TriggerComponent::HandlePlayCinematic(Entity* targetEntity, std::vector= 2) { - GeneralUtils::TryParse(argArray.at(1), leadIn); + leadIn = GeneralUtils::TryParse(argArray.at(1)).value_or(leadIn); if (argArray.size() >= 3 && argArray.at(2) == "wait") { wait = eEndBehavior::WAIT; if (argArray.size() >= 4 && argArray.at(3) == "unlock") { @@ -344,12 +337,16 @@ void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector argArray) { if (argArray.size() < 3) return; - int32_t effectID = 0; - if (!GeneralUtils::TryParse(argArray.at(1), effectID)) return; + const auto effectID = GeneralUtils::TryParse(argArray.at(1)); + if (!effectID) return; std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2)); + float priority = 1; - if (argArray.size() == 4) GeneralUtils::TryParse(argArray.at(3), priority); - GameMessages::SendPlayFXEffect(targetEntity, effectID, effectType, argArray.at(0), LWOOBJID_EMPTY, priority); + if (argArray.size() == 4) { + priority = GeneralUtils::TryParse(argArray.at(3)).value_or(priority); + } + + GameMessages::SendPlayFXEffect(targetEntity, effectID.value(), effectType, argArray.at(0), LWOOBJID_EMPTY, priority); } void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){ @@ -358,8 +355,7 @@ void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){ LOG_DEBUG("Skill component not found!"); return; } - uint32_t skillId; - GeneralUtils::TryParse(args, skillId); + const uint32_t skillId = GeneralUtils::TryParse(args).value_or(0); skillComponent->CastSkill(skillId, targetEntity->GetObjectID()); } @@ -381,17 +377,16 @@ void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::v phantomPhysicsComponent->SetEffectType(effectType); phantomPhysicsComponent->SetDirectionalMultiplier(std::stof(argArray.at(1))); if (argArray.size() > 4) { - NiPoint3 direction = NiPoint3Constant::ZERO; - GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), direction); + const NiPoint3 direction = + GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4)).value_or(NiPoint3Constant::ZERO); + phantomPhysicsComponent->SetDirection(direction); } if (argArray.size() > 5) { - uint32_t min; - GeneralUtils::TryParse(argArray.at(6), min); + const uint32_t min = GeneralUtils::TryParse(argArray.at(6)).value_or(0); phantomPhysicsComponent->SetMin(min); - uint32_t max; - GeneralUtils::TryParse(argArray.at(7), max); + const uint32_t max = GeneralUtils::TryParse(argArray.at(7)).value_or(0); phantomPhysicsComponent->SetMax(max); } diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 55b0a2d03..d3f15315a 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -468,14 +468,14 @@ void Item::DisassembleModel(uint32_t numToDismantle) { // First iteration gets the count std::map parts; while (currentBrick) { - auto* designID = currentBrick->Attribute("designID"); + const char* const designID = currentBrick->Attribute("designID"); if (designID) { - uint32_t designId; - if (!GeneralUtils::TryParse(designID, designId)) { + const auto designId = GeneralUtils::TryParse(designID); + if (!designId) { LOG("Failed to parse designID %s", designID); continue; } - parts[designId]++; + parts[designId.value()]++; } currentBrick = currentBrick->NextSiblingElement(searchTerm.c_str()); diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index 54db9e9cb..1d0867866 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -87,10 +87,8 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) { m_Items = {}; while (std::getline(stream, token, ',')) { - int32_t value; - if (GeneralUtils::TryParse(token, value)) { - m_Items.push_back(value); - } + const auto validToken = GeneralUtils::TryParse(token); + if (validToken) m_Items.push_back(validToken.value()); } m_Equipped = {}; diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index 604276eca..2fe9bc9fa 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -27,19 +27,15 @@ MissionTask::MissionTask(Mission* mission, CDMissionTasks* info, uint32_t mask) std::string token; while (std::getline(stream, token, ',')) { - uint32_t parameter; - if (GeneralUtils::TryParse(token, parameter)) { - parameters.push_back(parameter); - } + const auto parameter = GeneralUtils::TryParse(token); + if (parameter) parameters.push_back(parameter.value()); } stream = std::istringstream(info->targetGroup); while (std::getline(stream, token, ',')) { - uint32_t parameter; - if (GeneralUtils::TryParse(token, parameter)) { - targets.push_back(parameter); - } + const auto parameter = GeneralUtils::TryParse(token); + if (parameter) targets.push_back(parameter.value()); } } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp index cc817cd71..0aad74dd8 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -5,7 +5,7 @@ #include "dCommonVars.h" BehaviorMessageBase::BehaviorMessageBase(AMFArrayValue* arguments) { - behaviorId = GetBehaviorIdFromArgument(arguments); + this->behaviorId = GetBehaviorIdFromArgument(arguments); } int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) { @@ -13,12 +13,13 @@ int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) auto* behaviorIDValue = arguments->Get(key); if (behaviorIDValue && behaviorIDValue->GetValueType() == eAmf::String) { - GeneralUtils::TryParse(behaviorIDValue->GetValue(), behaviorId); + this->behaviorId = + GeneralUtils::TryParse(behaviorIDValue->GetValue()).value_or(this->behaviorId); } else if (arguments->Get(key) && arguments->Get(key)->GetValueType() != eAmf::Undefined) { throw std::invalid_argument("Unable to find behavior ID"); } - return behaviorId; + return this->behaviorId; } int32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index 12059b5bf..bd855962c 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -40,10 +40,8 @@ Precondition::Precondition(const uint32_t condition) { std::string token; while (std::getline(stream, token, ',')) { - uint32_t value; - if (GeneralUtils::TryParse(token, value)) { - this->values.push_back(value); - } + const auto validToken = GeneralUtils::TryParse(token); + if (validToken) this->values.push_back(validToken.value()); } } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index ef12c396d..169426abe 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -113,13 +113,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > eGameMasterLevel::CIVILIAN) { if (args.size() != 1) return; - uint32_t level_intermed = 0; + const auto level_intermed = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], level_intermed)) { + if (!level_intermed) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid gm level."); return; } - eGameMasterLevel level = static_cast(level_intermed); + eGameMasterLevel level = static_cast(level_intermed.value()); #ifndef DEVELOPER_SERVER if (user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER) { @@ -378,26 +378,27 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "resetmission" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - uint32_t missionId; - if (!GeneralUtils::TryParse(args[0], missionId)) { + const auto missionId = GeneralUtils::TryParse(args[0]); + if (!missionId) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission ID."); return; } auto* missionComponent = entity->GetComponent(); if (!missionComponent) return; - missionComponent->ResetMission(missionId); + missionComponent->ResetMission(missionId.value()); } // Log command to database Database::Get()->InsertSlashCommandUsage(entity->GetObjectID(), chatCommand); if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { // could break characters so only allow if GM > 0 - int32_t minifigItemId; - if (!GeneralUtils::TryParse(args[1], minifigItemId)) { + const auto minifigItemIdExists = GeneralUtils::TryParse(args[1]); + if (!minifigItemIdExists) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID."); return; } + const int32_t minifigItemId = minifigItemIdExists.value(); Game::entityManager->DestructEntity(entity, sysAddr); auto* charComp = entity->GetComponent(); std::string lowerName = args[0]; @@ -457,14 +458,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - int32_t emoteID; + const auto emoteID = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], emoteID)) { + if (!emoteID) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid emote ID."); return; } - entity->GetCharacter()->UnlockEmote(emoteID); + entity->GetCharacter()->UnlockEmote(emoteID.value()); } if (chatCommand == "force-save" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -486,19 +487,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - float boost; - - if (!GeneralUtils::TryParse(args[0], boost)) { + const auto boostOptional = GeneralUtils::TryParse(args[0]); + if (!boostOptional) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid boost."); return; } + const float boost = boostOptional.value(); auto* controllablePhysicsComponent = entity->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->SetSpeedMultiplier(boost); - // speedboost possesables + // speedboost possessables auto possessor = entity->GetComponent(); if (possessor) { auto possessedID = possessor->GetPossessable(); @@ -527,14 +528,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - uint32_t scheme; + const auto scheme = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], scheme)) { + if (!scheme) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid control scheme."); return; } - GameMessages::SendSetPlayerControlScheme(entity, static_cast(scheme)); + GameMessages::SendSetPlayerControlScheme(entity, static_cast(scheme.value())); ChatPackets::SendSystemMessage(sysAddr, u"Switched control scheme."); return; @@ -574,29 +575,28 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { - uint32_t size; - - if (!GeneralUtils::TryParse(args.at(0), size)) { + const auto sizeOptional = GeneralUtils::TryParse(args[0]); + if (!sizeOptional) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid size."); return; } + const uint32_t size = sizeOptional.value(); eInventoryType selectedInventory = eInventoryType::ITEMS; // a possible inventory was provided if we got more than 1 argument if (args.size() >= 2) { - selectedInventory = eInventoryType::INVALID; - if (!GeneralUtils::TryParse(args.at(1), selectedInventory)) { + selectedInventory = GeneralUtils::TryParse(args.at(1)).value_or(eInventoryType::INVALID); + if (selectedInventory == eInventoryType::INVALID) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid inventory."); + return; + } else { // In this case, we treat the input as a string and try to find it in the reflection list std::transform(args.at(1).begin(), args.at(1).end(), args.at(1).begin(), ::toupper); for (uint32_t index = 0; index < NUMBER_OF_INVENTORIES; index++) { if (std::string_view(args.at(1)) == std::string_view(InventoryType::InventoryTypeToString(static_cast(index)))) selectedInventory = static_cast(index); } } - if (selectedInventory == eInventoryType::INVALID) { - ChatPackets::SendSystemMessage(sysAddr, u"Invalid inventory."); - return; - } ChatPackets::SendSystemMessage(sysAddr, u"Setting inventory " + GeneralUtils::ASCIIToUTF16(args.at(1)) + @@ -643,48 +643,48 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "addmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; - uint32_t missionID; + const auto missionID = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], missionID)) { + if (!missionID) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id."); return; } auto comp = static_cast(entity->GetComponent(eReplicaComponentType::MISSION)); - if (comp) comp->AcceptMission(missionID, true); + if (comp) comp->AcceptMission(missionID.value(), true); return; } if (chatCommand == "completemission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; - uint32_t missionID; + const auto missionID = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], missionID)) { + if (!missionID) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id."); return; } auto comp = static_cast(entity->GetComponent(eReplicaComponentType::MISSION)); - if (comp) comp->CompleteMission(missionID, true); + if (comp) comp->CompleteMission(missionID.value(), true); return; } if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { - int32_t flagId; + const auto flagId = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], flagId)) { + if (!flagId) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid flag id."); return; } - entity->GetCharacter()->SetPlayerFlag(flagId, true); + entity->GetCharacter()->SetPlayerFlag(flagId.value(), true); } if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 2) { - int32_t flagId; - std::string onOffFlag = args[0]; - if (!GeneralUtils::TryParse(args[1], flagId)) { + const auto flagId = GeneralUtils::TryParse(args.at(1)); + std::string onOffFlag = args.at(0); + if (!flagId) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid flag id."); return; } @@ -692,28 +692,26 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid flag type."); return; } - entity->GetCharacter()->SetPlayerFlag(flagId, onOffFlag == "on"); + entity->GetCharacter()->SetPlayerFlag(flagId.value(), onOffFlag == "on"); } if (chatCommand == "clearflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { - int32_t flagId; + const auto flagId = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], flagId)) { + if (!flagId) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid flag id."); return; } - entity->GetCharacter()->SetPlayerFlag(flagId, false); + entity->GetCharacter()->SetPlayerFlag(flagId.value(), false); } if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { - int32_t effectID = 0; + const auto effectID = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], effectID)) { - return; - } + if (!effectID) return; // FIXME: use fallible ASCIIToUTF16 conversion, because non-ascii isn't valid anyway - GameMessages::SendPlayFXEffect(entity->GetObjectID(), effectID, GeneralUtils::ASCIIToUTF16(args[1]), args[2]); + GameMessages::SendPlayFXEffect(entity->GetObjectID(), effectID.value(), GeneralUtils::ASCIIToUTF16(args.at(1)), args.at(2)); } if (chatCommand == "stopeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { @@ -775,34 +773,32 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "gmadditem" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 1) { - uint32_t itemLOT; + const auto itemLOT = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], itemLOT)) { + if (!itemLOT) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid item LOT."); return; } InventoryComponent* inventory = static_cast(entity->GetComponent(eReplicaComponentType::INVENTORY)); - inventory->AddItem(itemLOT, 1, eLootSourceType::MODERATION); + inventory->AddItem(itemLOT.value(), 1, eLootSourceType::MODERATION); } else if (args.size() == 2) { - uint32_t itemLOT; - - if (!GeneralUtils::TryParse(args[0], itemLOT)) { + const auto itemLOT = GeneralUtils::TryParse(args.at(0)); + if (!itemLOT) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid item LOT."); return; } - uint32_t count; - - if (!GeneralUtils::TryParse(args[1], count)) { + const auto count = GeneralUtils::TryParse(args.at(1)); + if (!count) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid item count."); return; } InventoryComponent* inventory = static_cast(entity->GetComponent(eReplicaComponentType::INVENTORY)); - inventory->AddItem(itemLOT, count, eLootSourceType::MODERATION); + inventory->AddItem(itemLOT.value(), count.value(), eLootSourceType::MODERATION); } else { ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /gmadditem "); } @@ -822,9 +818,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit receiverID = playerInfo->id; - LOT lot; + const auto lot = GeneralUtils::TryParse(args.at(1)); - if (!GeneralUtils::TryParse(args[1], lot)) { + if (!lot) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid item lot."); return; } @@ -837,7 +833,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit mailInsert.subject = "Lost item"; mailInsert.body = "This is a replacement item for one you lost."; mailInsert.itemID = LWOOBJID_EMPTY; - mailInsert.itemLOT = lot; + mailInsert.itemLOT = lot.value(); mailInsert.itemSubkey = LWOOBJID_EMPTY; mailInsert.itemCount = 1; Database::Get()->InsertNewMail(mailInsert); @@ -871,46 +867,47 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit NiPoint3 pos{}; if (args.size() == 3) { - float x, y, z; - - if (!GeneralUtils::TryParse(args[0], x)) { + const auto x = GeneralUtils::TryParse(args.at(0)); + if (!x) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid x."); return; } - if (!GeneralUtils::TryParse(args[1], y)) { + const auto y = GeneralUtils::TryParse(args.at(1)); + if (!y) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid y."); return; } - if (!GeneralUtils::TryParse(args[2], z)) { + const auto z = GeneralUtils::TryParse(args.at(2)); + if (!z) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid z."); return; } - pos.SetX(x); - pos.SetY(y); - pos.SetZ(z); + pos.SetX(x.value()); + pos.SetY(y.value()); + pos.SetZ(z.value()); LOG("Teleporting objectID: %llu to %f, %f, %f", entity->GetObjectID(), pos.x, pos.y, pos.z); GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); } else if (args.size() == 2) { - float x, z; - - if (!GeneralUtils::TryParse(args[0], x)) { + const auto x = GeneralUtils::TryParse(args.at(0)); + if (!x) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid x."); return; } - if (!GeneralUtils::TryParse(args[1], z)) { + const auto z = GeneralUtils::TryParse(args.at(1)); + if (!z) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid z."); return; } - pos.SetX(x); + pos.SetX(x.value()); pos.SetY(0.0f); - pos.SetZ(z); + pos.SetZ(z.value()); LOG("Teleporting objectID: %llu to X: %f, Z: %f", entity->GetObjectID(), pos.x, pos.z); GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); @@ -970,10 +967,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit float speedScale = 1.0f; if (args.size() >= 1) { - float tempScaleStore; + const auto tempScaleStore = GeneralUtils::TryParse(args.at(0)); - if (GeneralUtils::TryParse(args[0], tempScaleStore)) { - speedScale = tempScaleStore; + if (tempScaleStore) { + speedScale = tempScaleStore.value(); } else { ChatPackets::SendSystemMessage(sysAddr, u"Failed to parse speed scale argument."); } @@ -1025,16 +1022,17 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit time_t expire = 1; // Default to indefinate mute if (args.size() >= 2) { - uint32_t days = 0; - uint32_t hours = 0; - if (!GeneralUtils::TryParse(args[1], days)) { + const auto days = GeneralUtils::TryParse(args[1]); + if (!days) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid days."); return; } + std::optional hours; if (args.size() >= 3) { - if (!GeneralUtils::TryParse(args[2], hours)) { + hours = GeneralUtils::TryParse(args[2]); + if (!hours) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid hours."); return; @@ -1042,8 +1040,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } expire = time(NULL); - expire += 24 * 60 * 60 * days; - expire += 60 * 60 * hours; + expire += 24 * 60 * 60 * days.value(); + expire += 60 * 60 * hours.value_or(0); } if (accountId != 0) Database::Get()->UpdateAccountUnmuteTime(accountId, expire); @@ -1143,14 +1141,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "startcelebration" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { - int32_t celebration; + const auto celebration = GeneralUtils::TryParse(args.at(0)); - if (!GeneralUtils::TryParse(args[0], celebration)) { + if (!celebration) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid celebration."); return; } - GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration); + GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration.value()); } if (chatCommand == "buffmed" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -1204,15 +1202,15 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ControllablePhysicsComponent* comp = static_cast(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!comp) return; - uint32_t lot; + const auto lot = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], lot)) { + if (!lot) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid lot."); return; } EntityInfo info; - info.lot = lot; + info.lot = lot.value(); info.pos = comp->GetPosition(); info.rot = comp->GetRotation(); info.spawner = nullptr; @@ -1233,28 +1231,29 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto controllablePhysicsComponent = entity->GetComponent(); if (!controllablePhysicsComponent) return; - LOT lot{}; - uint32_t numberToSpawn{}; - float radiusToSpawnWithin{}; - - if (!GeneralUtils::TryParse(args[0], lot)) { + const auto lot = GeneralUtils::TryParse(args[0]); + if (!lot) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid lot."); return; } - if (!GeneralUtils::TryParse(args[1], numberToSpawn) && numberToSpawn > 0) { + const auto numberToSpawnOptional = GeneralUtils::TryParse(args[1]); + if (!numberToSpawnOptional && numberToSpawnOptional.value() > 0) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid number of enemies to spawn."); return; } + uint32_t numberToSpawn = numberToSpawnOptional.value(); // Must spawn within a radius of at least 0.0f - if (!GeneralUtils::TryParse(args[2], radiusToSpawnWithin) && radiusToSpawnWithin < 0.0f) { + const auto radiusToSpawnWithinOptional = GeneralUtils::TryParse(args[2]); + if (!radiusToSpawnWithinOptional && radiusToSpawnWithinOptional.value() < 0.0f) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid radius to spawn within."); return; } + const float radiusToSpawnWithin = radiusToSpawnWithinOptional.value(); EntityInfo info; - info.lot = lot; + info.lot = lot.value(); info.spawner = nullptr; info.spawnerID = entity->GetObjectID(); info.spawnerNodeID = 0; @@ -1281,12 +1280,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - int32_t uscore; - - if (!GeneralUtils::TryParse(args[0], uscore)) { + const auto uscoreOptional = GeneralUtils::TryParse(args[0]); + if (!uscoreOptional) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid uscore."); return; } + const int32_t uscore = uscoreOptional.value(); CharacterComponent* character = entity->GetComponent(); if (character) character->SetUScore(character->GetUScore() + uscore); @@ -1294,9 +1293,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit eLootSourceType lootType = eLootSourceType::MODERATION; - int32_t type; - if (args.size() >= 2 && GeneralUtils::TryParse(args[1], type)) { - lootType = static_cast(type); + if (args.size() >= 2) { + const auto type = GeneralUtils::TryParse(args[1]); + lootType = type.value_or(lootType); } GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); @@ -1322,14 +1321,15 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity = requestedPlayer->GetOwner(); } - uint32_t requestedLevel; + const auto requestedLevelOptional = GeneralUtils::TryParse(args[0]); uint32_t oldLevel; - // first check the level is valid - if (!GeneralUtils::TryParse(args[0], requestedLevel)) { + // first check the level is valid + if (!requestedLevelOptional) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid level."); return; } + uint32_t requestedLevel = requestedLevelOptional.value(); // query to set our uscore to the correct value for this level auto characterComponent = entity->GetComponent(); @@ -1402,27 +1402,27 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if ((chatCommand == "freemoney" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) && args.size() == 1) { - int64_t money; + const auto money = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], money)) { + if (!money) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid money."); return; } auto* ch = entity->GetCharacter(); - ch->SetCoins(ch->GetCoins() + money, eLootSourceType::MODERATION); + ch->SetCoins(ch->GetCoins() + money.value(), eLootSourceType::MODERATION); } if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - int32_t money; + const auto money = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], money)) { + if (!money) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid money."); return; } auto* ch = entity->GetCharacter(); - ch->SetCoins(money, eLootSourceType::MODERATION); + ch->SetCoins(money.value(), eLootSourceType::MODERATION); } // Allow for this on even while not a GM, as it sometimes toggles incorrrectly. @@ -1435,17 +1435,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* destroyableComponent = entity->GetComponent(); - int32_t state = false; + const auto state = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], state)) { + if (!state) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid state."); return; } - if (destroyableComponent != nullptr) { - destroyableComponent->SetIsGMImmune(state); - } - + if (destroyableComponent) destroyableComponent->SetIsGMImmune(state.value()); return; } @@ -1453,53 +1450,47 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "attackimmune" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* destroyableComponent = entity->GetComponent(); - int32_t state = false; + const auto state = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], state)) { + if (!state) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid state."); return; } - if (destroyableComponent != nullptr) { - destroyableComponent->SetIsImmune(state); - } - + if (destroyableComponent) destroyableComponent->SetIsImmune(state.value()); return; } if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* buffComponent = entity->GetComponent(); - int32_t id = 0; - int32_t duration = 0; - - if (!GeneralUtils::TryParse(args[0], id)) { + const auto id = GeneralUtils::TryParse(args[0]); + if (!id) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid buff id."); return; } - if (!GeneralUtils::TryParse(args[1], duration)) { + const auto duration = GeneralUtils::TryParse(args[1]); + if (!duration) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid buff duration."); return; } - if (buffComponent != nullptr) { - buffComponent->ApplyBuff(id, duration, entity->GetObjectID()); - } - + if (buffComponent) buffComponent->ApplyBuff(id.value(), duration.value(), entity->GetObjectID()); return; } if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change..."); - uint32_t reqZone; LWOCLONEID cloneId = 0; bool force = false; - if (!GeneralUtils::TryParse(args[0], reqZone)) { + const auto reqZoneOptional = GeneralUtils::TryParse(args[0]); + if (!reqZoneOptional) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid zone."); return; } + const LWOMAPID reqZone = reqZoneOptional.value(); if (args.size() > 1) { auto index = 1; @@ -1510,9 +1501,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit force = true; } - if (args.size() > index && !GeneralUtils::TryParse(args[index], cloneId)) { - ChatPackets::SendSystemMessage(sysAddr, u"Invalid clone id."); - return; + if (args.size() > index) { + const auto cloneIdOptional = GeneralUtils::TryParse(args[index]); + if (!cloneIdOptional) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid clone id."); + return; + } + cloneId = cloneIdOptional.value(); } } @@ -1550,23 +1545,21 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "createprivate" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { - uint32_t zone; - - if (!GeneralUtils::TryParse(args[0], zone)) { + const auto zone = GeneralUtils::TryParse(args[0]); + if (!zone) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid zone."); return; } - uint32_t clone; - - if (!GeneralUtils::TryParse(args[1], clone)) { + const auto clone = GeneralUtils::TryParse(args[1]); + if (!clone) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid clone."); return; } const auto& password = args[2]; - ZoneInstanceManager::Instance()->CreatePrivateZone(Game::server, zone, clone, password); + ZoneInstanceManager::Instance()->CreatePrivateZone(Game::server, zone.value(), clone.value(), password); ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16("Sent request for private zone with password: " + password)); @@ -1593,14 +1586,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (args.size() >= 1) { - float time; + const auto time = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], time)) { + if (!time) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid boost time."); return; } else { GameMessages::SendVehicleAddPassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); - entity->AddCallbackTimer(time, [vehicle]() { + entity->AddCallbackTimer(time.value(), [vehicle]() { if (!vehicle) return; GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); }); @@ -1676,20 +1669,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "reforge" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 2) { - LOT baseItem; - LOT reforgedItem; + const auto baseItem = GeneralUtils::TryParse(args[0]); + if (!baseItem) return; - if (!GeneralUtils::TryParse(args[0], baseItem)) return; - if (!GeneralUtils::TryParse(args[1], reforgedItem)) return; + const auto reforgedItem = GeneralUtils::TryParse(args[1]); + if (!reforgedItem) return; auto* inventoryComponent = entity->GetComponent(); - - if (inventoryComponent == nullptr) return; + if (!inventoryComponent) return; std::vector data{}; - data.push_back(new LDFData(u"reforgedLOT", reforgedItem)); + data.push_back(new LDFData(u"reforgedLOT", reforgedItem.value())); - inventoryComponent->AddItem(baseItem, 1, eLootSourceType::MODERATION, eInventoryType::INVALID, data); + inventoryComponent->AddItem(baseItem.value(), 1, eLootSourceType::MODERATION, eInventoryType::INVALID, data); } if (chatCommand == "crash" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR) { @@ -1743,8 +1735,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit VanityUtilities::SpawnVanity(); dpWorld::Reload(); auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); - for (auto entity : entities) { - auto* scriptedActivityComponent = entity->GetComponent(); + for (const auto* const entity : entities) { + auto* const scriptedActivityComponent = entity->GetComponent(); if (!scriptedActivityComponent) continue; scriptedActivityComponent->ReloadConfig(); @@ -1755,19 +1747,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "rollloot" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR && args.size() >= 3) { - uint32_t lootMatrixIndex = 0; - uint32_t targetLot = 0; - uint32_t loops = 1; + const auto lootMatrixIndex = GeneralUtils::TryParse(args[0]); + if (!lootMatrixIndex) return; - if (!GeneralUtils::TryParse(args[0], lootMatrixIndex)) return; - if (!GeneralUtils::TryParse(args[1], targetLot)) return; - if (!GeneralUtils::TryParse(args[2], loops)) return; + const auto targetLot = GeneralUtils::TryParse(args[1]); + if (!targetLot) return; + + const auto loops = GeneralUtils::TryParse(args[2]); + if (!loops) return; uint64_t totalRuns = 0; for (uint32_t i = 0; i < loops; i++) { while (true) { - auto lootRoll = Loot::RollLootMatrix(lootMatrixIndex); + auto lootRoll = Loot::RollLootMatrix(lootMatrixIndex.value()); totalRuns += 1; bool doBreak = false; for (const auto& kv : lootRoll) { @@ -1780,26 +1773,30 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } std::u16string message = u"Ran loot drops looking for " - + GeneralUtils::to_u16string(targetLot) + + GeneralUtils::to_u16string(targetLot.value()) + u", " - + GeneralUtils::to_u16string(loops) + + GeneralUtils::to_u16string(loops.value()) + u" times. It ran " + GeneralUtils::to_u16string(totalRuns) + u" times. Averaging out at " - + GeneralUtils::to_u16string(static_cast(totalRuns) / loops); + + GeneralUtils::to_u16string(static_cast(totalRuns) / loops.value()); ChatPackets::SendSystemMessage(sysAddr, message); } if (chatCommand == "deleteinven" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { eInventoryType inventoryType = eInventoryType::INVALID; - if (!GeneralUtils::TryParse(args[0], inventoryType)) { + + const auto inventoryTypeOptional = GeneralUtils::TryParse(args[0]); + if (!inventoryTypeOptional) { // In this case, we treat the input as a string and try to find it in the reflection list std::transform(args[0].begin(), args[0].end(), args[0].begin(), ::toupper); LOG("looking for inventory %s", args[0].c_str()); for (uint32_t index = 0; index < NUMBER_OF_INVENTORIES; index++) { if (std::string_view(args[0]) == std::string_view(InventoryType::InventoryTypeToString(static_cast(index)))) inventoryType = static_cast(index); } + } else { + inventoryType = inventoryTypeOptional.value(); } if (inventoryType == eInventoryType::INVALID || inventoryType >= NUMBER_OF_INVENTORIES) { @@ -1821,32 +1818,32 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "castskill" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto* skillComponent = entity->GetComponent(); if (skillComponent) { - uint32_t skillId; + const auto skillId = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], skillId)) { + if (!skillId) { ChatPackets::SendSystemMessage(sysAddr, u"Error getting skill ID."); return; } else { - skillComponent->CastSkill(skillId, entity->GetObjectID(), entity->GetObjectID()); + skillComponent->CastSkill(skillId.value(), entity->GetObjectID(), entity->GetObjectID()); ChatPackets::SendSystemMessage(sysAddr, u"Cast skill"); } } } if (chatCommand == "setskillslot" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 2) { - uint32_t skillId; - int slot; - auto* inventoryComponent = entity->GetComponent(); + auto* const inventoryComponent = entity->GetComponent(); if (inventoryComponent) { - if (!GeneralUtils::TryParse(args[0], slot)) { + const auto slot = GeneralUtils::TryParse(args[0]); + if (!slot) { ChatPackets::SendSystemMessage(sysAddr, u"Error getting slot."); return; } else { - if (!GeneralUtils::TryParse(args[1], skillId)) { + const auto skillId = GeneralUtils::TryParse(args[1]); + if (!skillId) { ChatPackets::SendSystemMessage(sysAddr, u"Error getting skill."); return; } else { - if (inventoryComponent->SetSkill(slot, skillId)) ChatPackets::SendSystemMessage(sysAddr, u"Set skill to slot successfully"); + if (inventoryComponent->SetSkill(slot.value(), skillId.value())) ChatPackets::SendSystemMessage(sysAddr, u"Set skill to slot successfully"); else ChatPackets::SendSystemMessage(sysAddr, u"Set skill to slot failed"); } } @@ -1856,13 +1853,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "setfaction" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto* destroyableComponent = entity->GetComponent(); if (destroyableComponent) { - int32_t faction; + const auto faction = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], faction)) { + if (!faction) { ChatPackets::SendSystemMessage(sysAddr, u"Error getting faction."); return; } else { - destroyableComponent->SetFaction(faction); + destroyableComponent->SetFaction(faction.value()); ChatPackets::SendSystemMessage(sysAddr, u"Set faction and updated enemies list"); } } @@ -1871,13 +1868,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "addfaction" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto* destroyableComponent = entity->GetComponent(); if (destroyableComponent) { - int32_t faction; + const auto faction = GeneralUtils::TryParse(args[0]); - if (!GeneralUtils::TryParse(args[0], faction)) { + if (!faction) { ChatPackets::SendSystemMessage(sysAddr, u"Error getting faction."); return; } else { - destroyableComponent->AddFaction(faction); + destroyableComponent->AddFaction(faction.value()); ChatPackets::SendSystemMessage(sysAddr, u"Added faction and updated enemies list"); } } @@ -1908,13 +1905,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "inspect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { Entity* closest = nullptr; - eReplicaComponentType component; - std::u16string ldf; bool isLDF = false; - if (!GeneralUtils::TryParse(args[0], component)) { + auto component = GeneralUtils::TryParse(args[0]); + if (!component) { component = eReplicaComponentType::INVALID; ldf = GeneralUtils::UTF8ToUTF16(args[0]); @@ -1926,7 +1922,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto closestDistance = 0.0f; - const auto candidates = Game::entityManager->GetEntitiesByComponent(component); + const auto candidates = Game::entityManager->GetEntitiesByComponent(component.value()); for (auto* candidate : candidates) { if (candidate->GetLOT() == 1 || candidate->GetLOT() == 8092) { @@ -1937,7 +1933,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit continue; } - if (closest == nullptr) { + if (!closest) { closest = candidate; closestDistance = NiPoint3::Distance(candidate->GetPosition(), reference); @@ -1954,9 +1950,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (closest == nullptr) { - return; - } + if (!closest) return; Game::entityManager->SerializeEntity(closest); @@ -1982,20 +1976,18 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (args.size() >= 2) { if (args[1] == "-m" && args.size() >= 3) { - auto* movingPlatformComponent = closest->GetComponent(); + auto* const movingPlatformComponent = closest->GetComponent(); - int32_t value = 0; + const auto mValue = GeneralUtils::TryParse(args[2]); - if (movingPlatformComponent == nullptr || !GeneralUtils::TryParse(args[2], value)) { - return; - } + if (!movingPlatformComponent || !mValue) return; movingPlatformComponent->SetSerialized(true); - if (value == -1) { + if (mValue == -1) { movingPlatformComponent->StopPathing(); } else { - movingPlatformComponent->GotoWaypoint(value); + movingPlatformComponent->GotoWaypoint(mValue.value()); } Game::entityManager->SerializeEntity(closest); @@ -2036,13 +2028,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (args.size() >= 3) { - int32_t faction; - if (!GeneralUtils::TryParse(args[2], faction)) { - return; - } + const auto faction = GeneralUtils::TryParse(args[2]); + if (!faction) return; destuctable->SetFaction(-1); - destuctable->AddFaction(faction, true); + destuctable->AddFaction(faction.value(), true); } } else if (args[1] == "-cf") { auto* destuctable = entity->GetComponent(); diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index a46ed81af..9ae9930ce 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -17,7 +17,8 @@ InstanceManager::InstanceManager(Logger* logger, const std::string& externalIP) { mLogger = logger; mExternalIP = externalIP; - GeneralUtils::TryParse(Game::config->GetValue("world_port_start"), m_LastPort); + m_LastPort = + GeneralUtils::TryParse(Game::config->GetValue("world_port_start")).value_or(m_LastPort); m_LastInstanceID = LWOINSTANCEID_INVALID; } diff --git a/dMasterServer/InstanceManager.h b/dMasterServer/InstanceManager.h index b9f1ec5a1..1fc4af439 100644 --- a/dMasterServer/InstanceManager.h +++ b/dMasterServer/InstanceManager.h @@ -134,7 +134,7 @@ class InstanceManager { Logger* mLogger; std::string mExternalIP; std::vector m_Instances; - unsigned short m_LastPort = 3000; + uint16_t m_LastPort = 3000; LWOINSTANCEID m_LastInstanceID; /** diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 749b41305..1fade06e4 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -89,9 +89,8 @@ int main(int argc, char** argv) { if (!dConfig::Exists("worldconfig.ini")) LOG("Could not find worldconfig.ini, using default settings"); - uint32_t clientNetVersion = 171022; const auto clientNetVersionString = Game::config->GetValue("client_net_version"); - if (!clientNetVersionString.empty()) GeneralUtils::TryParse(clientNetVersionString, clientNetVersion); + const uint32_t clientNetVersion = GeneralUtils::TryParse(clientNetVersionString).value_or(171022); LOG("Using net version %i", clientNetVersion); diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 9982f89ed..25ccc9029 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -8,6 +8,7 @@ #include "ZoneInstanceManager.h" #include "MD5.h" #include "GeneralUtils.h" +#include "ClientVersion.h" #include @@ -38,10 +39,9 @@ void AuthPackets::LoadClaimCodes() { auto rcstring = Game::config->GetValue("rewardcodes"); auto codestrings = GeneralUtils::SplitString(rcstring, ','); for(auto const &codestring: codestrings){ - uint32_t code = -1; - if(GeneralUtils::TryParse(codestring, code) && code != -1){ - claimCodes.push_back(code); - } + const auto code = GeneralUtils::TryParse(codestring); + + if (code && code.value() != -1) claimCodes.push_back(code.value()); } } @@ -73,9 +73,8 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c RakNet::BitStream bitStream; BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM); - uint32_t clientNetVersion = 171022; const auto clientNetVersionString = Game::config->GetValue("client_net_version"); - if (!clientNetVersionString.empty()) GeneralUtils::TryParse(clientNetVersionString, clientNetVersion); + const uint32_t clientNetVersion = GeneralUtils::TryParse(clientNetVersionString).value_or(171022); bitStream.Write(clientNetVersion); bitStream.Write(861228100); @@ -242,12 +241,12 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd loginResponse.Write(LUString(Game::config->GetValue("event_7"))); loginResponse.Write(LUString(Game::config->GetValue("event_8"))); - uint16_t version_major = 1; - uint16_t version_current = 10; - uint16_t version_minor = 64; - GeneralUtils::TryParse(Game::config->GetValue("version_major"), version_major); - GeneralUtils::TryParse(Game::config->GetValue("version_current"), version_current); - GeneralUtils::TryParse(Game::config->GetValue("version_minor"), version_minor); + const uint16_t version_major = + GeneralUtils::TryParse(Game::config->GetValue("version_major")).value_or(ClientVersion::major); + const uint16_t version_current = + GeneralUtils::TryParse(Game::config->GetValue("version_current")).value_or(ClientVersion::current); + const uint16_t version_minor = + GeneralUtils::TryParse(Game::config->GetValue("version_minor")).value_or(ClientVersion::minor); loginResponse.Write(version_major); loginResponse.Write(version_current); diff --git a/dPhysics/dpWorld.cpp b/dPhysics/dpWorld.cpp index 4ed548580..c9bc742ad 100644 --- a/dPhysics/dpWorld.cpp +++ b/dPhysics/dpWorld.cpp @@ -26,9 +26,15 @@ namespace { void dpWorld::Initialize(unsigned int zoneID, bool generateNewNavMesh) { const auto physSpTilecount = Game::config->GetValue("phys_sp_tilecount"); - if (!physSpTilecount.empty()) GeneralUtils::TryParse(physSpTilecount, phys_sp_tilecount); + if (!physSpTilecount.empty()) { + phys_sp_tilecount = GeneralUtils::TryParse(physSpTilecount).value_or(phys_sp_tilecount); + } + const auto physSpTilesize = Game::config->GetValue("phys_sp_tilesize"); - if (!physSpTilesize.empty()) GeneralUtils::TryParse(physSpTilesize, phys_sp_tilesize); + if (!physSpTilesize.empty()) { + phys_sp_tilesize = GeneralUtils::TryParse(physSpTilesize).value_or(phys_sp_tilesize); + } + const auto physSpatialPartitioning = Game::config->GetValue("phys_spatial_partitioning"); if (!physSpatialPartitioning.empty()) phys_spatial_partitioning = physSpatialPartitioning == "1"; diff --git a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp index 60b750cf2..357187ef4 100644 --- a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp +++ b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp @@ -33,14 +33,12 @@ void AmDropshipComputer::OnUse(Entity* self, Entity* user) { void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { const auto myGroup = GeneralUtils::UTF16ToWTF8(self->GetVar(u"spawner_name")); - int32_t pipeNum = 0; - if (!GeneralUtils::TryParse(myGroup.substr(10, 1), pipeNum)) { - return; - } + const auto pipeNum = GeneralUtils::TryParse(myGroup.substr(10, 1)); + if (!pipeNum) return; const auto pipeGroup = myGroup.substr(0, 10); - const auto nextPipeNum = pipeNum + 1; + const auto nextPipeNum = pipeNum.value() + 1; const auto samePipeSpawners = Game::zoneManager->GetSpawnersByName(myGroup); @@ -70,11 +68,9 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { } void AmDropshipComputer::OnTimerDone(Entity* self, std::string timerName) { - auto* quickBuildComponent = self->GetComponent(); + const auto* const quickBuildComponent = self->GetComponent(); - if (quickBuildComponent == nullptr) { - return; - } + if (!quickBuildComponent) return; if (timerName == "reset" && quickBuildComponent->GetState() == eQuickBuildState::OPEN) { self->Smash(self->GetObjectID(), eKillType::SILENT); diff --git a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp index 0c0f75157..1eaad3c9a 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp @@ -144,13 +144,10 @@ void AmSkullkinTower::OnChildRemoved(Entity* self, Entity* child) { ); for (const auto& mission : missions) { - int32_t missionID = 0; + const auto missionID = GeneralUtils::TryParse(mission); + if (!missionID) continue; - if (!GeneralUtils::TryParse(mission, missionID)) { - continue; - } - - missionIDs.push_back(missionID); + missionIDs.push_back(missionID.value()); } } diff --git a/dScripts/02_server/Map/AM/AmTemplateSkillVolume.cpp b/dScripts/02_server/Map/AM/AmTemplateSkillVolume.cpp index 3acc9063a..82f1481ab 100644 --- a/dScripts/02_server/Map/AM/AmTemplateSkillVolume.cpp +++ b/dScripts/02_server/Map/AM/AmTemplateSkillVolume.cpp @@ -12,12 +12,9 @@ void AmTemplateSkillVolume::OnSkillEventFired(Entity* self, Entity* caster, cons const auto missionIDs = GeneralUtils::SplitString(missionIDsVariable, '_'); for (const auto& missionIDStr : missionIDs) { - int32_t missionID = 0; + const auto missionID = GeneralUtils::TryParse(missionIDStr); + if (!missionID) continue; - if (!GeneralUtils::TryParse(missionIDStr, missionID)) { - continue; - } - - missionComponent->ForceProgressTaskType(missionID, 1, 1, false); + missionComponent->ForceProgressTaskType(missionID.value(), 1, 1, false); } } diff --git a/dScripts/ChooseYourDestinationNsToNt.cpp b/dScripts/ChooseYourDestinationNsToNt.cpp index f9ca0a796..b736883c4 100644 --- a/dScripts/ChooseYourDestinationNsToNt.cpp +++ b/dScripts/ChooseYourDestinationNsToNt.cpp @@ -41,11 +41,9 @@ void ChooseYourDestinationNsToNt::SetDestination(Entity* self, Entity* player) { void ChooseYourDestinationNsToNt::BaseChoiceBoxRespond(Entity* self, Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier) { if (button != -1) { const auto newMapStr = GeneralUtils::UTF16ToWTF8(buttonIdentifier).substr(7, -1); - - int32_t newMap = 0; - if (!GeneralUtils::TryParse(newMapStr, newMap)) { - return; - } + const auto newMap = GeneralUtils::TryParse(newMapStr); + + if (!newMap) return; std::u16string strText = u""; @@ -56,7 +54,7 @@ void ChooseYourDestinationNsToNt::BaseChoiceBoxRespond(Entity* self, Entity* sen } self->SetVar(u"teleportString", strText); - self->SetVar(u"transferZoneID", GeneralUtils::to_u16string(newMap)); + self->SetVar(u"transferZoneID", GeneralUtils::to_u16string(newMap.value())); GameMessages::SendDisplayMessageBox(sender->GetObjectID(), true, self->GetObjectID(), u"TransferBox", 0, strText, u"", sender->GetSystemAddress()); } else { diff --git a/dScripts/ai/FV/FvBrickPuzzleServer.cpp b/dScripts/ai/FV/FvBrickPuzzleServer.cpp index e1f1ac881..f8601e3fa 100644 --- a/dScripts/ai/FV/FvBrickPuzzleServer.cpp +++ b/dScripts/ai/FV/FvBrickPuzzleServer.cpp @@ -7,10 +7,8 @@ void FvBrickPuzzleServer::OnStartup(Entity* self) { const auto myGroup = GeneralUtils::UTF16ToWTF8(self->GetVar(u"spawner_name")); - int32_t pipeNum = 0; - if (!GeneralUtils::TryParse(myGroup.substr(10, 1), pipeNum)) { - return; - } + const auto pipeNum = GeneralUtils::TryParse(myGroup.substr(10, 1)); + if (!pipeNum) return; if (pipeNum != 1) { self->AddTimer("reset", 30); @@ -20,14 +18,12 @@ void FvBrickPuzzleServer::OnStartup(Entity* self) { void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { const auto myGroup = GeneralUtils::UTF16ToWTF8(self->GetVar(u"spawner_name")); - int32_t pipeNum = 0; - if (!GeneralUtils::TryParse(myGroup.substr(10, 1), pipeNum)) { - return; - } + const auto pipeNum = GeneralUtils::TryParse(myGroup.substr(10, 1)); + if (!pipeNum) return; const auto pipeGroup = myGroup.substr(0, 10); - const auto nextPipeNum = pipeNum + 1; + const auto nextPipeNum = pipeNum.value() + 1; const auto samePipeSpawners = Game::zoneManager->GetSpawnersByName(myGroup); @@ -37,7 +33,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { samePipeSpawners[0]->Deactivate(); } - if (killer != nullptr && killer->IsPlayer()) { + if (killer && killer->IsPlayer()) { const auto nextPipe = pipeGroup + std::to_string(nextPipeNum); const auto nextPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 6df5d0daa..bb879dbdf 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -208,8 +208,7 @@ int main(int argc, char** argv) { UserManager::Instance()->Initialize(); - bool dontGenerateDCF = false; - GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf"), dontGenerateDCF); + const bool dontGenerateDCF = GeneralUtils::TryParse(Game::config->GetValue("dont_generate_dcf")).value_or(false); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF); Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, &Game::lastSignal, zoneID); diff --git a/dZoneManager/Level.cpp b/dZoneManager/Level.cpp index 2606b46f5..9524d908b 100644 --- a/dZoneManager/Level.cpp +++ b/dZoneManager/Level.cpp @@ -14,6 +14,7 @@ #include "CDFeatureGatingTable.h" #include "CDClientManager.h" #include "AssetManager.h" +#include "ClientVersion.h" #include "dConfig.h" Level::Level(Zone* parentZone, const std::string& filepath) { @@ -211,12 +212,12 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { CDFeatureGatingTable* featureGatingTable = CDClientManager::GetTable(); CDFeatureGating gating; - gating.major = 1; - gating.current = 10; - gating.minor = 64; - GeneralUtils::TryParse(Game::config->GetValue("version_major"), gating.major); - GeneralUtils::TryParse(Game::config->GetValue("version_current"), gating.current); - GeneralUtils::TryParse(Game::config->GetValue("version_minor"), gating.minor); + gating.major = + GeneralUtils::TryParse(Game::config->GetValue("version_major")).value_or(ClientVersion::major); + gating.current = + GeneralUtils::TryParse(Game::config->GetValue("version_current")).value_or(ClientVersion::current); + gating.minor = + GeneralUtils::TryParse(Game::config->GetValue("version_minor")).value_or(ClientVersion::minor); const auto zoneControlObject = Game::zoneManager->GetZoneControlObject(); DluAssert(zoneControlObject != nullptr);