Backport custom song support. Prefs are CustomSongsEnable, CustomSongsMaxCount, CustomSongsLoadTimeout, CustomSongsMaxSeconds, CustomSongsMaxMegabytes. Metrics are NumProfileSongGroupColors and the colors with it. Profile custom load function is passed PlayerNumber now. Stepmania must run as root to save USB profile scores. (#1470)

This commit is contained in:
Kyzentun
2017-06-06 06:30:06 -06:00
committed by Colby Klein
parent 1c920a4197
commit 2aee27a276
22 changed files with 627 additions and 240 deletions
+103 -4
View File
@@ -5,6 +5,7 @@
#include "XmlFile.h"
#include "IniFile.h"
#include "GameManager.h"
#include "GameState.h"
#include "RageLog.h"
#include "Song.h"
#include "SongManager.h"
@@ -72,6 +73,31 @@ StringToX(ProfileType);
LuaXType(ProfileType);
Profile::~Profile()
{
ClearSongs();
}
void Profile::ClearSongs()
{
if(m_songs.empty())
{
return;
}
Song* gamestate_curr_song= GAMESTATE->m_pCurSong;
for(size_t i= 0; i < m_songs.size(); ++i)
{
Song* curr_song= m_songs[i];
if(curr_song == gamestate_curr_song)
{
GAMESTATE->m_pCurSong.Set(NULL);
}
delete curr_song;
}
m_songs.clear();
}
int Profile::HighScoresForASong::GetNumTimesPlayed() const
{
int iCount = 0;
@@ -1044,7 +1070,7 @@ void Profile::IncrementCategoryPlayCount( StepsType st, RankingCategory rc )
if( X==NULL ) LOG->Warn("Failed to read section " #X); \
else Load##X##FromNode(X); }
void Profile::LoadCustomFunction( RString sDir )
void Profile::LoadCustomFunction(RString sDir, PlayerNumber pn)
{
/* Get the theme's custom load function:
* [Profile]
@@ -1058,10 +1084,18 @@ void Profile::LoadCustomFunction( RString sDir )
// Pass profile and profile directory as arguments
this->PushSelf(L);
LuaHelpers::Push(L, sDir);
if(pn == PlayerNumber_Invalid)
{
lua_pushnil(L);
}
else
{
Enum::Push(L, pn);
}
// Run it
RString Error= "Error running CustomLoadFunction: ";
LuaHelpers::RunScriptOnStack(L, Error, 2, 0, true);
LuaHelpers::RunScriptOnStack(L, Error, 3, 0, true);
LUA->Release(L);
}
@@ -1148,11 +1182,65 @@ ProfileLoadResult Profile::LoadAllFromDir( RString sDir, bool bRequireSignature
if (ret != ProfileLoadResult_Success)
return ret;
LoadCustomFunction( sDir );
LoadCustomFunction(sDir, PlayerNumber_Invalid);
return ProfileLoadResult_Success;
}
// Custom songs are not stored with all the normal songs because walking the
// entire song list to remove custom songs when unloading the profile is
// wasteful. -Kyz
void Profile::LoadSongsFromDir(RString const& dir, ProfileSlot prof_slot)
{
if(!PREFSMAN->m_custom_songs_enable)
{
return;
}
RString songs_folder= dir + "Songs";
if(FILEMAN->DoesFileExist(songs_folder))
{
LOG->Trace("Found songs folder in profile.");
vector<RString> song_folders;
RageTimer song_load_start_time;
song_load_start_time.Touch();
FILEMAN->GetDirListing(songs_folder + "/*", song_folders, true, true);
StripCvsAndSvn(song_folders);
StripMacResourceForks(song_folders);
LOG->Trace("Found %i songs in profile.", int(song_folders.size()));
// Only songs that are successfully loaded count towards the limit. -Kyz
for(size_t song_index= 0; song_index < song_folders.size()
&& m_songs.size() < PREFSMAN->m_custom_songs_max_count;
++song_index)
{
RString& song_dir_name= song_folders[song_index];
Song* new_song= new Song;
if(!new_song->LoadFromSongDir(song_dir_name, false, prof_slot))
{
// The song failed to load.
LOG->Trace("Song %s failed to load.", song_dir_name.c_str());
delete new_song;
}
else
{
new_song->SetEnabled(true);
m_songs.push_back(new_song);
}
if(song_load_start_time.Ago() > PREFSMAN->m_custom_songs_load_timeout)
{
break;
}
}
float load_time= song_load_start_time.Ago();
LOG->Trace("Successfully loaded %zu songs in %.6f from profile.", m_songs.size(), load_time);
}
else
{
LOG->Trace("No songs folder in profile.");
}
}
ProfileLoadResult Profile::LoadStatsFromDir(RString dir, bool require_signature)
{
dir= dir + PROFILEMAN->GetStatsPrefix();
@@ -2699,7 +2787,17 @@ public:
return 1;
}
DEFINE_METHOD( GetGUID, m_sGuid );
static int get_songs(T* p, lua_State* L)
{
lua_createtable(L, p->m_songs.size(), 0);
int song_tab= lua_gettop(L);
for(size_t i= 0; i < p->m_songs.size(); ++i)
{
p->m_songs[i]->PushSelf(L);
lua_rawseti(L, song_tab, i+1);
}
return 1;
}
LunaProfile()
{
ADD_METHOD( AddScreenshot );
@@ -2769,6 +2867,7 @@ public:
ADD_METHOD( GetLastPlayedSong );
ADD_METHOD( GetLastPlayedCourse );
ADD_METHOD( GetGUID );
ADD_METHOD(get_songs);
}
};