1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

minor refactoring of VCMIDirs, bugfixing

- VCMIDirs represent XDG specification more closely (partial #1310)
- Minor bugfixing, including #1327 #1328 and #1306
This commit is contained in:
Ivan Savenko 2013-07-08 20:55:22 +00:00
parent 410ec92668
commit 4ac2a6e8b6
13 changed files with 108 additions and 65 deletions

View File

@ -170,7 +170,7 @@ void init()
static void prog_version(void)
{
printf("%s\n", GameConstants::VCMI_VERSION.c_str());
printf(" data directory: %s\n", VCMIDirs::get().dataPath().c_str());
printf(" data directory: %s\n", VCMIDirs::get().dataPaths().back().c_str());
printf(" library directory: %s\n", VCMIDirs::get().libraryPath().c_str());
printf(" path to server: %s\n", VCMIDirs::get().serverPath().c_str());
}
@ -279,7 +279,7 @@ int main(int argc, char** argv)
console->start();
atexit(dispose);
CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Client_log.txt", console);
CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Client_log.txt", console);
logConfig.configureDefault();
logGlobal->infoStream() <<"Creating console "<<pomtime.getDiff();
@ -324,8 +324,8 @@ int main(int argc, char** argv)
{
logGlobal->errorStream() << "Fatal error: failed to load settings!";
logGlobal->errorStream() << "Possible reasons:";
logGlobal->errorStream() << "\tCorrupted local configuration file at " << VCMIDirs::get().localPath() << "/config/settings.json";
logGlobal->errorStream() << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().dataPath() << "/config/schemas/settings.json";
logGlobal->errorStream() << "\tCorrupted local configuration file at " << VCMIDirs::get().userConfigPath() << "/settings.json";
logGlobal->errorStream() << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().userConfigPath() << "/schemas/settings.json";
logGlobal->errorStream() << "VCMI will now exit...";
exit(EXIT_FAILURE);
}
@ -534,7 +534,7 @@ void processCommand(const std::string &message)
{
std::cout<<"Command accepted.\t";
std::string outPath = VCMIDirs::get().localPath() + "/extracted/";
std::string outPath = VCMIDirs::get().userCachePath() + "/extracted/";
auto iterator = CResourceHandler::get()->getIterator([](const ResourceID & ident)
{
@ -662,8 +662,7 @@ void processCommand(const std::string &message)
CDefEssential * cde = CDefHandler::giveDefEss(URI);
std::string outName = CResourceHandler::get()->getResource(ResourceID("SPRITES/" + URI)).getResourceName();
std::string outPath = VCMIDirs::get().localPath() + "/extracted/";
std::string outPath = VCMIDirs::get().userCachePath() + "/extracted/";
boost::filesystem::create_directories(outPath + outName);
@ -684,7 +683,7 @@ void processCommand(const std::string &message)
if (CResourceHandler::get()->existsResource(ResourceID(URI)))
{
std::string outName = CResourceHandler::get()->getResource(ResourceID(URI)).getResourceName();
std::string outPath = VCMIDirs::get().localPath() + "/extracted/";
std::string outPath = VCMIDirs::get().userCachePath() + "/extracted/";
std::string fullPath = outPath + outName;
auto data = CResourceHandler::get()->loadData(ResourceID(URI));

View File

@ -1599,7 +1599,7 @@ int CPlayerInterface::getLastIndex( std::string namePrefix)
using namespace boost::filesystem;
using namespace boost::algorithm;
path gamesDir = VCMIDirs::get().localPath() + "/Games";
path gamesDir = VCMIDirs::get().userSavePath();
std::map<std::time_t, int> dates; //save number => datestamp
directory_iterator enddir;

View File

@ -826,7 +826,7 @@ CServerHandler::~CServerHandler()
void CServerHandler::callServer()
{
setThreadName("CServerHandler::callServer");
std::string logName = VCMIDirs::get().localPath() + "/server_log.txt";
std::string logName = VCMIDirs::get().userCachePath() + "/server_log.txt";
std::string comm = VCMIDirs::get().serverPath() + " --port=" + port + " > " + logName;
int result = std::system(comm.c_str());
if (result == 0)

View File

@ -2,6 +2,7 @@
#include "Graphics.h"
#include "../lib/filesystem/CResourceLoader.h"
#include "../lib/filesystem/CBinaryReader.h"
#include "CDefHandler.h"
#include "gui/SDL_Extensions.h"
#include <SDL_ttf.h>
@ -65,18 +66,18 @@ void Graphics::loadPaletteAndColors()
}
neutralColorPalette = new SDL_Color[32];
std::ifstream ncp;
ncp.open(CResourceHandler::get()->getResourceName(ResourceID("config/NEUTRAL.PAL")), std::ios::binary);
auto stream = CResourceHandler::get()->load(ResourceID("config/NEUTRAL.PAL"));
CBinaryReader reader(stream.get());
for(int i=0; i<32; ++i)
{
ncp.read((char*)&neutralColorPalette[i].r,1);
ncp.read((char*)&neutralColorPalette[i].g,1);
ncp.read((char*)&neutralColorPalette[i].b,1);
ncp.read((char*)&neutralColorPalette[i].unused,1);
neutralColorPalette[i].r = reader.readUInt8();
neutralColorPalette[i].g = reader.readUInt8();
neutralColorPalette[i].b = reader.readUInt8();
neutralColorPalette[i].unused = reader.readUInt8();
neutralColorPalette[i].unused = !neutralColorPalette[i].unused;
}
//colors initialization
int3 kolory[] = {int3(0xff,0,0),int3(0x31,0x52,0xff),int3(0x9c,0x73,0x52),int3(0x42,0x94,0x29),
int3(0xff,0x84,0x0),int3(0x8c,0x29,0xa5),int3(0x09,0x9c,0xa5),int3(0xc6,0x7b,0x8c)};

View File

@ -171,7 +171,7 @@
"horde1": { "id" : 18, "upgrades" : 31 },
"horde1Upgr": { "id" : 19, "upgrades" : 38, "requires" : [ 18 ], "mode" : "auto" },
"special2": { "id" : 21, "requires" : [ 17 ] },
"special3": { "id" : 22, "requires" : [ 18, 19 ] },
"special3": { "id" : 22, "requires" : [ 18 ] },
"horde2": { "id" : 24, "upgrades" : 34 },
"horde2Upgr": { "id" : 25, "upgrades" : 41, "requires" : [ 24 ], "mode" : "auto" },
"grail": { "id" : 26, "mode" : "grail"},

View File

@ -76,7 +76,7 @@
{ "x":313, "y":244, "file":"DATA/NEUTRAL1.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
{ "x":586, "y":246, "file":"DATA/EVIL2.H3C", "image":"CAMPEV2S", "video":"CEVIL2", "open": true },
{ "x":34, "y":417, "file":"DATA/GOOD3.H3C", "image":"CAMPGD3S", "video":"CGOOD3", "open": true },
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
{ "x":404, "y":414, "file":"DATA/SECRET1.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
]
},
{
@ -111,7 +111,7 @@
{ "x":313, "y":244, "file":"DATA/SANDRO.H3C", "image":"CAMPRN1", "video":"RISE", "open": true },
{ "x":586, "y":246, "file":"DATA/YOG.H3C", "image":"CAMPBB1", "video":"BIRTH", "open": true },
{ "x":34, "y":417, "file":"DATA/FINAL.H3C", "image":"CAMPUA1", "video":"UNHOLY", "open": true },
{ "x":404, "y":414, "file":"DATA/SECRET1.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
]
},

View File

@ -16,9 +16,10 @@ static VCMIDirs VCMIDirsGlobal;
VCMIDirs::VCMIDirs()
{
// initialize local directory and create folders to which VCMI needs write access
boost::filesystem::create_directory(localPath());
boost::filesystem::create_directory(localPath() + "/config");
boost::filesystem::create_directory(localPath() + "/Games");
boost::filesystem::create_directory(userDataPath());
boost::filesystem::create_directory(userCachePath());
boost::filesystem::create_directory(userConfigPath());
boost::filesystem::create_directory(userSavePath());
}
VCMIDirs & VCMIDirs::get()
@ -26,27 +27,47 @@ VCMIDirs & VCMIDirs::get()
return VCMIDirsGlobal;
}
std::string VCMIDirs::userCachePath() const
{
return userDataPath();
}
std::string VCMIDirs::userConfigPath() const
{
return userDataPath() + "/config";
}
std::string VCMIDirs::userSavePath() const
{
return userDataPath() + "/Games";
}
std::vector<std::string> VCMIDirs::configPaths() const
{
return std::vector<std::string>(1, dataPaths()[0] + "/config");
}
//FIXME: find way to at least decrease size of this ifdef (along with cleanup in CMake)
#if defined(_WIN32)
std::string VCMIDirs::localPath() const
std::string VCMIDirs::userDataPath() const
{
return dataPath();
return dataPaths()[0];
}
std::string VCMIDirs::libraryPath() const
{
return dataPath();
return userDataPath();
}
std::string VCMIDirs::serverPath() const
{
return dataPath() + "\\" + "VCMI_server.exe";
return userDataPath() + "\\" + "VCMI_server.exe";
}
std::string VCMIDirs::dataPath() const
std::vector<std::string> VCMIDirs::dataPaths() const
{
return ".";
return std::vector<std::string>(1, ".");
}
std::string VCMIDirs::libraryName(std::string basename) const
@ -56,7 +77,7 @@ std::string VCMIDirs::libraryName(std::string basename) const
#elif defined(__APPLE__)
std::string VCMIDirs::localPath() const
std::string VCMIDirs::userDataPath() const
{
// This is Cocoa code that should be normally used to get path to Application Support folder but can't use it here for now...
// NSArray* urls = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
@ -80,9 +101,9 @@ std::string VCMIDirs::serverPath() const
return "./vcmiserver";
}
std::string VCMIDirs::dataPath() const
std::vector<std::string> VCMIDirs::dataPaths() const
{
return "../Data";
return std::vector<std::string>(1, "../Data");
}
std::string VCMIDirs::libraryName(std::string basename) const
@ -92,7 +113,7 @@ std::string VCMIDirs::libraryName(std::string basename) const
#else
std::string VCMIDirs::localPath() const
std::string VCMIDirs::userDataPath() const
{
if (getenv("HOME") != nullptr )
return std::string(getenv("HOME")) + "/.vcmi";
@ -109,9 +130,9 @@ std::string VCMIDirs::serverPath() const
return std::string(M_BIN_DIR) + "/" + "vcmiserver";
}
std::string VCMIDirs::dataPath() const
std::vector<std::string> VCMIDirs::dataPaths() const
{
return M_DATA_DIR;
return std::vector<std::string>(1, M_DATA_DIR);
}
std::string VCMIDirs::libraryName(std::string basename) const

View File

@ -21,18 +21,30 @@ public:
/// get singleton instance
static VCMIDirs & get();
/// Path to local, user-specific directory (e.g. ~/.vcmi on *nix systems)
std::string localPath() const;
/// Path to user-specific data directory
std::string userDataPath() const;
/// Path to "cache" directory, can be used for any non-essential files
std::string userCachePath() const;
/// Path to writeable directory with user configs
std::string userConfigPath() const;
/// Path to saved games
std::string userSavePath() const;
/// Path to config directories, e.g. <data dir>/config. First items have higher priority
std::vector<std::string> configPaths() const;
/// Paths to global system-wide data directories. First items have higher priority
std::vector<std::string> dataPaths() const;
/// Full path to vcmiserver executable, including server name (e.g. /usr/bin/vcmiserver)
std::string serverPath() const;
/// Path where vcmi libraries can be found (in AI and Scripting subdirectories)
std::string libraryPath() const;
/// Path to vcmiserver, including server name (e.g. /usr/bin/vcmiserver)
std::string serverPath() const;
/// Path to global system-wide data directory
std::string dataPath() const;
/// Returns system-specific name for dynamic libraries ("libStupidAI.so" or "StupidAI.dll")
/// Returns system-specific name for dynamic libraries ( StupidAI => "libStupidAI.so" or "StupidAI.dll")
std::string libraryName(std::string basename) const;
};

View File

@ -332,25 +332,26 @@ void CResourceHandler::initialize()
initialLoader = new CResourceLoader;
resourceLoader = new CResourceLoader;
shared_ptr<ISimpleResourceLoader> rootDir(new CFilesystemLoader(VCMIDirs::get().dataPath(), 0, true));
initialLoader->addLoader("GLOBAL/", rootDir, false);
initialLoader->addLoader("ALL/", rootDir, false);
auto userDir = rootDir;
//add local directory to "ALL" but only if it differs from root dir (true for linux)
if (VCMIDirs::get().dataPath() != VCMIDirs::get().localPath())
for (auto path : VCMIDirs::get().dataPaths())
{
userDir = shared_ptr<ISimpleResourceLoader>(new CFilesystemLoader(VCMIDirs::get().localPath(), 0, true));
initialLoader->addLoader("ALL/", userDir, false);
shared_ptr<ISimpleResourceLoader> loader(new CFilesystemLoader(path, 0, true));
initialLoader->addLoader("GLOBAL/", loader, false);
initialLoader->addLoader("ALL/", loader, false);
}
//create "LOCAL" dir with current userDir (may be same as rootDir)
initialLoader->addLoader("LOCAL/", userDir, false);
{
shared_ptr<ISimpleResourceLoader> loader(new CFilesystemLoader(VCMIDirs::get().userDataPath(), 0, true));
initialLoader->addLoader("LOCAL/", loader, false);
if (!vstd::contains(VCMIDirs::get().dataPaths(), VCMIDirs::get().userDataPath()))
initialLoader->addLoader("ALL/", loader, false);
}
recurseInDir("ALL/CONFIG", 0);// look for configs
recurseInDir("ALL/DATA", 0); // look for archives
recurseInDir("ALL/MODS", 2); // look for mods. Depth 2 is required for now but won't cause issues if no mods present
recurseInDir("ALL/MODS", 2); // look for mods. Depth 2 is required for now but won't cause spped issues if no mods present
}
void CResourceHandler::loadDirectory(const std::string &prefix, const std::string &mountPoint, const JsonNode & config)

View File

@ -364,13 +364,13 @@ void ERMInterpreter::scanForScripts()
{
using namespace boost::filesystem;
//parser checking
if(!exists(VCMIDirs::get().dataPath() + "/Data/s/"))
if(!exists(VCMIDirs::get().dataPaths().back() + "/Data/s/"))
{
logGlobal->warnStream() << "Warning: Folder " << VCMIDirs::get().dataPath() << "/Data/s/ doesn't exist!";
logGlobal->warnStream() << "Warning: Folder " << VCMIDirs::get().dataPaths().back() << "/Data/s/ doesn't exist!";
return;
}
directory_iterator enddir;
for (directory_iterator dir(VCMIDirs::get().dataPath() + "/Data/s"); dir!=enddir; dir++)
for (directory_iterator dir(VCMIDirs::get().dataPaths().back() + "/Data/s"); dir!=enddir; dir++)
{
if(is_regular(dir->status()))
{

View File

@ -3765,12 +3765,21 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
}
else if (message == "vcmiarmenelos") //build all buildings in selected town
{
CGTownInstance *town = gs->getTown(gs->getPlayer(player)->currentSelection);
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
CGTownInstance *town;
if (hero)
town = hero->visitedTown;
else
town = gs->getTown(gs->getPlayer(player)->currentSelection);
if (town)
{
for (auto & build : town->town->buildings)
{
if (!town->hasBuilt(build.first) && !build.second->Name().empty())
if (!town->hasBuilt(build.first)
&& !build.second->Name().empty()
&& build.first != BuildingID::SHIP)
{
buildStructure(town->id, build.first, true);
}

View File

@ -536,7 +536,7 @@ static void handleCommandOptions(int argc, char *argv[])
int main(int argc, char** argv)
{
console = new CConsoleHandler;
CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Server_log.txt", console);
CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Server_log.txt", console);
logConfig.configureDefault();
preinitDLL(console);

View File

@ -22,7 +22,7 @@
CVcmiTestConfig::CVcmiTestConfig()
{
console = new CConsoleHandler;
CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Test_log.txt", console);
CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Test_log.txt", console);
logConfig.configureDefault();
preinitDLL(console);
settings.init();