about summary refs log tree commit diff stats
path: root/src/ap_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ap_state.cpp')
-rw-r--r--src/ap_state.cpp102
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; }
564int AP_GetLevel2Requirement() { return GetState().level_2_requirement; } 567int AP_GetLevel2Requirement() { return GetState().level_2_requirement; }
565 568
566bool AP_IsLocationVisible(int classification) { 569bool 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
579VictoryCondition AP_GetVictoryCondition() { 593VictoryCondition AP_GetVictoryCondition() {