edits cleanup:
- only allow reasonable file sizes - only allow one Steps per edit file - only allow 5 edits per-song, per-profile
This commit is contained in:
@@ -243,11 +243,8 @@ void DifficultyList::PositionItems()
|
||||
int iCurrentRow[NUM_PLAYERS];
|
||||
GetCurrentRows( iCurrentRow );
|
||||
|
||||
for( int pn = 0;pn < NUM_PLAYERS; ++pn )
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
if( !GAMESTATE->IsHumanPlayer(pn) )
|
||||
continue;
|
||||
|
||||
float fY = 0;
|
||||
if( iCurrentRow[pn] < (int) m_Rows.size() )
|
||||
fY = m_Rows[iCurrentRow[pn]]->m_fY;
|
||||
@@ -360,10 +357,8 @@ void DifficultyList::TweenOnScreen()
|
||||
|
||||
PositionItems();
|
||||
|
||||
for( int pn = 0; pn < NUM_PLAYERS; ++pn )
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
if( !GAMESTATE->IsHumanPlayer(pn) )
|
||||
continue;
|
||||
COMMAND( m_Cursors[pn], "TweenOn" );
|
||||
}
|
||||
}
|
||||
@@ -382,10 +377,8 @@ void DifficultyList::Show()
|
||||
HideRows();
|
||||
PositionItems();
|
||||
|
||||
for( int pn = 0; pn < NUM_PLAYERS; ++pn )
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
if( !GAMESTATE->IsHumanPlayer(pn) )
|
||||
continue;
|
||||
COMMAND( m_Cursors[pn], "Show" );
|
||||
}
|
||||
}
|
||||
@@ -395,10 +388,8 @@ void DifficultyList::Hide()
|
||||
m_bShown = false;
|
||||
PositionItems();
|
||||
|
||||
for( int pn = 0; pn < NUM_PLAYERS; ++pn )
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
if( !GAMESTATE->IsHumanPlayer(pn) )
|
||||
continue;
|
||||
COMMAND( m_Cursors[pn], "Hide" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "RageLog.h"
|
||||
#include "RageUtil.h"
|
||||
#include "SongManager.h"
|
||||
#include "RageFileManager.h"
|
||||
|
||||
#define MAX_EDIT_SIZE_BYTES 20*1024 // 20 KB
|
||||
|
||||
void SMLoader::LoadFromSMTokens(
|
||||
CString sNotesType,
|
||||
@@ -376,6 +379,13 @@ bool SMLoader::LoadEdit( CString sEditFilePath, ProfileSlot slot )
|
||||
{
|
||||
LOG->Trace( "Song::LoadEdit(%s)", sEditFilePath.c_str() );
|
||||
|
||||
int iBytes = FILEMAN->GetFileSizeInBytes( sEditFilePath );
|
||||
if( iBytes > MAX_EDIT_SIZE_BYTES )
|
||||
{
|
||||
LOG->Warn( "The edit '%s' is unreasonably large. It won't be loaded.", sEditFilePath.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
MsdFile msd;
|
||||
bool bResult = msd.ReadFile( sEditFilePath );
|
||||
if( !bResult )
|
||||
@@ -407,6 +417,12 @@ bool SMLoader::LoadEdit( CString sEditFilePath, ProfileSlot slot )
|
||||
LOG->Warn( "The edit file '%s' required a song '%s' that isn't present.", sEditFilePath.c_str(), sSongFullTitle.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pSong->GetNumStepsLoadedFromProfile(slot) >= MAX_EDITS_PER_SONG_PER_PLAYER )
|
||||
{
|
||||
LOG->Warn( "The song '%s' already has the maximum number of edits allowed for ProfileSlotP%d.", sSongFullTitle.c_str(), slot+1 );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else if( 0==stricmp(sValueName,"NOTES") )
|
||||
@@ -433,6 +449,8 @@ bool SMLoader::LoadEdit( CString sEditFilePath, ProfileSlot slot )
|
||||
|
||||
pNewNotes->SetLoadedFromProfile( slot );
|
||||
pNewNotes->SetDifficulty( DIFFICULTY_EDIT );
|
||||
|
||||
return true; // Only allow one Steps per edit file!
|
||||
}
|
||||
else
|
||||
LOG->Trace( "Unexpected value named '%s'", sValueName.c_str() );
|
||||
|
||||
@@ -489,7 +489,7 @@ bool Profile::LoadAllFromDir( CString sDir, bool bRequireSignature )
|
||||
// Don't unreasonably large stats.xml files.
|
||||
//
|
||||
int iBytes = FILEMAN->GetFileSizeInBytes( fn );
|
||||
if( iBytes > REASONABLE_STATS_XML_SIZE_BYTES )
|
||||
if( iBytes > MAX_STATS_XML_SIZE_BYTES )
|
||||
{
|
||||
LOG->Warn( "The file '%s' is unreasonably large. It won't be loaded.", fn.c_str() );
|
||||
break;
|
||||
@@ -591,12 +591,16 @@ bool Profile::SaveAllToDir( CString sDir, bool bSignData ) const
|
||||
|
||||
SaveStatsWebPageToDir( sDir );
|
||||
|
||||
//
|
||||
// create edits dir
|
||||
//
|
||||
CString sEditsTempFile = sDir + EDITS_SUBDIR + "temp";
|
||||
RageFile f;
|
||||
f.Open( sDir + EDITS_SUBDIR + "temp", RageFile::WRITE );
|
||||
f.Close();
|
||||
|
||||
FILEMAN->FlushDirCache( sDir + EDITS_SUBDIR );
|
||||
|
||||
FILEMAN->Remove( sEditsTempFile );
|
||||
|
||||
return true;
|
||||
@@ -767,7 +771,7 @@ void Profile::LoadEditableDataFromDir( CString sDir )
|
||||
// Don't load unreasonably large editable.xml files.
|
||||
//
|
||||
int iBytes = FILEMAN->GetFileSizeInBytes( fn );
|
||||
if( iBytes > REASONABLE_EDITABLE_INI_SIZE_BYTES )
|
||||
if( iBytes > MAX_EDITABLE_INI_SIZE_BYTES )
|
||||
{
|
||||
LOG->Warn( "The file '%s' is unreasonably large. It won't be loaded.", fn.c_str() );
|
||||
return;
|
||||
|
||||
@@ -48,8 +48,8 @@ const CString PUBLIC_KEY_FILE = "public.key";
|
||||
const CString SCREENSHOTS_SUBDIR = "Screenshots/";
|
||||
const CString EDITS_SUBDIR = "Edits/";
|
||||
|
||||
#define REASONABLE_EDITABLE_INI_SIZE_BYTES 2*1000 // 2KB
|
||||
#define REASONABLE_STATS_XML_SIZE_BYTES 5*1000*1000 // 5MB
|
||||
#define MAX_EDITABLE_INI_SIZE_BYTES 2*1024 // 2KB
|
||||
#define MAX_STATS_XML_SIZE_BYTES 2*1024*1024 // 2MB
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -714,7 +714,7 @@ void ScreenManager::SystemMessage( CString sMessage )
|
||||
|
||||
void ScreenManager::SystemMessageNoAnimate( CString sMessage )
|
||||
{
|
||||
LOG->Trace( "%s", sMessage.c_str() );
|
||||
// LOG->Trace( "%s", sMessage.c_str() ); // don't log because the caller is likely calling us every frame
|
||||
m_SystemLayer->SystemMessageNoAnimate( sMessage );
|
||||
}
|
||||
|
||||
|
||||
@@ -1317,6 +1317,18 @@ void Song::FreeAllLoadedFromProfiles()
|
||||
}
|
||||
}
|
||||
|
||||
int Song::GetNumStepsLoadedFromProfile( ProfileSlot slot ) const
|
||||
{
|
||||
int iCount = 0;
|
||||
for( unsigned s=0; s<m_apNotes.size(); s++ )
|
||||
{
|
||||
Steps* pSteps = m_apNotes[s];
|
||||
if( pSteps->GetLoadedFromProfileSlot() == slot )
|
||||
iCount++;
|
||||
}
|
||||
return iCount;
|
||||
}
|
||||
|
||||
bool Song::HasSignificantBpmChangesOrStops() const
|
||||
{
|
||||
// Don't consider BPM changes that only are only for maintaining sync as
|
||||
|
||||
@@ -42,6 +42,7 @@ SongManager* SONGMAN = NULL; // global and accessable from anywhere in our progr
|
||||
#define SONGS_DIR "Songs/"
|
||||
#define COURSES_DIR "Courses/"
|
||||
|
||||
#define MAX_EDITS_PER_PROFILE 200
|
||||
|
||||
#define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors")
|
||||
#define GROUP_COLOR( i ) THEME->GetMetricC("SongManager",ssprintf("GroupColor%d",i+1))
|
||||
@@ -966,7 +967,9 @@ void SongManager::LoadAllFromProfiles()
|
||||
CStringArray asEditsFilesWithPath;
|
||||
GetDirListing( sEditsDir+"*.sm", asEditsFilesWithPath, false, true );
|
||||
|
||||
for( unsigned i=0; i<asEditsFilesWithPath.size(); i++ )
|
||||
unsigned size = min( asEditsFilesWithPath.size(), (unsigned)MAX_EDITS_PER_PROFILE );
|
||||
|
||||
for( unsigned i=0; i<size; i++ )
|
||||
{
|
||||
CString sEditFileWithPath = asEditsFilesWithPath[i];
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
// Use a special value of difficulty
|
||||
bool IsAnEdit() const { return m_Difficulty == DIFFICULTY_EDIT; }
|
||||
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != PROFILE_SLOT_INVALID; }
|
||||
ProfileSlot GetLoadedFromProfileSlot() const { return m_LoadedFromProfile; }
|
||||
CString GetDescription() const { return Real()->m_sDescription; }
|
||||
Difficulty GetDifficulty() const { return Real()->m_Difficulty; }
|
||||
ProfileSlot GetLoadedFromProfile() const { return m_LoadedFromProfile; }
|
||||
|
||||
@@ -23,6 +23,8 @@ class LyricsLoader;
|
||||
class Profile;
|
||||
class StepsID;
|
||||
|
||||
#define MAX_EDITS_PER_SONG_PER_PLAYER 5
|
||||
#define MAX_EDITS_PER_SONG 5*2
|
||||
|
||||
extern const int FILE_CACHE_VERSION;
|
||||
|
||||
@@ -203,6 +205,7 @@ public:
|
||||
|
||||
void FreeAllLoadedFromProfiles();
|
||||
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != PROFILE_SLOT_INVALID; }
|
||||
int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const;
|
||||
|
||||
private:
|
||||
void AdjustDuplicateSteps(); // part of TidyUpData
|
||||
|
||||
Reference in New Issue
Block a user