diff --git a/.clang-format b/.clang-format index 10acf5f..28a4b68 100644 --- a/.clang-format +++ b/.clang-format @@ -14,7 +14,7 @@ BraceWrapping: AfterStruct: false BeforeElse: false IndentBraces: false -NamespaceIndentation: None +NamespaceIndentation: All PointerAlignment: Left SortIncludes: false SpaceAfterCStyleCast: false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a98c7f..7e0f982 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,29 +26,19 @@ jobs: version: "0.0.0-ci" run_tests: "true" + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + # Pinned so the gate cannot drift with whatever LLVM the runner image ships. - name: clang-format check shell: pwsh run: | - $clangFormat = Get-Command clang-format -ErrorAction SilentlyContinue - if (-not $clangFormat) { - Write-Host "clang-format not on PATH; trying LLVM install locations" - $candidates = @( - "C:\Program Files\LLVM\bin\clang-format.exe", - "C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\bin\clang-format.exe" - ) - foreach ($c in $candidates) { - if (Test-Path $c) { $clangFormat = $c; break } - } - } else { - $clangFormat = $clangFormat.Source - } - if (-not $clangFormat) { - Write-Host "clang-format unavailable on runner - skipping style check" - exit 0 - } + python -m pip install --quiet clang-format==22.1.8 $files = Get-ChildItem -Recurse src,loader,compat,tests -Include *.cpp,*.h,*.c | Where-Object { $_.FullName -notmatch '\\vendor\\' } - & $clangFormat --dry-run --Werror @($files.FullName) + clang-format --dry-run --Werror @($files.FullName) if ($LASTEXITCODE -ne 0) { throw "clang-format check failed" } - name: Upload artifacts diff --git a/compat/logger_stub.cpp b/compat/logger_stub.cpp index fa9dac4..386ec5e 100644 --- a/compat/logger_stub.cpp +++ b/compat/logger_stub.cpp @@ -44,7 +44,8 @@ namespace { vsnprintf(message, _countof(message), format, args); wchar_t wide[MAX_MESSAGE]; - if (MultiByteToWideChar(CP_UTF8, 0, message, -1, wide, static_cast(_countof(wide))) > 0) { + if (MultiByteToWideChar(CP_UTF8, 0, message, -1, wide, static_cast(_countof(wide))) > + 0) { GW::Chat::WriteChat(GWTOOLBOX_CHAN, wide, L"GWDash", transient); } } @@ -55,7 +56,7 @@ namespace { _vsnwprintf_s(message, _countof(message), _TRUNCATE, format, args); GW::Chat::WriteChat(GWTOOLBOX_CHAN, message, L"GWDash", transient); } -} +} // namespace namespace Log { void Log(const char* msg, ...) @@ -145,7 +146,8 @@ namespace Log { void FatalAssert(const char* expr, const char* file, const unsigned line) { char line_buffer[MAX_MESSAGE]; - snprintf(line_buffer, _countof(line_buffer), "[GWDash] assertion failed: %s (%s:%u)\n", expr, file, line); + snprintf(line_buffer, _countof(line_buffer), "[GWDash] assertion failed: %s (%s:%u)\n", + expr, file, line); OutputDebugStringA(line_buffer); } -} +} // namespace Log diff --git a/loader/Loader.cpp b/loader/Loader.cpp index f57d22b..e66aec6 100644 --- a/loader/Loader.cpp +++ b/loader/Loader.cpp @@ -49,8 +49,8 @@ namespace { { std::vector buffer(MAX_PATH); for (;;) { - const DWORD length = GetModuleFileNameW(plugin_handle, buffer.data(), - static_cast(buffer.size())); + const DWORD length = + GetModuleFileNameW(plugin_handle, buffer.data(), static_cast(buffer.size())); if (length == 0) { return {}; } @@ -152,11 +152,12 @@ namespace { * returning nullptr from ToolboxPluginInstance is not an option. */ class FallbackPlugin final : public ToolboxPlugin { - public: + public: [[nodiscard]] const char* Name() const override { return "GWDash"; } [[nodiscard]] bool HasSettings() const override { return true; } - void Initialize(ImGuiContext* ctx, const ImGuiAllocFns allocator_fns, const HMODULE toolbox_dll) override + void Initialize(ImGuiContext* ctx, const ImGuiAllocFns allocator_fns, + const HMODULE toolbox_dll) override { ToolboxPlugin::Initialize(ctx, allocator_fns, toolbox_dll); if (!reported) { @@ -164,7 +165,8 @@ namespace { Debug(load_error.empty() ? "payload failed to load" : load_error); // Visible once without needing GWCA WriteChat in the loader. MessageBoxA(nullptr, - load_error.empty() ? "GWDash.core.dll failed to load." : load_error.c_str(), + load_error.empty() ? "GWDash.core.dll failed to load." + : load_error.c_str(), "GWDash", MB_OK | MB_ICONWARNING); } } @@ -177,10 +179,10 @@ namespace { ImGui::TextWrapped("Loader version %s", GWDASH_VERSION); } - private: + private: bool reported = false; }; -} +} // namespace DLLAPI ToolboxPlugin* ToolboxPluginInstance() { @@ -207,9 +209,11 @@ DLLAPI ToolboxPlugin* ToolboxPluginInstance() } using InstanceFn = ToolboxPlugin* (*)(); - const auto entry = reinterpret_cast(GetProcAddress(payload, "ToolboxPluginInstance")); + const auto entry = + reinterpret_cast(GetProcAddress(payload, "ToolboxPluginInstance")); if (!entry) { - load_error = "GWDash.core.dll has no ToolboxPluginInstance export - the install looks corrupt."; + load_error = + "GWDash.core.dll has no ToolboxPluginInstance export - the install looks corrupt."; FreeLibrary(payload); return instance; } @@ -220,8 +224,7 @@ DLLAPI ToolboxPlugin* ToolboxPluginInstance() // The payload therefore has to tolerate repeated Initialize/Terminate // cycles if the user unloads and reloads us from the Plugins panel. instance = forwarded; - } - else { + } else { load_error = "GWDash.core.dll returned no plugin instance."; FreeLibrary(payload); } diff --git a/src/GWDashPlugin.cpp b/src/GWDashPlugin.cpp index 017c64e..b8d129c 100644 --- a/src/GWDashPlugin.cpp +++ b/src/GWDashPlugin.cpp @@ -90,8 +90,7 @@ namespace { if (!GetSaveFileNameW(&ofn)) { return {}; } - } - else { + } else { ofn.Flags |= OFN_FILEMUSTEXIST; if (!GetOpenFileNameW(&ofn)) { return {}; @@ -100,11 +99,8 @@ namespace { return file; } - void DrawValueRow(const char* label, - const std::string& value, - const ImVec4& value_color, - const std::string& age, - const char* tooltip) + void DrawValueRow(const char* label, const std::string& value, const ImVec4& value_color, + const std::string& age, const char* tooltip) { ImGui::BeginGroup(); @@ -132,14 +128,16 @@ namespace { } } - std::string ChatPriceTooltip(const char* title, const gwdash::ChatPrice& price, const bool ready) + std::string ChatPriceTooltip(const char* title, const gwdash::ChatPrice& price, + const bool ready) { if (!ready) { return std::string(title) + " - waiting for trade-chat mentions"; } - return std::string(title) + " - recency-weighted median (n=" + std::to_string(price.n) + ")"; + return std::string(title) + " - recency-weighted median (n=" + std::to_string(price.n) + + ")"; } -} +} // namespace DLLAPI ToolboxPlugin* ToolboxPluginInstance() { @@ -159,7 +157,7 @@ namespace { plugin->OnChatCommand(argc, argv); } } -} +} // namespace GWDashPlugin::GWDashPlugin() { @@ -172,7 +170,8 @@ const char* GWDashPlugin::Icon() const return ICON_COINS; } -void GWDashPlugin::Initialize(ImGuiContext* ctx, const ImGuiAllocFns allocator_fns, const HMODULE toolbox_dll) +void GWDashPlugin::Initialize(ImGuiContext* ctx, const ImGuiAllocFns allocator_fns, + const HMODULE toolbox_dll) { ToolboxUIPlugin::Initialize(ctx, allocator_fns, toolbox_dll); @@ -210,8 +209,7 @@ void GWDashPlugin::Terminate() void GWDashPlugin::ApplyRefreshInterval() { - const int index = std::clamp(refresh_index_, 0, - static_cast(REFRESH_CHOICES.size()) - 1); + const int index = std::clamp(refresh_index_, 0, static_cast(REFRESH_CHOICES.size()) - 1); prices_.SetIntervalSeconds(REFRESH_CHOICES[static_cast(index)]); } @@ -284,8 +282,7 @@ void GWDashPlugin::Update(const float delta) if (GuildWarsHasFocus()) { seconds_unfocused_ = 0.0f; - } - else { + } else { seconds_unfocused_ += delta; } @@ -319,7 +316,8 @@ void GWDashPlugin::DrawRows(const gwdash::PriceState& state) return gwdash::FormatAge(*at, now); }; - const auto color_for = [&](const std::optional& price, const std::optional& at) { + const auto color_for = [&](const std::optional& price, + const std::optional& at) { if (!price.has_value()) { return COLOR_MISSING; } @@ -335,27 +333,27 @@ void GWDashPlugin::DrawRows(const gwdash::PriceState& state) ? gwdash::FormatGold(*snapshot.ecto.price) : "--"; DrawValueRow("Ecto", ecto_value, color_for(snapshot.ecto.price, snapshot.ecto.at), - age_for(snapshot.ecto.at), "Ectoplasm - average of the NPC trader's buy/sell price"); + age_for(snapshot.ecto.at), + "Ectoplasm - average of the NPC trader's buy/sell price"); if (show_ecto_spread_ && snapshot.ecto.buy.has_value() && snapshot.ecto.sell.has_value()) { - ImGui::TextDisabled(" buy %s / sell %s", - gwdash::FormatGold(*snapshot.ecto.buy).c_str(), + ImGui::TextDisabled(" buy %s / sell %s", gwdash::FormatGold(*snapshot.ecto.buy).c_str(), gwdash::FormatGold(*snapshot.ecto.sell).c_str()); } const std::string arms_value = state.has_data && snapshot.armbrace.price.has_value() ? gwdash::FormatEcto(*snapshot.armbrace.price) : "--"; - const std::string arms_tip = ChatPriceTooltip( - "Armbrace of Truth", snapshot.armbrace, snapshot.armbrace.price.has_value()); + const std::string arms_tip = ChatPriceTooltip("Armbrace of Truth", snapshot.armbrace, + snapshot.armbrace.price.has_value()); DrawValueRow("Arms", arms_value, color_for(snapshot.armbrace.price, snapshot.armbrace.at), age_for(snapshot.armbrace.at), arms_tip.c_str()); const std::string dye_value = state.has_data && snapshot.blackdye.price.has_value() ? gwdash::FormatGold(*snapshot.blackdye.price) : "--"; - const std::string dye_tip = ChatPriceTooltip( - "Black Dye", snapshot.blackdye, snapshot.blackdye.price.has_value()); + const std::string dye_tip = + ChatPriceTooltip("Black Dye", snapshot.blackdye, snapshot.blackdye.price.has_value()); DrawValueRow("Black Dye", dye_value, color_for(snapshot.blackdye.price, snapshot.blackdye.at), age_for(snapshot.blackdye.at), dye_tip.c_str()); } @@ -365,9 +363,13 @@ void GWDashPlugin::DrawCompact(const gwdash::PriceState& state) const gwdash::PriceSnapshot& snapshot = state.snapshot; const std::string line = - "Ecto " + (snapshot.ecto.price.has_value() ? gwdash::FormatGold(*snapshot.ecto.price) : "--") + - " | Arms " + (snapshot.armbrace.price.has_value() ? gwdash::FormatEcto(*snapshot.armbrace.price) : "--") + - " | BD " + (snapshot.blackdye.price.has_value() ? gwdash::FormatGold(*snapshot.blackdye.price) : "--"); + "Ecto " + + (snapshot.ecto.price.has_value() ? gwdash::FormatGold(*snapshot.ecto.price) : "--") + + " | Arms " + + (snapshot.armbrace.price.has_value() ? gwdash::FormatEcto(*snapshot.armbrace.price) + : "--") + + " | BD " + + (snapshot.blackdye.price.has_value() ? gwdash::FormatGold(*snapshot.blackdye.price) : "--"); ImGui::TextUnformatted(line.c_str()); } @@ -390,18 +392,18 @@ void GWDashPlugin::DrawStatusLine(const gwdash::PriceState& state) if (ImGui::IsItemHovered()) { ImGui::SetTooltip("%s", state.error.empty() ? "no connection" : state.error.c_str()); } - } - else { + } else { const int64_t age_at = state.snapshot.at > 0 ? state.snapshot.at : state.received_at; if (age_at > 0) { if (state.from_cache) { - ImGui::TextDisabled("updated %s ago (cached)", gwdash::FormatAge(age_at, now).c_str()); - } - else { + ImGui::TextDisabled("updated %s ago (cached)", + gwdash::FormatAge(age_at, now).c_str()); + } else { ImGui::TextDisabled("updated %s ago", gwdash::FormatAge(age_at, now).c_str()); } if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Source: %s", state.source.empty() ? "unknown" : state.source.c_str()); + ImGui::SetTooltip("Source: %s", + state.source.empty() ? "unknown" : state.source.c_str()); } } } @@ -421,8 +423,7 @@ void GWDashPlugin::DrawSendConfirmPopup() open_send_confirm_ = false; } - if (ImGui::BeginPopupModal("Send trade preset?", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { + if (ImGui::BeginPopupModal("Send trade preset?", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::TextWrapped("Send to trade chat?\n\n%s", pending_send_line_.c_str()); if (!gwdash::CanSendTradeChat()) { ImGui::TextColored(COLOR_ERROR, "Not in an outpost."); @@ -535,9 +536,8 @@ void GWDashPlugin::DrawTradePresetSettings() if (!trade_presets_.LoadOk()) { ImGui::TextColored(COLOR_ERROR, "%s", - trade_presets_.LoadError().empty() - ? "Failed to load presets.json" - : trade_presets_.LoadError().c_str()); + trade_presets_.LoadError().empty() ? "Failed to load presets.json" + : trade_presets_.LoadError().c_str()); if (ImGui::Button("Reset presets")) { trade_presets_.Reset(); preset_edit_drafts_.clear(); @@ -557,8 +557,7 @@ void GWDashPlugin::DrawTradePresetSettings() if (trade_presets_.ExportToFile(path, error)) { WriteChat("Exported trade presets."); presets_ui_error_.clear(); - } - else { + } else { presets_ui_error_ = error; } } @@ -573,8 +572,7 @@ void GWDashPlugin::DrawTradePresetSettings() PersistPresets(); WriteChat("Imported trade presets."); presets_ui_error_.clear(); - } - else { + } else { presets_ui_error_ = error; } } @@ -593,8 +591,7 @@ void GWDashPlugin::DrawTradePresetSettings() const bool expanded = ImGui::CollapsingHeader(header.c_str(), flags); if (expanded && open_preset_editor_ != preset.name) { open_preset_editor_ = preset.name; - } - else if (!expanded && open_preset_editor_ == preset.name) { + } else if (!expanded && open_preset_editor_ == preset.name) { open_preset_editor_.clear(); } @@ -615,7 +612,8 @@ void GWDashPlugin::DrawTradePresetSettings() draft.rename.fill('\0'); draft.message.fill('\0'); strncpy_s(draft.rename.data(), draft.rename.size(), preset.name.c_str(), _TRUNCATE); - strncpy_s(draft.message.data(), draft.message.size(), preset.message.c_str(), _TRUNCATE); + strncpy_s(draft.message.data(), draft.message.size(), preset.message.c_str(), + _TRUNCATE); } ImGui::Combo("Kind", &draft.kind_index, KIND_COMBO); @@ -628,26 +626,23 @@ void GWDashPlugin::DrawTradePresetSettings() if (ImGui::Button("Save")) { std::string error; - if (trade_presets_.Upsert(preset.name, KindLabel(draft.kind_index), draft.message.data(), - error)) { + if (trade_presets_.Upsert(preset.name, KindLabel(draft.kind_index), + draft.message.data(), error)) { if (draft.rename[0] != '\0' && gwdash::SanitizePresetName(draft.rename.data()) != preset.name) { if (!trade_presets_.Rename(preset.name, draft.rename.data(), error)) { presets_ui_error_ = error; - } - else { + } else { preset_edit_drafts_.erase(preset.name); open_preset_editor_ = gwdash::SanitizePresetName(draft.rename.data()); PersistPresets(); presets_ui_error_.clear(); } - } - else { + } else { PersistPresets(); presets_ui_error_.clear(); } - } - else { + } else { presets_ui_error_ = error; } } @@ -668,8 +663,7 @@ void GWDashPlugin::DrawTradePresetSettings() std::string error; if (trade_presets_.Move(preset.name, -1, error)) { PersistPresets(); - } - else if (!error.empty()) { + } else if (!error.empty()) { presets_ui_error_ = error; } } @@ -678,8 +672,7 @@ void GWDashPlugin::DrawTradePresetSettings() std::string error; if (trade_presets_.Move(preset.name, 1, error)) { PersistPresets(); - } - else if (!error.empty()) { + } else if (!error.empty()) { presets_ui_error_ = error; } } @@ -689,8 +682,7 @@ void GWDashPlugin::DrawTradePresetSettings() if (trade_presets_.Duplicate(preset.name, error)) { PersistPresets(); presets_ui_error_.clear(); - } - else { + } else { presets_ui_error_ = error; } } @@ -700,8 +692,7 @@ void GWDashPlugin::DrawTradePresetSettings() if (trade_presets_.SetDefault(preset.name, error)) { PersistPresets(); presets_ui_error_.clear(); - } - else { + } else { presets_ui_error_ = error; } } @@ -726,14 +717,13 @@ void GWDashPlugin::DrawTradePresetSettings() ImGui::Combo("Kind##new", &draft_kind_index_, KIND_COMBO); ImGui::InputTextWithHint("Message##new", "e.g. 27e arms", draft_message_.data(), draft_message_.size()); - ImGui::TextDisabled("Preview: %s", - gwdash::ComposeTradeLine(KindLabel(draft_kind_index_), draft_message_.data()) - .c_str()); + ImGui::TextDisabled( + "Preview: %s", + gwdash::ComposeTradeLine(KindLabel(draft_kind_index_), draft_message_.data()).c_str()); if (trade_presets_.List().size() >= gwdash::MAX_TRADE_PRESETS) { ImGui::TextDisabled("At most %zu presets.", gwdash::MAX_TRADE_PRESETS); - } - else if (ImGui::Button("Add")) { + } else if (ImGui::Button("Add")) { std::string error; if (trade_presets_.Upsert(draft_name_.data(), KindLabel(draft_kind_index_), draft_message_.data(), error)) { @@ -742,8 +732,7 @@ void GWDashPlugin::DrawTradePresetSettings() draft_message_.fill('\0'); draft_kind_index_ = 1; presets_ui_error_.clear(); - } - else { + } else { presets_ui_error_ = error; } } @@ -771,8 +760,7 @@ void GWDashPlugin::Draw(IDirect3DDevice9*) if (compact_) { DrawCompact(state); - } - else { + } else { DrawRows(state); } @@ -801,7 +789,10 @@ void GWDashPlugin::DrawSettings() ImGui::Separator(); - if (ImGui::Combo("Refresh every", &refresh_index_, "60 seconds\0" "2 minutes\0" "5 minutes\0")) { + if (ImGui::Combo("Refresh every", &refresh_index_, + "60 seconds\0" + "2 minutes\0" + "5 minutes\0")) { ApplyRefreshInterval(); } ImGui::Checkbox("Slow down while Guild Wars is in the background", &throttle_unfocused_); @@ -836,8 +827,9 @@ void GWDashPlugin::DrawSettings() ImGui::TextDisabled("Updates: %s", update.message.c_str()); } if (update.loader_outdated) { - ImGui::TextColored(COLOR_STALE, "%s", - "This release also updates GWDash.dll. Re-run the installer to pick it up."); + ImGui::TextColored( + COLOR_STALE, "%s", + "This release also updates GWDash.dll. Re-run the installer to pick it up."); } ImGui::TextDisabled("Version %s | source %s", GWDASH_VERSION, @@ -906,9 +898,11 @@ void GWDashPlugin::WritePricesToChat() const std::string line = "Ecto "; line += snapshot.ecto.price.has_value() ? gwdash::FormatGold(*snapshot.ecto.price) : "--"; line += " | Armbrace "; - line += snapshot.armbrace.price.has_value() ? gwdash::FormatEcto(*snapshot.armbrace.price) : "--"; + line += + snapshot.armbrace.price.has_value() ? gwdash::FormatEcto(*snapshot.armbrace.price) : "--"; line += " | Black Dye "; - line += snapshot.blackdye.price.has_value() ? gwdash::FormatGold(*snapshot.blackdye.price) : "--"; + line += + snapshot.blackdye.price.has_value() ? gwdash::FormatGold(*snapshot.blackdye.price) : "--"; WriteChat(line); } @@ -925,28 +919,21 @@ void GWDashPlugin::OnChatCommand(const int argc, const LPWSTR* argv) if (argument == L"show") { *visible = true; - } - else if (argument == L"hide") { + } else if (argument == L"hide") { *visible = false; - } - else if (argument == L"toggle") { + } else if (argument == L"toggle") { *visible = !*visible; - } - else if (argument == L"refresh") { + } else if (argument == L"refresh") { prices_.RequestRefresh(); WriteChat("Refreshing prices..."); - } - else if (argument == L"prices") { + } else if (argument == L"prices") { WritePricesToChat(); - } - else if (argument == L"update") { + } else if (argument == L"update") { updater_.RequestCheck(); WriteChat("Checking for updates..."); - } - else if (argument == L"version") { + } else if (argument == L"version") { WriteChat(std::string("GWDash ") + GWDASH_VERSION); - } - else if (argument == L"presets") { + } else if (argument == L"presets") { const auto& presets = trade_presets_.List(); if (presets.empty()) { WriteChat("No trade presets. Add some under Toolbox → Settings → GWDash."); @@ -955,18 +942,17 @@ void GWDashPlugin::OnChatCommand(const int argc, const LPWSTR* argv) WriteChat(std::string("Trade presets (") + std::to_string(presets.size()) + "):"); for (const gwdash::TradePreset& preset : presets) { const std::string line = gwdash::ComposeTradeLine(preset.kind, preset.message); - WriteChat(" /gwdash send " + preset.name + (preset.is_default ? " *" : "") + - " " + line); + WriteChat(" /gwdash send " + preset.name + (preset.is_default ? " *" : "") + " " + + line); } - } - else if (argument == L"send") { + } else if (argument == L"send") { if (argc < 3) { WriteChat("Usage: /gwdash send "); return; } SendPresetByName(PluginUtils::WStringToString(argv[2])); - } - else { - WriteChat("Usage: /gwdash [show|hide|toggle|refresh|prices|update|version|presets|send ]"); + } else { + WriteChat( + "Usage: /gwdash [show|hide|toggle|refresh|prices|update|version|presets|send ]"); } } diff --git a/src/GWDashPlugin.h b/src/GWDashPlugin.h index 9e33c6a..11917b7 100644 --- a/src/GWDashPlugin.h +++ b/src/GWDashPlugin.h @@ -16,7 +16,7 @@ * Values and formatting mirror gwdash.com so both agree at a glance. */ class GWDashPlugin final : public ToolboxUIPlugin { -public: + public: GWDashPlugin(); ~GWDashPlugin() override = default; @@ -39,7 +39,7 @@ class GWDashPlugin final : public ToolboxUIPlugin { /** Handles /gwdash. Runs on the game thread. */ void OnChatCommand(int argc, const LPWSTR* argv); -private: + private: void DrawRows(const gwdash::PriceState& state); void DrawCompact(const gwdash::PriceState& state); void DrawStatusLine(const gwdash::PriceState& state); diff --git a/src/Http.cpp b/src/Http.cpp index e54a2b1..b626bef 100644 --- a/src/Http.cpp +++ b/src/Http.cpp @@ -24,7 +24,7 @@ namespace { constexpr int MAX_REDIRECTS = 3; class Handle { - public: + public: Handle() = default; explicit Handle(const HINTERNET handle) : handle_(handle) {} ~Handle() { Close(); } @@ -46,7 +46,7 @@ namespace { [[nodiscard]] HINTERNET get() const { return handle_; } explicit operator bool() const { return handle_ != nullptr; } - private: + private: void Close() { if (handle_) { @@ -63,12 +63,14 @@ namespace { if (value.empty()) { return {}; } - const int needed = MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast(value.size()), nullptr, 0); + const int needed = MultiByteToWideChar(CP_UTF8, 0, value.data(), + static_cast(value.size()), nullptr, 0); if (needed <= 0) { return {}; } std::wstring out(static_cast(needed), L'\0'); - MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast(value.size()), out.data(), needed); + MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast(value.size()), out.data(), + needed); return out; } @@ -77,14 +79,14 @@ namespace { if (value.empty()) { return {}; } - const int needed = WideCharToMultiByte(CP_UTF8, 0, value.data(), static_cast(value.size()), - nullptr, 0, nullptr, nullptr); + const int needed = WideCharToMultiByte( + CP_UTF8, 0, value.data(), static_cast(value.size()), nullptr, 0, nullptr, nullptr); if (needed <= 0) { return {}; } std::string out(static_cast(needed), '\0'); - WideCharToMultiByte(CP_UTF8, 0, value.data(), static_cast(value.size()), - out.data(), needed, nullptr, nullptr); + WideCharToMultiByte(CP_UTF8, 0, value.data(), static_cast(value.size()), out.data(), + needed, nullptr, nullptr); return out; } @@ -135,7 +137,8 @@ namespace { DWORD status = 0; DWORD size = sizeof(status); if (!WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - WINHTTP_HEADER_NAME_BY_INDEX, &status, &size, WINHTTP_NO_HEADER_INDEX)) { + WINHTTP_HEADER_NAME_BY_INDEX, &status, &size, + WINHTTP_NO_HEADER_INDEX)) { return 0; } return static_cast(status); @@ -144,15 +147,15 @@ namespace { std::string QueryEtag(const HINTERNET request) { DWORD size = 0; - WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM, L"ETag", - WINHTTP_NO_OUTPUT_BUFFER, &size, WINHTTP_NO_HEADER_INDEX); + WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM, L"ETag", WINHTTP_NO_OUTPUT_BUFFER, &size, + WINHTTP_NO_HEADER_INDEX); if (size == 0 || size > 1024) { return {}; } std::wstring value(size / sizeof(wchar_t), L'\0'); - if (!WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM, L"ETag", - value.data(), &size, WINHTTP_NO_HEADER_INDEX)) { + if (!WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM, L"ETag", value.data(), &size, + WINHTTP_NO_HEADER_INDEX)) { return {}; } while (!value.empty() && value.back() == L'\0') { @@ -221,9 +224,11 @@ namespace { SEND_TIMEOUT_MS, RECEIVE_TIMEOUT_MS); DWORD disable = WINHTTP_DISABLE_REDIRECTS; - WinHttpSetOption(out.session.get(), WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable)); + WinHttpSetOption(out.session.get(), WINHTTP_OPTION_DISABLE_FEATURE, &disable, + sizeof(disable)); - out.connection = Handle(WinHttpConnect(out.session.get(), host.data(), components.nPort, 0)); + out.connection = + Handle(WinHttpConnect(out.session.get(), host.data(), components.nPort, 0)); if (!out.connection) { error = LastErrorMessage("WinHttpConnect"); return false; @@ -243,7 +248,8 @@ namespace { if (IsSafeEtag(etag)) { headers += L"If-None-Match: " + Widen(etag) + L"\r\n"; } - WinHttpAddRequestHeaders(out.request.get(), headers.c_str(), static_cast(headers.size()), + WinHttpAddRequestHeaders(out.request.get(), headers.c_str(), + static_cast(headers.size()), WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); if (!WinHttpSendRequest(out.request.get(), WINHTTP_NO_ADDITIONAL_HEADERS, 0, @@ -287,15 +293,11 @@ namespace { error = "too many redirects"; return false; } -} +} // namespace namespace gwdash::http { - bool Get(const std::wstring& url, - const std::string& etag, - const std::size_t max_bytes, - Response& out, - std::string& error, - const wchar_t* accept) + bool Get(const std::wstring& url, const std::string& etag, const std::size_t max_bytes, + Response& out, std::string& error, const wchar_t* accept) { Request request; if (!OpenRequest(url, etag, accept, request, error)) { @@ -337,9 +339,7 @@ namespace gwdash::http { return true; } - bool Download(const std::wstring& url, - const fs::path& destination, - const std::size_t max_bytes, + bool Download(const std::wstring& url, const fs::path& destination, const std::size_t max_bytes, std::string& error) { Request request; @@ -416,8 +416,9 @@ namespace gwdash::http { DWORD object_length = 0; DWORD written = 0; - if (BCryptGetProperty(algorithm, BCRYPT_OBJECT_LENGTH, reinterpret_cast(&object_length), - sizeof(object_length), &written, 0) != 0) { + if (BCryptGetProperty(algorithm, BCRYPT_OBJECT_LENGTH, + reinterpret_cast(&object_length), sizeof(object_length), + &written, 0) != 0) { BCryptCloseAlgorithmProvider(algorithm, 0); return {}; } @@ -448,7 +449,8 @@ namespace gwdash::http { if (ok) { std::array digest{}; - if (BCryptFinishHash(hash, digest.data(), static_cast(digest.size()), 0) == 0) { + if (BCryptFinishHash(hash, digest.data(), static_cast(digest.size()), 0) == + 0) { static constexpr char HEX[] = "0123456789abcdef"; result.reserve(digest.size() * 2); for (const UCHAR byte : digest) { @@ -463,4 +465,4 @@ namespace gwdash::http { BCryptCloseAlgorithmProvider(algorithm, 0); return result; } -} +} // namespace gwdash::http diff --git a/src/Http.h b/src/Http.h index 9015491..68585ea 100644 --- a/src/Http.h +++ b/src/Http.h @@ -17,21 +17,15 @@ namespace gwdash::http { * Blocking HTTPS GET to an allowlisted host. `etag` is sent as If-None-Match * when it is non-empty and free of CR/LF/control characters (else ignored). * Returns false only on transport errors; check `out.status` otherwise. - * `accept` defaults to application/json; pass "*/*" for binary assets. + * `accept` defaults to application/json; pass star-slash-star for binary assets. */ - bool Get(const std::wstring& url, - const std::string& etag, - std::size_t max_bytes, - Response& out, - std::string& error, - const wchar_t* accept = L"application/json"); + bool Get(const std::wstring& url, const std::string& etag, std::size_t max_bytes, Response& out, + std::string& error, const wchar_t* accept = L"application/json"); /** Blocking HTTPS download to an allowlisted host; creates parent directories. */ - bool Download(const std::wstring& url, - const std::filesystem::path& destination, - std::size_t max_bytes, - std::string& error); + bool Download(const std::wstring& url, const std::filesystem::path& destination, + std::size_t max_bytes, std::string& error); /** Lowercase hex SHA-256 of a file, empty on failure. */ std::string FileSha256(const std::filesystem::path& path); -} +} // namespace gwdash::http diff --git a/src/Manifest.cpp b/src/Manifest.cpp index 8698341..79eae1a 100644 --- a/src/Manifest.cpp +++ b/src/Manifest.cpp @@ -12,14 +12,12 @@ extern "C" { #include "UpdatePublicKey.h" -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::ManifestFile; static constexpr auto value = object("name", &T::name, "sha256", &T::sha256); }; -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::UpdateManifest; static constexpr auto value = object("v", &T::v, "version", &T::version, "files", &T::files); }; @@ -93,8 +91,8 @@ namespace gwdash { return true; } - bool VerifyManifestSignature(const std::string_view signing_bytes, const std::string_view sig_hex, - std::string& error) + bool VerifyManifestSignature(const std::string_view signing_bytes, + const std::string_view sig_hex, std::string& error) { const std::vector signature = DecodeHex(sig_hex); if (signature.size() != 64) { @@ -111,4 +109,4 @@ namespace gwdash { error.clear(); return true; } -} +} // namespace gwdash diff --git a/src/Manifest.h b/src/Manifest.h index c959509..4d20ef9 100644 --- a/src/Manifest.h +++ b/src/Manifest.h @@ -28,4 +28,4 @@ namespace gwdash { /** Decode lowercase/uppercase hex; empty on failure. */ std::vector DecodeHex(std::string_view hex); -} +} // namespace gwdash diff --git a/src/Paths.cpp b/src/Paths.cpp index da7b4bf..08dff42 100644 --- a/src/Paths.cpp +++ b/src/Paths.cpp @@ -15,8 +15,8 @@ namespace { { std::vector buffer(MAX_PATH); for (;;) { - const DWORD length = GetModuleFileNameW(plugin_handle, buffer.data(), - static_cast(buffer.size())); + const DWORD length = + GetModuleFileNameW(plugin_handle, buffer.data(), static_cast(buffer.size())); if (length == 0) { return fs::current_path(); } @@ -26,7 +26,7 @@ namespace { buffer.resize(buffer.size() * 2); } } -} +} // namespace namespace gwdash { const fs::path& DataDirectory() @@ -106,4 +106,4 @@ namespace gwdash { } return true; } -} +} // namespace gwdash diff --git a/src/Paths.h b/src/Paths.h index 4ba9424..acbc749 100644 --- a/src/Paths.h +++ b/src/Paths.h @@ -33,4 +33,4 @@ namespace gwdash { /** Writes via a temporary file plus rename so readers never see a partial write. */ bool WriteFileAtomic(const std::filesystem::path& path, const std::string& contents); -} +} // namespace gwdash diff --git a/src/PriceClient.cpp b/src/PriceClient.cpp index 84cb5a1..c119b33 100644 --- a/src/PriceClient.cpp +++ b/src/PriceClient.cpp @@ -23,7 +23,7 @@ namespace { { return gwdash::NowMs(); } -} +} // namespace namespace gwdash { PriceClient::~PriceClient() @@ -175,8 +175,7 @@ namespace gwdash { std::lock_guard lock(state_mutex_); if (ok) { state_.consecutive_failures = 0; - } - else { + } else { if (state_.consecutive_failures < 100) { state_.consecutive_failures += 1; } @@ -188,11 +187,10 @@ namespace gwdash { } std::unique_lock lock(wait_mutex_); - wait_cv_.wait_for(lock, std::chrono::seconds(wait_seconds), [this] { - return stop_.load() || refresh_.exchange(false); - }); + wait_cv_.wait_for(lock, std::chrono::seconds(wait_seconds), + [this] { return stop_.load() || refresh_.exchange(false); }); } finished_ = true; } -} +} // namespace gwdash diff --git a/src/PriceClient.h b/src/PriceClient.h index a8db934..c6e13da 100644 --- a/src/PriceClient.h +++ b/src/PriceClient.h @@ -29,7 +29,7 @@ namespace gwdash { * used when that fails. */ class PriceClient { - public: + public: PriceClient() = default; ~PriceClient(); @@ -51,7 +51,7 @@ namespace gwdash { [[nodiscard]] PriceState State() const; - private: + private: void Run(); void LoadCache(); bool FetchOnce(const std::wstring& url, const char* source, std::string& etag); @@ -73,4 +73,4 @@ namespace gwdash { std::string primary_etag_; std::string fallback_etag_; }; -} +} // namespace gwdash diff --git a/src/PriceSnapshot.cpp b/src/PriceSnapshot.cpp index a782b2d..2771a8f 100644 --- a/src/PriceSnapshot.cpp +++ b/src/PriceSnapshot.cpp @@ -2,37 +2,22 @@ #include -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::TraderPrice; - static constexpr auto value = object( - "price", &T::price, - "buy", &T::buy, - "sell", &T::sell, - "unit", &T::unit, - "src", &T::src, - "at", &T::at); + static constexpr auto value = object("price", &T::price, "buy", &T::buy, "sell", &T::sell, + "unit", &T::unit, "src", &T::src, "at", &T::at); }; -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::ChatPrice; - static constexpr auto value = object( - "price", &T::price, - "unit", &T::unit, - "n", &T::n, - "at", &T::at); + static constexpr auto value = + object("price", &T::price, "unit", &T::unit, "n", &T::n, "at", &T::at); }; -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::PriceSnapshot; - static constexpr auto value = object( - "v", &T::v, - "at", &T::at, - "ecto", &T::ecto, - "armbrace", &T::armbrace, - "blackdye", &T::blackdye); + static constexpr auto value = object("v", &T::v, "at", &T::at, "ecto", &T::ecto, "armbrace", + &T::armbrace, "blackdye", &T::blackdye); }; namespace gwdash { @@ -51,4 +36,4 @@ namespace gwdash { out = std::move(staged); return true; } -} +} // namespace gwdash diff --git a/src/PriceSnapshot.h b/src/PriceSnapshot.h index a7d7cd9..436f618 100644 --- a/src/PriceSnapshot.h +++ b/src/PriceSnapshot.h @@ -53,12 +53,10 @@ namespace gwdash { const double k = static_cast(gold) / 1000.0; if (k >= 100.0) { snprintf(buffer, sizeof(buffer), "%lldk", static_cast(k + 0.5)); - } - else { + } else { snprintf(buffer, sizeof(buffer), "%.1fk", k); } - } - else { + } else { snprintf(buffer, sizeof(buffer), "%lld", gold); } return buffer; @@ -74,8 +72,7 @@ namespace gwdash { const long long whole = static_cast(value + 0.0001); if (value - static_cast(whole) < 0.05) { snprintf(buffer, sizeof(buffer), "%llde", whole); - } - else { + } else { snprintf(buffer, sizeof(buffer), "%.1fe", value); } return buffer; @@ -92,16 +89,13 @@ namespace gwdash { char buffer[32]; if (seconds < 60) { snprintf(buffer, sizeof(buffer), "%llds", static_cast(seconds)); - } - else if (seconds < 3600) { + } else if (seconds < 3600) { snprintf(buffer, sizeof(buffer), "%lldm", static_cast(seconds / 60)); - } - else if (seconds < 86400) { + } else if (seconds < 86400) { snprintf(buffer, sizeof(buffer), "%lldh", static_cast(seconds / 3600)); - } - else { + } else { snprintf(buffer, sizeof(buffer), "%lldd", static_cast(seconds / 86400)); } return buffer; } -} +} // namespace gwdash diff --git a/src/TimeUtil.h b/src/TimeUtil.h index 8f47a13..c525814 100644 --- a/src/TimeUtil.h +++ b/src/TimeUtil.h @@ -9,4 +9,4 @@ namespace gwdash { using namespace std::chrono; return duration_cast(system_clock::now().time_since_epoch()).count(); } -} +} // namespace gwdash diff --git a/src/TradePresetText.cpp b/src/TradePresetText.cpp index b999b8e..6aaa147 100644 --- a/src/TradePresetText.cpp +++ b/src/TradePresetText.cpp @@ -23,11 +23,10 @@ namespace { if (head != "wtb" && head != "wts" && head != "wtt") { return false; } - return message.size() == 3 || - std::isspace(static_cast(message[3])) || + return message.size() == 3 || std::isspace(static_cast(message[3])) || message[3] == ':'; } -} +} // namespace namespace gwdash { std::string SanitizePresetName(const std::string_view raw) @@ -60,8 +59,7 @@ namespace gwdash { out.reserve(std::min(raw.size(), MAX_PRESET_MESSAGE_LEN)); std::size_t start = 0; - while (start < raw.size() && - std::isspace(static_cast(raw[start]))) { + while (start < raw.size() && std::isspace(static_cast(raw[start]))) { ++start; } @@ -103,4 +101,4 @@ namespace gwdash { } return line; } -} +} // namespace gwdash diff --git a/src/TradePresetText.h b/src/TradePresetText.h index b8ab285..3a9817f 100644 --- a/src/TradePresetText.h +++ b/src/TradePresetText.h @@ -15,4 +15,4 @@ namespace gwdash { std::string SanitizePresetKind(std::string_view raw); std::string SanitizePresetMessage(std::string_view raw); std::string ComposeTradeLine(std::string_view kind, std::string_view message); -} +} // namespace gwdash diff --git a/src/TradePresets.cpp b/src/TradePresets.cpp index 6dc3590..6e43964 100644 --- a/src/TradePresets.cpp +++ b/src/TradePresets.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include #include #include @@ -21,7 +23,7 @@ namespace gwdash { int v = 1; std::vector presets; }; -} +} // namespace gwdash namespace { constexpr std::size_t MAX_PRESETS_FILE_BYTES = 64 * 1024; @@ -52,38 +54,32 @@ namespace { } int suffix = 2; for (;;) { - const bool taken = std::any_of( - presets.begin(), presets.end(), - [&](const gwdash::TradePreset& p) { return NamesEqual(p.name, candidate); }); + const bool taken = + std::any_of(presets.begin(), presets.end(), [&](const gwdash::TradePreset& p) { + return NamesEqual(p.name, candidate); + }); if (!taken) { return candidate; } - const std::string numbered = gwdash::SanitizePresetName( - std::string(base) + "_" + std::to_string(suffix++)); + const std::string numbered = + gwdash::SanitizePresetName(std::string(base) + "_" + std::to_string(suffix++)); candidate = numbered.empty() ? ("copy" + std::to_string(suffix)) : numbered; if (candidate.size() > gwdash::MAX_PRESET_NAME_LEN) { candidate.resize(gwdash::MAX_PRESET_NAME_LEN); } } } -} +} // namespace -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::TradePreset; - static constexpr auto value = object( - "name", &T::name, - "kind", &T::kind, - "message", &T::message, - "default", &T::is_default); + static constexpr auto value = object("name", &T::name, "kind", &T::kind, "message", &T::message, + "default", &T::is_default); }; -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::PresetsFilePayload; - static constexpr auto value = object( - "v", &T::v, - "presets", &T::presets); + static constexpr auto value = object("v", &T::v, "presets", &T::presets); }; namespace gwdash { @@ -118,9 +114,10 @@ namespace gwdash { if (next.name.empty() || next.message.empty()) { continue; } - const bool duplicate = std::any_of( - cleaned.begin(), cleaned.end(), - [&](const TradePreset& existing) { return NamesEqual(existing.name, next.name); }); + const bool duplicate = + std::any_of(cleaned.begin(), cleaned.end(), [&](const TradePreset& existing) { + return NamesEqual(existing.name, next.name); + }); if (duplicate) { continue; } @@ -269,9 +266,9 @@ namespace gwdash { if (key.empty()) { return false; } - const auto it = std::find_if( - presets_.begin(), presets_.end(), - [&](const TradePreset& preset) { return NamesEqual(preset.name, key); }); + const auto it = + std::find_if(presets_.begin(), presets_.end(), + [&](const TradePreset& preset) { return NamesEqual(preset.name, key); }); if (it == presets_.end()) { return false; } @@ -346,9 +343,9 @@ namespace gwdash { error.clear(); return true; } - const auto it = std::find_if( - presets_.begin(), presets_.end(), - [&](const TradePreset& preset) { return NamesEqual(preset.name, name); }); + const auto it = + std::find_if(presets_.begin(), presets_.end(), + [&](const TradePreset& preset) { return NamesEqual(preset.name, name); }); if (it == presets_.end()) { error = "Unknown preset."; return false; @@ -459,4 +456,4 @@ namespace gwdash { } return TrySend(*preset, error); } -} +} // namespace gwdash diff --git a/src/TradePresets.h b/src/TradePresets.h index a7f1187..5a159c4 100644 --- a/src/TradePresets.h +++ b/src/TradePresets.h @@ -24,7 +24,7 @@ namespace gwdash { * Send goes through GW::Chat::SendChat('$', ...) and must run on the game thread. */ class TradePresets { - public: + public: [[nodiscard]] const std::vector& List() const { return presets_; } [[nodiscard]] bool LoadOk() const { return load_ok_; } [[nodiscard]] const std::string& LoadError() const { return load_error_; } @@ -50,7 +50,7 @@ namespace gwdash { bool TrySend(const TradePreset& preset, std::string& error); bool TrySendByName(std::string_view name, std::string& error); - private: + private: bool WritePayload(const std::filesystem::path& path, std::string& error) const; bool ReadPayload(const std::string& json, std::vector& out, std::string& error) const; @@ -60,4 +60,4 @@ namespace gwdash { bool load_ok_ = true; std::string load_error_; }; -} +} // namespace gwdash diff --git a/src/UpdatePublicKey.h b/src/UpdatePublicKey.h index efa820c..1513e1d 100644 --- a/src/UpdatePublicKey.h +++ b/src/UpdatePublicKey.h @@ -11,6 +11,7 @@ namespace gwdash { * GWDASH_UPDATE_ED25519_SK (64 hex chars). */ constexpr std::array UPDATE_PUBLIC_KEY = { - 0xd4, 0x2f, 0x06, 0x47, 0xaa, 0x32, 0xb0, 0x78, 0xc3, 0x8e, 0x2b, 0x14, 0xd6, 0xed, 0x45, 0xdb, - 0x0b, 0xdd, 0xaa, 0x48, 0xa3, 0xf8, 0x9a, 0xdb, 0x3d, 0xb4, 0xdc, 0x4c, 0x5d, 0xbe, 0x30, 0xd2}; -} + 0xd4, 0x2f, 0x06, 0x47, 0xaa, 0x32, 0xb0, 0x78, 0xc3, 0x8e, 0x2b, + 0x14, 0xd6, 0xed, 0x45, 0xdb, 0x0b, 0xdd, 0xaa, 0x48, 0xa3, 0xf8, + 0x9a, 0xdb, 0x3d, 0xb4, 0xdc, 0x4c, 0x5d, 0xbe, 0x30, 0xd2}; +} // namespace gwdash diff --git a/src/Updater.cpp b/src/Updater.cpp index 6867368..ca8db6a 100644 --- a/src/Updater.cpp +++ b/src/Updater.cpp @@ -32,22 +32,18 @@ namespace gwdash::github { bool prerelease = false; std::vector assets; }; -} +} // namespace gwdash::github -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::github::Asset; - static constexpr auto value = object("name", &T::name, "browser_download_url", &T::browser_download_url); + static constexpr auto value = + object("name", &T::name, "browser_download_url", &T::browser_download_url); }; -template <> -struct glz::meta { +template <> struct glz::meta { using T = gwdash::github::Release; - static constexpr auto value = object( - "tag_name", &T::tag_name, - "draft", &T::draft, - "prerelease", &T::prerelease, - "assets", &T::assets); + static constexpr auto value = object("tag_name", &T::tag_name, "draft", &T::draft, "prerelease", + &T::prerelease, "assets", &T::assets); }; namespace { @@ -77,13 +73,14 @@ namespace { if (value.empty()) { return {}; } - const int needed = MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast(value.size()), - nullptr, 0); + const int needed = MultiByteToWideChar(CP_UTF8, 0, value.data(), + static_cast(value.size()), nullptr, 0); if (needed <= 0) { return {}; } std::wstring out(static_cast(needed), L'\0'); - MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast(value.size()), out.data(), needed); + MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast(value.size()), out.data(), + needed); return out; } @@ -93,9 +90,8 @@ namespace { while (!value.empty() && is_space(static_cast(value.back()))) { value.pop_back(); } - const auto begin = std::ranges::find_if_not(value, [&](const char c) { - return is_space(static_cast(c)); - }); + const auto begin = std::ranges::find_if_not( + value, [&](const char c) { return is_space(static_cast(c)); }); value.erase(value.begin(), begin); return value; } @@ -150,7 +146,8 @@ namespace { return {}; } - const gwdash::github::Asset* FindAsset(const gwdash::github::Release& release, const std::string& name) + const gwdash::github::Asset* FindAsset(const gwdash::github::Release& release, + const std::string& name) { for (const auto& asset : release.assets) { if (asset.name == name) { @@ -159,7 +156,7 @@ namespace { } return nullptr; } -} +} // namespace namespace gwdash { Updater::~Updater() @@ -267,7 +264,8 @@ namespace gwdash { return; } if (response.status != 200) { - SetStatus(UpdateStatus::Failed, "Update check failed: HTTP " + std::to_string(response.status)); + SetStatus(UpdateStatus::Failed, + "Update check failed: HTTP " + std::to_string(response.status)); return; } if (!response.etag.empty()) { @@ -281,7 +279,8 @@ namespace gwdash { return; } if (release.draft || release.prerelease) { - SetStatus(UpdateStatus::UpToDate, "Latest GitHub release is draft/prerelease - ignoring."); + SetStatus(UpdateStatus::UpToDate, + "Latest GitHub release is draft/prerelease - ignoring."); return; } @@ -299,7 +298,8 @@ namespace gwdash { if (!auto_install_.load()) { SetStatus(UpdateStatus::Available, "Version " + latest + " is available."); - Notify("GWDash " + latest + " is available. Enable auto-update or run the installer again."); + Notify("GWDash " + latest + + " is available. Enable auto-update or run the installer again."); return; } @@ -307,7 +307,8 @@ namespace gwdash { const fs::path pending_dir = PendingDirectory(); const std::string staged_version = ReadFile(pending_dir / L"version.txt", 64); if (StripVersionPrefix(staged_version) == latest) { - SetStatus(UpdateStatus::Staged, "Version " + latest + " is ready - restart Guild Wars to apply."); + SetStatus(UpdateStatus::Staged, + "Version " + latest + " is ready - restart Guild Wars to apply."); return; } @@ -385,7 +386,8 @@ namespace gwdash { std::error_code ec; fs::path download = pending_dir / CORE_ASSET; download += L".part"; - if (!http::Download(Widen(core->browser_download_url), download, MAX_PAYLOAD_BYTES, error)) { + if (!http::Download(Widen(core->browser_download_url), download, MAX_PAYLOAD_BYTES, + error)) { SetStatus(UpdateStatus::Failed, "Download failed: " + error); return; } @@ -418,8 +420,10 @@ namespace gwdash { state_.loader_outdated = loader_outdated; } - SetStatus(UpdateStatus::Staged, "Version " + latest + " is ready - restart Guild Wars to apply."); - Notify("GWDash " + latest + " downloaded. It will be active the next time you start Guild Wars."); + SetStatus(UpdateStatus::Staged, + "Version " + latest + " is ready - restart Guild Wars to apply."); + Notify("GWDash " + latest + + " downloaded. It will be active the next time you start Guild Wars."); if (loader_outdated) { Notify("This release also updates the loader. Run the installer once to pick it up: " "irm https://gwdash.com/install.ps1 | iex"); @@ -433,9 +437,8 @@ namespace gwdash { for (;;) { { std::unique_lock lock(wait_mutex_); - wait_cv_.wait_for(lock, std::chrono::seconds(wait_seconds), [this] { - return stop_.load() || check_now_.exchange(false); - }); + wait_cv_.wait_for(lock, std::chrono::seconds(wait_seconds), + [this] { return stop_.load() || check_now_.exchange(false); }); } if (stop_.load()) { break; @@ -447,4 +450,4 @@ namespace gwdash { finished_ = true; } -} +} // namespace gwdash diff --git a/src/Updater.h b/src/Updater.h index d0a86d7..0b903a7 100644 --- a/src/Updater.h +++ b/src/Updater.h @@ -38,7 +38,7 @@ namespace gwdash { * start, which is the only moment nothing holds a file lock on it. */ class Updater { - public: + public: Updater() = default; ~Updater(); @@ -60,7 +60,7 @@ namespace gwdash { /** Moves queued chat messages out; call from the game thread. */ std::vector TakeNotifications(); - private: + private: void Run(); void CheckOnce(); void Notify(std::string message); @@ -82,4 +82,4 @@ namespace gwdash { std::atomic_bool running_{false}; std::atomic_bool auto_install_{true}; }; -} +} // namespace gwdash diff --git a/tests/gwdash_tests.cpp b/tests/gwdash_tests.cpp index e3cf657..9335c42 100644 --- a/tests/gwdash_tests.cpp +++ b/tests/gwdash_tests.cpp @@ -20,7 +20,7 @@ namespace { ++failures; } } -} +} // namespace int main() {