From 33bf1f9653ed608de5554940dc8a0c3f5dc7e4ea Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Mon, 10 Jun 2024 19:13:22 -0400 Subject: Go back to old logging system Brought in libfmt to handle string formatting and replace a bunch of ostringstream uses. --- CMakeLists.txt | 5 +++- src/ap_state.cpp | 79 +++++++++++++++++++++++++++--------------------------- src/game_data.cpp | 63 +++++++++++++++++++++---------------------- src/logger.cpp | 32 ++++++++++++++++++++++ src/logger.h | 8 ++++++ src/main.cpp | 12 --------- src/subway_map.cpp | 14 +++++----- src/version.h | 7 +++-- vcpkg.json | 3 ++- 9 files changed, 126 insertions(+), 97 deletions(-) create mode 100644 src/logger.cpp create mode 100644 src/logger.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cd62c55..f9f1117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ find_package(wxWidgets CONFIG REQUIRED) find_package(OpenSSL REQUIRED) find_package(yaml-cpp REQUIRED) find_package(websocketpp REQUIRED) +find_package(fmt REQUIRED) include_directories( vendor/hkutil @@ -22,6 +23,7 @@ include_directories( ${yaml-cpp_INCLUDE_DIRS} ${OpenSSL_INCLUDE_DIRS} vendor/whereami + ${fmt_INCLUDE_DIRS} vendor ) @@ -45,8 +47,9 @@ add_executable(lingo_ap_tracker "src/global.cpp" "src/subway_map.cpp" "src/network_set.cpp" + "src/logger.cpp" "vendor/whereami/whereami.c" ) set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 20) set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) -target_link_libraries(lingo_ap_tracker PRIVATE OpenSSL::SSL OpenSSL::Crypto websocketpp::websocketpp wx::core wx::base wx::net yaml-cpp::yaml-cpp) +target_link_libraries(lingo_ap_tracker PRIVATE fmt::fmt OpenSSL::SSL OpenSSL::Crypto websocketpp::websocketpp wx::core wx::base wx::net yaml-cpp::yaml-cpp) diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 8ff0ccd..e4d892b 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp @@ -4,6 +4,7 @@ #define _WEBSOCKETPP_CPP11_STRICT_ #pragma comment(lib, "crypt32") +#include #include #include @@ -21,6 +22,7 @@ #include #include "game_data.h" +#include "logger.h" #include "tracker_frame.h" #include "tracker_state.h" @@ -75,7 +77,7 @@ struct APState { void Connect(std::string server, std::string player, std::string password) { if (!initialized) { - wxLogVerbose("Initializing APState..."); + TrackerLog("Initializing APState..."); std::thread([this]() { for (;;) { @@ -91,14 +93,14 @@ struct APState { }).detach(); for (int panel_id : GD_GetAchievementPanels()) { - tracked_data_storage_keys.push_back( - "Achievement|" + GD_GetPanel(panel_id).achievement_name); + tracked_data_storage_keys.push_back(fmt::format( + "Achievement|{}", GD_GetPanel(panel_id).achievement_name)); } for (const MapArea& map_area : GD_GetMapAreas()) { for (const Location& location : map_area.locations) { tracked_data_storage_keys.push_back( - "Hunt|" + std::to_string(location.ap_location_id)); + fmt::format("Hunt|{}", location.ap_location_id)); } } @@ -109,10 +111,10 @@ struct APState { } tracker_frame->SetStatusMessage("Connecting to Archipelago server...."); - wxLogStatus("Connecting to Archipelago server (%s)...", server); + TrackerLog(fmt::format("Connecting to Archipelago server ({})...", server)); { - wxLogVerbose("Destroying old AP client..."); + TrackerLog("Destroying old AP client..."); std::lock_guard client_guard(client_mutex); @@ -158,10 +160,10 @@ struct APState { apclient->set_room_info_handler([this, player, password]() { inventory.clear(); - wxLogStatus("Connected to Archipelago server. Authenticating as %s %s", - player, - (password.empty() ? "without password" - : "with password " + password)); + TrackerLog(fmt::format( + "Connected to Archipelago server. Authenticating as {} {}", player, + (password.empty() ? "without password" + : "with password " + password))); tracker_frame->SetStatusMessage( "Connected to Archipelago server. Authenticating..."); @@ -173,7 +175,7 @@ struct APState { [this](const std::list& locations) { for (const int64_t location_id : locations) { checked_locations.insert(location_id); - wxLogVerbose("Location: %lld", location_id); + TrackerLog(fmt::format("Location: {}", location_id)); } RefreshTracker(false); @@ -182,14 +184,14 @@ struct APState { apclient->set_slot_disconnected_handler([this]() { tracker_frame->SetStatusMessage( "Disconnected from Archipelago. Attempting to reconnect..."); - wxLogStatus( + TrackerLog( "Slot disconnected from Archipelago. Attempting to reconnect..."); }); apclient->set_socket_disconnected_handler([this]() { tracker_frame->SetStatusMessage( "Disconnected from Archipelago. Attempting to reconnect..."); - wxLogStatus( + TrackerLog( "Socket disconnected from Archipelago. Attempting to reconnect..."); }); @@ -197,7 +199,7 @@ struct APState { [this](const std::list& items) { for (const APClient::NetworkItem& item : items) { inventory[item.item]++; - wxLogVerbose("Item: %lld", item.item); + TrackerLog(fmt::format("Item: {}", item.item)); } RefreshTracker(false); @@ -222,10 +224,10 @@ struct APState { apclient->set_slot_connected_handler([this, &connection_mutex]( const nlohmann::json& slot_data) { tracker_frame->SetStatusMessage("Connected to Archipelago!"); - wxLogStatus("Connected to Archipelago!"); + TrackerLog("Connected to Archipelago!"); data_storage_prefix = - "Lingo_" + std::to_string(apclient->get_player_number()) + "_"; + fmt::format("Lingo_{}_", apclient->get_player_number()); door_shuffle_mode = slot_data["shuffle_doors"].get(); color_shuffle = slot_data["shuffle_colors"].get() == 1; painting_shuffle = slot_data["shuffle_paintings"].get() == 1; @@ -277,18 +279,18 @@ struct APState { corrected_keys.push_back(data_storage_prefix + key); } - { - std::ostringstream vdsks; - vdsks << "_read_client_status_" << apclient->get_team_number() << "_" - << apclient->get_player_number(); - victory_data_storage_key = vdsks.str(); - } + victory_data_storage_key = + fmt::format("_read_client_status_{}_{}", apclient->get_team_number(), + apclient->get_player_number()); corrected_keys.push_back(victory_data_storage_key); apclient->Get(corrected_keys); apclient->SetNotify(corrected_keys); + ResetReachabilityRequirements(); + RefreshTracker(true); + { std::lock_guard connection_lock(connection_mutex); if (!has_connection_result) { @@ -333,7 +335,7 @@ struct APState { } std::string full_message = hatkirby::implode(error_messages, " "); - wxLogError(wxString(full_message)); + TrackerLog(full_message); wxMessageBox(full_message, "Connection failed", wxOK | wxICON_ERROR); }); @@ -355,7 +357,7 @@ struct APState { DestroyClient(); tracker_frame->SetStatusMessage("Disconnected from Archipelago."); - wxLogStatus("Timeout while connecting to Archipelago server."); + TrackerLog("Timeout while connecting to Archipelago server."); wxMessageBox("Timeout while connecting to Archipelago server.", "Connection failed", wxOK | wxICON_ERROR); @@ -374,9 +376,6 @@ struct APState { } if (connected) { - ResetReachabilityRequirements(); - RefreshTracker(true); - } else { client_active = false; } } @@ -384,11 +383,12 @@ struct APState { void HandleDataStorage(const std::string& key, const nlohmann::json& value) { if (value.is_boolean()) { data_storage[key] = value.get(); - wxLogVerbose("Data storage %s retrieved as %s", key, - (value.get() ? "true" : "false")); + TrackerLog(fmt::format("Data storage {} retrieved as {}", key, + (value.get() ? "true" : "false"))); } else if (value.is_number()) { data_storage[key] = value.get(); - wxLogVerbose("Data storage %s retrieved as %d", key, value.get()); + TrackerLog(fmt::format("Data storage {} retrieved as {}", key, + value.get())); } else if (value.is_object()) { if (key.ends_with("PlayerPos")) { auto map_value = value.get>(); @@ -397,7 +397,7 @@ struct APState { data_storage[key] = value.get>(); } - wxLogVerbose("Data storage %s retrieved as dictionary", key); + TrackerLog(fmt::format("Data storage {} retrieved as dictionary", key)); } else if (value.is_null()) { if (key.ends_with("PlayerPos")) { player_pos = std::nullopt; @@ -405,7 +405,7 @@ struct APState { data_storage.erase(key); } - wxLogVerbose("Data storage %s retrieved as null", key); + TrackerLog(fmt::format("Data storage {} retrieved as null", key)); } else if (value.is_array()) { auto list_value = value.get>(); @@ -416,8 +416,8 @@ struct APState { data_storage[key] = list_value; } - wxLogVerbose("Data storage %s retrieved as list: [%s]", key, - hatkirby::implode(list_value, ", ")); + TrackerLog(fmt::format("Data storage {} retrieved as list: [{}]", key, + hatkirby::implode(list_value, ", "))); } } @@ -427,7 +427,7 @@ struct APState { bool HasCheckedHuntPanel(int location_id) { std::string key = - data_storage_prefix + "Hunt|" + std::to_string(location_id); + fmt::format("{}Hunt|{}", data_storage_prefix, location_id); return data_storage.count(key) && std::any_cast(data_storage.at(key)); } @@ -436,12 +436,13 @@ struct APState { } bool HasAchievement(const std::string& name) { - std::string key = data_storage_prefix + "Achievement|" + name; + std::string key = + fmt::format("{}Achievement|{}", data_storage_prefix, name); return data_storage.count(key) && std::any_cast(data_storage.at(key)); } const std::set& GetCheckedPaintings() { - std::string key = data_storage_prefix + "Paintings"; + std::string key = fmt::format("{}Paintings", data_storage_prefix); if (!data_storage.count(key)) { data_storage[key] = std::set(); } @@ -458,7 +459,7 @@ struct APState { } void RefreshTracker(bool reset) { - wxLogVerbose("Refreshing display..."); + TrackerLog("Refreshing display..."); RecalculateReachability(); @@ -472,7 +473,7 @@ struct APState { int64_t GetItemId(const std::string& item_name) { int64_t ap_id = apclient->get_item_id(item_name); if (ap_id == APClient::INVALID_NAME_ID) { - wxLogError("Could not find AP item ID for %s", item_name); + TrackerLog(fmt::format("Could not find AP item ID for {}", item_name)); } return ap_id; diff --git a/src/game_data.cpp b/src/game_data.cpp index 85f7f51..77e435a 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp @@ -1,11 +1,6 @@ #include "game_data.h" -#include - -#ifndef WX_PRECOMP -#include -#endif - +#include #include #include @@ -13,6 +8,7 @@ #include #include "global.h" +#include "logger.h" namespace { @@ -36,7 +32,7 @@ LingoColor GetColorForString(const std::string &str) { } else if (str == "purple") { return LingoColor::kPurple; } else { - wxLogError("Invalid color: %s", str); + TrackerLog(fmt::format("Invalid color: {}", str)); return LingoColor::kNone; } @@ -88,7 +84,7 @@ struct GameData { ap_id_by_color_[GetColorForString(input_name)] = ids_config["special_items"][color_name].as(); } else { - wxLogError("Missing AP item ID for color %s", color_name); + TrackerLog(fmt::format("Missing AP item ID for color {}", color_name)); } }; @@ -165,7 +161,8 @@ struct GameData { // This shouldn't happen. std::ostringstream formatted; formatted << entrance_it; - wxLogError("Error reading game data: %s", formatted.str()); + TrackerLog( + fmt::format("Error reading game data: {}", formatted.str())); break; } } @@ -290,8 +287,9 @@ struct GameData { [panels_[panel_id].name] .as(); } else { - wxLogError("Missing AP location ID for panel %s - %s", - rooms_[room_id].name, panels_[panel_id].name); + TrackerLog(fmt::format("Missing AP location ID for panel {} - {}", + rooms_[room_id].name, + panels_[panel_id].name)); } } } @@ -354,8 +352,9 @@ struct GameData { [doors_[door_id].name]["item"] .as(); } else { - wxLogError("Missing AP item ID for door %s - %s", - rooms_[room_id].name, doors_[door_id].name); + TrackerLog(fmt::format("Missing AP item ID for door {} - {}", + rooms_[room_id].name, + doors_[door_id].name)); } } @@ -369,8 +368,8 @@ struct GameData { ids_config["door_groups"][doors_[door_id].group_name] .as(); } else { - wxLogError("Missing AP item ID for door group %s", - doors_[door_id].group_name); + TrackerLog(fmt::format("Missing AP item ID for door group {}", + doors_[door_id].group_name)); } } @@ -380,11 +379,11 @@ struct GameData { } else if (!door_it.second["skip_location"] && !door_it.second["event"]) { if (has_external_panels) { - wxLogError( - "%s - %s has panels from other rooms but does not have an " + TrackerLog(fmt::format( + "{} - {} has panels from other rooms but does not have an " "explicit location name and is not marked skip_location or " "event", - rooms_[room_id].name, doors_[door_id].name); + rooms_[room_id].name, doors_[door_id].name)); } doors_[door_id].location_name = @@ -404,8 +403,9 @@ struct GameData { [doors_[door_id].name]["location"] .as(); } else { - wxLogError("Missing AP location ID for door %s - %s", - rooms_[room_id].name, doors_[door_id].name); + TrackerLog(fmt::format("Missing AP location ID for door {} - {}", + rooms_[room_id].name, + doors_[door_id].name)); } } @@ -473,8 +473,8 @@ struct GameData { progressive_item_id = ids_config["progression"][progressive_item_name].as(); } else { - wxLogError("Missing AP item ID for progressive item %s", - progressive_item_name); + TrackerLog(fmt::format("Missing AP item ID for progressive item {}", + progressive_item_name)); } int index = 1; @@ -553,14 +553,13 @@ struct GameData { int area_id = AddOrGetArea(area_name); MapArea &map_area = map_areas_[area_id]; // room field should be the original room ID - map_area.locations.push_back( - {.name = section_name, - .ap_location_name = location_name, - .ap_location_id = panel.ap_location_id, - .room = panel.room, - .panels = {panel.id}, - .classification = classification, - .hunt = panel.hunt}); + map_area.locations.push_back({.name = section_name, + .ap_location_name = location_name, + .ap_location_id = panel.ap_location_id, + .room = panel.room, + .panels = {panel.id}, + .classification = classification, + .hunt = panel.hunt}); locations_by_name[location_name] = {area_id, map_area.locations.size() - 1}; } @@ -638,7 +637,7 @@ struct GameData { // Report errors. for (const std::string &area : malconfigured_areas_) { - wxLogError("Area data not found for: %s", area); + TrackerLog(fmt::format("Area data not found for: {}", area)); } // Read in subway items. @@ -709,7 +708,7 @@ struct GameData { for (const auto &[tag, items] : subway_tags) { if (items.size() == 1) { - wxLogWarning("Singleton subway item tag: %s", tag); + TrackerLog(fmt::format("Singleton subway item tag: {}", tag)); } } } diff --git a/src/logger.cpp b/src/logger.cpp new file mode 100644 index 0000000..09fc331 --- /dev/null +++ b/src/logger.cpp @@ -0,0 +1,32 @@ +#include "logger.h" + +#include +#include +#include + +#include "global.h" + +namespace { + +class Logger { + public: + Logger() : logfile_(GetAbsolutePath("debug.log")) {} + + void LogLine(const std::string& text) { + std::lock_guard guard(file_mutex_); + logfile_ << "[" << std::chrono::system_clock::now() << "] " << text + << std::endl; + logfile_.flush(); + } + + private: + std::ofstream logfile_; + std::mutex file_mutex_; +}; + +} // namespace + +void TrackerLog(std::string text) { + static Logger* instance = new Logger(); + instance->LogLine(text); +} diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..a27839f --- /dev/null +++ b/src/logger.h @@ -0,0 +1,8 @@ +#ifndef LOGGER_H_9BDD07EA +#define LOGGER_H_9BDD07EA + +#include + +void TrackerLog(std::string message); + +#endif /* end of include guard: LOGGER_H_9BDD07EA */ diff --git a/src/main.cpp b/src/main.cpp index b327b25..1d7cc9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,25 +4,13 @@ #include #endif -#include - #include "global.h" #include "tracker_config.h" #include "tracker_frame.h" -static std::ofstream* logfile; - class TrackerApp : public wxApp { public: virtual bool OnInit() { - logfile = new std::ofstream(GetAbsolutePath("debug.log")); - wxLog::SetActiveTarget(new wxLogStream(logfile)); - wxLog::SetVerbose(true); - -#ifndef NDEBUG - wxLog::SetActiveTarget(new wxLogWindow(nullptr, "Debug Log")); -#endif - GetTrackerConfig().Load(); TrackerFrame *frame = new TrackerFrame(); diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 5c99567..c7b2c8a 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include "ap_state.h" @@ -85,10 +86,8 @@ void SubwayMap::OnConnect() { if (!AP_IsSunwarpShuffle() && subway_item.sunwarp && subway_item.sunwarp->type != SubwaySunwarpType::kFinal) { - std::ostringstream tag; - tag << "sunwarp" << subway_item.sunwarp->dots; - - tagged[tag.str()].push_back(subway_item.id); + std::string tag = fmt::format("subway{}", subway_item.sunwarp->dots); + tagged[tag].push_back(subway_item.id); } if (!AP_IsPilgrimageEnabled() && @@ -100,8 +99,7 @@ void SubwayMap::OnConnect() { if (AP_IsSunwarpShuffle()) { for (const auto &[index, mapping] : AP_GetSunwarpMapping()) { - std::ostringstream tag; - tag << "sunwarp" << mapping.dots; + std::string tag = fmt::format("sunwarp{}", mapping.dots); SubwaySunwarp fromWarp; if (index < 6) { @@ -121,8 +119,8 @@ void SubwayMap::OnConnect() { toWarp.type = SubwaySunwarpType::kExit; } - tagged[tag.str()].push_back(GD_GetSubwayItemForSunwarp(fromWarp)); - tagged[tag.str()].push_back(GD_GetSubwayItemForSunwarp(toWarp)); + tagged[tag].push_back(GD_GetSubwayItemForSunwarp(fromWarp)); + tagged[tag].push_back(GD_GetSubwayItemForSunwarp(toWarp)); } } diff --git a/src/version.h b/src/version.h index 7aab91b..060d557 100644 --- a/src/version.h +++ b/src/version.h @@ -1,9 +1,10 @@ #ifndef VERSION_H_C757E53C #define VERSION_H_C757E53C -#include #include +#include + struct Version { int major = 0; int minor = 0; @@ -24,9 +25,7 @@ struct Version { } std::string ToString() const { - std::ostringstream output; - output << "v" << major << "." << minor << "." << revision; - return output.str(); + return fmt::format("v{}.{}.{}", major, minor, revision); } bool operator<(const Version& rhs) const { diff --git a/vcpkg.json b/vcpkg.json index 925212a..e13d228 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,6 +3,7 @@ "websocketpp", "wxwidgets", "openssl", - "yaml-cpp" + "yaml-cpp", + "fmt" ] } -- cgit 1.4.1