From 85c3255568434deb1b1bb185aadfb7aa6f0581dc Mon Sep 17 00:00:00 2001 From: nytmyr <53322305+nytmyr@users.noreply.github.com> Date: Wed, 29 Apr 2026 01:59:19 -0500 Subject: [PATCH 1/3] [Bots] Command add fix for spelltypeids/spelltypenames (#5074) --- zone/bot_command.cpp | 6 +++--- zone/bot_command.h | 2 +- zone/bot_commands/bot_spelltypes.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 594d28b47..966d951b7 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -775,7 +775,7 @@ void helper_send_usage_required_bots(Client *bot_owner, uint16 spell_type) bot_owner->Message(Chat::Green, "%s", description.c_str()); } -void SendSpellTypeWindow(Client* c, const Seperator* sep) { +void SendSpellTypeWindow(Client* c, const Seperator* sep, bool short_names) { std::string arg0 = sep->arg[0]; std::string arg1 = sep->arg[1]; @@ -828,7 +828,7 @@ void SendSpellTypeWindow(Client* c, const Seperator* sep) { std::string popup_text = DialogueWindow::TableRow( DialogueWindow::TableCell(DialogueWindow::ColorMessage(goldenrod, spell_type_field)) + - DialogueWindow::TableCell((!arg0.compare("^spelltypeids") ? DialogueWindow::ColorMessage(goldenrod, id_field) : DialogueWindow::ColorMessage(goldenrod, shortname_field))) + DialogueWindow::TableCell((!short_names ? DialogueWindow::ColorMessage(goldenrod, id_field) : DialogueWindow::ColorMessage(goldenrod, shortname_field))) ); popup_text += DialogueWindow::TableRow( @@ -845,7 +845,7 @@ void SendSpellTypeWindow(Client* c, const Seperator* sep) { popup_text += DialogueWindow::TableRow( DialogueWindow::TableCell(DialogueWindow::ColorMessage(forest_green, Bot::GetSpellTypeNameByID(i))) + - DialogueWindow::TableCell((!arg0.compare("^spelltypeids") ? DialogueWindow::ColorMessage(slate_blue, std::to_string(i)) : DialogueWindow::ColorMessage(slate_blue, Bot::GetSpellTypeShortNameByID(i)))) + DialogueWindow::TableCell((!short_names ? DialogueWindow::ColorMessage(slate_blue, std::to_string(i)) : DialogueWindow::ColorMessage(slate_blue, Bot::GetSpellTypeShortNameByID(i)))) ); } diff --git a/zone/bot_command.h b/zone/bot_command.h index 6f3de0544..870697b4d 100644 --- a/zone/bot_command.h +++ b/zone/bot_command.h @@ -1182,4 +1182,4 @@ bool helper_is_help_or_usage(const char* arg); bool helper_no_available_bots(Client *bot_owner, Bot *my_bot = nullptr); void helper_send_available_subcommands(Client *bot_owner, const char* command_simile, std::vector subcommand_list); void helper_send_usage_required_bots(Client *bot_owner, uint16 spell_type); -void SendSpellTypeWindow(Client* c, const Seperator* sep); +void SendSpellTypeWindow(Client* c, const Seperator* sep, bool short_names = false); diff --git a/zone/bot_commands/bot_spelltypes.cpp b/zone/bot_commands/bot_spelltypes.cpp index f9b39fc7b..7e7f0fa39 100644 --- a/zone/bot_commands/bot_spelltypes.cpp +++ b/zone/bot_commands/bot_spelltypes.cpp @@ -24,5 +24,5 @@ void bot_command_spelltype_ids(Client* c, const Seperator* sep) void bot_command_spelltype_names(Client* c, const Seperator* sep) { - SendSpellTypeWindow(c, sep); + SendSpellTypeWindow(c, sep, true); } From d7e010a3ec4f64a946f846cd51235e1b3d9fd2d3 Mon Sep 17 00:00:00 2001 From: Dan <3968021+sh0ber@users.noreply.github.com> Date: Thu, 7 May 2026 23:24:15 -0400 Subject: [PATCH 2/3] strings: refactor Money and add MoneyShort (#5075) --- common/strings.cpp | 159 ++++++++++++++------------------------------- common/strings.h | 3 +- 2 files changed, 52 insertions(+), 110 deletions(-) diff --git a/common/strings.cpp b/common/strings.cpp index 7419de9bc..5f9f17cd5 100644 --- a/common/strings.cpp +++ b/common/strings.cpp @@ -380,118 +380,59 @@ std::string Strings::NumberToWords(unsigned long long int n) return res; } -std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 copper) -{ - std::string money_string = "Unknown"; - if (copper && silver && gold && platinum) { // CSGP - money_string = fmt::format( - "{} platinum, {} gold, {} silver, and {} copper", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(gold)), - Strings::Commify(std::to_string(silver)), - Strings::Commify(std::to_string(copper)) - ); +std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 copper, bool commify) { + uint64 values[] = { platinum, gold, silver, copper }; + const char* names[] = { " platinum", " gold", " silver", " copper" }; + + std::vector parts; + for (int i = 0; i < 4; ++i) { + if (values[i] > 0) { + std::string s = std::to_string(values[i]); + parts.push_back((commify ? Strings::Commify(s) : s) + names[i]); + } } - else if (copper && silver && !gold && platinum) { // CSP - money_string = fmt::format( - "{} platinum, {} silver, and {} copper", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(silver)), - Strings::Commify(std::to_string(copper)) - ); + + if (parts.empty()) return "0 copper"; + if (parts.size() == 1) return parts[0]; + + std::string result; + for (size_t i = 0; i < parts.size(); ++i) { + result += parts[i]; + if (i < parts.size() - 2) { + result += ", "; + } + else if (i == parts.size() - 2) { + // Oxford comma logic: ", and " for 3+ items, " and " for 2 + result += (parts.size() > 2) ? ", and " : " and "; + } } - else if (copper && silver && gold && !platinum) { // CSG - money_string = fmt::format( - "{} gold, {} silver, and {} copper", - Strings::Commify(std::to_string(gold)), - Strings::Commify(std::to_string(silver)), - Strings::Commify(std::to_string(copper)) - ); - } - else if (copper && !silver && !gold && platinum) { // CP - money_string = fmt::format( - "{} platinum and {} copper", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(copper)) - ); - } - else if (copper && silver && !gold && !platinum) { // CS - money_string = fmt::format( - "{} silver and {} copper", - Strings::Commify(std::to_string(silver)), - Strings::Commify(std::to_string(copper)) - ); - } - else if (!copper && silver && gold && platinum) { // SGP - money_string = fmt::format( - "{} platinum, {} gold, and {} silver", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(gold)), - Strings::Commify(std::to_string(silver)) - ); - } - else if (!copper && silver && !gold && platinum) { // SP - money_string = fmt::format( - "{} platinum and {} silver", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(silver)) - ); - } - else if (!copper && silver && gold && !platinum) { // SG - money_string = fmt::format( - "{} gold and {} silver", - Strings::Commify(std::to_string(gold)), - Strings::Commify(std::to_string(silver)) - ); - } - else if (copper && !silver && gold && platinum) { // CGP - money_string = fmt::format( - "{} platinum, {} gold, and {} copper", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(gold)), - Strings::Commify(std::to_string(copper)) - ); - } - else if (copper && !silver && gold && !platinum) { // CG - money_string = fmt::format( - "{} gold and {} copper", - Strings::Commify(std::to_string(gold)), - Strings::Commify(std::to_string(copper)) - ); - } - else if (!copper && !silver && gold && platinum) { // GP - money_string = fmt::format( - "{} platinum and {} gold", - Strings::Commify(std::to_string(platinum)), - Strings::Commify(std::to_string(gold)) - ); - } - else if (!copper && !silver && !gold && platinum) { // P - money_string = fmt::format( - "{} platinum", - Strings::Commify(std::to_string(platinum)) - ); - } - else if (!copper && !silver && gold && !platinum) { // G - money_string = fmt::format( - "{} gold", - Strings::Commify(std::to_string(gold)) - ); - } - else if (!copper && silver && !gold && !platinum) { // S - money_string = fmt::format( - "{} silver", - Strings::Commify(std::to_string(silver)) - ); - } - else if (copper && !silver && !gold && !platinum) { // C - money_string = fmt::format( - "{} copper", - Strings::Commify(std::to_string(copper)) - ); - } - return money_string; + + return result; } + +std::string Strings::MoneyShort(uint64 copper, bool commify) { + // Matches merchant format + uint64 values[] = { + copper / 1000, + (copper / 100) % 10, + (copper / 10) % 10, + copper % 10 + }; + const char* names[] = { " platinum", " gold", " silver", " copper" }; + + std::string result; + for (int i = 0; i < 4; ++i) { + if (values[i] > 0) { + if (!result.empty()) result += " "; + + std::string s = std::to_string(values[i]); + result += (commify ? Strings::Commify(s) : s) + names[i]; + } + } + + return result.empty() ? "0 copper" : result; +} + std::string Strings::SecondsToTime(int duration, bool is_milliseconds) { if (duration <= 0) { diff --git a/common/strings.h b/common/strings.h index 5a5b93deb..85ae4415b 100644 --- a/common/strings.h +++ b/common/strings.h @@ -62,7 +62,8 @@ public: static std::string Join(const std::vector &ar, const std::string &delim); static std::string Join(const std::vector &ar, const std::string &delim); static std::string MillisecondsToTime(int duration); - static std::string Money(uint64 platinum, uint64 gold = 0, uint64 silver = 0, uint64 copper = 0); + static std::string Money(uint64 platinum, uint64 gold = 0, uint64 silver = 0, uint64 copper = 0, bool commify = true); + static std::string MoneyShort(uint64 copper = 0, bool commify = true); // Matches merchant format when commify is false static std::string NumberToWords(unsigned long long int n); static std::string Repeat(std::string s, int n); static std::string Replace(std::string subject, const std::string &search, const std::string &replace); From ef6dfe0469c19578ee0817ea40917be825a0791e Mon Sep 17 00:00:00 2001 From: Knightly <55611098+Knightly1@users.noreply.github.com> Date: Thu, 7 May 2026 17:25:01 -1000 Subject: [PATCH 3/3] Load openssl libs from executable directory and update logging (#5078) --- loginserver/CMakeLists.txt | 10 ++++++++++ loginserver/encryption.cpp | 12 ++++++++++++ loginserver/main.cpp | 7 +------ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index 71466df1b..67d0658c2 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -37,3 +37,13 @@ target_include_directories(loginserver PRIVATE ..) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) set_property(TARGET loginserver PROPERTY FOLDER executables/servers) + +# vcpkg doesn't copy legacy.dll automatically because it is loaded at runtime, not via the import table. +if(WIN32 AND DEFINED VCPKG_INSTALLED_DIR AND DEFINED VCPKG_TARGET_TRIPLET) + add_custom_command(TARGET loginserver POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$,${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/bin/legacy.dll,${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/legacy.dll>" + "$/legacy.dll" + VERBATIM + ) +endif() diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index 3fa140768..db8142394 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -182,6 +182,18 @@ static OSSL_PROVIDER *s_default_provider = nullptr; bool eqcrypt_init() { #ifdef EQEMU_USE_OPENSSL +#ifdef _WIN32 + // Set OpenSSL default provider search path to the executable directory. + char* exe_path = nullptr; + if (_get_pgmptr(&exe_path) == 0 && exe_path != nullptr && *exe_path != '\0') { + std::string exe_dir{exe_path}; + if (auto sep = exe_dir.find_last_of("\\/"); sep != std::string::npos) { + exe_dir.resize(sep); + OSSL_PROVIDER_set_default_search_path(nullptr, exe_dir.c_str()); + } + } +#endif + if (!s_default_provider) { s_default_provider = OSSL_PROVIDER_load(nullptr, "default"); } diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 9b9766223..106fdc7df 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -159,6 +159,7 @@ void start_web_server() int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformLogin); + EQEmuLogSys::Instance()->LoadLogSettingsDefaults(); set_exception_handler(); if (!eqcrypt_init()) { @@ -166,12 +167,6 @@ int main(int argc, char **argv) return 1; } - LogInfo("Logging System Init"); - - if (argc == 1) { - EQEmuLogSys::Instance()->LoadLogSettingsDefaults(); - } - PathManager::Instance()->Init(); // command handler