Added connection status to archi file select

This commit is contained in:
Jerom Venneker
2025-07-15 19:07:19 +02:00
parent e272300245
commit 9fbf67fc94
10 changed files with 130 additions and 9 deletions

View File

@@ -178,6 +178,7 @@ typedef struct ShipArchipelagoSaveContextData {
u32 lastReceivedItemIndex;
char roomHash[100];
char slotName[17];
char archiUri[50];
ArchipelagoLocationData locations[RC_MAX];
} ShipArchipelagoSaveContextData;

View File

@@ -111,6 +111,24 @@ std::array<std::string, LANGUAGE_MAX> ArchipelagoSettingsMenuText[ASM_MAX]{
"Todo",
"Todo",
},
//ASM_CHAR_START_TO_CONNECT
{
"Start to automatically connect to this slot",
"Todo",
"Todo",
},
//ASM_CHAR_SELECT_CONNECTED_TO_OTHER_SLOT
{
"Connected to a different slot",
"Todo",
"Todo",
},
// ASM_CHAR_SELECT_CHANGE_CONNECTION_INFO
{
"Z-Connection Settings",
"Z-Todo",
"Z-Todo",
}
};
const char* SohFileSelect_GetRandomizerSettingText(uint8_t optionIndex, uint8_t language) {

View File

@@ -30,6 +30,9 @@ typedef enum {
ASM_CONNECTING,
ASM_CONNECTED,
ASM_STATUS,
ASM_CHAR_START_TO_CONNECT,
ASM_CHAR_SELECT_CONNECTED_TO_OTHER_SLOT,
ASM_CHAR_SELECT_CHANGE_CONNECTION_INFO,
ASM_MAX
} ArchipelagoSettingsMenuEnums;

View File

@@ -45,9 +45,10 @@ bool ArchipelagoClient::StartClient() {
disconnecting = false;
retries = 0;
uri = CVarGetString(CVAR_REMOTE_ARCHIPELAGO("ServerAddress"), "localhost:38281");
apClient = std::unique_ptr<APClient>(
new APClient(uuid, AP_Client_consts::AP_GAME_NAME,
CVarGetString(CVAR_REMOTE_ARCHIPELAGO("ServerAddress"), "localhost:38281"), "cacert.pem"));
uri, "cacert.pem"));
CVarSetInteger(CVAR_REMOTE_ARCHIPELAGO("ConnectionStatus"), 1); // Connecting
@@ -424,6 +425,23 @@ void ArchipelagoClient::Poll() {
apClient->poll();
}
bool ArchipelagoClient::slotMatch(const std::string& slotName, const std::string& roomHash) {
if (apClient == nullptr) {
return false;
}
if(disconnecting) {
return false;
}
const std::string seed = apClient->get_seed();
const std::string slot = GetSlotName();
const bool seedMatch = apClient->get_seed().compare(roomHash) == 0;
const bool slotMatch = GetSlotName().compare(slotName) == 0;
return seedMatch && slotMatch;
}
bool ArchipelagoClient::isRightSaveLoaded() const {
const bool seedMatch = apClient->get_seed().compare(gSaveContext.ship.quest.data.archipelago.roomHash) == 0;
const bool slotMatch = GetSlotName().compare(gSaveContext.ship.quest.data.archipelago.slotName) == 0;
@@ -524,6 +542,8 @@ extern "C" void Archipelago_InitSaveFile() {
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.roomHash));
SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.slotName, client.apClient->get_slot(),
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.slotName));
SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.archiUri, client.uri,
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.archiUri));
for (uint32_t i = 0; i < scoutedItems.size(); i++) {
RandomizerCheck rc = Rando::StaticData::locationNameToEnum[scoutedItems[i].locationName];
@@ -546,6 +566,8 @@ void LoadArchipelagoData() {
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.roomHash));
SaveManager::Instance->LoadCharArray("slotName", gSaveContext.ship.quest.data.archipelago.slotName,
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.slotName));
SaveManager::Instance->LoadCharArray("archiUri", gSaveContext.ship.quest.data.archipelago.archiUri,
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.archiUri));
SaveManager::Instance->LoadArray(
"locations", ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations), [](size_t i) {
@@ -567,6 +589,7 @@ void SaveArchipelagoData(SaveContext* saveContext, int sectionID, bool fullSave)
SaveManager::Instance->SaveData("roomHash", saveContext->ship.quest.data.archipelago.roomHash);
SaveManager::Instance->SaveData("slotName", saveContext->ship.quest.data.archipelago.slotName);
SaveManager::Instance->SaveData("archiUri", saveContext->ship.quest.data.archipelago.archiUri);
SaveManager::Instance->SaveArray(
"locations", ARRAY_COUNT(saveContext->ship.quest.data.archipelago.locations), [&](size_t i) {
@@ -587,6 +610,8 @@ void InitArchipelagoData(bool isDebug) {
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.roomHash));
SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.slotName, "",
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.slotName));
SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.archiUri, "",
ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.archiUri));
for (uint32_t i = 0; i < ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations); i++) {
SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.locations[i].itemName, "",

View File

@@ -62,11 +62,14 @@ class ArchipelagoClient {
void SendMessageToConsole(const std::string message);
void Poll();
bool slotMatch(const std::string& slotName, const std::string& roomHash);
std::unique_ptr<APClient> apClient;
bool itemQueued;
bool disconnecting;
bool isDeathLinkedDeath;
int retries;
std::string uri;
protected:
ArchipelagoClient();

View File

@@ -2728,6 +2728,12 @@ extern "C" void ParseArchipelago() {
OTRGlobals::Instance->gRandoContext->ParseArchipelago();
}
extern "C" bool checkArchipelagoSlotInfo(const char* slotName, const char* roomHash) {
const std::string slot = std::string(slotName);
const std::string room = std::string(roomHash);
return ArchipelagoClient::GetInstance().slotMatch(slot, room);
}
extern "C" void CheckTracker_RecalculateAvailableChecks() {
CheckTracker::RecalculateAvailableChecks();
}

View File

@@ -173,6 +173,7 @@ void CheckTracker_RecalculateAvailableChecks();
GetItemID RetrieveGetItemIDFromItemID(ItemID itemID);
RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID);
void ParseArchipelago();
bool checkArchipelagoSlotInfo(const char* slotName, const char* roomHash);
void Messagebox_ShowErrorBox(char* title, char* body);
#endif

View File

@@ -154,6 +154,9 @@ SaveManager::SaveManager() {
info.buildVersionMinor = 0;
info.buildVersionPatch = 0;
memset(&info.buildVersion, 0, sizeof(info.buildVersion));
memset(&info.archiUri, 0, sizeof(info.archiUri));
memset(&info.slotName, 0, sizeof(info.slotName));
}
}
@@ -509,6 +512,13 @@ void SaveManager::InitMeta(int fileNum) {
fileMetaInfo[fileNum].buildVersionPatch = gSaveContext.ship.stats.buildVersionPatch;
SohUtils::CopyStringToCharArray(fileMetaInfo[fileNum].buildVersion, gSaveContext.ship.stats.buildVersion,
ARRAY_COUNT(fileMetaInfo[fileNum].buildVersion));
SohUtils::CopyStringToCharArray(fileMetaInfo[fileNum].archiUri, gSaveContext.ship.quest.data.archipelago.archiUri,
ARRAY_COUNT(fileMetaInfo[fileNum].archiUri));
SohUtils::CopyStringToCharArray(fileMetaInfo[fileNum].slotName, gSaveContext.ship.quest.data.archipelago.slotName,
ARRAY_COUNT(fileMetaInfo[fileNum].slotName));
SohUtils::CopyStringToCharArray(fileMetaInfo[fileNum].archiRoomSeed, gSaveContext.ship.quest.data.archipelago.roomHash,
ARRAY_COUNT(fileMetaInfo[fileNum].archiRoomSeed));
}
void SaveManager::InitFile(bool isDebug) {

View File

@@ -33,6 +33,10 @@ typedef struct {
s32 filenameLanguage;
s32 gregFound;
s32 hasWallet;
char archiRoomSeed[100];
char slotName[17];
char archiUri[50];
} SaveFileMetaInfo;
typedef enum {

View File

@@ -2478,7 +2478,8 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
&deathCountSplit[2]);
// draw death count
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) == 0 || this->menuMode != FS_MENU_MODE_SELECT) {
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) == 0 || this->menuMode != FS_MENU_MODE_SELECT ||
Save_GetSaveMetaInfo(this->selectedFileIndex)->archiSave) {
for (i = 0, vtxOffset = 0; i < 3; i++, vtxOffset += 4) {
FileChoose_DrawCharacter(this->state.gfxCtx, sp54->fontBuf + deathCountSplit[i] * FONT_CHAR_TEX_SIZE,
vtxOffset);
@@ -2504,7 +2505,8 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
i = Save_GetSaveMetaInfo(fileIndex)->healthCapacity / 0x10;
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) == 0 || this->menuMode != FS_MENU_MODE_SELECT) {
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) == 0 || this->menuMode != FS_MENU_MODE_SELECT ||
Save_GetSaveMetaInfo(this->selectedFileIndex)->archiSave) {
// draw hearts
for (vtxOffset = 0, j = 0; j < i; j++, vtxOffset += 4) {
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex] + vtxOffset] + 0x30, 4, 0);
@@ -2521,7 +2523,8 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
textAlpha = 255;
}
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) != 0 && this->menuMode == FS_MENU_MODE_SELECT) {
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) != 0 && this->menuMode == FS_MENU_MODE_SELECT &&
Save_GetSaveMetaInfo(this->selectedFileIndex)->archiSave == 0) {
DrawMoreInfo(this, fileIndex, textAlpha);
} else {
// draw quest items
@@ -2545,6 +2548,53 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
}
}
}
if(Save_GetSaveMetaInfo(this->selectedFileIndex)->archiSave) {
uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language;
// Connection status text
int statusPos = 61 + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_STATUS, language),
58, 133, 200, 200, 200, textAlpha, 0.8f, true);
const bool connectedToThisSlot = checkArchipelagoSlotInfo(Save_GetSaveMetaInfo(this->selectedFileIndex)->slotName,
Save_GetSaveMetaInfo(this->selectedFileIndex)->archiRoomSeed);
switch(CVarGetInteger(CVAR_REMOTE_ARCHIPELAGO("ConnectionStatus"), 0)) {
case 0: // Not Connected
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_NOT_CONNECTED, language),
statusPos, 133, 255, 120, 120, textAlpha, 0.8f, true);
break;
case 1: // Connecting
case 2: // Connection error, retrying
case 3: // Connected
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTING, language),
statusPos, 133, 185, 185, 185, textAlpha, 0.8f, true);
break;
case 4: // Connected + Locations Scouted
if(connectedToThisSlot) {
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTED, language),
statusPos, 133, 120, 255, 120, textAlpha, 0.8f, true);
} else {
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_CHAR_SELECT_CONNECTED_TO_OTHER_SLOT, language),
statusPos, 133, 255, 255, 120, textAlpha, 0.8f, true);
}
break;
}
if(!connectedToThisSlot) {
Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_CHAR_START_TO_CONNECT, language),
58, 144, 200, 200, 200, textAlpha, 0.8f, true);
}
//Interface_DrawTextLine(this->state.gfxCtx,
// SohFileSelect_GetArchipelagoSettingText(ASM_CHAR_SELECT_CHANGE_CONNECTION_INFO, language), 95, 220,
// 100, 250, 255, textAlpha, 1.0f, true);
}
}
CLOSE_DISPS(this->state.gfxCtx);
@@ -2944,25 +2994,25 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
155, 185, 185, 185, textAlpha, 0.8f, true);
// Connection status text
Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_STATUS, language), 70,
int statusPos = 75 + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_STATUS, language), 70,
175, 255, 255, 255, textAlpha, 0.8f, true);
switch (CVarGetInteger(CVAR_REMOTE_ARCHIPELAGO("ConnectionStatus"), 0)) {
case 0: // Not Connected
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_NOT_CONNECTED, language), 110, 175,
SohFileSelect_GetArchipelagoSettingText(ASM_NOT_CONNECTED, language), statusPos, 175,
255, 120, 120, textAlpha, 0.8f, true);
break;
case 1: // Connecting
case 2: // Connection error, retrying
case 3: // Connected
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTING, language), 110, 175, 185,
SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTING, language), statusPos, 175, 185,
185, 185, textAlpha, 0.8f, true);
break;
case 4: // Connected + Locations Scouted
Interface_DrawTextLine(this->state.gfxCtx,
SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTED, language), 110, 175, 120,
SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTED, language), statusPos, 175, 120,
255, 120, textAlpha, 0.8f, true);
break;
}
@@ -3005,7 +3055,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
// Draw the small file name box instead when more meta info is enabled
if (CVarGetInteger(CVAR_ENHANCEMENT("FileSelectMoreInfo"), 0) != 0 &&
this->menuMode == FS_MENU_MODE_SELECT) {
this->menuMode == FS_MENU_MODE_SELECT && Save_GetSaveMetaInfo(this->selectedFileIndex)->archiSave == 0) {
// Location of file 1 small name box vertices
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[68], 4, 0);