File directory cleanup and options window separation
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
#include "objects/object_link_child/object_link_child.h"
|
||||
#include "soh_assets.h"
|
||||
#include "kaleido.h"
|
||||
#include "soh/Enhancements/randomizer/archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
#include "archipelago.h"
|
||||
#include "soh/SohGui/UIWidgets.hpp"
|
||||
#include "soh/util.h"
|
||||
#include <apuuid.hpp>
|
||||
#include <apclient.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "static_data.h"
|
||||
#include "../game-interactor/GameInteractor.h"
|
||||
|
||||
ArchipelagoClient::ArchipelagoClient() {
|
||||
std::string uuid = ap_get_uuid("uuid");
|
||||
|
||||
ItemRecievedCallback = nullptr;
|
||||
game_won = false;
|
||||
|
||||
namespace apc = AP_Client_consts;
|
||||
CVarSetInteger("archipelago_connected", 0);
|
||||
strncpy(server_address, CVarGetString(apc::SETTING_ADDRESS, apc::DEFAULT_SERVER_NAME), apc::MAX_ADDRESS_LENGTH);
|
||||
strncpy(slot_name, CVarGetString(apc::SETTING_NAME, ""), apc::MAX_PLAYER_NAME_LENGHT);
|
||||
|
||||
// call poll every frame
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([](){ArchipelagoClient::getInstance().poll();});
|
||||
}
|
||||
|
||||
ArchipelagoClient& ArchipelagoClient::getInstance() {
|
||||
static ArchipelagoClient Client;
|
||||
return Client;
|
||||
}
|
||||
|
||||
bool ArchipelagoClient::start_client() {
|
||||
if(apclient != NULL) {
|
||||
apclient.reset();
|
||||
}
|
||||
|
||||
apclient = std::unique_ptr<APClient>(new APClient(uuid, AP_Client_consts::AP_GAME_NAME, server_address));
|
||||
|
||||
apclient->set_room_info_handler([&]() {
|
||||
std::list<std::string> tags;
|
||||
// tags.push_back("DeathLink"); // todo, implement deathlink
|
||||
apclient->ConnectSlot(slot_name, password, 0b001, tags);
|
||||
});
|
||||
|
||||
apclient->set_items_received_handler([&](const std::list<APClient::NetworkItem>& items) {
|
||||
for(const APClient::NetworkItem& item : items) {
|
||||
on_item_recieved(item.item, false); // todo get rid of notify, since it doesn't work for us right now anyway
|
||||
}
|
||||
});
|
||||
|
||||
apclient->set_location_info_handler([&](const std::list<APClient::NetworkItem>& items) {
|
||||
scouted_items.clear();
|
||||
|
||||
for(const APClient::NetworkItem& item: items) {
|
||||
ApItem apItem;
|
||||
const std::string game = apclient->get_player_game(item.player);
|
||||
apItem.itemName = apclient->get_item_name(item.item, game);
|
||||
apItem.locationName = apclient->get_location_name(item.location, game);
|
||||
apItem.playerName = apclient->get_player_alias(item.player);
|
||||
apItem.flags = item.flags;
|
||||
apItem.index = item.index;
|
||||
scouted_items.push_back(apItem);
|
||||
|
||||
const std::string itemName = apItem.itemName;
|
||||
const std::string playerName = apItem.playerName;
|
||||
const std::string locationName = apItem.locationName;
|
||||
SPDLOG_TRACE("Location scouted: {} for {} in location {}", itemName, playerName, locationName);
|
||||
}
|
||||
|
||||
}); // todo maybe move these functions to a lambda, since they don't have to be static anymore
|
||||
apclient->set_location_checked_handler([&](const std::list<int64_t> locations) {
|
||||
// todo implement me
|
||||
});
|
||||
|
||||
save_data();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::start_location_scouts() {
|
||||
std::set<int64_t> missing_loc_set = apclient->get_missing_locations();
|
||||
std::set<int64_t> found_loc_set = apclient->get_checked_locations();
|
||||
std::list<int64_t> location_list;
|
||||
for(const int64_t loc_id : missing_loc_set) {
|
||||
location_list.emplace_back(loc_id);
|
||||
}
|
||||
for(const int64_t loc_id : found_loc_set) {
|
||||
location_list.emplace_back(loc_id);
|
||||
}
|
||||
apclient->LocationScouts(location_list);
|
||||
}
|
||||
|
||||
void ArchipelagoClient::save_data() {
|
||||
CVarSetString(AP_Client_consts::SETTING_ADDRESS, server_address);
|
||||
CVarSetString(AP_Client_consts::SETTING_NAME, slot_name);
|
||||
}
|
||||
|
||||
bool ArchipelagoClient::isConnected() {
|
||||
return apclient->get_state() == APClient::State::SLOT_CONNECTED;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::check_location(RandomizerCheck SoH_check_id) {
|
||||
//std::string_view ap_name = Rando::StaticData::SohCheckToAP[SoH_check_id];
|
||||
std::string ap_name = Rando::StaticData::GetLocation(SoH_check_id)->GetName();
|
||||
if(ap_name.empty()) {
|
||||
return;
|
||||
}
|
||||
int64_t ap_item_id = apclient->get_location_id(std::string(ap_name));
|
||||
SPDLOG_TRACE("Checked: {}({}), sending to AP server", ap_name, ap_item_id);
|
||||
|
||||
// currently not sending, because i only get so many real chances
|
||||
if(!isConnected()) {
|
||||
return;
|
||||
}
|
||||
apclient->LocationChecks({ap_item_id});
|
||||
}
|
||||
|
||||
void ArchipelagoClient::addItemRecievedCallback(std::function<void(const std::string&)> callback) {
|
||||
ItemRecievedCallback = callback;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::removeItemRecievedCallback(std::function<void(const std::string&)> old_callback) {
|
||||
ItemRecievedCallback = nullptr;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::on_connected() {
|
||||
// todo implement me
|
||||
SPDLOG_TRACE("AP Connected!!");
|
||||
}
|
||||
//void ArchipelagoClient::on_couldntConnect(AP_ConnectionStatus connection_status) {
|
||||
// // todo implement me
|
||||
//}
|
||||
|
||||
void ArchipelagoClient::on_item_recieved(int64_t recieved_item_id, bool notify_player) {
|
||||
// call each callback
|
||||
const std::string item_name = apclient->get_item_name(recieved_item_id, AP_Client_consts::AP_GAME_NAME);
|
||||
ArchipelagoClient& ap_client = ArchipelagoClient::getInstance();
|
||||
if(ap_client.ItemRecievedCallback) {
|
||||
SPDLOG_TRACE("item recieved: {}, notify: {}", item_name, notify_player);
|
||||
ap_client.ItemRecievedCallback.operator()(item_name); // somehow passing it through the itemname breaks it????
|
||||
}
|
||||
}
|
||||
|
||||
void ArchipelagoClient::send_game_won() {
|
||||
if(!game_won) {
|
||||
apclient->StatusUpdate(APClient::ClientStatus::GOAL);
|
||||
game_won = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ArchipelagoClient::poll() {
|
||||
if(apclient == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
apclient->poll();
|
||||
}
|
||||
|
||||
const std::string& ArchipelagoClient::get_slot_name() const {
|
||||
if(apclient == NULL) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return apclient->get_slot();
|
||||
}
|
||||
|
||||
char* ArchipelagoClient::get_server_address_buff() {
|
||||
return server_address;
|
||||
}
|
||||
char* ArchipelagoClient::get_slot_name_buff() {
|
||||
return slot_name;
|
||||
}
|
||||
char* ArchipelagoClient::get_password_buff() {
|
||||
return password;
|
||||
}
|
||||
|
||||
const std::map<std::string, int>& ArchipelagoClient::get_slot_data() {
|
||||
return slot_data;
|
||||
}
|
||||
|
||||
const std::vector<ArchipelagoClient::ApItem>& ArchipelagoClient::get_scouted_items() {
|
||||
return scouted_items;
|
||||
}
|
||||
|
||||
|
||||
void ArchipelagoWindow::ArchipelagoDrawConnectPage() {
|
||||
ArchipelagoClient& AP_client = ArchipelagoClient::getInstance();
|
||||
ImGui::SeparatorText("Connection info");
|
||||
ImGui::InputText("Server Address", AP_client.get_server_address_buff(), AP_Client_consts::MAX_ADDRESS_LENGTH);
|
||||
ImGui::InputText("Slot Name", AP_client.get_slot_name_buff(), AP_Client_consts::MAX_PLAYER_NAME_LENGHT);
|
||||
ImGui::InputText("Password (leave blank for no password)", AP_client.get_password_buff(), AP_Client_consts::MAX_PASSWORD_LENGTH, ImGuiInputTextFlags_Password);
|
||||
|
||||
static char connected_text[25] = "Disconnected";
|
||||
if(ImGui::Button("Connect")) {
|
||||
bool success = AP_client.start_client();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(connected_text);
|
||||
|
||||
APClient::State con_state = APClient::State::DISCONNECTED;
|
||||
|
||||
if(AP_client.apclient) {
|
||||
con_state = AP_client.apclient->get_state();
|
||||
}
|
||||
|
||||
switch (con_state) {
|
||||
case APClient::State::DISCONNECTED: {
|
||||
strncpy(connected_text, "Disconnected!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::SOCKET_CONNECTING: {
|
||||
strncpy(connected_text, "Socket Connecting!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::SOCKET_CONNECTED: {
|
||||
strncpy(connected_text, "Socket Connected!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::ROOM_INFO: {
|
||||
strncpy(connected_text, "Room info Recieved!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::SLOT_CONNECTED: {
|
||||
strncpy(connected_text, "Slot Connected!", 25);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if(ImGui::Button("scout")) {
|
||||
AP_client.start_location_scouts();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button("link up")) {
|
||||
CVarSetInteger("archipelago_connected", 1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void ArchipelagoWindow::DrawElement() {
|
||||
ArchipelagoDrawConnectPage();
|
||||
UIWidgets::PaddedSeparator();
|
||||
|
||||
if(ImGui::Button("give blue ruppie")) {
|
||||
ArchipelagoClient::getInstance().on_item_recieved(66077, true);
|
||||
}
|
||||
};
|
||||
@@ -1,100 +0,0 @@
|
||||
#pragma once
|
||||
#include "archipelago_settings_window.h"
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "static_data.h"
|
||||
#include <vector>
|
||||
|
||||
// forward declerations
|
||||
class APClient;
|
||||
|
||||
|
||||
namespace AP_Client_consts {
|
||||
static constexpr int MAX_ADDRESS_LENGTH = 64;
|
||||
static constexpr int MAX_PLAYER_NAME_LENGHT = 17;
|
||||
static constexpr int MAX_PASSWORD_LENGTH = 32;
|
||||
static constexpr char const* DEFAULT_SERVER_NAME = "archipelago.gg:<port number>";
|
||||
|
||||
static constexpr char const* SETTING_ADDRESS = "AP_server_address";
|
||||
static constexpr char const* SETTING_NAME = "AP_slot_name";
|
||||
|
||||
static constexpr char const* AP_GAME_NAME = "Ocarina of Time (SoH)";
|
||||
}
|
||||
|
||||
class ArchipelagoClient{
|
||||
public:
|
||||
struct ApItem {
|
||||
std::string itemName;
|
||||
std::string locationName;
|
||||
std::string playerName;
|
||||
unsigned int flags;
|
||||
int index;
|
||||
};
|
||||
|
||||
static ArchipelagoClient& getInstance();
|
||||
|
||||
bool start_client();
|
||||
bool stop_client();
|
||||
|
||||
void start_location_scouts();
|
||||
|
||||
// getters
|
||||
const std::string& get_slot_name() const;
|
||||
|
||||
char* get_server_address_buff();
|
||||
char* get_slot_name_buff();
|
||||
char* get_password_buff();
|
||||
const std::map<std::string, int>& get_slot_data();
|
||||
const std::vector<ApItem>& get_scouted_items();
|
||||
|
||||
bool isConnected();
|
||||
void check_location(RandomizerCheck SoH_check_id);
|
||||
|
||||
// callback slots
|
||||
void addItemRecievedCallback(std::function<void(const std::string&)> callback);
|
||||
void removeItemRecievedCallback(std::function<void(const std::string&)> old_callback);
|
||||
|
||||
|
||||
// todo move me back down when done testing
|
||||
void on_item_recieved(int64_t recieved_item_id, bool notify_player);
|
||||
|
||||
void send_game_won();
|
||||
|
||||
void poll();
|
||||
|
||||
std::unique_ptr<APClient> apclient;
|
||||
|
||||
protected:
|
||||
ArchipelagoClient();
|
||||
|
||||
private:
|
||||
ArchipelagoClient(ArchipelagoClient &) = delete;
|
||||
void operator=(const ArchipelagoClient &) = delete;
|
||||
std::string uuid;
|
||||
|
||||
static std::shared_ptr<ArchipelagoClient> instance; // is this even used?
|
||||
static bool initialized;
|
||||
|
||||
char server_address[AP_Client_consts::MAX_ADDRESS_LENGTH];
|
||||
char slot_name[AP_Client_consts::MAX_PLAYER_NAME_LENGHT];
|
||||
char password[AP_Client_consts::MAX_PLAYER_NAME_LENGHT];
|
||||
|
||||
bool game_won;
|
||||
|
||||
std::map<std::string, int> slot_data;
|
||||
std::set<int64_t> locations;
|
||||
std::vector<ApItem> scouted_items;
|
||||
|
||||
void save_data();
|
||||
|
||||
// callback functions
|
||||
void on_connected();
|
||||
|
||||
void on_location_checked(int64_t location_id);
|
||||
void on_deathlink_recieved() { }; // TODO: implement me
|
||||
|
||||
// callbacks
|
||||
std::function<void(const std::string&)> ItemRecievedCallback;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef ARCHIPELAGO_H
|
||||
#define ARCHIPELAGO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ARCHIPELAGO_H
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class ArchipelagoClient;
|
||||
|
||||
class ArchipelagoWindow : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
void InitElement() override {};
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override{};
|
||||
|
||||
private:
|
||||
//std::shared_ptr<ArchipelagoClient AP_client = nullptr;
|
||||
|
||||
void ArchipelagoDrawConnectPage();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "macros.h"
|
||||
#include "3drando/hints.hpp"
|
||||
#include "../kaleido.h"
|
||||
#include "archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "hint.h"
|
||||
#include "fishsanity.h"
|
||||
#include "trial.h"
|
||||
#include "archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "soh/Notification/Notification.h"
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/Enhancements/randomizer/ShuffleFairies.h"
|
||||
#include "archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "soh/util.h"
|
||||
#include "fishsanity.h"
|
||||
#include "randomizerTypes.h"
|
||||
#include "archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
#include "soh/Notification/Notification.h"
|
||||
|
||||
extern std::map<RandomizerCheckArea, std::string> rcAreaNames;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <unordered_map>
|
||||
#include "static_data.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
#include "archipelago_mappings.h"
|
||||
#include "soh/Network/Archipelago/ArchipelagoMappings.h"
|
||||
|
||||
namespace Rando {
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "assets/textures/parameter_static/parameter_static.h"
|
||||
#include <soh/SohGui/SohGui.hpp>
|
||||
#include "soh/SohGui/UIWidgets.hpp"
|
||||
#include "soh/Enhancements/randomizer/archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
|
||||
extern "C" {
|
||||
extern SaveContext gSaveContext;
|
||||
|
||||
@@ -1,2 +1,185 @@
|
||||
#include "Archipelago.h"
|
||||
#include "soh/util.h"
|
||||
#include <apuuid.hpp>
|
||||
#include <apclient.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
|
||||
ArchipelagoClient::ArchipelagoClient() {
|
||||
std::string uuid = ap_get_uuid("uuid");
|
||||
|
||||
ItemRecievedCallback = nullptr;
|
||||
game_won = false;
|
||||
|
||||
namespace apc = AP_Client_consts;
|
||||
CVarSetInteger("archipelago_connected", 0);
|
||||
strncpy(server_address, CVarGetString(apc::SETTING_ADDRESS, apc::DEFAULT_SERVER_NAME), apc::MAX_ADDRESS_LENGTH);
|
||||
strncpy(slot_name, CVarGetString(apc::SETTING_NAME, ""), apc::MAX_PLAYER_NAME_LENGHT);
|
||||
|
||||
// call poll every frame
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([](){ArchipelagoClient::getInstance().poll();});
|
||||
}
|
||||
|
||||
ArchipelagoClient& ArchipelagoClient::getInstance() {
|
||||
static ArchipelagoClient Client;
|
||||
return Client;
|
||||
}
|
||||
|
||||
bool ArchipelagoClient::start_client() {
|
||||
if(apclient != NULL) {
|
||||
apclient.reset();
|
||||
}
|
||||
|
||||
apclient = std::unique_ptr<APClient>(new APClient(uuid, AP_Client_consts::AP_GAME_NAME, server_address));
|
||||
|
||||
apclient->set_room_info_handler([&]() {
|
||||
std::list<std::string> tags;
|
||||
// tags.push_back("DeathLink"); // todo, implement deathlink
|
||||
apclient->ConnectSlot(slot_name, password, 0b001, tags);
|
||||
});
|
||||
|
||||
apclient->set_items_received_handler([&](const std::list<APClient::NetworkItem>& items) {
|
||||
for(const APClient::NetworkItem& item : items) {
|
||||
on_item_recieved(item.item, false); // todo get rid of notify, since it doesn't work for us right now anyway
|
||||
}
|
||||
});
|
||||
|
||||
apclient->set_location_info_handler([&](const std::list<APClient::NetworkItem>& items) {
|
||||
scouted_items.clear();
|
||||
|
||||
for(const APClient::NetworkItem& item: items) {
|
||||
ApItem apItem;
|
||||
const std::string game = apclient->get_player_game(item.player);
|
||||
apItem.itemName = apclient->get_item_name(item.item, game);
|
||||
apItem.locationName = apclient->get_location_name(item.location, game);
|
||||
apItem.playerName = apclient->get_player_alias(item.player);
|
||||
apItem.flags = item.flags;
|
||||
apItem.index = item.index;
|
||||
scouted_items.push_back(apItem);
|
||||
|
||||
const std::string itemName = apItem.itemName;
|
||||
const std::string playerName = apItem.playerName;
|
||||
const std::string locationName = apItem.locationName;
|
||||
SPDLOG_TRACE("Location scouted: {} for {} in location {}", itemName, playerName, locationName);
|
||||
}
|
||||
|
||||
}); // todo maybe move these functions to a lambda, since they don't have to be static anymore
|
||||
apclient->set_location_checked_handler([&](const std::list<int64_t> locations) {
|
||||
// todo implement me
|
||||
});
|
||||
|
||||
save_data();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::start_location_scouts() {
|
||||
std::set<int64_t> missing_loc_set = apclient->get_missing_locations();
|
||||
std::set<int64_t> found_loc_set = apclient->get_checked_locations();
|
||||
std::list<int64_t> location_list;
|
||||
for(const int64_t loc_id : missing_loc_set) {
|
||||
location_list.emplace_back(loc_id);
|
||||
}
|
||||
for(const int64_t loc_id : found_loc_set) {
|
||||
location_list.emplace_back(loc_id);
|
||||
}
|
||||
apclient->LocationScouts(location_list);
|
||||
}
|
||||
|
||||
void ArchipelagoClient::save_data() {
|
||||
CVarSetString(AP_Client_consts::SETTING_ADDRESS, server_address);
|
||||
CVarSetString(AP_Client_consts::SETTING_NAME, slot_name);
|
||||
}
|
||||
|
||||
bool ArchipelagoClient::isConnected() {
|
||||
return apclient->get_state() == APClient::State::SLOT_CONNECTED;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::check_location(RandomizerCheck SoH_check_id) {
|
||||
//std::string_view ap_name = Rando::StaticData::SohCheckToAP[SoH_check_id];
|
||||
std::string ap_name = Rando::StaticData::GetLocation(SoH_check_id)->GetName();
|
||||
if(ap_name.empty()) {
|
||||
return;
|
||||
}
|
||||
int64_t ap_item_id = apclient->get_location_id(std::string(ap_name));
|
||||
SPDLOG_TRACE("Checked: {}({}), sending to AP server", ap_name, ap_item_id);
|
||||
|
||||
// currently not sending, because i only get so many real chances
|
||||
if(!isConnected()) {
|
||||
return;
|
||||
}
|
||||
apclient->LocationChecks({ap_item_id});
|
||||
}
|
||||
|
||||
void ArchipelagoClient::addItemRecievedCallback(std::function<void(const std::string&)> callback) {
|
||||
ItemRecievedCallback = callback;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::removeItemRecievedCallback(std::function<void(const std::string&)> old_callback) {
|
||||
ItemRecievedCallback = nullptr;
|
||||
}
|
||||
|
||||
void ArchipelagoClient::on_connected() {
|
||||
// todo implement me
|
||||
SPDLOG_TRACE("AP Connected!!");
|
||||
}
|
||||
//void ArchipelagoClient::on_couldntConnect(AP_ConnectionStatus connection_status) {
|
||||
// // todo implement me
|
||||
//}
|
||||
|
||||
void ArchipelagoClient::on_item_recieved(int64_t recieved_item_id, bool notify_player) {
|
||||
// call each callback
|
||||
const std::string item_name = apclient->get_item_name(recieved_item_id, AP_Client_consts::AP_GAME_NAME);
|
||||
ArchipelagoClient& ap_client = ArchipelagoClient::getInstance();
|
||||
if(ap_client.ItemRecievedCallback) {
|
||||
SPDLOG_TRACE("item recieved: {}, notify: {}", item_name, notify_player);
|
||||
ap_client.ItemRecievedCallback.operator()(item_name); // somehow passing it through the itemname breaks it????
|
||||
}
|
||||
}
|
||||
|
||||
void ArchipelagoClient::send_game_won() {
|
||||
if(!game_won) {
|
||||
apclient->StatusUpdate(APClient::ClientStatus::GOAL);
|
||||
game_won = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ArchipelagoClient::poll() {
|
||||
if(apclient == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
apclient->poll();
|
||||
}
|
||||
|
||||
const std::string& ArchipelagoClient::get_slot_name() const {
|
||||
if(apclient == NULL) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return apclient->get_slot();
|
||||
}
|
||||
|
||||
char* ArchipelagoClient::get_server_address_buff() {
|
||||
return server_address;
|
||||
}
|
||||
char* ArchipelagoClient::get_slot_name_buff() {
|
||||
return slot_name;
|
||||
}
|
||||
char* ArchipelagoClient::get_password_buff() {
|
||||
return password;
|
||||
}
|
||||
|
||||
const std::map<std::string, int>& ArchipelagoClient::get_slot_data() {
|
||||
return slot_data;
|
||||
}
|
||||
|
||||
const std::vector<ArchipelagoClient::ApItem>& ArchipelagoClient::get_scouted_items() {
|
||||
return scouted_items;
|
||||
}
|
||||
|
||||
@@ -1 +1,97 @@
|
||||
#pragma once
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
#include <vector>
|
||||
|
||||
// Forward declaration
|
||||
class APClient;
|
||||
|
||||
namespace AP_Client_consts {
|
||||
static constexpr int MAX_ADDRESS_LENGTH = 64;
|
||||
static constexpr int MAX_PLAYER_NAME_LENGHT = 17;
|
||||
static constexpr int MAX_PASSWORD_LENGTH = 32;
|
||||
static constexpr char const* DEFAULT_SERVER_NAME = "archipelago.gg:<port number>";
|
||||
|
||||
static constexpr char const* SETTING_ADDRESS = "AP_server_address";
|
||||
static constexpr char const* SETTING_NAME = "AP_slot_name";
|
||||
|
||||
static constexpr char const* AP_GAME_NAME = "Ocarina of Time (SoH)";
|
||||
}
|
||||
|
||||
class ArchipelagoClient{
|
||||
public:
|
||||
struct ApItem {
|
||||
std::string itemName;
|
||||
std::string locationName;
|
||||
std::string playerName;
|
||||
unsigned int flags;
|
||||
int index;
|
||||
};
|
||||
|
||||
static ArchipelagoClient& getInstance();
|
||||
|
||||
bool start_client();
|
||||
bool stop_client();
|
||||
|
||||
void start_location_scouts();
|
||||
|
||||
// getters
|
||||
const std::string& get_slot_name() const;
|
||||
|
||||
char* get_server_address_buff();
|
||||
char* get_slot_name_buff();
|
||||
char* get_password_buff();
|
||||
const std::map<std::string, int>& get_slot_data();
|
||||
const std::vector<ApItem>& get_scouted_items();
|
||||
|
||||
bool isConnected();
|
||||
void check_location(RandomizerCheck SoH_check_id);
|
||||
|
||||
// callback slots
|
||||
void addItemRecievedCallback(std::function<void(const std::string&)> callback);
|
||||
void removeItemRecievedCallback(std::function<void(const std::string&)> old_callback);
|
||||
|
||||
|
||||
// todo move me back down when done testing
|
||||
void on_item_recieved(int64_t recieved_item_id, bool notify_player);
|
||||
|
||||
void send_game_won();
|
||||
|
||||
void poll();
|
||||
|
||||
std::unique_ptr<APClient> apclient;
|
||||
|
||||
protected:
|
||||
ArchipelagoClient();
|
||||
|
||||
private:
|
||||
ArchipelagoClient(ArchipelagoClient &) = delete;
|
||||
void operator=(const ArchipelagoClient &) = delete;
|
||||
std::string uuid;
|
||||
|
||||
static std::shared_ptr<ArchipelagoClient> instance; // is this even used?
|
||||
static bool initialized;
|
||||
|
||||
char server_address[AP_Client_consts::MAX_ADDRESS_LENGTH];
|
||||
char slot_name[AP_Client_consts::MAX_PLAYER_NAME_LENGHT];
|
||||
char password[AP_Client_consts::MAX_PLAYER_NAME_LENGHT];
|
||||
|
||||
bool game_won;
|
||||
|
||||
std::map<std::string, int> slot_data;
|
||||
std::set<int64_t> locations;
|
||||
std::vector<ApItem> scouted_items;
|
||||
|
||||
void save_data();
|
||||
|
||||
// callback functions
|
||||
void on_connected();
|
||||
|
||||
void on_location_checked(int64_t location_id);
|
||||
void on_deathlink_recieved() { }; // TODO: implement me
|
||||
|
||||
// callbacks
|
||||
std::function<void(const std::string&)> ItemRecievedCallback;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
|
||||
constexpr std::pair<std::string_view, RandomizerGet> ap_item_mapping_pairs[] = {
|
||||
{ "Bombs (5)", RG_BOMBS_5 },
|
||||
66
soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.cpp
Normal file
66
soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "ArchipelagoSettingsWindow.h"
|
||||
#include "Archipelago.h"
|
||||
|
||||
#include <apclient.hpp>
|
||||
#include "soh/SohGui/UIWidgets.hpp"
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
|
||||
void ArchipelagoSettingsWindow::DrawElement() {
|
||||
ArchipelagoClient& AP_client = ArchipelagoClient::getInstance();
|
||||
ImGui::SeparatorText("Connection info");
|
||||
ImGui::InputText("Server Address", AP_client.get_server_address_buff(), AP_Client_consts::MAX_ADDRESS_LENGTH);
|
||||
ImGui::InputText("Slot Name", AP_client.get_slot_name_buff(), AP_Client_consts::MAX_PLAYER_NAME_LENGHT);
|
||||
ImGui::InputText("Password (leave blank for no password)", AP_client.get_password_buff(),
|
||||
AP_Client_consts::MAX_PASSWORD_LENGTH, ImGuiInputTextFlags_Password);
|
||||
|
||||
static char connected_text[25] = "Disconnected";
|
||||
if (ImGui::Button("Connect")) {
|
||||
bool success = AP_client.start_client();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(connected_text);
|
||||
|
||||
APClient::State con_state = APClient::State::DISCONNECTED;
|
||||
|
||||
if (AP_client.apclient) {
|
||||
con_state = AP_client.apclient->get_state();
|
||||
}
|
||||
|
||||
switch (con_state) {
|
||||
case APClient::State::DISCONNECTED: {
|
||||
strncpy(connected_text, "Disconnected!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::SOCKET_CONNECTING: {
|
||||
strncpy(connected_text, "Socket Connecting!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::SOCKET_CONNECTED: {
|
||||
strncpy(connected_text, "Socket Connected!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::ROOM_INFO: {
|
||||
strncpy(connected_text, "Room info Recieved!", 25);
|
||||
break;
|
||||
}
|
||||
case APClient::State::SLOT_CONNECTED: {
|
||||
strncpy(connected_text, "Slot Connected!", 25);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (ImGui::Button("scout")) {
|
||||
AP_client.start_location_scouts();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("link up")) {
|
||||
CVarSetInteger("archipelago_connected", 1);
|
||||
}
|
||||
|
||||
UIWidgets::PaddedSeparator();
|
||||
|
||||
if(ImGui::Button("give blue ruppie")) {
|
||||
ArchipelagoClient::getInstance().on_item_recieved(66077, true);
|
||||
}
|
||||
};
|
||||
20
soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.h
Normal file
20
soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#ifndef ARCHIPELAGO_SETTINGS_WINDOW_H
|
||||
#define ARCHIPELAGO_SETTINGS_WINDOW_H
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
class ArchipelagoClient;
|
||||
|
||||
class ArchipelagoSettingsWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
~ArchipelagoSettingsWindow() {};
|
||||
|
||||
protected:
|
||||
void InitElement() override {};
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override {};
|
||||
};
|
||||
|
||||
#endif // ARCHIPELAGO_SETTINGS_WINDOW_H
|
||||
@@ -27,13 +27,13 @@
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/Presets/Presets.h"
|
||||
#include "soh/resource/type/Skeleton.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
#include "soh/Enhancements/debugger/MessageViewer.h"
|
||||
#include "soh/Notification/Notification.h"
|
||||
#include "soh/Enhancements/TimeDisplay/TimeDisplay.h"
|
||||
#include "soh/Network/Archipelago/ArchipelagoSettingsWindow.h"
|
||||
|
||||
namespace SohGui {
|
||||
|
||||
@@ -94,7 +94,7 @@ std::shared_ptr<ItemTrackerSettingsWindow> mItemTrackerSettingsWindow;
|
||||
std::shared_ptr<ItemTrackerWindow> mItemTrackerWindow;
|
||||
std::shared_ptr<TimeSplitWindow> mTimeSplitWindow;
|
||||
std::shared_ptr<PlandomizerWindow> mPlandomizerWindow;
|
||||
std::shared_ptr<ArchipelagoWindow> mArchipelagoWindow;
|
||||
std::shared_ptr<ArchipelagoSettingsWindow> mArchipelagoSettingsWindow;
|
||||
std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
|
||||
std::shared_ptr<SohModalWindow> mModalWindow;
|
||||
std::shared_ptr<Notification::Window> mNotificationWindow;
|
||||
@@ -196,9 +196,9 @@ void SetupGuiElements() {
|
||||
mPlandomizerWindow =
|
||||
std::make_shared<PlandomizerWindow>(CVAR_WINDOW("PlandomizerEditor"), "Plandomizer Editor", ImVec2(850, 760));
|
||||
gui->AddGuiWindow(mPlandomizerWindow);
|
||||
mArchipelagoWindow =
|
||||
std::make_shared<ArchipelagoWindow>(CVAR_WINDOW("ArchipelagoWindow"), "Archipelago", ImVec2(850, 760));
|
||||
gui->AddGuiWindow(mArchipelagoWindow);
|
||||
mArchipelagoSettingsWindow =
|
||||
std::make_shared<ArchipelagoSettingsWindow>(CVAR_WINDOW("ArchipelagoSettingsWindow"), "Archipelago", ImVec2(850, 760));
|
||||
gui->AddGuiWindow(mArchipelagoSettingsWindow);
|
||||
mModalWindow = std::make_shared<SohModalWindow>(CVAR_WINDOW("ModalWindow"), "Modal Window");
|
||||
gui->AddGuiWindow(mModalWindow);
|
||||
mModalWindow->Show();
|
||||
@@ -241,7 +241,7 @@ void Destroy() {
|
||||
mInputViewerSettings = nullptr;
|
||||
mTimeSplitWindow = nullptr;
|
||||
mPlandomizerWindow = nullptr;
|
||||
mArchipelagoWindow = nullptr;
|
||||
mArchipelagoSettingsWindow = nullptr;
|
||||
mTimeDisplayWindow = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "soh/Enhancements/randomizer/randomizer_settings_window.h"
|
||||
#include "soh/Enhancements/timesplits/TimeSplits.h"
|
||||
#include "soh/Enhancements/randomizer/Plandomizer.h"
|
||||
#include "soh/Enhancements/randomizer/archipelago.h"
|
||||
#include "soh/Network/Archipelago/Archipelago.h"
|
||||
#include "SohModals.h"
|
||||
|
||||
namespace SohGui {
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "soh/Enhancements/enemyrandomizer.h"
|
||||
#include "soh/Enhancements/timesplits/TimeSplits.h"
|
||||
#include "soh/Enhancements/randomizer/Plandomizer.h"
|
||||
#include "soh/Enhancements/randomizer/archipelago.h"
|
||||
#include "soh/Enhancements/TimeDisplay/TimeDisplay.h"
|
||||
|
||||
// FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but
|
||||
|
||||
@@ -103,11 +103,11 @@ void SohMenu::AddMenuRandomizer() {
|
||||
// Archipelago
|
||||
path.sidebarName = "Archipelago";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
AddWidget(path, "Popout Archipelago Development Window", WIDGET_WINDOW_BUTTON)
|
||||
.CVar(CVAR_WINDOW("ArchipelagoWindow"))
|
||||
AddWidget(path, "Popout Archipelago Settings Window", WIDGET_WINDOW_BUTTON)
|
||||
.CVar(CVAR_WINDOW("ArchipelagoSettingsWindow"))
|
||||
.RaceDisable(false)
|
||||
.WindowName("Archipelago")
|
||||
.Options(WindowButtonOptions().Tooltip("Enables the Archipelago development Window."));
|
||||
.WindowName("Archipelago Settings")
|
||||
.Options(WindowButtonOptions().Tooltip("Enables the Archipelago Settings Window."));
|
||||
|
||||
// Item Tracker
|
||||
path.sidebarName = "Item Tracker";
|
||||
|
||||
Reference in New Issue
Block a user