diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-10 19:13:22 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-10 19:13:22 -0400 |
| commit | 33bf1f9653ed608de5554940dc8a0c3f5dc7e4ea (patch) | |
| tree | b1db5d3e83ccd8c5219d5db12b01bc3d152b79d1 | |
| parent | 3b3c3ca4ed98c8d1e884f6c9f8f63d7b7c76e37b (diff) | |
| download | lingo-ap-tracker-33bf1f9653ed608de5554940dc8a0c3f5dc7e4ea.tar.gz lingo-ap-tracker-33bf1f9653ed608de5554940dc8a0c3f5dc7e4ea.tar.bz2 lingo-ap-tracker-33bf1f9653ed608de5554940dc8a0c3f5dc7e4ea.zip | |
Go back to old logging system
Brought in libfmt to handle string formatting and replace a bunch of ostringstream uses.
| -rw-r--r-- | CMakeLists.txt | 5 | ||||
| -rw-r--r-- | src/ap_state.cpp | 79 | ||||
| -rw-r--r-- | src/game_data.cpp | 63 | ||||
| -rw-r--r-- | src/logger.cpp | 32 | ||||
| -rw-r--r-- | src/logger.h | 8 | ||||
| -rw-r--r-- | src/main.cpp | 12 | ||||
| -rw-r--r-- | src/subway_map.cpp | 14 | ||||
| -rw-r--r-- | src/version.h | 7 | ||||
| -rw-r--r-- | vcpkg.json | 3 |
9 files changed, 126 insertions, 97 deletions
| 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) | |||
| 10 | find_package(OpenSSL REQUIRED) | 10 | find_package(OpenSSL REQUIRED) |
| 11 | find_package(yaml-cpp REQUIRED) | 11 | find_package(yaml-cpp REQUIRED) |
| 12 | find_package(websocketpp REQUIRED) | 12 | find_package(websocketpp REQUIRED) |
| 13 | find_package(fmt REQUIRED) | ||
| 13 | 14 | ||
| 14 | include_directories( | 15 | include_directories( |
| 15 | vendor/hkutil | 16 | vendor/hkutil |
| @@ -22,6 +23,7 @@ include_directories( | |||
| 22 | ${yaml-cpp_INCLUDE_DIRS} | 23 | ${yaml-cpp_INCLUDE_DIRS} |
| 23 | ${OpenSSL_INCLUDE_DIRS} | 24 | ${OpenSSL_INCLUDE_DIRS} |
| 24 | vendor/whereami | 25 | vendor/whereami |
| 26 | ${fmt_INCLUDE_DIRS} | ||
| 25 | vendor | 27 | vendor |
| 26 | ) | 28 | ) |
| 27 | 29 | ||
| @@ -45,8 +47,9 @@ add_executable(lingo_ap_tracker | |||
| 45 | "src/global.cpp" | 47 | "src/global.cpp" |
| 46 | "src/subway_map.cpp" | 48 | "src/subway_map.cpp" |
| 47 | "src/network_set.cpp" | 49 | "src/network_set.cpp" |
| 50 | "src/logger.cpp" | ||
| 48 | "vendor/whereami/whereami.c" | 51 | "vendor/whereami/whereami.c" |
| 49 | ) | 52 | ) |
| 50 | set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 20) | 53 | set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 20) |
| 51 | set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) | 54 | set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) |
| 52 | target_link_libraries(lingo_ap_tracker PRIVATE OpenSSL::SSL OpenSSL::Crypto websocketpp::websocketpp wx::core wx::base wx::net yaml-cpp::yaml-cpp) | 55 | 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 @@ | |||
| 4 | #define _WEBSOCKETPP_CPP11_STRICT_ | 4 | #define _WEBSOCKETPP_CPP11_STRICT_ |
| 5 | #pragma comment(lib, "crypt32") | 5 | #pragma comment(lib, "crypt32") |
| 6 | 6 | ||
| 7 | #include <fmt/core.h> | ||
| 7 | #include <hkutil/string.h> | 8 | #include <hkutil/string.h> |
| 8 | 9 | ||
| 9 | #include <any> | 10 | #include <any> |
| @@ -21,6 +22,7 @@ | |||
| 21 | #include <tuple> | 22 | #include <tuple> |
| 22 | 23 | ||
| 23 | #include "game_data.h" | 24 | #include "game_data.h" |
| 25 | #include "logger.h" | ||
| 24 | #include "tracker_frame.h" | 26 | #include "tracker_frame.h" |
| 25 | #include "tracker_state.h" | 27 | #include "tracker_state.h" |
| 26 | 28 | ||
| @@ -75,7 +77,7 @@ struct APState { | |||
| 75 | 77 | ||
| 76 | void Connect(std::string server, std::string player, std::string password) { | 78 | void Connect(std::string server, std::string player, std::string password) { |
| 77 | if (!initialized) { | 79 | if (!initialized) { |
| 78 | wxLogVerbose("Initializing APState..."); | 80 | TrackerLog("Initializing APState..."); |
| 79 | 81 | ||
| 80 | std::thread([this]() { | 82 | std::thread([this]() { |
| 81 | for (;;) { | 83 | for (;;) { |
| @@ -91,14 +93,14 @@ struct APState { | |||
| 91 | }).detach(); | 93 | }).detach(); |
| 92 | 94 | ||
| 93 | for (int panel_id : GD_GetAchievementPanels()) { | 95 | for (int panel_id : GD_GetAchievementPanels()) { |
| 94 | tracked_data_storage_keys.push_back( | 96 | tracked_data_storage_keys.push_back(fmt::format( |
| 95 | "Achievement|" + GD_GetPanel(panel_id).achievement_name); | 97 | "Achievement|{}", GD_GetPanel(panel_id).achievement_name)); |
| 96 | } | 98 | } |
| 97 | 99 | ||
| 98 | for (const MapArea& map_area : GD_GetMapAreas()) { | 100 | for (const MapArea& map_area : GD_GetMapAreas()) { |
| 99 | for (const Location& location : map_area.locations) { | 101 | for (const Location& location : map_area.locations) { |
| 100 | tracked_data_storage_keys.push_back( | 102 | tracked_data_storage_keys.push_back( |
| 101 | "Hunt|" + std::to_string(location.ap_location_id)); | 103 | fmt::format("Hunt|{}", location.ap_location_id)); |
| 102 | } | 104 | } |
| 103 | } | 105 | } |
| 104 | 106 | ||
| @@ -109,10 +111,10 @@ struct APState { | |||
| 109 | } | 111 | } |
| 110 | 112 | ||
| 111 | tracker_frame->SetStatusMessage("Connecting to Archipelago server...."); | 113 | tracker_frame->SetStatusMessage("Connecting to Archipelago server...."); |
| 112 | wxLogStatus("Connecting to Archipelago server (%s)...", server); | 114 | TrackerLog(fmt::format("Connecting to Archipelago server ({})...", server)); |
| 113 | 115 | ||
| 114 | { | 116 | { |
| 115 | wxLogVerbose("Destroying old AP client..."); | 117 | TrackerLog("Destroying old AP client..."); |
| 116 | 118 | ||
| 117 | std::lock_guard client_guard(client_mutex); | 119 | std::lock_guard client_guard(client_mutex); |
| 118 | 120 | ||
| @@ -158,10 +160,10 @@ struct APState { | |||
| 158 | apclient->set_room_info_handler([this, player, password]() { | 160 | apclient->set_room_info_handler([this, player, password]() { |
| 159 | inventory.clear(); | 161 | inventory.clear(); |
| 160 | 162 | ||
| 161 | wxLogStatus("Connected to Archipelago server. Authenticating as %s %s", | 163 | TrackerLog(fmt::format( |
| 162 | player, | 164 | "Connected to Archipelago server. Authenticating as {} {}", player, |
| 163 | (password.empty() ? "without password" | 165 | (password.empty() ? "without password" |
| 164 | : "with password " + password)); | 166 | : "with password " + password))); |
| 165 | tracker_frame->SetStatusMessage( | 167 | tracker_frame->SetStatusMessage( |
| 166 | "Connected to Archipelago server. Authenticating..."); | 168 | "Connected to Archipelago server. Authenticating..."); |
| 167 | 169 | ||
| @@ -173,7 +175,7 @@ struct APState { | |||
| 173 | [this](const std::list<int64_t>& locations) { | 175 | [this](const std::list<int64_t>& locations) { |
| 174 | for (const int64_t location_id : locations) { | 176 | for (const int64_t location_id : locations) { |
| 175 | checked_locations.insert(location_id); | 177 | checked_locations.insert(location_id); |
| 176 | wxLogVerbose("Location: %lld", location_id); | 178 | TrackerLog(fmt::format("Location: {}", location_id)); |
| 177 | } | 179 | } |
| 178 | 180 | ||
| 179 | RefreshTracker(false); | 181 | RefreshTracker(false); |
| @@ -182,14 +184,14 @@ struct APState { | |||
| 182 | apclient->set_slot_disconnected_handler([this]() { | 184 | apclient->set_slot_disconnected_handler([this]() { |
| 183 | tracker_frame->SetStatusMessage( | 185 | tracker_frame->SetStatusMessage( |
| 184 | "Disconnected from Archipelago. Attempting to reconnect..."); | 186 | "Disconnected from Archipelago. Attempting to reconnect..."); |
| 185 | wxLogStatus( | 187 | TrackerLog( |
| 186 | "Slot disconnected from Archipelago. Attempting to reconnect..."); | 188 | "Slot disconnected from Archipelago. Attempting to reconnect..."); |
| 187 | }); | 189 | }); |
| 188 | 190 | ||
| 189 | apclient->set_socket_disconnected_handler([this]() { | 191 | apclient->set_socket_disconnected_handler([this]() { |
| 190 | tracker_frame->SetStatusMessage( | 192 | tracker_frame->SetStatusMessage( |
| 191 | "Disconnected from Archipelago. Attempting to reconnect..."); | 193 | "Disconnected from Archipelago. Attempting to reconnect..."); |
| 192 | wxLogStatus( | 194 | TrackerLog( |
| 193 | "Socket disconnected from Archipelago. Attempting to reconnect..."); | 195 | "Socket disconnected from Archipelago. Attempting to reconnect..."); |
| 194 | }); | 196 | }); |
| 195 | 197 | ||
| @@ -197,7 +199,7 @@ struct APState { | |||
| 197 | [this](const std::list<APClient::NetworkItem>& items) { | 199 | [this](const std::list<APClient::NetworkItem>& items) { |
| 198 | for (const APClient::NetworkItem& item : items) { | 200 | for (const APClient::NetworkItem& item : items) { |
| 199 | inventory[item.item]++; | 201 | inventory[item.item]++; |
| 200 | wxLogVerbose("Item: %lld", item.item); | 202 | TrackerLog(fmt::format("Item: {}", item.item)); |
| 201 | } | 203 | } |
| 202 | 204 | ||
| 203 | RefreshTracker(false); | 205 | RefreshTracker(false); |
| @@ -222,10 +224,10 @@ struct APState { | |||
| 222 | apclient->set_slot_connected_handler([this, &connection_mutex]( | 224 | apclient->set_slot_connected_handler([this, &connection_mutex]( |
| 223 | const nlohmann::json& slot_data) { | 225 | const nlohmann::json& slot_data) { |
| 224 | tracker_frame->SetStatusMessage("Connected to Archipelago!"); | 226 | tracker_frame->SetStatusMessage("Connected to Archipelago!"); |
| 225 | wxLogStatus("Connected to Archipelago!"); | 227 | TrackerLog("Connected to Archipelago!"); |
| 226 | 228 | ||
| 227 | data_storage_prefix = | 229 | data_storage_prefix = |
| 228 | "Lingo_" + std::to_string(apclient->get_player_number()) + "_"; | 230 | fmt::format("Lingo_{}_", apclient->get_player_number()); |
| 229 | door_shuffle_mode = slot_data["shuffle_doors"].get<DoorShuffleMode>(); | 231 | door_shuffle_mode = slot_data["shuffle_doors"].get<DoorShuffleMode>(); |
| 230 | color_shuffle = slot_data["shuffle_colors"].get<int>() == 1; | 232 | color_shuffle = slot_data["shuffle_colors"].get<int>() == 1; |
| 231 | painting_shuffle = slot_data["shuffle_paintings"].get<int>() == 1; | 233 | painting_shuffle = slot_data["shuffle_paintings"].get<int>() == 1; |
| @@ -277,18 +279,18 @@ struct APState { | |||
| 277 | corrected_keys.push_back(data_storage_prefix + key); | 279 | corrected_keys.push_back(data_storage_prefix + key); |
| 278 | } | 280 | } |
| 279 | 281 | ||
| 280 | { | 282 | victory_data_storage_key = |
| 281 | std::ostringstream vdsks; | 283 | fmt::format("_read_client_status_{}_{}", apclient->get_team_number(), |
| 282 | vdsks << "_read_client_status_" << apclient->get_team_number() << "_" | 284 | apclient->get_player_number()); |
| 283 | << apclient->get_player_number(); | ||
| 284 | victory_data_storage_key = vdsks.str(); | ||
| 285 | } | ||
| 286 | 285 | ||
| 287 | corrected_keys.push_back(victory_data_storage_key); | 286 | corrected_keys.push_back(victory_data_storage_key); |
| 288 | 287 | ||
| 289 | apclient->Get(corrected_keys); | 288 | apclient->Get(corrected_keys); |
| 290 | apclient->SetNotify(corrected_keys); | 289 | apclient->SetNotify(corrected_keys); |
| 291 | 290 | ||
| 291 | ResetReachabilityRequirements(); | ||
| 292 | RefreshTracker(true); | ||
| 293 | |||
| 292 | { | 294 | { |
| 293 | std::lock_guard connection_lock(connection_mutex); | 295 | std::lock_guard connection_lock(connection_mutex); |
| 294 | if (!has_connection_result) { | 296 | if (!has_connection_result) { |
| @@ -333,7 +335,7 @@ struct APState { | |||
| 333 | } | 335 | } |
| 334 | 336 | ||
| 335 | std::string full_message = hatkirby::implode(error_messages, " "); | 337 | std::string full_message = hatkirby::implode(error_messages, " "); |
| 336 | wxLogError(wxString(full_message)); | 338 | TrackerLog(full_message); |
| 337 | 339 | ||
| 338 | wxMessageBox(full_message, "Connection failed", wxOK | wxICON_ERROR); | 340 | wxMessageBox(full_message, "Connection failed", wxOK | wxICON_ERROR); |
| 339 | }); | 341 | }); |
| @@ -355,7 +357,7 @@ struct APState { | |||
| 355 | DestroyClient(); | 357 | DestroyClient(); |
| 356 | 358 | ||
| 357 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); | 359 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); |
| 358 | wxLogStatus("Timeout while connecting to Archipelago server."); | 360 | TrackerLog("Timeout while connecting to Archipelago server."); |
| 359 | wxMessageBox("Timeout while connecting to Archipelago server.", | 361 | wxMessageBox("Timeout while connecting to Archipelago server.", |
| 360 | "Connection failed", wxOK | wxICON_ERROR); | 362 | "Connection failed", wxOK | wxICON_ERROR); |
| 361 | 363 | ||
| @@ -374,9 +376,6 @@ struct APState { | |||
| 374 | } | 376 | } |
| 375 | 377 | ||
| 376 | if (connected) { | 378 | if (connected) { |
| 377 | ResetReachabilityRequirements(); | ||
| 378 | RefreshTracker(true); | ||
| 379 | } else { | ||
| 380 | client_active = false; | 379 | client_active = false; |
| 381 | } | 380 | } |
| 382 | } | 381 | } |
| @@ -384,11 +383,12 @@ struct APState { | |||
| 384 | void HandleDataStorage(const std::string& key, const nlohmann::json& value) { | 383 | void HandleDataStorage(const std::string& key, const nlohmann::json& value) { |
| 385 | if (value.is_boolean()) { | 384 | if (value.is_boolean()) { |
| 386 | data_storage[key] = value.get<bool>(); | 385 | data_storage[key] = value.get<bool>(); |
| 387 | wxLogVerbose("Data storage %s retrieved as %s", key, | 386 | TrackerLog(fmt::format("Data storage {} retrieved as {}", key, |
| 388 | (value.get<bool>() ? "true" : "false")); | 387 | (value.get<bool>() ? "true" : "false"))); |
| 389 | } else if (value.is_number()) { | 388 | } else if (value.is_number()) { |
| 390 | data_storage[key] = value.get<int>(); | 389 | data_storage[key] = value.get<int>(); |
| 391 | wxLogVerbose("Data storage %s retrieved as %d", key, value.get<int>()); | 390 | TrackerLog(fmt::format("Data storage {} retrieved as {}", key, |
| 391 | value.get<int>())); | ||
| 392 | } else if (value.is_object()) { | 392 | } else if (value.is_object()) { |
| 393 | if (key.ends_with("PlayerPos")) { | 393 | if (key.ends_with("PlayerPos")) { |
| 394 | auto map_value = value.get<std::map<std::string, int>>(); | 394 | auto map_value = value.get<std::map<std::string, int>>(); |
| @@ -397,7 +397,7 @@ struct APState { | |||
| 397 | data_storage[key] = value.get<std::map<std::string, int>>(); | 397 | data_storage[key] = value.get<std::map<std::string, int>>(); |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | wxLogVerbose("Data storage %s retrieved as dictionary", key); | 400 | TrackerLog(fmt::format("Data storage {} retrieved as dictionary", key)); |
| 401 | } else if (value.is_null()) { | 401 | } else if (value.is_null()) { |
| 402 | if (key.ends_with("PlayerPos")) { | 402 | if (key.ends_with("PlayerPos")) { |
| 403 | player_pos = std::nullopt; | 403 | player_pos = std::nullopt; |
| @@ -405,7 +405,7 @@ struct APState { | |||
| 405 | data_storage.erase(key); | 405 | data_storage.erase(key); |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | wxLogVerbose("Data storage %s retrieved as null", key); | 408 | TrackerLog(fmt::format("Data storage {} retrieved as null", key)); |
| 409 | } else if (value.is_array()) { | 409 | } else if (value.is_array()) { |
| 410 | auto list_value = value.get<std::vector<std::string>>(); | 410 | auto list_value = value.get<std::vector<std::string>>(); |
| 411 | 411 | ||
| @@ -416,8 +416,8 @@ struct APState { | |||
| 416 | data_storage[key] = list_value; | 416 | data_storage[key] = list_value; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | wxLogVerbose("Data storage %s retrieved as list: [%s]", key, | 419 | TrackerLog(fmt::format("Data storage {} retrieved as list: [{}]", key, |
| 420 | hatkirby::implode(list_value, ", ")); | 420 | hatkirby::implode(list_value, ", "))); |
| 421 | } | 421 | } |
| 422 | } | 422 | } |
| 423 | 423 | ||
| @@ -427,7 +427,7 @@ struct APState { | |||
| 427 | 427 | ||
| 428 | bool HasCheckedHuntPanel(int location_id) { | 428 | bool HasCheckedHuntPanel(int location_id) { |
| 429 | std::string key = | 429 | std::string key = |
| 430 | data_storage_prefix + "Hunt|" + std::to_string(location_id); | 430 | fmt::format("{}Hunt|{}", data_storage_prefix, location_id); |
| 431 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); | 431 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); |
| 432 | } | 432 | } |
| 433 | 433 | ||
| @@ -436,12 +436,13 @@ struct APState { | |||
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | bool HasAchievement(const std::string& name) { | 438 | bool HasAchievement(const std::string& name) { |
| 439 | std::string key = data_storage_prefix + "Achievement|" + name; | 439 | std::string key = |
| 440 | fmt::format("{}Achievement|{}", data_storage_prefix, name); | ||
| 440 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); | 441 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); |
| 441 | } | 442 | } |
| 442 | 443 | ||
| 443 | const std::set<std::string>& GetCheckedPaintings() { | 444 | const std::set<std::string>& GetCheckedPaintings() { |
| 444 | std::string key = data_storage_prefix + "Paintings"; | 445 | std::string key = fmt::format("{}Paintings", data_storage_prefix); |
| 445 | if (!data_storage.count(key)) { | 446 | if (!data_storage.count(key)) { |
| 446 | data_storage[key] = std::set<std::string>(); | 447 | data_storage[key] = std::set<std::string>(); |
| 447 | } | 448 | } |
| @@ -458,7 +459,7 @@ struct APState { | |||
| 458 | } | 459 | } |
| 459 | 460 | ||
| 460 | void RefreshTracker(bool reset) { | 461 | void RefreshTracker(bool reset) { |
| 461 | wxLogVerbose("Refreshing display..."); | 462 | TrackerLog("Refreshing display..."); |
| 462 | 463 | ||
| 463 | RecalculateReachability(); | 464 | RecalculateReachability(); |
| 464 | 465 | ||
| @@ -472,7 +473,7 @@ struct APState { | |||
| 472 | int64_t GetItemId(const std::string& item_name) { | 473 | int64_t GetItemId(const std::string& item_name) { |
| 473 | int64_t ap_id = apclient->get_item_id(item_name); | 474 | int64_t ap_id = apclient->get_item_id(item_name); |
| 474 | if (ap_id == APClient::INVALID_NAME_ID) { | 475 | if (ap_id == APClient::INVALID_NAME_ID) { |
| 475 | wxLogError("Could not find AP item ID for %s", item_name); | 476 | TrackerLog(fmt::format("Could not find AP item ID for {}", item_name)); |
| 476 | } | 477 | } |
| 477 | 478 | ||
| 478 | return ap_id; | 479 | 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 @@ | |||
| 1 | #include "game_data.h" | 1 | #include "game_data.h" |
| 2 | 2 | ||
| 3 | #include <wx/wxprec.h> | 3 | #include <fmt/core.h> |
| 4 | |||
| 5 | #ifndef WX_PRECOMP | ||
| 6 | #include <wx/wx.h> | ||
| 7 | #endif | ||
| 8 | |||
| 9 | #include <hkutil/string.h> | 4 | #include <hkutil/string.h> |
| 10 | #include <yaml-cpp/yaml.h> | 5 | #include <yaml-cpp/yaml.h> |
| 11 | 6 | ||
| @@ -13,6 +8,7 @@ | |||
| 13 | #include <sstream> | 8 | #include <sstream> |
| 14 | 9 | ||
| 15 | #include "global.h" | 10 | #include "global.h" |
| 11 | #include "logger.h" | ||
| 16 | 12 | ||
| 17 | namespace { | 13 | namespace { |
| 18 | 14 | ||
| @@ -36,7 +32,7 @@ LingoColor GetColorForString(const std::string &str) { | |||
| 36 | } else if (str == "purple") { | 32 | } else if (str == "purple") { |
| 37 | return LingoColor::kPurple; | 33 | return LingoColor::kPurple; |
| 38 | } else { | 34 | } else { |
| 39 | wxLogError("Invalid color: %s", str); | 35 | TrackerLog(fmt::format("Invalid color: {}", str)); |
| 40 | 36 | ||
| 41 | return LingoColor::kNone; | 37 | return LingoColor::kNone; |
| 42 | } | 38 | } |
| @@ -88,7 +84,7 @@ struct GameData { | |||
| 88 | ap_id_by_color_[GetColorForString(input_name)] = | 84 | ap_id_by_color_[GetColorForString(input_name)] = |
| 89 | ids_config["special_items"][color_name].as<int>(); | 85 | ids_config["special_items"][color_name].as<int>(); |
| 90 | } else { | 86 | } else { |
| 91 | wxLogError("Missing AP item ID for color %s", color_name); | 87 | TrackerLog(fmt::format("Missing AP item ID for color {}", color_name)); |
| 92 | } | 88 | } |
| 93 | }; | 89 | }; |
| 94 | 90 | ||
| @@ -165,7 +161,8 @@ struct GameData { | |||
| 165 | // This shouldn't happen. | 161 | // This shouldn't happen. |
| 166 | std::ostringstream formatted; | 162 | std::ostringstream formatted; |
| 167 | formatted << entrance_it; | 163 | formatted << entrance_it; |
| 168 | wxLogError("Error reading game data: %s", formatted.str()); | 164 | TrackerLog( |
| 165 | fmt::format("Error reading game data: {}", formatted.str())); | ||
| 169 | break; | 166 | break; |
| 170 | } | 167 | } |
| 171 | } | 168 | } |
| @@ -290,8 +287,9 @@ struct GameData { | |||
| 290 | [panels_[panel_id].name] | 287 | [panels_[panel_id].name] |
| 291 | .as<int>(); | 288 | .as<int>(); |
| 292 | } else { | 289 | } else { |
| 293 | wxLogError("Missing AP location ID for panel %s - %s", | 290 | TrackerLog(fmt::format("Missing AP location ID for panel {} - {}", |
| 294 | rooms_[room_id].name, panels_[panel_id].name); | 291 | rooms_[room_id].name, |
| 292 | panels_[panel_id].name)); | ||
| 295 | } | 293 | } |
| 296 | } | 294 | } |
| 297 | } | 295 | } |
| @@ -354,8 +352,9 @@ struct GameData { | |||
| 354 | [doors_[door_id].name]["item"] | 352 | [doors_[door_id].name]["item"] |
| 355 | .as<int>(); | 353 | .as<int>(); |
| 356 | } else { | 354 | } else { |
| 357 | wxLogError("Missing AP item ID for door %s - %s", | 355 | TrackerLog(fmt::format("Missing AP item ID for door {} - {}", |
| 358 | rooms_[room_id].name, doors_[door_id].name); | 356 | rooms_[room_id].name, |
| 357 | doors_[door_id].name)); | ||
| 359 | } | 358 | } |
| 360 | } | 359 | } |
| 361 | 360 | ||
| @@ -369,8 +368,8 @@ struct GameData { | |||
| 369 | ids_config["door_groups"][doors_[door_id].group_name] | 368 | ids_config["door_groups"][doors_[door_id].group_name] |
| 370 | .as<int>(); | 369 | .as<int>(); |
| 371 | } else { | 370 | } else { |
| 372 | wxLogError("Missing AP item ID for door group %s", | 371 | TrackerLog(fmt::format("Missing AP item ID for door group {}", |
| 373 | doors_[door_id].group_name); | 372 | doors_[door_id].group_name)); |
| 374 | } | 373 | } |
| 375 | } | 374 | } |
| 376 | 375 | ||
| @@ -380,11 +379,11 @@ struct GameData { | |||
| 380 | } else if (!door_it.second["skip_location"] && | 379 | } else if (!door_it.second["skip_location"] && |
| 381 | !door_it.second["event"]) { | 380 | !door_it.second["event"]) { |
| 382 | if (has_external_panels) { | 381 | if (has_external_panels) { |
| 383 | wxLogError( | 382 | TrackerLog(fmt::format( |
| 384 | "%s - %s has panels from other rooms but does not have an " | 383 | "{} - {} has panels from other rooms but does not have an " |
| 385 | "explicit location name and is not marked skip_location or " | 384 | "explicit location name and is not marked skip_location or " |
| 386 | "event", | 385 | "event", |
| 387 | rooms_[room_id].name, doors_[door_id].name); | 386 | rooms_[room_id].name, doors_[door_id].name)); |
| 388 | } | 387 | } |
| 389 | 388 | ||
| 390 | doors_[door_id].location_name = | 389 | doors_[door_id].location_name = |
| @@ -404,8 +403,9 @@ struct GameData { | |||
| 404 | [doors_[door_id].name]["location"] | 403 | [doors_[door_id].name]["location"] |
| 405 | .as<int>(); | 404 | .as<int>(); |
| 406 | } else { | 405 | } else { |
| 407 | wxLogError("Missing AP location ID for door %s - %s", | 406 | TrackerLog(fmt::format("Missing AP location ID for door {} - {}", |
| 408 | rooms_[room_id].name, doors_[door_id].name); | 407 | rooms_[room_id].name, |
| 408 | doors_[door_id].name)); | ||
| 409 | } | 409 | } |
| 410 | } | 410 | } |
| 411 | 411 | ||
| @@ -473,8 +473,8 @@ struct GameData { | |||
| 473 | progressive_item_id = | 473 | progressive_item_id = |
| 474 | ids_config["progression"][progressive_item_name].as<int>(); | 474 | ids_config["progression"][progressive_item_name].as<int>(); |
| 475 | } else { | 475 | } else { |
| 476 | wxLogError("Missing AP item ID for progressive item %s", | 476 | TrackerLog(fmt::format("Missing AP item ID for progressive item {}", |
| 477 | progressive_item_name); | 477 | progressive_item_name)); |
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | int index = 1; | 480 | int index = 1; |
| @@ -553,14 +553,13 @@ struct GameData { | |||
| 553 | int area_id = AddOrGetArea(area_name); | 553 | int area_id = AddOrGetArea(area_name); |
| 554 | MapArea &map_area = map_areas_[area_id]; | 554 | MapArea &map_area = map_areas_[area_id]; |
| 555 | // room field should be the original room ID | 555 | // room field should be the original room ID |
| 556 | map_area.locations.push_back( | 556 | map_area.locations.push_back({.name = section_name, |
| 557 | {.name = section_name, | 557 | .ap_location_name = location_name, |
| 558 | .ap_location_name = location_name, | 558 | .ap_location_id = panel.ap_location_id, |
| 559 | .ap_location_id = panel.ap_location_id, | 559 | .room = panel.room, |
| 560 | .room = panel.room, | 560 | .panels = {panel.id}, |
| 561 | .panels = {panel.id}, | 561 | .classification = classification, |
| 562 | .classification = classification, | 562 | .hunt = panel.hunt}); |
| 563 | .hunt = panel.hunt}); | ||
| 564 | locations_by_name[location_name] = {area_id, | 563 | locations_by_name[location_name] = {area_id, |
| 565 | map_area.locations.size() - 1}; | 564 | map_area.locations.size() - 1}; |
| 566 | } | 565 | } |
| @@ -638,7 +637,7 @@ struct GameData { | |||
| 638 | 637 | ||
| 639 | // Report errors. | 638 | // Report errors. |
| 640 | for (const std::string &area : malconfigured_areas_) { | 639 | for (const std::string &area : malconfigured_areas_) { |
| 641 | wxLogError("Area data not found for: %s", area); | 640 | TrackerLog(fmt::format("Area data not found for: {}", area)); |
| 642 | } | 641 | } |
| 643 | 642 | ||
| 644 | // Read in subway items. | 643 | // Read in subway items. |
| @@ -709,7 +708,7 @@ struct GameData { | |||
| 709 | 708 | ||
| 710 | for (const auto &[tag, items] : subway_tags) { | 709 | for (const auto &[tag, items] : subway_tags) { |
| 711 | if (items.size() == 1) { | 710 | if (items.size() == 1) { |
| 712 | wxLogWarning("Singleton subway item tag: %s", tag); | 711 | TrackerLog(fmt::format("Singleton subway item tag: {}", tag)); |
| 713 | } | 712 | } |
| 714 | } | 713 | } |
| 715 | } | 714 | } |
| 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 @@ | |||
| 1 | #include "logger.h" | ||
| 2 | |||
| 3 | #include <chrono> | ||
| 4 | #include <fstream> | ||
| 5 | #include <mutex> | ||
| 6 | |||
| 7 | #include "global.h" | ||
| 8 | |||
| 9 | namespace { | ||
| 10 | |||
| 11 | class Logger { | ||
| 12 | public: | ||
| 13 | Logger() : logfile_(GetAbsolutePath("debug.log")) {} | ||
| 14 | |||
| 15 | void LogLine(const std::string& text) { | ||
| 16 | std::lock_guard guard(file_mutex_); | ||
| 17 | logfile_ << "[" << std::chrono::system_clock::now() << "] " << text | ||
| 18 | << std::endl; | ||
| 19 | logfile_.flush(); | ||
| 20 | } | ||
| 21 | |||
| 22 | private: | ||
| 23 | std::ofstream logfile_; | ||
| 24 | std::mutex file_mutex_; | ||
| 25 | }; | ||
| 26 | |||
| 27 | } // namespace | ||
| 28 | |||
| 29 | void TrackerLog(std::string text) { | ||
| 30 | static Logger* instance = new Logger(); | ||
| 31 | instance->LogLine(text); | ||
| 32 | } | ||
| 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 @@ | |||
| 1 | #ifndef LOGGER_H_9BDD07EA | ||
| 2 | #define LOGGER_H_9BDD07EA | ||
| 3 | |||
| 4 | #include <string> | ||
| 5 | |||
| 6 | void TrackerLog(std::string message); | ||
| 7 | |||
| 8 | #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 @@ | |||
| 4 | #include <wx/wx.h> | 4 | #include <wx/wx.h> |
| 5 | #endif | 5 | #endif |
| 6 | 6 | ||
| 7 | #include <fstream> | ||
| 8 | |||
| 9 | #include "global.h" | 7 | #include "global.h" |
| 10 | #include "tracker_config.h" | 8 | #include "tracker_config.h" |
| 11 | #include "tracker_frame.h" | 9 | #include "tracker_frame.h" |
| 12 | 10 | ||
| 13 | static std::ofstream* logfile; | ||
| 14 | |||
| 15 | class TrackerApp : public wxApp { | 11 | class TrackerApp : public wxApp { |
| 16 | public: | 12 | public: |
| 17 | virtual bool OnInit() { | 13 | virtual bool OnInit() { |
| 18 | logfile = new std::ofstream(GetAbsolutePath("debug.log")); | ||
| 19 | wxLog::SetActiveTarget(new wxLogStream(logfile)); | ||
| 20 | wxLog::SetVerbose(true); | ||
| 21 | |||
| 22 | #ifndef NDEBUG | ||
| 23 | wxLog::SetActiveTarget(new wxLogWindow(nullptr, "Debug Log")); | ||
| 24 | #endif | ||
| 25 | |||
| 26 | GetTrackerConfig().Load(); | 14 | GetTrackerConfig().Load(); |
| 27 | 15 | ||
| 28 | TrackerFrame *frame = new TrackerFrame(); | 16 | 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 @@ | |||
| 3 | #include <wx/dcbuffer.h> | 3 | #include <wx/dcbuffer.h> |
| 4 | #include <wx/dcgraph.h> | 4 | #include <wx/dcgraph.h> |
| 5 | 5 | ||
| 6 | #include <fmt/core.h> | ||
| 6 | #include <sstream> | 7 | #include <sstream> |
| 7 | 8 | ||
| 8 | #include "ap_state.h" | 9 | #include "ap_state.h" |
| @@ -85,10 +86,8 @@ void SubwayMap::OnConnect() { | |||
| 85 | 86 | ||
| 86 | if (!AP_IsSunwarpShuffle() && subway_item.sunwarp && | 87 | if (!AP_IsSunwarpShuffle() && subway_item.sunwarp && |
| 87 | subway_item.sunwarp->type != SubwaySunwarpType::kFinal) { | 88 | subway_item.sunwarp->type != SubwaySunwarpType::kFinal) { |
| 88 | std::ostringstream tag; | 89 | std::string tag = fmt::format("subway{}", subway_item.sunwarp->dots); |
| 89 | tag << "sunwarp" << subway_item.sunwarp->dots; | 90 | tagged[tag].push_back(subway_item.id); |
| 90 | |||
| 91 | tagged[tag.str()].push_back(subway_item.id); | ||
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | if (!AP_IsPilgrimageEnabled() && | 93 | if (!AP_IsPilgrimageEnabled() && |
| @@ -100,8 +99,7 @@ void SubwayMap::OnConnect() { | |||
| 100 | 99 | ||
| 101 | if (AP_IsSunwarpShuffle()) { | 100 | if (AP_IsSunwarpShuffle()) { |
| 102 | for (const auto &[index, mapping] : AP_GetSunwarpMapping()) { | 101 | for (const auto &[index, mapping] : AP_GetSunwarpMapping()) { |
| 103 | std::ostringstream tag; | 102 | std::string tag = fmt::format("sunwarp{}", mapping.dots); |
| 104 | tag << "sunwarp" << mapping.dots; | ||
| 105 | 103 | ||
| 106 | SubwaySunwarp fromWarp; | 104 | SubwaySunwarp fromWarp; |
| 107 | if (index < 6) { | 105 | if (index < 6) { |
| @@ -121,8 +119,8 @@ void SubwayMap::OnConnect() { | |||
| 121 | toWarp.type = SubwaySunwarpType::kExit; | 119 | toWarp.type = SubwaySunwarpType::kExit; |
| 122 | } | 120 | } |
| 123 | 121 | ||
| 124 | tagged[tag.str()].push_back(GD_GetSubwayItemForSunwarp(fromWarp)); | 122 | tagged[tag].push_back(GD_GetSubwayItemForSunwarp(fromWarp)); |
| 125 | tagged[tag.str()].push_back(GD_GetSubwayItemForSunwarp(toWarp)); | 123 | tagged[tag].push_back(GD_GetSubwayItemForSunwarp(toWarp)); |
| 126 | } | 124 | } |
| 127 | } | 125 | } |
| 128 | 126 | ||
| 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 @@ | |||
| 1 | #ifndef VERSION_H_C757E53C | 1 | #ifndef VERSION_H_C757E53C |
| 2 | #define VERSION_H_C757E53C | 2 | #define VERSION_H_C757E53C |
| 3 | 3 | ||
| 4 | #include <sstream> | ||
| 5 | #include <regex> | 4 | #include <regex> |
| 6 | 5 | ||
| 6 | #include <fmt/core.h> | ||
| 7 | |||
| 7 | struct Version { | 8 | struct Version { |
| 8 | int major = 0; | 9 | int major = 0; |
| 9 | int minor = 0; | 10 | int minor = 0; |
| @@ -24,9 +25,7 @@ struct Version { | |||
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | std::string ToString() const { | 27 | std::string ToString() const { |
| 27 | std::ostringstream output; | 28 | return fmt::format("v{}.{}.{}", major, minor, revision); |
| 28 | output << "v" << major << "." << minor << "." << revision; | ||
| 29 | return output.str(); | ||
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | bool operator<(const Version& rhs) const { | 31 | 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 @@ | |||
| 3 | "websocketpp", | 3 | "websocketpp", |
| 4 | "wxwidgets", | 4 | "wxwidgets", |
| 5 | "openssl", | 5 | "openssl", |
| 6 | "yaml-cpp" | 6 | "yaml-cpp", |
| 7 | "fmt" | ||
| 7 | ] | 8 | ] |
| 8 | } | 9 | } |
