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