Skip to content

Commit

Permalink
More graceful handling of challenge / autohost config failures
Browse files Browse the repository at this point in the history
  • Loading branch information
past-due committed Jul 5, 2024
1 parent 21d2f04 commit 61deca4
Showing 1 changed file with 49 additions and 27 deletions.
76 changes: 49 additions & 27 deletions src/multiint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5667,7 +5667,7 @@ static void updateMapWidgets(LEVEL_DATASET *mapData)
widgSetString(psWScreen, MULTIOP_MAP + 1, name.toUtf8().c_str()); //What a horrible, horrible way to do this! FIX ME! (See addBlueForm)
}

static void loadMapChallengeSettings(WzConfig& ini)
static bool loadMapChallengeSettings(WzConfig& ini)
{
ini.beginGroup("locked"); // GUI lockdown
{
Expand All @@ -5687,19 +5687,23 @@ static void loadMapChallengeSettings(WzConfig& ini)
{
ini.beginGroup("challenge");
{
sstrcpy(game.map, ini.value("map", game.map).toWzString().toUtf8().c_str());
game.hash = levGetMapNameHash(game.map);
char mapName[256] = {0};
sstrcpy(mapName, ini.value("map", game.map).toWzString().toUtf8().c_str());
Sha256 mapHash = levGetMapNameHash(mapName);

LEVEL_DATASET* mapData = levFindDataSet(game.map, &game.hash);
LEVEL_DATASET* mapData = levFindDataSet(mapName, &mapHash);
if (!mapData)
{
code_part log_level = (bIsAutoHostOrAutoGame) ? LOG_ERROR : LOG_FATAL;
debug(log_level, "Map %s not found!", game.map);
if (bIsAutoHostOrAutoGame)
debug(log_level, "Map %s not found!", mapName);
if (bIsAutoHostOrAutoGame && headlessGameMode())
{
wzQuit(1);
}
return false;
}
sstrcpy(game.map, mapName);
game.hash = mapHash;
game.maxPlayers = mapData->players;

uint8_t configuredMaxPlayers = ini.value("maxPlayers", game.maxPlayers).toUInt();
Expand Down Expand Up @@ -5746,6 +5750,8 @@ static void loadMapChallengeSettings(WzConfig& ini)
}
ini.endGroup();
}

return true;
}


Expand Down Expand Up @@ -5961,13 +5967,13 @@ static void resetPlayerConfiguration(const bool bShouldResetLocal = false)
/**
* Loads challenge and player configurations from level/autohost/test .json-files.
*/
static void loadMapChallengeAndPlayerSettings(bool forceLoadPlayers = false)
static bool loadMapChallengeAndPlayerSettings(bool forceLoadPlayers = false)
{
char aFileName[256];
LEVEL_DATASET* psLevel = levFindDataSet(game.map, &game.hash);

ASSERT_OR_RETURN(, psLevel, "No level found for %s", game.map);
ASSERT_OR_RETURN(, psLevel->game >= 0 && psLevel->game < LEVEL_MAXFILES, "Invalid psLevel->game: %" PRIi16 " - may be a corrupt level load (%s; hash: %s)", psLevel->game, game.map, game.hash.toString().c_str());
ASSERT_OR_RETURN(false, psLevel, "No level found for %s", game.map);
ASSERT_OR_RETURN(false, psLevel->game >= 0 && psLevel->game < LEVEL_MAXFILES, "Invalid psLevel->game: %" PRIi16 " - may be a corrupt level load (%s; hash: %s)", psLevel->game, game.map, game.hash.toString().c_str());
sstrcpy(aFileName, psLevel->apDataFiles[psLevel->game].c_str());
aFileName[std::max<size_t>(strlen(aFileName), 4) - 4] = '\0';
sstrcat(aFileName, ".json");
Expand Down Expand Up @@ -5998,17 +6004,19 @@ static void loadMapChallengeAndPlayerSettings(bool forceLoadPlayers = false)
resetPlayerConfiguration();
}

return;
return !warnIfMissing; // not treated as fatal failure unless warnIfMissing
}
WzConfig ini(ininame, WzConfig::ReadOnly);

loadMapChallengeSettings(ini);
bool retVal = loadMapChallengeSettings(ini);

