mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- files in local directories (saves & configs) now always have higher
priority than mods. Fixes #1685 and #1733 - fixed possible crash on exit in dispose() function - (vcmibuilder) fixes problem with partial mp3 -> ogg conversion
This commit is contained in:
parent
afcb7072eb
commit
d2ae847ecf
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
const CGameInfo * CGI; //game info for general use
|
||||
CClientState * CCS;
|
||||
CClientState * CCS = nullptr;
|
||||
|
||||
CGameInfo::CGameInfo()
|
||||
{
|
||||
|
@ -751,8 +751,11 @@ void dispose()
|
||||
|
||||
// cleanup, mostly to remove false leaks from analyzer
|
||||
CResourceHandler::clear();
|
||||
if (CCS)
|
||||
{
|
||||
CCS->musich->release();
|
||||
CCS->soundh->release();
|
||||
}
|
||||
CMessage::dispose();
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ struct ComponentsToBlit
|
||||
|
||||
namespace
|
||||
{
|
||||
CDefHandler * ok, *cancel;
|
||||
CDefHandler * ok = nullptr, *cancel = nullptr;
|
||||
std::vector<std::vector<SDL_Surface*> > piecesOfBox; //in colors of all players
|
||||
SDL_Surface * background = nullptr;
|
||||
}
|
||||
@ -100,9 +100,9 @@ void CMessage::init()
|
||||
|
||||
void CMessage::dispose()
|
||||
{
|
||||
for (int i=0; i<PlayerColor::PLAYER_LIMIT_I; i++)
|
||||
for (auto & piece : piecesOfBox)
|
||||
{
|
||||
for (auto & elem : piecesOfBox[i])
|
||||
for (auto & elem : piece)
|
||||
{
|
||||
SDL_FreeSurface(elem);
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ void CSelectionScreen::startScenario()
|
||||
overWrite += boost::bind(&CCallback::save, LOCPLINT->cb.get(), saveGameName);
|
||||
overWrite += boost::bind(&CGuiHandler::popIntTotally, &GH, this);
|
||||
|
||||
if(CResourceHandler::get()->existsResource(ResourceID(saveGameName, EResType::CLIENT_SAVEGAME)))
|
||||
if(CResourceHandler::get("local")->existsResource(ResourceID(saveGameName, EResType::CLIENT_SAVEGAME)))
|
||||
{
|
||||
std::string hlp = CGI->generaltexth->allTexts[493]; //%s exists. Overwrite?
|
||||
boost::algorithm::replace_first(hlp, "%s", sel->txt->text);
|
||||
@ -1354,7 +1354,7 @@ void SelectionTab::select( int position )
|
||||
|
||||
if(txt)
|
||||
{
|
||||
std::string filename = *CResourceHandler::get()->getResourceName(
|
||||
std::string filename = *CResourceHandler::get("local")->getResourceName(
|
||||
ResourceID(curItems[py]->fileURI, EResType::CLIENT_SAVEGAME));
|
||||
txt->setText(CFileInfo(filename).getBaseName());
|
||||
}
|
||||
@ -1479,7 +1479,7 @@ void SelectionTab::printMaps(SDL_Surface *to)
|
||||
}
|
||||
else
|
||||
{
|
||||
name = CFileInfo(*CResourceHandler::get()->getResourceName(
|
||||
name = CFileInfo(*CResourceHandler::get("local")->getResourceName(
|
||||
ResourceID(currentItem->fileURI, EResType::CLIENT_SAVEGAME))).getBaseName();
|
||||
}
|
||||
|
||||
|
@ -241,17 +241,17 @@ void CClient::loadGame( const std::string & fname )
|
||||
CStopWatch tmh;
|
||||
try
|
||||
{
|
||||
std::string clientSaveName = *CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
|
||||
std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
|
||||
std::string controlServerSaveName;
|
||||
|
||||
if (CResourceHandler::get()->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME)))
|
||||
if (CResourceHandler::get("local")->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME)))
|
||||
{
|
||||
controlServerSaveName = *CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME));
|
||||
controlServerSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME));
|
||||
}
|
||||
else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler
|
||||
{
|
||||
controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1";
|
||||
CResourceHandler::get()->createResource(controlServerSaveName, true);
|
||||
CResourceHandler::get("local")->createResource(controlServerSaveName, true);
|
||||
}
|
||||
|
||||
if(clientSaveName.empty())
|
||||
|
@ -793,7 +793,7 @@ void YourTurn::applyCl( CClient *cl )
|
||||
void SaveGame::applyCl(CClient *cl)
|
||||
{
|
||||
CFileInfo info(fname);
|
||||
CResourceHandler::get()->createResource(info.getStem() + ".vcgm1");
|
||||
CResourceHandler::get("local")->createResource(info.getStem() + ".vcgm1");
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -59,11 +59,11 @@ void SettingsStorage::init()
|
||||
{
|
||||
std::string confName = "config/settings.json";
|
||||
|
||||
// Porbably new install. Create initial configuration
|
||||
if (!CResourceHandler::get()->existsResource(ResourceID(confName)))
|
||||
CResourceHandler::get()->createResource(confName);
|
||||
else
|
||||
JsonNode(ResourceID("config/settings.json")).swap(config);
|
||||
JsonUtils::assembleFromFiles(confName).swap(config);
|
||||
|
||||
// Probably new install. Create config file to save settings to
|
||||
if (!CResourceHandler::get("local")->existsResource(ResourceID(confName)))
|
||||
CResourceHandler::get("local")->createResource(confName);
|
||||
|
||||
JsonUtils::maximize(config, "vcmi:settings");
|
||||
JsonUtils::validate(config, "vcmi:settings", "settings");
|
||||
|
@ -547,12 +547,12 @@ std::vector <TModID> CModHandler::resolveDependencies(std::vector <TModID> input
|
||||
|
||||
static JsonNode loadModSettings(std::string path)
|
||||
{
|
||||
if (CResourceHandler::get()->existsResource(ResourceID(path)))
|
||||
if (CResourceHandler::get("local")->existsResource(ResourceID(path)))
|
||||
{
|
||||
return JsonNode(ResourceID(path, EResType::TEXT));
|
||||
}
|
||||
// Probably new install. Create initial configuration
|
||||
CResourceHandler::get()->createResource(path);
|
||||
CResourceHandler::get("local")->createResource(path);
|
||||
return JsonNode();
|
||||
}
|
||||
|
||||
@ -687,7 +687,7 @@ static ui32 calculateModChecksum(const std::string modName, ISimpleResourceLoade
|
||||
if (modName != "core")
|
||||
{
|
||||
ResourceID modConfFile("mods/" + modName + "/mod", EResType::TEXT);
|
||||
ui32 configChecksum = CResourceHandler::getInitial()->load(modConfFile)->calculateCRC32();
|
||||
ui32 configChecksum = CResourceHandler::get("initial")->load(modConfFile)->calculateCRC32();
|
||||
modChecksum.process_bytes(reinterpret_cast<const void *>(&configChecksum), sizeof(configChecksum));
|
||||
}
|
||||
// third - add all detected text files from this mod into checksum
|
||||
@ -717,7 +717,7 @@ void CModHandler::loadModFilesystems()
|
||||
for(std::string & modName : activeMods)
|
||||
{
|
||||
CModInfo & mod = allMods[modName];
|
||||
CResourceHandler::addFilesystem(modName, genModFilesystem(modName, mod.config));
|
||||
CResourceHandler::addFilesystem("data", modName, genModFilesystem(modName, mod.config));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,6 @@
|
||||
#include "../VCMIDirs.h"
|
||||
#include "../CStopWatch.h"
|
||||
|
||||
CFilesystemList * CResourceHandler::resourceLoader = nullptr;
|
||||
CFilesystemList * CResourceHandler::initialLoader = nullptr;
|
||||
std::map<std::string, ISimpleResourceLoader*> CResourceHandler::knownLoaders = std::map<std::string, ISimpleResourceLoader*>();
|
||||
|
||||
CFilesystemGenerator::CFilesystemGenerator(std::string prefix):
|
||||
@ -75,7 +73,7 @@ void CFilesystemGenerator::loadDirectory(const std::string &mountPoint, const Js
|
||||
|
||||
ResourceID resID(URI, EResType::DIRECTORY);
|
||||
|
||||
for(auto & loader : CResourceHandler::getInitial()->getResourcesWithName(resID))
|
||||
for(auto & loader : CResourceHandler::get("initial")->getResourcesWithName(resID))
|
||||
{
|
||||
auto filename = loader->getResourceName(resID);
|
||||
filesystem->addLoader(new CFilesystemLoader(mountPoint, *filename, depth), false);
|
||||
@ -85,7 +83,7 @@ void CFilesystemGenerator::loadDirectory(const std::string &mountPoint, const Js
|
||||
void CFilesystemGenerator::loadZipArchive(const std::string &mountPoint, const JsonNode & config)
|
||||
{
|
||||
std::string URI = prefix + config["path"].String();
|
||||
auto filename = CResourceHandler::getInitial()->getResourceName(ResourceID(URI, EResType::ARCHIVE_ZIP));
|
||||
auto filename = CResourceHandler::get("initial")->getResourceName(ResourceID(URI, EResType::ARCHIVE_ZIP));
|
||||
if (filename)
|
||||
filesystem->addLoader(new CZipLoader(mountPoint, *filename), false);
|
||||
}
|
||||
@ -94,7 +92,7 @@ template<EResType::Type archiveType>
|
||||
void CFilesystemGenerator::loadArchive(const std::string &mountPoint, const JsonNode & config)
|
||||
{
|
||||
std::string URI = prefix + config["path"].String();
|
||||
auto filename = CResourceHandler::getInitial()->getResourceName(ResourceID(URI, archiveType));
|
||||
auto filename = CResourceHandler::get("initial")->getResourceName(ResourceID(URI, archiveType));
|
||||
if (filename)
|
||||
filesystem->addLoader(new CArchiveLoader(mountPoint, *filename), false);
|
||||
}
|
||||
@ -102,10 +100,10 @@ void CFilesystemGenerator::loadArchive(const std::string &mountPoint, const Json
|
||||
void CFilesystemGenerator::loadJsonMap(const std::string &mountPoint, const JsonNode & config)
|
||||
{
|
||||
std::string URI = prefix + config["path"].String();
|
||||
auto filename = CResourceHandler::getInitial()->getResourceName(ResourceID(URI, EResType::TEXT));
|
||||
auto filename = CResourceHandler::get("initial")->getResourceName(ResourceID(URI, EResType::TEXT));
|
||||
if (filename)
|
||||
{
|
||||
auto configData = CResourceHandler::getInitial()->load(ResourceID(URI, EResType::TEXT))->readAll();
|
||||
auto configData = CResourceHandler::get("initial")->load(ResourceID(URI, EResType::TEXT))->readAll();
|
||||
const JsonNode config((char*)configData.first.get(), configData.second);
|
||||
filesystem->addLoader(new CMappedFileLoader(mountPoint, config), false);
|
||||
}
|
||||
@ -113,14 +111,17 @@ void CFilesystemGenerator::loadJsonMap(const std::string &mountPoint, const Json
|
||||
|
||||
void CResourceHandler::clear()
|
||||
{
|
||||
delete resourceLoader;
|
||||
delete initialLoader;
|
||||
delete knownLoaders["root"];
|
||||
}
|
||||
|
||||
void CResourceHandler::initialize()
|
||||
ISimpleResourceLoader * CResourceHandler::createInitial()
|
||||
{
|
||||
//temporary filesystem that will be used to initialize main one.
|
||||
//used to solve several case-sensivity issues like Mp3 vs MP3
|
||||
auto initialLoader = new CFilesystemList;
|
||||
|
||||
//recurse only into specific directories
|
||||
auto recurseInDir = [](std::string URI, int depth)
|
||||
auto recurseInDir = [&](std::string URI, int depth)
|
||||
{
|
||||
ResourceID ID(URI, EResType::DIRECTORY);
|
||||
|
||||
@ -135,10 +136,6 @@ void CResourceHandler::initialize()
|
||||
}
|
||||
};
|
||||
|
||||
//temporary filesystem that will be used to initialize main one.
|
||||
//used to solve several case-sensivity issues like Mp3 vs MP3
|
||||
initialLoader = new CFilesystemList;
|
||||
|
||||
for (auto & path : VCMIDirs::get().dataPaths())
|
||||
{
|
||||
if (boost::filesystem::is_directory(path)) // some of system-provided paths may not exist
|
||||
@ -148,13 +145,43 @@ void CResourceHandler::initialize()
|
||||
|
||||
recurseInDir("CONFIG", 0);// look for configs
|
||||
recurseInDir("DATA", 0); // look for archives
|
||||
//TODO: improve mod loading process so depth 2 will no longer be needed
|
||||
recurseInDir("MODS", 2); // look for mods. Depth 2 is required for now but won't cause speed issues if no mods present
|
||||
recurseInDir("MODS", 64); // look for mods.
|
||||
|
||||
return initialLoader;
|
||||
}
|
||||
|
||||
void CResourceHandler::initialize()
|
||||
{
|
||||
// Create tree-loke structure that looks like this:
|
||||
// root
|
||||
// |
|
||||
// |- initial
|
||||
// |
|
||||
// |- data
|
||||
// | |-core
|
||||
// | |-mod1
|
||||
// | |-modN
|
||||
// |
|
||||
// |- local
|
||||
// |-saves
|
||||
// |-config
|
||||
|
||||
knownLoaders["root"] = new CFilesystemList();
|
||||
knownLoaders["saves"] = new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath());
|
||||
knownLoaders["config"] = new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath());
|
||||
|
||||
auto localFS = new CFilesystemList();
|
||||
localFS->addLoader(knownLoaders["saves"], true);
|
||||
localFS->addLoader(knownLoaders["config"], true);
|
||||
|
||||
addFilesystem("root", "initial", createInitial());
|
||||
addFilesystem("root", "data", new CFilesystemList());
|
||||
addFilesystem("root", "local", localFS);
|
||||
}
|
||||
|
||||
ISimpleResourceLoader * CResourceHandler::get()
|
||||
{
|
||||
return get("");
|
||||
return get("root");
|
||||
}
|
||||
|
||||
ISimpleResourceLoader * CResourceHandler::get(std::string identifier)
|
||||
@ -162,31 +189,22 @@ ISimpleResourceLoader * CResourceHandler::get(std::string identifier)
|
||||
return knownLoaders.at(identifier);
|
||||
}
|
||||
|
||||
ISimpleResourceLoader * CResourceHandler::getInitial()
|
||||
{
|
||||
assert(initialLoader);
|
||||
return initialLoader;
|
||||
}
|
||||
|
||||
void CResourceHandler::load(const std::string &fsConfigURI)
|
||||
{
|
||||
auto fsConfigData = initialLoader->load(ResourceID(fsConfigURI, EResType::TEXT))->readAll();
|
||||
auto fsConfigData = get("initial")->load(ResourceID(fsConfigURI, EResType::TEXT))->readAll();
|
||||
|
||||
const JsonNode fsConfig((char*)fsConfigData.first.get(), fsConfigData.second);
|
||||
|
||||
resourceLoader = new CFilesystemList();
|
||||
knownLoaders[""] = resourceLoader;
|
||||
addFilesystem("core", createFileSystem("", fsConfig["filesystem"]));
|
||||
|
||||
// hardcoded system-specific path, may not be inside any of data directories
|
||||
resourceLoader->addLoader(new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath()), true);
|
||||
resourceLoader->addLoader(new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath()), true);
|
||||
addFilesystem("data", "core", createFileSystem("", fsConfig["filesystem"]));
|
||||
}
|
||||
|
||||
void CResourceHandler::addFilesystem(const std::string & identifier, ISimpleResourceLoader * loader)
|
||||
void CResourceHandler::addFilesystem(const std::string & parent, const std::string & identifier, ISimpleResourceLoader * loader)
|
||||
{
|
||||
assert(knownLoaders.count(identifier) == 0);
|
||||
resourceLoader->addLoader(loader, false);
|
||||
|
||||
auto list = dynamic_cast<CFilesystemList *>(knownLoaders.at(parent));
|
||||
assert(list);
|
||||
list->addLoader(loader, false);
|
||||
knownLoaders[identifier] = loader;
|
||||
}
|
||||
|
||||
@ -201,7 +219,7 @@ std::vector<std::string> CResourceHandler::getAvailableMods()
|
||||
{
|
||||
static const std::string modDir = "MODS/";
|
||||
|
||||
auto list = initialLoader->getFilteredFiles([](const ResourceID & id) -> bool
|
||||
auto list = get("initial")->getFilteredFiles([](const ResourceID & id) -> bool
|
||||
{
|
||||
return id.getType() == EResType::DIRECTORY
|
||||
&& boost::range::count(id.getName(), '/') == 1
|
||||
@ -218,8 +236,8 @@ std::vector<std::string> CResourceHandler::getAvailableMods()
|
||||
|
||||
if (name == "WOG") // check if wog is actually present. Hack-ish but better than crash
|
||||
{
|
||||
if (!initialLoader->existsResource(ResourceID("DATA/ZVS", EResType::DIRECTORY)) &&
|
||||
!initialLoader->existsResource(ResourceID("MODS/WOG/DATA/ZVS", EResType::DIRECTORY)))
|
||||
if (!get("initial")->existsResource(ResourceID("DATA/ZVS", EResType::DIRECTORY)) &&
|
||||
!get("initial")->existsResource(ResourceID("MODS/WOG/DATA/ZVS", EResType::DIRECTORY)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -52,6 +52,12 @@ public:
|
||||
*/
|
||||
class DLL_LINKAGE CResourceHandler
|
||||
{
|
||||
/**
|
||||
* @brief createInitial - creates instance of initial loader
|
||||
* that contains data necessary to load main FS
|
||||
*/
|
||||
static ISimpleResourceLoader * createInitial();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Gets an instance of resource loader.
|
||||
@ -62,7 +68,6 @@ public:
|
||||
*/
|
||||
static ISimpleResourceLoader * get();
|
||||
static ISimpleResourceLoader * get(std::string identifier);
|
||||
static ISimpleResourceLoader * getInitial();
|
||||
|
||||
/**
|
||||
* Creates instance of initial resource loader.
|
||||
@ -89,7 +94,7 @@ public:
|
||||
* @param identifier name of this loader by which it can be retrieved later
|
||||
* @param loader resource loader to add
|
||||
*/
|
||||
static void addFilesystem(const std::string & identifier, ISimpleResourceLoader * loader);
|
||||
static void addFilesystem(const std::string & parent, const std::string & identifier, ISimpleResourceLoader * loader);
|
||||
|
||||
/**
|
||||
* @brief createModFileSystem - creates filesystem out of config file
|
||||
@ -107,6 +112,4 @@ public:
|
||||
private:
|
||||
/** Instance of resource loader */
|
||||
static std::map<std::string, ISimpleResourceLoader*> knownLoaders;
|
||||
static CFilesystemList * resourceLoader;
|
||||
static CFilesystemList * initialLoader;
|
||||
};
|
||||
|
@ -2226,8 +2226,8 @@ void CGameHandler::save(const std::string & filename )
|
||||
{
|
||||
logGlobal->errorStream() << "Saving to " << filename;
|
||||
CFileInfo info(filename);
|
||||
//CResourceHandler::get()->createResource(info.getStem() + ".vlgm1");
|
||||
CResourceHandler::get()->createResource(info.getStem() + ".vsgm1");
|
||||
//CResourceHandler::get("local")->createResource(info.getStem() + ".vlgm1");
|
||||
CResourceHandler::get("local")->createResource(info.getStem() + ".vsgm1");
|
||||
|
||||
{
|
||||
logGlobal->infoStream() << "Ordering clients to serialize...";
|
||||
@ -2239,14 +2239,14 @@ void CGameHandler::save(const std::string & filename )
|
||||
{
|
||||
// {
|
||||
// logGlobal->infoStream() << "Serializing game info...";
|
||||
// CSaveFile save(CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::LIB_SAVEGAME)));
|
||||
// CSaveFile save(CResourceHandler::get("local")->getResourceName(ResourceID(info.getStem(), EResType::LIB_SAVEGAME)));
|
||||
// // char hlp[8] = "VCMISVG";
|
||||
// // save << hlp;
|
||||
// saveCommonState(save);
|
||||
// }
|
||||
|
||||
{
|
||||
CSaveFile save(*CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::SERVER_SAVEGAME)));
|
||||
CSaveFile save(*CResourceHandler::get("local")->getResourceName(ResourceID(info.getStem(), EResType::SERVER_SAVEGAME)));
|
||||
saveCommonState(save);
|
||||
logGlobal->infoStream() << "Saving server state";
|
||||
save << *this;
|
||||
|
@ -464,7 +464,7 @@ void CVCMIServer::loadGame()
|
||||
// CMapHeader dum;
|
||||
// StartInfo *si;
|
||||
//
|
||||
// CLoadFile lf(CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::LIB_SAVEGAME)));
|
||||
// CLoadFile lf(CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::LIB_SAVEGAME)));
|
||||
// lf >> sig >> dum >> si;
|
||||
// logNetwork->infoStream() <<"Reading save signature";
|
||||
//
|
||||
@ -477,7 +477,7 @@ void CVCMIServer::loadGame()
|
||||
// }
|
||||
|
||||
{
|
||||
CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)), minSupportedVersion);
|
||||
CLoadFile lf(*CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)), minSupportedVersion);
|
||||
gh.loadCommonState(lf);
|
||||
lf >> gh;
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ then
|
||||
OIFS="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
for file in `find "$dest_dir" -type f -name "*.mp3"`
|
||||
for file in `find "$dest_dir" -type f -iname "*.mp3"`
|
||||
do
|
||||
echo "Converting $file"
|
||||
ogg=${file%.*}
|
||||
|
Loading…
Reference in New Issue
Block a user