From 325ea53e7bb873870b46d3e38b2b314493a22f79 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 3 May 2023 18:27:37 -0400 Subject: Refactored APState It is no longer a class, because it didn't need to be. --- ap_state.cpp | 245 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 143 insertions(+), 102 deletions(-) (limited to 'ap_state.cpp') diff --git a/ap_state.cpp b/ap_state.cpp index 8b7339a..c13b87c 100644 --- a/ap_state.cpp +++ b/ap_state.cpp @@ -11,9 +11,14 @@ #include #include #include +#include +#include +#include #include +#include #include "game_data.h" +#include "tracker_frame.h" #include "tracker_state.h" constexpr int AP_MAJOR = 0; @@ -22,29 +27,81 @@ constexpr int AP_REVISION = 0; constexpr int ITEM_HANDLING = 7; // <- all -static APClient* apclient = nullptr; +namespace { -APState::APState() { - std::thread([this]() { - for (;;) { - { - std::lock_guard client_guard(client_mutex_); - if (apclient) { - apclient->poll(); +APClient* apclient = nullptr; + +bool initialized = false; + +TrackerFrame* tracker_frame; + +bool client_active = false; +std::mutex client_mutex; + +bool connected = false; +bool has_connection_result = false; + +std::map inventory; +std::set checked_locations; + +std::map, int64_t> ap_id_by_location_id; +std::map ap_id_by_item_name; +std::map ap_id_by_color; +std::map progressive_item_by_ap_id; + +DoorShuffleMode door_shuffle_mode = kNO_DOORS; +bool color_shuffle = false; +bool painting_shuffle = false; + +std::map painting_mapping; + +void RefreshTracker() { + GetTrackerState().CalculateState(); + tracker_frame->UpdateIndicators(); +} + +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) { + std::cout << "Could not find AP item ID for " << item_name << std::endl; + } + + return ap_id; +} + +void DestroyClient() { + client_active = false; + apclient->reset(); + delete apclient; + apclient = nullptr; +} + +} // namespace + +void AP_SetTrackerFrame(TrackerFrame* arg) { tracker_frame = arg; } + +void AP_Connect(std::string server, std::string player, std::string password) { + if (!initialized) { + std::thread([]() { + for (;;) { + { + std::lock_guard client_guard(client_mutex); + if (apclient) { + apclient->poll(); + } } + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } + }).detach(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - }).detach(); -} + initialized = true; + } -void APState::Connect(std::string server, std::string player, - std::string password) { - tracker_frame_->SetStatusMessage("Connecting to Archipelago server...."); + tracker_frame->SetStatusMessage("Connecting to Archipelago server...."); { - std::lock_guard client_guard(client_mutex_); + std::lock_guard client_guard(client_mutex); if (apclient) { DestroyClient(); @@ -53,20 +110,20 @@ void APState::Connect(std::string server, std::string player, apclient = new APClient(ap_get_uuid(""), "Lingo", server); } - inventory_.clear(); - checked_locations_.clear(); - door_shuffle_mode_ = kNO_DOORS; - color_shuffle_ = false; - painting_shuffle_ = false; - painting_mapping_.clear(); + inventory.clear(); + checked_locations.clear(); + door_shuffle_mode = kNO_DOORS; + color_shuffle = false; + painting_shuffle = false; + painting_mapping.clear(); - connected_ = false; - has_connection_result_ = false; + connected = false; + has_connection_result = false; - apclient->set_room_info_handler([this, player, password]() { - inventory_.clear(); + apclient->set_room_info_handler([player, password]() { + inventory.clear(); - tracker_frame_->SetStatusMessage( + tracker_frame->SetStatusMessage( "Connected to Archipelago server. Authenticating..."); apclient->ConnectSlot(player, password, ITEM_HANDLING, {"Tracker"}, @@ -74,61 +131,60 @@ void APState::Connect(std::string server, std::string player, }); apclient->set_location_checked_handler( - [this](const std::list& locations) { + [](const std::list& locations) { for (const int64_t location_id : locations) { - checked_locations_.insert(location_id); + checked_locations.insert(location_id); std::cout << "Location: " << location_id << std::endl; } RefreshTracker(); }); - apclient->set_slot_disconnected_handler([this]() { - tracker_frame_->SetStatusMessage( + apclient->set_slot_disconnected_handler([]() { + tracker_frame->SetStatusMessage( "Disconnected from Archipelago. Attempting to reconnect..."); }); - apclient->set_socket_disconnected_handler([this]() { - tracker_frame_->SetStatusMessage( + apclient->set_socket_disconnected_handler([]() { + tracker_frame->SetStatusMessage( "Disconnected from Archipelago. Attempting to reconnect..."); }); apclient->set_items_received_handler( - [this](const std::list& items) { + [](const std::list& items) { for (const APClient::NetworkItem& item : items) { - inventory_[item.item]++; + inventory[item.item]++; std::cout << "Item: " << item.item << std::endl; } RefreshTracker(); }); - apclient->set_slot_connected_handler([this](const nlohmann::json& slot_data) { - tracker_frame_->SetStatusMessage("Connected to Archipelago!"); + apclient->set_slot_connected_handler([](const nlohmann::json& slot_data) { + tracker_frame->SetStatusMessage("Connected to Archipelago!"); - door_shuffle_mode_ = slot_data["shuffle_doors"].get(); - color_shuffle_ = slot_data["shuffle_colors"].get(); - painting_shuffle_ = slot_data["shuffle_paintings"].get(); + door_shuffle_mode = slot_data["shuffle_doors"].get(); + color_shuffle = slot_data["shuffle_colors"].get(); + painting_shuffle = slot_data["shuffle_paintings"].get(); - if (painting_shuffle_ && slot_data.contains("painting_entrance_to_exit")) { - painting_mapping_.clear(); + if (painting_shuffle && slot_data.contains("painting_entrance_to_exit")) { + painting_mapping.clear(); for (const auto& mapping_it : slot_data["painting_entrance_to_exit"].items()) { - painting_mapping_[mapping_it.key()] = mapping_it.value(); + painting_mapping[mapping_it.key()] = mapping_it.value(); } } - connected_ = true; - has_connection_result_ = true; + connected = true; + has_connection_result = true; }); - apclient->set_slot_refused_handler([this]( - const std::list& errors) { - connected_ = false; - has_connection_result_ = true; + apclient->set_slot_refused_handler([](const std::list& errors) { + connected = false; + has_connection_result = true; - tracker_frame_->SetStatusMessage("Disconnected from Archipelago."); + tracker_frame->SetStatusMessage("Disconnected from Archipelago."); std::vector error_messages; error_messages.push_back("Could not connect to Archipelago."); @@ -158,19 +214,19 @@ void APState::Connect(std::string server, std::string player, wxMessageBox(full_message, "Connection failed", wxOK | wxICON_ERROR); }); - client_active_ = true; + client_active = true; int timeout = 5000; // 5 seconds int interval = 100; int remaining_loops = timeout / interval; - while (!has_connection_result_) { + while (!has_connection_result) { if (interval == 0) { - connected_ = false; - has_connection_result_ = true; + connected = false; + has_connection_result = true; DestroyClient(); - tracker_frame_->SetStatusMessage("Disconnected from Archipelago."); + tracker_frame->SetStatusMessage("Disconnected from Archipelago."); wxMessageBox("Timeout while connecting to Archipelago server.", "Connection failed", wxOK | wxICON_ERROR); @@ -181,7 +237,7 @@ void APState::Connect(std::string server, std::string player, interval--; } - if (connected_) { + if (connected) { for (const MapArea& map_area : GetGameData().GetMapAreas()) { for (int section_id = 0; section_id < map_area.locations.size(); section_id++) { @@ -192,91 +248,76 @@ void APState::Connect(std::string server, std::string player, std::cout << "Could not find AP location ID for " << location.ap_location_name << std::endl; } else { - ap_id_by_location_id_[{map_area.id, section_id}] = ap_id; + ap_id_by_location_id[{map_area.id, section_id}] = ap_id; } } } for (const Door& door : GetGameData().GetDoors()) { if (!door.skip_item) { - ap_id_by_item_name_[door.item_name] = GetItemId(door.item_name); + ap_id_by_item_name[door.item_name] = GetItemId(door.item_name); if (!door.group_name.empty() && - !ap_id_by_item_name_.count(door.group_name)) { - ap_id_by_item_name_[door.group_name] = GetItemId(door.group_name); + !ap_id_by_item_name.count(door.group_name)) { + ap_id_by_item_name[door.group_name] = GetItemId(door.group_name); } for (const ProgressiveRequirement& prog_req : door.progressives) { - ap_id_by_item_name_[prog_req.item_name] = GetItemId(prog_req.item_name); + ap_id_by_item_name[prog_req.item_name] = + GetItemId(prog_req.item_name); } } } - ap_id_by_color_[LingoColor::kBlack] = GetItemId("Black"); - ap_id_by_color_[LingoColor::kRed] = GetItemId("Red"); - ap_id_by_color_[LingoColor::kBlue] = GetItemId("Blue"); - ap_id_by_color_[LingoColor::kYellow] = GetItemId("Yellow"); - ap_id_by_color_[LingoColor::kPurple] = GetItemId("Purple"); - ap_id_by_color_[LingoColor::kOrange] = GetItemId("Orange"); - ap_id_by_color_[LingoColor::kGreen] = GetItemId("Green"); - ap_id_by_color_[LingoColor::kBrown] = GetItemId("Brown"); - ap_id_by_color_[LingoColor::kGray] = GetItemId("Gray"); + ap_id_by_color[LingoColor::kBlack] = GetItemId("Black"); + ap_id_by_color[LingoColor::kRed] = GetItemId("Red"); + ap_id_by_color[LingoColor::kBlue] = GetItemId("Blue"); + ap_id_by_color[LingoColor::kYellow] = GetItemId("Yellow"); + ap_id_by_color[LingoColor::kPurple] = GetItemId("Purple"); + ap_id_by_color[LingoColor::kOrange] = GetItemId("Orange"); + ap_id_by_color[LingoColor::kGreen] = GetItemId("Green"); + ap_id_by_color[LingoColor::kBrown] = GetItemId("Brown"); + ap_id_by_color[LingoColor::kGray] = GetItemId("Gray"); RefreshTracker(); } else { - client_active_ = false; + client_active = false; } } -bool APState::HasCheckedGameLocation(int area_id, int section_id) const { +bool AP_HasCheckedGameLocation(int area_id, int section_id) { std::tuple location_key = {area_id, section_id}; - if (ap_id_by_location_id_.count(location_key)) { - return checked_locations_.count(ap_id_by_location_id_.at(location_key)); + if (ap_id_by_location_id.count(location_key)) { + return checked_locations.count(ap_id_by_location_id.at(location_key)); } else { return false; } } -bool APState::HasColorItem(LingoColor color) const { - if (ap_id_by_color_.count(color)) { - return inventory_.count(ap_id_by_color_.at(color)); +bool AP_HasColorItem(LingoColor color) { + if (ap_id_by_color.count(color)) { + return inventory.count(ap_id_by_color.at(color)); } else { return false; } } -bool APState::HasItem(const std::string& item, int quantity) const { - if (ap_id_by_item_name_.count(item)) { - int64_t ap_id = ap_id_by_item_name_.at(item); - return inventory_.count(ap_id) && inventory_.at(ap_id) >= quantity; +bool AP_HasItem(const std::string& item, int quantity) { + if (ap_id_by_item_name.count(item)) { + int64_t ap_id = ap_id_by_item_name.at(item); + return inventory.count(ap_id) && inventory.at(ap_id) >= quantity; } else { return false; } } -void APState::RefreshTracker() { - GetTrackerState().CalculateState(); - tracker_frame_->UpdateIndicators(); -} - -int64_t APState::GetItemId(const std::string& item_name) { - int64_t ap_id = apclient->get_item_id(item_name); - if (ap_id == APClient::INVALID_NAME_ID) { - std::cout << "Could not find AP item ID for " << item_name << std::endl; - } +DoorShuffleMode AP_GetDoorShuffleMode() { return door_shuffle_mode; } - return ap_id; -} +bool AP_IsColorShuffle() { return color_shuffle; } -void APState::DestroyClient() { - client_active_ = false; - apclient->reset(); - delete apclient; - apclient = nullptr; -} +bool AP_IsPaintingShuffle() { return painting_shuffle; } -APState& GetAPState() { - static APState* instance = new APState(); - return *instance; +const std::map AP_GetPaintingMapping() { + return painting_mapping; } -- cgit 1.4.1