From a9056c20d1fb7209bc3a57d0044da4dfd6beb3b6 Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Tue, 15 Jul 2014 13:28:06 -0600 Subject: [PATCH] Changed NoteSkinManager to use new error reporting and avoid crashing. Fixed DoChangeTheme to switch to the InitialScreen if the screen doesn't exist in the theme being changed to. Fixed error reporting in MeterDisplay. --- src/DifficultyList.cpp | 6 +++- src/GameLoop.cpp | 7 ++++ src/GameState.cpp | 2 +- src/MeterDisplay.cpp | 6 ++-- src/NoteSkinManager.cpp | 80 ++++++++++++++++++++++++++++------------- src/ScreenManager.cpp | 5 +++ 6 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/DifficultyList.cpp b/src/DifficultyList.cpp index d24d44ad5e..d24fadd9f4 100644 --- a/src/DifficultyList.cpp +++ b/src/DifficultyList.cpp @@ -37,7 +37,11 @@ void StepsDisplayList::LoadFromNode( const XNode* pNode ) { ActorFrame::LoadFromNode( pNode ); - ASSERT_M( !m_sName.empty(), "StepsDisplayList must have a Name" ); + if(m_sName.empty()) + { + LuaHelpers::ReportScriptError("StepsDisplayList must have a Name"); + return; + } ITEMS_SPACING_Y.Load( m_sName, "ItemsSpacingY" ); NUM_SHOWN_ITEMS.Load( m_sName, "NumShownItems" ); diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp index d30cba98da..74ccdb0d6a 100644 --- a/src/GameLoop.cpp +++ b/src/GameLoop.cpp @@ -145,6 +145,13 @@ namespace StepMania::ResetGame(); SCREENMAN->ThemeChanged(); + // Not all themes use the same screen names! Check whether the new + // screen is valid in the new theme before setting it. Use the + // InitialScreen metric if it's not. + if(!SCREENMAN->IsScreenNameValid(g_sNewScreen)) + { + g_sNewScreen= THEME->GetMetric("Common", "InitialScreen"); + } SCREENMAN->SetNewScreen( g_sNewScreen ); g_sNewTheme = RString(); diff --git a/src/GameState.cpp b/src/GameState.cpp index 0436e65a43..67a3135d87 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -223,7 +223,7 @@ void GameState::ApplyGameCommand( const RString &sCommand, PlayerNumber pn ) RString sWhy; if( !m.IsPlayable(&sWhy) ) { - LuaHelpers::ReportScriptErrorFmt("Can't apply mode \"%s\": %s", sCommand.c_str(), sWhy.c_str()); + LuaHelpers::ReportScriptErrorFmt("Can't apply GameCommand \"%s\": %s", sCommand.c_str(), sWhy.c_str()); return; } diff --git a/src/MeterDisplay.cpp b/src/MeterDisplay.cpp index 389b5311ce..9fa6e19c4c 100644 --- a/src/MeterDisplay.cpp +++ b/src/MeterDisplay.cpp @@ -35,11 +35,9 @@ void MeterDisplay::LoadFromNode( const XNode* pNode ) if( pStream == NULL ) { LuaHelpers::ReportScriptErrorFmt("%s: MeterDisplay: missing the \"Stream\" attribute", ActorUtil::GetWhere(pNode).c_str()); + return; } - else - { - m_sprStream.LoadActorFromNode( pStream, this ); - } + m_sprStream.LoadActorFromNode( pStream, this ); m_sprStream->SetName( "Stream" ); //LOAD_ALL_COMMANDS( m_sprStream ); this->AddChild( m_sprStream ); diff --git a/src/NoteSkinManager.cpp b/src/NoteSkinManager.cpp index fa4b5415bc..0ca23377a6 100644 --- a/src/NoteSkinManager.cpp +++ b/src/NoteSkinManager.cpp @@ -112,7 +112,11 @@ void NoteSkinManager::LoadNoteSkinDataRecursive( const RString &sNoteSkinName_, while(1) { ++iDepth; - ASSERT_M( iDepth < 20, "Circular NoteSkin fallback references detected." ); + if(iDepth >= 20) + { + LuaHelpers::ReportScriptError("Circular NoteSkin fallback references detected.", "NOTESKIN_ERROR"); + return; + } RString sDir = SpecialFiles::NOTESKINS_DIR + m_pCurGame->m_szName + "/" + sNoteSkinName + "/"; if( !FILEMAN->IsADirectory(sDir) ) @@ -120,8 +124,9 @@ void NoteSkinManager::LoadNoteSkinDataRecursive( const RString &sNoteSkinName_, sDir = GLOBAL_BASE_DIR + sNoteSkinName + "/"; if( !FILEMAN->IsADirectory(sDir) ) { - LOG->Trace( "NoteSkin \"%s\" references skin \"%s\" that is not present", - data_out.sName.c_str(), sNoteSkinName.c_str() ); + LuaHelpers::ReportScriptError("NoteSkin \"" + data_out.sName + + "\" references skin \"" + sNoteSkinName + "\" that is not present", + "NOTESKIN_ERROR"); return; } } @@ -234,7 +239,11 @@ void NoteSkinManager::GetAllNoteSkinNamesForGame( const Game *pGame, vector::const_iterator it = g_mapNameToData.find(sNoteSkinName); @@ -245,8 +254,12 @@ RString NoteSkinManager::GetMetric( const RString &sButtonName, const RString &s if( data.metrics.GetValue( sButtonName, sValue, sReturn ) ) return sReturn; if( !data.metrics.GetValue( "NoteDisplay", sValue, sReturn ) ) - RageException::Throw( "Could not read metric \"%s::%s\" or \"NoteDisplay::%s\" in \"%s\".", - sButtonName.c_str(), sValue.c_str(), sValue.c_str(), sNoteSkinName.c_str() ); + { + LuaHelpers::ReportScriptError("Could not read metric \"" + sButtonName + + "::" + sValue + "\" or \"NoteDisplay::" + sValue + "\" in \"" + + sNoteSkinName + "\".", "NOTESKIN_ERROR"); + return ""; + } return sReturn; } @@ -320,15 +333,18 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl sButtonName.c_str(), sElement.c_str(), sPaths.c_str() ); - if( Dialog::AbortRetryIgnore(message) == Dialog::retry ) + switch(LuaHelpers::ReportScriptError(message, "NOTESKIN_ERROR", true)) { - FOREACH_CONST( RString, data.vsDirSearchOrder, dir ) - FILEMAN->FlushDirCache( *dir ); - g_PathCache.clear(); - return GetPath( sButtonName, sElement ); + case Dialog::retry: + FOREACH_CONST(RString, data.vsDirSearchOrder, dir) + FILEMAN->FlushDirCache(*dir); + g_PathCache.clear(); + return GetPath(sButtonName, sElement); + case Dialog::abort: + RageException::Throw("%s", message.c_str()); + case Dialog::ignore: + return ""; } - - RageException::Throw( "%s", message.c_str() ); } int iLevel = 0; @@ -355,15 +371,18 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl "Verify that this redirect is correct.", sPath.c_str(), sNewFileName.c_str()); - if( Dialog::AbortRetryIgnore(message) == Dialog::retry ) + switch(LuaHelpers::ReportScriptError(message, "NOTESKIN_ERROR", true)) { - FOREACH_CONST( RString, data.vsDirSearchOrder, dir ) - FILEMAN->FlushDirCache( *dir ); - g_PathCache.clear(); - return GetPath( sButtonName, sElement ); + case Dialog::retry: + FOREACH_CONST(RString, data.vsDirSearchOrder, dir) + FILEMAN->FlushDirCache(*dir); + g_PathCache.clear(); + return GetPath(sButtonName, sElement); + case Dialog::abort: + RageException::Throw("%s", message.c_str()); + case Dialog::ignore: + return ""; } - - RageException::Throw( "%s", message.c_str() ); } sPath = sRealPath; @@ -376,7 +395,11 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl bool NoteSkinManager::PushActorTemplate( Lua *L, const RString &sButton, const RString &sElement, bool bSpriteOnly ) { map::const_iterator iter = g_mapNameToData.find( m_sCurrentNoteSkin ); - ASSERT( iter != g_mapNameToData.end() ); + if(iter == g_mapNameToData.end()) + { + LuaHelpers::ReportScriptError("No current noteskin set!", "NOTESKIN_ERROR"); + return false; + } const NoteSkinData &data = iter->second; LuaThreadVariable varPlayer( "Player", LuaReference::Create(m_PlayerNumber) ); @@ -385,7 +408,11 @@ bool NoteSkinManager::PushActorTemplate( Lua *L, const RString &sButton, const R LuaThreadVariable varElement( "Element", sElement ); LuaThreadVariable varSpriteOnly( "SpriteOnly", LuaReference::Create(bSpriteOnly) ); - ASSERT( !data.m_Loader.IsNil() ); + if(data.m_Loader.IsNil()) + { + LuaHelpers::ReportScriptError("No loader for noteskin!", "NOTESKIN_ERROR"); + return false; + } data.m_Loader.PushSelf( L ); lua_remove( L, -2 ); lua_getfield( L, -1, "Load" ); @@ -437,7 +464,7 @@ RString NoteSkinManager::GetPathFromDirAndFile( const RString &sDir, const RStri if( matches.size() > 1 ) { RString sError = "Multiple files match '"+sDir+sFileName+"'. Please remove all but one of these files."; - Dialog::OK( sError ); + LuaHelpers::ReportScriptError(sError, "NOTESKIN_ERROR"); } return matches[0]; @@ -469,7 +496,12 @@ public: static int x ## ForNoteSkin( T* p, lua_State *L ) \ { \ const RString sOldNoteSkin = p->GetCurrentNoteSkin(); \ - p->SetCurrentNoteSkin( SArg(n+1) ); \ + RString nsname= SArg(n+1); \ + if(!p->DoesNoteSkinExist(nsname)) \ + { \ + luaL_error(L, "Noteskin \"%s\" does not exist.", nsname.c_str()); \ + } \ + p->SetCurrentNoteSkin( nsname ); \ x( p, L ); \ p->SetCurrentNoteSkin( sOldNoteSkin ); \ return 1; \ diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index eacb2a207c..b8b75aa85d 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -722,6 +722,11 @@ void ScreenManager::LoadDelayedScreen() { RString sScreenName = m_sDelayedScreen; m_sDelayedScreen = ""; + if(!IsScreenNameValid(sScreenName)) + { + LuaHelpers::ReportScriptError("Tried to go to invalid screen: " + sScreenName, "INVALID_SCREEN"); + return; + } // Pop the top screen, if any. ScreenMessage SM = PopTopScreenInternal();