/* Do not load player settings if we are already hosting an online match */
if (!bIsOnline || forceLoadPlayers)
{
loadMapPlayerSettings(ini);
}

return retVal;
}

static void randomizeLimit(const char *name)
Expand Down Expand Up @@ -7655,6 +7663,21 @@ void WzMultiplayerOptionsTitleUI::start()
/* Entering the first time */
if (!bReenter)
{
// Initialize the inline chooser overlay screen
psInlineChooserOverlayScreen = W_SCREEN::make();
auto newRootFrm = W_FULLSCREENOVERLAY_CLICKFORM::make(MULTIOP_INLINE_OVERLAY_ROOT_FRM);
std::weak_ptr<WzMultiplayerOptionsTitleUI> psWeakTitleUI = std::dynamic_pointer_cast<WzMultiplayerOptionsTitleUI>(shared_from_this());
newRootFrm->onClickedFunc = [psWeakTitleUI]() {
widgScheduleTask([psWeakTitleUI]{
auto psTitleUI = psWeakTitleUI.lock();
ASSERT_OR_RETURN(, psTitleUI != nullptr, "Title UI is null");
psTitleUI->closeAllChoosers(); // this also removes the overlay screen
psTitleUI->updatePlayers();
});
};
newRootFrm->onCancelPressed = newRootFrm->onClickedFunc;
psInlineChooserOverlayScreen->psForm->attach(newRootFrm);

currentMultiOptionsTitleUI = std::dynamic_pointer_cast<WzMultiplayerOptionsTitleUI>(shared_from_this());
playerDisplayView = PlayerDisplayView::Players;
bRequestedSelfMoveToPlayers = false;
Expand All @@ -7665,7 +7688,21 @@ void WzMultiplayerOptionsTitleUI::start()
memset(&locked, 0, sizeof(locked));
spectatorHost = false;
defaultOpenSpectatorSlots = war_getMPopenSpectatorSlots();
loadMapChallengeAndPlayerSettings(true);
if (!loadMapChallengeAndPlayerSettings(true))
{
if (challengeActive)
{
changeTitleUI(std::make_shared<WzMsgBoxTitleUI>(WzString(_("Failed to load challenge:")), WzString(_("Failed to load the challenge's map or config")), parent));
return;
}
if (getHostLaunch() == HostLaunch::Autohost)
{
changeTitleUI(std::make_shared<WzMsgBoxTitleUI>(WzString(_("Failed to process autohost config:")), WzString::fromUtf8(astringf(_("Failed to load the autohost map or config from: %s"), wz_skirmish_test().c_str())), parent));
setHostLaunch(HostLaunch::Normal); // Don't load the autohost file on subsequent hosts
return;
}
// otherwise, treat as non-fatal...
}
game.isMapMod = false;
game.isRandom = false;
game.mapHasScavengers = true; // FIXME, should default to false
Expand All @@ -7681,21 +7718,6 @@ void WzMultiplayerOptionsTitleUI::start()
return hasPrefix;
});

// Initialize the inline chooser overlay screen
psInlineChooserOverlayScreen = W_SCREEN::make();
auto newRootFrm = W_FULLSCREENOVERLAY_CLICKFORM::make(MULTIOP_INLINE_OVERLAY_ROOT_FRM);
std::weak_ptr<WzMultiplayerOptionsTitleUI> psWeakTitleUI = std::dynamic_pointer_cast<WzMultiplayerOptionsTitleUI>(shared_from_this());
newRootFrm->onClickedFunc = [psWeakTitleUI]() {
widgScheduleTask([psWeakTitleUI]{
auto psTitleUI = psWeakTitleUI.lock();
ASSERT_OR_RETURN(, psTitleUI != nullptr, "Title UI is null");
psTitleUI->closeAllChoosers(); // this also removes the overlay screen
psTitleUI->updatePlayers();
});
};
newRootFrm->onCancelPressed = newRootFrm->onClickedFunc;
psInlineChooserOverlayScreen->psForm->attach(newRootFrm);

ingame.localOptionsReceived = false;

PLAYERSTATS playerStats;
Expand Down

0 comments on commit 61deca4

Please sign in to comment.