diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-07-16 15:17:21 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-07-16 15:17:21 -0400 |
| commit | 558fcd9bf0852b5c909822c374f7e445b63026e5 (patch) | |
| tree | f78d74f389c63f83da1878c9982de9a8e3343df0 /src/ap_state.cpp | |
| parent | 2944687cbbaa53d0815fea9f5f2506500e2e1db3 (diff) | |
| parent | a40d5a90a4759ecb03fe4591878c011d3c8c07be (diff) | |
| download | lingo-ap-tracker-558fcd9bf0852b5c909822c374f7e445b63026e5.tar.gz lingo-ap-tracker-558fcd9bf0852b5c909822c374f7e445b63026e5.tar.bz2 lingo-ap-tracker-558fcd9bf0852b5c909822c374f7e445b63026e5.zip | |
Merge branch 'main' into panels
Diffstat (limited to 'src/ap_state.cpp')
| -rw-r--r-- | src/ap_state.cpp | 102 |
1 files changed, 58 insertions, 44 deletions
| diff --git a/src/ap_state.cpp b/src/ap_state.cpp index a7565cf..d501e81 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 | ||
| @@ -76,7 +78,7 @@ struct APState { | |||
| 76 | 78 | ||
| 77 | void Connect(std::string server, std::string player, std::string password) { | 79 | void Connect(std::string server, std::string player, std::string password) { |
| 78 | if (!initialized) { | 80 | if (!initialized) { |
| 79 | wxLogVerbose("Initializing APState..."); | 81 | TrackerLog("Initializing APState..."); |
| 80 | 82 | ||
| 81 | std::thread([this]() { | 83 | std::thread([this]() { |
| 82 | for (;;) { | 84 | for (;;) { |
| @@ -92,14 +94,14 @@ struct APState { | |||
| 92 | }).detach(); | 94 | }).detach(); |
| 93 | 95 | ||
| 94 | for (int panel_id : GD_GetAchievementPanels()) { | 96 | for (int panel_id : GD_GetAchievementPanels()) { |
| 95 | tracked_data_storage_keys.push_back( | 97 | tracked_data_storage_keys.push_back(fmt::format( |
| 96 | "Achievement|" + GD_GetPanel(panel_id).achievement_name); | 98 | "Achievement|{}", GD_GetPanel(panel_id).achievement_name)); |
| 97 | } | 99 | } |
| 98 | 100 | ||
| 99 | for (const MapArea& map_area : GD_GetMapAreas()) { | 101 | for (const MapArea& map_area : GD_GetMapAreas()) { |
| 100 | for (const Location& location : map_area.locations) { | 102 | for (const Location& location : map_area.locations) { |
| 101 | tracked_data_storage_keys.push_back( | 103 | tracked_data_storage_keys.push_back( |
| 102 | "Hunt|" + std::to_string(location.ap_location_id)); | 104 | fmt::format("Hunt|{}", location.ap_location_id)); |
| 103 | } | 105 | } |
| 104 | } | 106 | } |
| 105 | 107 | ||
| @@ -110,10 +112,10 @@ struct APState { | |||
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | tracker_frame->SetStatusMessage("Connecting to Archipelago server...."); | 114 | tracker_frame->SetStatusMessage("Connecting to Archipelago server...."); |
| 113 | wxLogStatus("Connecting to Archipelago server (%s)...", server); | 115 | TrackerLog(fmt::format("Connecting to Archipelago server ({})...", server)); |
| 114 | 116 | ||
| 115 | { | 117 | { |
| 116 | wxLogVerbose("Destroying old AP client..."); | 118 | TrackerLog("Destroying old AP client..."); |
| 117 | 119 | ||
| 118 | std::lock_guard client_guard(client_mutex); | 120 | std::lock_guard client_guard(client_mutex); |
| 119 | 121 | ||
| @@ -160,10 +162,10 @@ struct APState { | |||
| 160 | apclient->set_room_info_handler([this, player, password]() { | 162 | apclient->set_room_info_handler([this, player, password]() { |
| 161 | inventory.clear(); | 163 | inventory.clear(); |
| 162 | 164 | ||
| 163 | wxLogStatus("Connected to Archipelago server. Authenticating as %s %s", | 165 | TrackerLog(fmt::format( |
| 164 | player, | 166 | "Connected to Archipelago server. Authenticating as {} {}", player, |
| 165 | (password.empty() ? "without password" | 167 | (password.empty() ? "without password" |
| 166 | : "with password " + password)); | 168 | : "with password " + password))); |
| 167 | tracker_frame->SetStatusMessage( | 169 | tracker_frame->SetStatusMessage( |
| 168 | "Connected to Archipelago server. Authenticating..."); | 170 | "Connected to Archipelago server. Authenticating..."); |
| 169 | 171 | ||
| @@ -175,7 +177,7 @@ struct APState { | |||
| 175 | [this](const std::list<int64_t>& locations) { | 177 | [this](const std::list<int64_t>& locations) { |
| 176 | for (const int64_t location_id : locations) { | 178 | for (const int64_t location_id : locations) { |
| 177 | checked_locations.insert(location_id); | 179 | checked_locations.insert(location_id); |
| 178 | wxLogVerbose("Location: %lld", location_id); | 180 | TrackerLog(fmt::format("Location: {}", location_id)); |
| 179 | } | 181 | } |
| 180 | 182 | ||
| 181 | RefreshTracker(false); | 183 | RefreshTracker(false); |
| @@ -184,14 +186,14 @@ struct APState { | |||
| 184 | apclient->set_slot_disconnected_handler([this]() { | 186 | apclient->set_slot_disconnected_handler([this]() { |
| 185 | tracker_frame->SetStatusMessage( | 187 | tracker_frame->SetStatusMessage( |
| 186 | "Disconnected from Archipelago. Attempting to reconnect..."); | 188 | "Disconnected from Archipelago. Attempting to reconnect..."); |
| 187 | wxLogStatus( | 189 | TrackerLog( |
| 188 | "Slot disconnected from Archipelago. Attempting to reconnect..."); | 190 | "Slot disconnected from Archipelago. Attempting to reconnect..."); |
| 189 | }); | 191 | }); |
| 190 | 192 | ||
| 191 | apclient->set_socket_disconnected_handler([this]() { | 193 | apclient->set_socket_disconnected_handler([this]() { |
| 192 | tracker_frame->SetStatusMessage( | 194 | tracker_frame->SetStatusMessage( |
| 193 | "Disconnected from Archipelago. Attempting to reconnect..."); | 195 | "Disconnected from Archipelago. Attempting to reconnect..."); |
| 194 | wxLogStatus( | 196 | TrackerLog( |
| 195 | "Socket disconnected from Archipelago. Attempting to reconnect..."); | 197 | "Socket disconnected from Archipelago. Attempting to reconnect..."); |
| 196 | }); | 198 | }); |
| 197 | 199 | ||
| @@ -199,7 +201,7 @@ struct APState { | |||
| 199 | [this](const std::list<APClient::NetworkItem>& items) { | 201 | [this](const std::list<APClient::NetworkItem>& items) { |
| 200 | for (const APClient::NetworkItem& item : items) { | 202 | for (const APClient::NetworkItem& item : items) { |
| 201 | inventory[item.item]++; | 203 | inventory[item.item]++; |
| 202 | wxLogVerbose("Item: %lld", item.item); | 204 | TrackerLog(fmt::format("Item: {}", item.item)); |
| 203 | } | 205 | } |
| 204 | 206 | ||
| 205 | RefreshTracker(false); | 207 | RefreshTracker(false); |
| @@ -221,13 +223,15 @@ struct APState { | |||
| 221 | RefreshTracker(false); | 223 | RefreshTracker(false); |
| 222 | }); | 224 | }); |
| 223 | 225 | ||
| 224 | apclient->set_slot_connected_handler([this, &connection_mutex]( | 226 | apclient->set_slot_connected_handler([this, player, server, |
| 227 | &connection_mutex]( | ||
| 225 | const nlohmann::json& slot_data) { | 228 | const nlohmann::json& slot_data) { |
| 226 | tracker_frame->SetStatusMessage("Connected to Archipelago!"); | 229 | tracker_frame->SetStatusMessage( |
| 227 | wxLogStatus("Connected to Archipelago!"); | 230 | fmt::format("Connected to Archipelago! ({}@{})", player, server)); |
| 231 | TrackerLog("Connected to Archipelago!"); | ||
| 228 | 232 | ||
| 229 | data_storage_prefix = | 233 | data_storage_prefix = |
| 230 | "Lingo_" + std::to_string(apclient->get_player_number()) + "_"; | 234 | fmt::format("Lingo_{}_", apclient->get_player_number()); |
| 231 | door_shuffle_mode = slot_data["shuffle_doors"].get<DoorShuffleMode>(); | 235 | door_shuffle_mode = slot_data["shuffle_doors"].get<DoorShuffleMode>(); |
| 232 | if (slot_data.contains("group_doors")) { | 236 | if (slot_data.contains("group_doors")) { |
| 233 | group_doors = slot_data.contains("group_doors") && | 237 | group_doors = slot_data.contains("group_doors") && |
| @@ -290,18 +294,18 @@ struct APState { | |||
| 290 | corrected_keys.push_back(data_storage_prefix + key); | 294 | corrected_keys.push_back(data_storage_prefix + key); |
| 291 | } | 295 | } |
| 292 | 296 | ||
| 293 | { | 297 | victory_data_storage_key = |
| 294 | std::ostringstream vdsks; | 298 | fmt::format("_read_client_status_{}_{}", apclient->get_team_number(), |
| 295 | vdsks << "_read_client_status_" << apclient->get_team_number() << "_" | 299 | apclient->get_player_number()); |
| 296 | << apclient->get_player_number(); | ||
| 297 | victory_data_storage_key = vdsks.str(); | ||
| 298 | } | ||
| 299 | 300 | ||
| 300 | corrected_keys.push_back(victory_data_storage_key); | 301 | corrected_keys.push_back(victory_data_storage_key); |
| 301 | 302 | ||
| 302 | apclient->Get(corrected_keys); | 303 | apclient->Get(corrected_keys); |
| 303 | apclient->SetNotify(corrected_keys); | 304 | apclient->SetNotify(corrected_keys); |
| 304 | 305 | ||
| 306 | ResetReachabilityRequirements(); | ||
| 307 | RefreshTracker(true); | ||
| 308 | |||
| 305 | { | 309 | { |
| 306 | std::lock_guard connection_lock(connection_mutex); | 310 | std::lock_guard connection_lock(connection_mutex); |
| 307 | if (!has_connection_result) { | 311 | if (!has_connection_result) { |
| @@ -346,7 +350,7 @@ struct APState { | |||
| 346 | } | 350 | } |
| 347 | 351 | ||
| 348 | std::string full_message = hatkirby::implode(error_messages, " "); | 352 | std::string full_message = hatkirby::implode(error_messages, " "); |
| 349 | wxLogError(wxString(full_message)); | 353 | TrackerLog(full_message); |
| 350 | 354 | ||
| 351 | wxMessageBox(full_message, "Connection failed", wxOK | wxICON_ERROR); | 355 | wxMessageBox(full_message, "Connection failed", wxOK | wxICON_ERROR); |
| 352 | }); | 356 | }); |
| @@ -368,7 +372,7 @@ struct APState { | |||
| 368 | DestroyClient(); | 372 | DestroyClient(); |
| 369 | 373 | ||
| 370 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); | 374 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); |
| 371 | wxLogStatus("Timeout while connecting to Archipelago server."); | 375 | TrackerLog("Timeout while connecting to Archipelago server."); |
| 372 | wxMessageBox("Timeout while connecting to Archipelago server.", | 376 | wxMessageBox("Timeout while connecting to Archipelago server.", |
| 373 | "Connection failed", wxOK | wxICON_ERROR); | 377 | "Connection failed", wxOK | wxICON_ERROR); |
| 374 | 378 | ||
| @@ -387,9 +391,6 @@ struct APState { | |||
| 387 | } | 391 | } |
| 388 | 392 | ||
| 389 | if (connected) { | 393 | if (connected) { |
| 390 | ResetReachabilityRequirements(); | ||
| 391 | RefreshTracker(true); | ||
| 392 | } else { | ||
| 393 | client_active = false; | 394 | client_active = false; |
| 394 | } | 395 | } |
| 395 | } | 396 | } |
| @@ -397,11 +398,12 @@ struct APState { | |||
| 397 | void HandleDataStorage(const std::string& key, const nlohmann::json& value) { | 398 | void HandleDataStorage(const std::string& key, const nlohmann::json& value) { |
| 398 | if (value.is_boolean()) { | 399 | if (value.is_boolean()) { |
| 399 | data_storage[key] = value.get<bool>(); | 400 | data_storage[key] = value.get<bool>(); |
| 400 | wxLogVerbose("Data storage %s retrieved as %s", key, | 401 | TrackerLog(fmt::format("Data storage {} retrieved as {}", key, |
| 401 | (value.get<bool>() ? "true" : "false")); | 402 | (value.get<bool>() ? "true" : "false"))); |
| 402 | } else if (value.is_number()) { | 403 | } else if (value.is_number()) { |
| 403 | data_storage[key] = value.get<int>(); | 404 | data_storage[key] = value.get<int>(); |
| 404 | wxLogVerbose("Data storage %s retrieved as %d", key, value.get<int>()); | 405 | TrackerLog(fmt::format("Data storage {} retrieved as {}", key, |
| 406 | value.get<int>())); | ||
| 405 | } else if (value.is_object()) { | 407 | } else if (value.is_object()) { |
| 406 | if (key.ends_with("PlayerPos")) { | 408 | if (key.ends_with("PlayerPos")) { |
| 407 | auto map_value = value.get<std::map<std::string, int>>(); | 409 | auto map_value = value.get<std::map<std::string, int>>(); |
| @@ -410,7 +412,7 @@ struct APState { | |||
| 410 | data_storage[key] = value.get<std::map<std::string, int>>(); | 412 | data_storage[key] = value.get<std::map<std::string, int>>(); |
| 411 | } | 413 | } |
| 412 | 414 | ||
| 413 | wxLogVerbose("Data storage %s retrieved as dictionary", key); | 415 | TrackerLog(fmt::format("Data storage {} retrieved as dictionary", key)); |
| 414 | } else if (value.is_null()) { | 416 | } else if (value.is_null()) { |
| 415 | if (key.ends_with("PlayerPos")) { | 417 | if (key.ends_with("PlayerPos")) { |
| 416 | player_pos = std::nullopt; | 418 | player_pos = std::nullopt; |
| @@ -418,7 +420,7 @@ struct APState { | |||
| 418 | data_storage.erase(key); | 420 | data_storage.erase(key); |
| 419 | } | 421 | } |
| 420 | 422 | ||
| 421 | wxLogVerbose("Data storage %s retrieved as null", key); | 423 | TrackerLog(fmt::format("Data storage {} retrieved as null", key)); |
| 422 | } else if (value.is_array()) { | 424 | } else if (value.is_array()) { |
| 423 | auto list_value = value.get<std::vector<std::string>>(); | 425 | auto list_value = value.get<std::vector<std::string>>(); |
| 424 | 426 | ||
| @@ -429,8 +431,8 @@ struct APState { | |||
| 429 | data_storage[key] = list_value; | 431 | data_storage[key] = list_value; |
| 430 | } | 432 | } |
| 431 | 433 | ||
| 432 | wxLogVerbose("Data storage %s retrieved as list: [%s]", key, | 434 | TrackerLog(fmt::format("Data storage {} retrieved as list: [{}]", key, |
| 433 | hatkirby::implode(list_value, ", ")); | 435 | hatkirby::implode(list_value, ", "))); |
| 434 | } | 436 | } |
| 435 | } | 437 | } |
| 436 | 438 | ||
| @@ -440,7 +442,7 @@ struct APState { | |||
| 440 | 442 | ||
| 441 | bool HasCheckedHuntPanel(int location_id) { | 443 | bool HasCheckedHuntPanel(int location_id) { |
| 442 | std::string key = | 444 | std::string key = |
| 443 | data_storage_prefix + "Hunt|" + std::to_string(location_id); | 445 | fmt::format("{}Hunt|{}", data_storage_prefix, location_id); |
| 444 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); | 446 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); |
| 445 | } | 447 | } |
| 446 | 448 | ||
| @@ -449,12 +451,13 @@ struct APState { | |||
| 449 | } | 451 | } |
| 450 | 452 | ||
| 451 | bool HasAchievement(const std::string& name) { | 453 | bool HasAchievement(const std::string& name) { |
| 452 | std::string key = data_storage_prefix + "Achievement|" + name; | 454 | std::string key = |
| 455 | fmt::format("{}Achievement|{}", data_storage_prefix, name); | ||
| 453 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); | 456 | return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key)); |
| 454 | } | 457 | } |
| 455 | 458 | ||
| 456 | const std::set<std::string>& GetCheckedPaintings() { | 459 | const std::set<std::string>& GetCheckedPaintings() { |
| 457 | std::string key = data_storage_prefix + "Paintings"; | 460 | std::string key = fmt::format("{}Paintings", data_storage_prefix); |
| 458 | if (!data_storage.count(key)) { | 461 | if (!data_storage.count(key)) { |
| 459 | data_storage[key] = std::set<std::string>(); | 462 | data_storage[key] = std::set<std::string>(); |
| 460 | } | 463 | } |
| @@ -471,7 +474,7 @@ struct APState { | |||
| 471 | } | 474 | } |
| 472 | 475 | ||
| 473 | void RefreshTracker(bool reset) { | 476 | void RefreshTracker(bool reset) { |
| 474 | wxLogVerbose("Refreshing display..."); | 477 | TrackerLog("Refreshing display..."); |
| 475 | 478 | ||
| 476 | RecalculateReachability(); | 479 | RecalculateReachability(); |
| 477 | 480 | ||
| @@ -485,7 +488,7 @@ struct APState { | |||
| 485 | int64_t GetItemId(const std::string& item_name) { | 488 | int64_t GetItemId(const std::string& item_name) { |
| 486 | int64_t ap_id = apclient->get_item_id(item_name); | 489 | int64_t ap_id = apclient->get_item_id(item_name); |
| 487 | if (ap_id == APClient::INVALID_NAME_ID) { | 490 | if (ap_id == APClient::INVALID_NAME_ID) { |
| 488 | wxLogError("Could not find AP item ID for %s", item_name); | 491 | TrackerLog(fmt::format("Could not find AP item ID for {}", item_name)); |
| 489 | } | 492 | } |
| 490 | 493 | ||
| 491 | return ap_id; | 494 | return ap_id; |
| @@ -564,16 +567,27 @@ int AP_GetMasteryRequirement() { return GetState().mastery_requirement; } | |||
| 564 | int AP_GetLevel2Requirement() { return GetState().level_2_requirement; } | 567 | int AP_GetLevel2Requirement() { return GetState().level_2_requirement; } |
| 565 | 568 | ||
| 566 | bool AP_IsLocationVisible(int classification) { | 569 | bool AP_IsLocationVisible(int classification) { |
| 570 | int world_state = 0; | ||
| 571 | |||
| 567 | switch (GetState().location_checks) { | 572 | switch (GetState().location_checks) { |
| 568 | case kNORMAL_LOCATIONS: | 573 | case kNORMAL_LOCATIONS: |
| 569 | return classification & kLOCATION_NORMAL; | 574 | world_state = kLOCATION_NORMAL; |
| 575 | break; | ||
| 570 | case kREDUCED_LOCATIONS: | 576 | case kREDUCED_LOCATIONS: |
| 571 | return classification & kLOCATION_REDUCED; | 577 | world_state = kLOCATION_REDUCED; |
| 578 | break; | ||
| 572 | case kPANELSANITY: | 579 | case kPANELSANITY: |
| 573 | return classification & kLOCATION_INSANITY; | 580 | world_state = kLOCATION_INSANITY; |
| 581 | break; | ||
| 574 | default: | 582 | default: |
| 575 | return false; | 583 | return false; |
| 576 | } | 584 | } |
| 585 | |||
| 586 | if (GetState().door_shuffle_mode && !GetState().early_color_hallways) { | ||
| 587 | world_state |= kLOCATION_SMALL_SPHERE_ONE; | ||
| 588 | } | ||
| 589 | |||
| 590 | return (world_state & classification); | ||
| 577 | } | 591 | } |
| 578 | 592 | ||
| 579 | VictoryCondition AP_GetVictoryCondition() { | 593 | VictoryCondition AP_GetVictoryCondition() { |
