diff options
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() { |