From bc81c9c8bf89c5181ce22b0f6510c0b28d01b183 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Mon, 16 Jul 2012 16:35:14 -0300 Subject: [PATCH] Packages system with .otpkg files When otclient initializes it tries to find all .otpkg files inside the current search paths (./ ./modules ./addons) and then add them to the front of current search paths. This way .otpkg can contains many modules/addons and modifications in a single file that otclient can recognize. otpkg files can be compressed files supported by PhysFS, which are ZIP (.zip) and LZMA (.7z). --- init.lua | 11 ++-- modules/client_skins/skins.lua | 14 ++--- modules/corelib/ui/uimessagebox.lua | 2 +- src/framework/core/resourcemanager.cpp | 72 ++++++++++++++++---------- src/framework/core/resourcemanager.h | 13 +++-- src/framework/luafunctions.cpp | 9 ++-- 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/init.lua b/init.lua index 3a3982dc..560fad2d 100644 --- a/init.lua +++ b/init.lua @@ -8,18 +8,21 @@ g_logger.setLogFile(g_resources.getWorkDir() .. g_app.getCompactName() .. ".log" g_logger.info(g_app.getName() .. ' ' .. g_app.getVersion() .. ' rev ' .. g_app.getBuildRevision() .. ' (' .. g_app.getBuildCommit() .. ') built on ' .. g_app.getBuildDate() .. ' for arch ' .. g_app.getBuildArch()) --add base folder to search path -g_resources.addToSearchPath(g_resources.getWorkDir()) +g_resources.addSearchPath(g_resources.getWorkDir()) -- add modules directory to the search path -if not g_resources.addToSearchPath(g_resources.getWorkDir() .. "modules", true) then +if not g_resources.addSearchPath(g_resources.getWorkDir() .. "modules", true) then g_logger.fatal("Unable to add modules directory to the search path.") end -- try to add addons path too -g_resources.addToSearchPath(g_resources.getWorkDir() .. "addons", true) +g_resources.addSearchPath(g_resources.getWorkDir() .. "addons", true) -- setup directory for saving configurations -g_resources.setupWriteDir(g_app.getCompactName()) +g_resources.setupUserWriteDir(g_app.getCompactName()) + +-- search all packages +g_resources.searchAndAddPackages('/', '.otpkg', true) -- load configurations g_configs.load("/config.otml") diff --git a/modules/client_skins/skins.lua b/modules/client_skins/skins.lua index 035dd4e5..e6bba852 100644 --- a/modules/client_skins/skins.lua +++ b/modules/client_skins/skins.lua @@ -27,7 +27,7 @@ function Skins.init() Skins.installSkins('skins') if installedSkins[defaultSkinName] then - g_resources.addToSearchPath(getSkinPath(defaultSkinName), 0) + g_resources.addSearchPath(getSkinPath(defaultSkinName), 0) end local userSkinName = g_settings.get('skin', 'false') @@ -50,9 +50,9 @@ function Skins.init() end function Skins.terminate() - g_resources.removeFromSearchPath(getSkinPath(defaultSkinName)) + g_resources.removeSearchPath(getSkinPath(defaultSkinName)) if currentSkin then - g_resources.removeFromSearchPath(getSkinPath(currentSkin.name)) + g_resources.removeSearchPath(getSkinPath(currentSkin.name)) end installedSkins = nil @@ -98,10 +98,12 @@ function Skins.setSkin(name) Skins.loadSkin(defaultSkin) end - if currentSkin then - g_resources.removeFromSearchPath(getSkinPath(currentSkin.name)) + if currentSkin and currentSkin.name ~= defaultSkinName then + g_resources.removeSearchPath(getSkinPath(currentSkin.name)) + end + if skin.name ~= defaultSkinName then + g_resources.addSearchPath(getSkinPath(skin.name), true) end - g_resources.addToSearchPath(getSkinPath(skin.name), true) Skins.loadSkin(skin) currentSkin = skin diff --git a/modules/corelib/ui/uimessagebox.lua b/modules/corelib/ui/uimessagebox.lua index 73381d48..81f02d70 100644 --- a/modules/corelib/ui/uimessagebox.lua +++ b/modules/corelib/ui/uimessagebox.lua @@ -38,7 +38,7 @@ function UIMessageBox.display(title, message, flags) connect(messagebox, { onEscape = function(self) self:cancel() end }) end - messagebox:lock() + --messagebox:lock() return messagebox end diff --git a/src/framework/core/resourcemanager.cpp b/src/framework/core/resourcemanager.cpp index a17e46ef..304fe7c7 100644 --- a/src/framework/core/resourcemanager.cpp +++ b/src/framework/core/resourcemanager.cpp @@ -65,7 +65,7 @@ void ResourceManager::discoverWorkDir(const std::string& appName, const std::str g_logger.fatal(stdext::format("Unable to find %s, the application cannot be initialized.", existentFile)); } -bool ResourceManager::setupWriteDir(const std::string& appWriteDirName) +bool ResourceManager::setupUserWriteDir(const std::string& appWriteDirName) { std::string userDir = PHYSFS_getUserDir(); std::string dirName; @@ -75,49 +75,69 @@ bool ResourceManager::setupWriteDir(const std::string& appWriteDirName) dirName = appWriteDirName; #endif std::string writeDir = userDir + dirName; + return setWriteDir(writeDir); +} + +bool ResourceManager::setWriteDir(const std::string& writeDir, bool create) +{ + if(!PHYSFS_setWriteDir(writeDir.c_str()) && !create) { + g_logger.error(stdext::format("Unable to set write directory '%s': %s", writeDir, PHYSFS_getLastError())); + return false; + } + + if(!PHYSFS_mkdir(writeDir.c_str())) { + g_logger.error(stdext::format("Unable to create write directory '%s': %s", writeDir, PHYSFS_getLastError())); + return false; + } if(!PHYSFS_setWriteDir(writeDir.c_str())) { - if(!PHYSFS_setWriteDir(userDir.c_str())) { - g_logger.error("User directory not found."); - return false; - } - if(!PHYSFS_mkdir(dirName.c_str())) { - g_logger.error("Cannot create directory for saving configurations."); - return false; - } - if(!PHYSFS_setWriteDir(writeDir.c_str())) { - g_logger.error("Unable to set write directory."); - return false; - } + g_logger.error(stdext::format("Unable to set write directory '%s': %s", writeDir, PHYSFS_getLastError())); + return false; } - addToSearchPath(writeDir, true); - //g_logger.debug(stdext::format("Setup write dir %s", writeDir)); + + if(!m_writeDir.empty()) + removeSearchPath(m_writeDir); + + m_writeDir = writeDir; + + if(!addSearchPath(writeDir)) + g_logger.error(stdext::format("Unable to add write directory '%s' to search path")); + return true; } -bool ResourceManager::addToSearchPath(const std::string& path, bool insertInFront) +bool ResourceManager::addSearchPath(const std::string& path, bool pushFront) { - if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1)) + if(!PHYSFS_addToSearchPath(path.c_str(), pushFront ? 0 : 1)) return false; - //g_logger.debug(stdext::format("Add search path %s", path)); + if(pushFront) + m_searchPaths.push_front(path); + else + m_searchPaths.push_back(path); m_hasSearchPath = true; return true; } -bool ResourceManager::removeFromSearchPath(const std::string& path) +bool ResourceManager::removeSearchPath(const std::string& path) { if(!PHYSFS_removeFromSearchPath(path.c_str())) return false; - //g_logger.debug(stdext::format("Remove search path %s", path)); + auto it = std::find(m_searchPaths.begin(), m_searchPaths.end(), path); + assert(it != m_searchPaths.end()); + m_searchPaths.erase(it); return true; } -void ResourceManager::searchAndAddPackages(const std::string& packagesDir, const std::string& packageExt, bool append) +void ResourceManager::searchAndAddPackages(const std::string& packagesDir, const std::string& packageExt) { - auto files = listDirectoryFiles(resolvePath(packagesDir)); - for(const std::string& file : files) { - if(boost::ends_with(file, packageExt)) - addToSearchPath(packagesDir + "/" + file, !append); + auto files = listDirectoryFiles(packagesDir); + for(auto it = files.rbegin(); it != files.rend(); ++it) { + const std::string& file = *it; + if(!boost::ends_with(file, packageExt)) + continue; + std::string package = getRealDir(packagesDir) + "/" + file; + if(!addSearchPath(package, true)) + g_logger.error(stdext::format("Unable to read package '%s': %s", package, PHYSFS_getLastError())); } } @@ -267,7 +287,7 @@ std::string ResourceManager::resolvePath(const std::string& path) std::string ResourceManager::getRealDir(const std::string& path) { std::string dir; - const char *cdir = PHYSFS_getRealDir(path.c_str()); + const char *cdir = PHYSFS_getRealDir(resolvePath(path).c_str()); if(cdir) dir = cdir; return dir; diff --git a/src/framework/core/resourcemanager.h b/src/framework/core/resourcemanager.h index 26282f9f..c4cd28f9 100644 --- a/src/framework/core/resourcemanager.h +++ b/src/framework/core/resourcemanager.h @@ -35,11 +35,12 @@ public: void terminate(); void discoverWorkDir(const std::string& appName, const std::string& existentFile); - bool setupWriteDir(const std::string& appWriteDirName); + bool setupUserWriteDir(const std::string& appWriteDirName); + bool setWriteDir(const std::string& writeDir, bool create = false); - bool addToSearchPath(const std::string& path, bool insertInFront = true); - bool removeFromSearchPath(const std::string& path); - void searchAndAddPackages(const std::string& packagesDir, const std::string& packagesExt, bool append); + bool addSearchPath(const std::string& path, bool pushFront = false); + bool removeSearchPath(const std::string& path); + void searchAndAddPackages(const std::string& packagesDir, const std::string& packagesExt); bool fileExists(const std::string& fileName); bool directoryExists(const std::string& directoryName); @@ -64,11 +65,15 @@ public: std::string resolvePath(const std::string& path); std::string getRealDir(const std::string& path); std::string getBaseDir(); + std::string getWriteDir() { return m_writeDir; } std::string getWorkDir() { return m_workDir; } + std::deque getSearchPaths() { return m_searchPaths; } private: std::string m_workDir; + std::string m_writeDir; Boolean m_hasSearchPath; + std::deque m_searchPaths; }; extern ResourceManager g_resources; diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 29ec2739..d511d553 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -125,12 +125,15 @@ void Application::registerLuaFunctions() // ResourceManager g_lua.registerSingletonClass("g_resources"); - g_lua.bindSingletonFunction("g_resources", "addToSearchPath", &ResourceManager::addToSearchPath, &g_resources); - g_lua.bindSingletonFunction("g_resources", "setupWriteDir", &ResourceManager::setupWriteDir, &g_resources); - g_lua.bindSingletonFunction("g_resources", "removeFromSearchPath", &ResourceManager::removeFromSearchPath, &g_resources); + g_lua.bindSingletonFunction("g_resources", "addSearchPath", &ResourceManager::addSearchPath, &g_resources); + g_lua.bindSingletonFunction("g_resources", "setupUserWriteDir", &ResourceManager::setupUserWriteDir, &g_resources); + g_lua.bindSingletonFunction("g_resources", "setWriteDir", &ResourceManager::setWriteDir, &g_resources); + g_lua.bindSingletonFunction("g_resources", "searchAndAddPackages", &ResourceManager::searchAndAddPackages, &g_resources); + g_lua.bindSingletonFunction("g_resources", "removeSearchPath", &ResourceManager::removeSearchPath, &g_resources); g_lua.bindSingletonFunction("g_resources", "fileExists", &ResourceManager::fileExists, &g_resources); g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources); g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &g_resources); + g_lua.bindSingletonFunction("g_resources", "getSearchPaths", &ResourceManager::getSearchPaths, &g_resources); // Module g_lua.registerClass();