From 8e71a27114e5b322f84c848cd9961f0f4917b323 Mon Sep 17 00:00:00 2001 From: Jon <> Date: Mon, 12 Aug 2024 11:32:26 +0100 Subject: [PATCH 1/2] Added basic logic to determine outpost to visit --- .../Dependencies/Headquarter | 2 +- GuildWarsPartySearch.Bot/main.cpp | 60 +++++++++++++++++-- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/GuildWarsPartySearch.Bot/Dependencies/Headquarter b/GuildWarsPartySearch.Bot/Dependencies/Headquarter index cd32d21..77964cc 160000 --- a/GuildWarsPartySearch.Bot/Dependencies/Headquarter +++ b/GuildWarsPartySearch.Bot/Dependencies/Headquarter @@ -1 +1 @@ -Subproject commit cd32d21972320cbb3ed99c7fb3a3ee890f8852f2 +Subproject commit 77964cc4059db288bf52133c4029b428c214524f diff --git a/GuildWarsPartySearch.Bot/main.cpp b/GuildWarsPartySearch.Bot/main.cpp index 51b0b2a..1ed4e5f 100644 --- a/GuildWarsPartySearch.Bot/main.cpp +++ b/GuildWarsPartySearch.Bot/main.cpp @@ -48,6 +48,14 @@ extern "C" { #define FAILED_TO_LOAD_CONFIG 4 #define FAILED_TO_CONNECT 5 +#define MapID_Ascalon_PreSearing 148 +#define MapID_Kamadan 449 +#define MapID_Kamadan_Halloween 818 +#define MapID_Kamadan_Wintersday 819 +#define MapID_Kamadan_Canthan_New_Year 820 +#define MapID_EmbarkBeach 857 +#define MapID_GreatTempleOfBalthazar 148 + struct BotConfiguration { std::string web_socket_url = ""; uint32_t map_id = 857; // Embark beach @@ -100,6 +108,9 @@ uint32_t map_id = 0; char character_name[42] = { 0 }; char account_uuid[128] = { 0 }; +uint32_t wanted_map_id = 0; +District wanted_district = District::DISTRICT_CURRENT; + static PluginObject* plugin_hook; static BotConfiguration bot_configuration; @@ -247,6 +258,26 @@ static void collect_instance_info() { assert(GetAccountUuid(account_uuid, ARRAY_SIZE(account_uuid)) > 0); } +static uint32_t calculate_map_to_visit(uint32_t map_id_requested, District* district_out) { + // @TODO: Figure out if a district for a map is available; this should already be given because we can see it on the world map + if (map_id_requested && IsMapUnlocked(map_id_requested)) { + // The map given is accessible + if (district_out && !*district_out) + *district_out = District::DISTRICT_CURRENT; + return map_id_requested; + } + uint32_t fallback_map_ids[] = { + 857, // Embark + 148, // Gtob + }; + for (auto fallback_id : fallback_map_ids) { + if (IsMapUnlocked(fallback_id)) + return fallback_id; + } + return 0; +} + + static void on_map_left(Event* event, void* params) { clear_party_search_advertisements(); } @@ -339,31 +370,47 @@ static void load_configuration() { if (bot_configuration.map_id == -1) { exit_with_status("No map specified. Use -mapid", FAILED_TO_LOAD_CONFIG); } + + wanted_map_id = bot_configuration.map_id; + wanted_district = bot_configuration.district; +} +// If the given map id isn't the normal one (i.e. festival, return the original. Useful for comparisons) +static uint32_t get_original_map_id(uint32_t map_id) { + switch(map_id) { + case MapID_Kamadan_Halloween: + case MapID_Kamadan_Wintersday: + case MapID_Kamadan_Canthan_New_Year: + return MapID_Kamadan; + // TODO: Other outposts that have festival versions + } + return map_id; } static bool in_correct_outpost() { if (!GetIsIngame()) return false; - if (!bot_configuration.map_id) - return true; if (!map_id) return false; - return ((!bot_configuration.map_id || map_id == bot_configuration.map_id) && - (bot_configuration.district == District::DISTRICT_CURRENT || district == bot_configuration.district) && + uint32_t check_map_id = get_original_map_id(map_id); + + return ((!wanted_map_id || check_map_id == wanted_map_id) && + (wanted_district == District::DISTRICT_CURRENT || district == wanted_district) && (!bot_configuration.district_number || district_number == bot_configuration.district_number)); } static void ensure_correct_outpost() { + wanted_map_id = calculate_map_to_visit(bot_configuration.map_id, &wanted_district); + if (!wanted_map_id) + exit_with_status("calculate_map_to_visit failed, ensure this character has gtob unlocked", 1); if (in_correct_outpost()) return; LogInfo("Zoning into outpost"); int res = 0; size_t retries = 4; - assert(bot_configuration.map_id); for (size_t i = 0; i < retries && !in_correct_outpost(); i++) { LogInfo("Travel attempt %d of %d", i + 1, retries); - res = travel_wait(bot_configuration.map_id, bot_configuration.district, bot_configuration.district_number); + res = travel_wait(wanted_map_id, wanted_district, bot_configuration.district_number); if (res == 38) { retries = 50; // District full, more retries } @@ -461,6 +508,7 @@ static int main_bot(void* param) while (running) { wait_until_ingame(); ensure_correct_outpost(); + connect_websocket(); if (party_advertisements_pending) { send_party_advertisements(); party_advertisements_pending = false; From dc7808ece80bd0651a728d414a3724b077709953 Mon Sep 17 00:00:00 2001 From: Jon <> Date: Mon, 12 Aug 2024 11:39:58 +0100 Subject: [PATCH 2/2] tweaks to websocket ready check --- GuildWarsPartySearch.Bot/main.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/GuildWarsPartySearch.Bot/main.cpp b/GuildWarsPartySearch.Bot/main.cpp index 8f5aca7..eae9325 100644 --- a/GuildWarsPartySearch.Bot/main.cpp +++ b/GuildWarsPartySearch.Bot/main.cpp @@ -58,7 +58,7 @@ extern "C" { struct BotConfiguration { std::string web_socket_url = ""; - uint32_t map_id = 857; // Embark beach + uint32_t map_id = 0; // Embark beach District district = District::DISTRICT_AMERICAN; uint32_t district_number = 0; int32_t connection_retries = 10; @@ -220,8 +220,13 @@ static PartySearchAdvertisement* create_party_search_advertisement(Event* event) return party; } +static bool is_websocket_ready(easywsclient::WebSocket::pointer ws) { + return ws && ws->getReadyState() == easywsclient::WebSocket::OPEN; +} + static int send_websocket(const std::string& payload) { - connect_websocket(); + if(!is_websocket_ready(ws)) + connect_websocket(); LogInfo("Websocket send:"); printf("%s\n", payload.c_str()); last_websocket_message = time_get_ms(); @@ -229,12 +234,12 @@ static int send_websocket(const std::string& payload) { return 0; } -static int send_ping() { - connect_websocket(); +static void send_ping() { + if (!is_websocket_ready(ws)) + return; // No need to connect if its not ready LogInfo("Sending ping"); last_websocket_message = time_get_ms(); ws->sendPing(); - return 0; } static int send_party_advertisements() { @@ -448,9 +453,8 @@ static void disconnect_websocket() { ws = NULL; } static easywsclient::WebSocket::pointer connect_websocket() { - if (ws && ws->getReadyState() == easywsclient::WebSocket::OPEN) + if (is_websocket_ready(ws)) return ws; - assert(*account_uuid && map_id); char user_agent[255]; char uuid_less_hyphens[ARRAY_SIZE(account_uuid)] = { 0 }; @@ -476,7 +480,7 @@ static easywsclient::WebSocket::pointer connect_websocket() { // Wait for websocket to open for (auto j = 0; j < 5000; j+=50) { ws->poll(); - if (ws->getReadyState() == easywsclient::WebSocket::OPEN) { + if (is_websocket_ready(ws)) { LogInfo("Websocket opened successfully"); party_advertisements_pending = true; last_websocket_message = time_get_ms(); @@ -524,7 +528,6 @@ static int main_bot(void* param) if (ws) { if (time_get_ms() - last_websocket_message > 30000) { send_ping(); - } ws->dispatch(on_websocket_message); ws->poll();