diff --git a/.gitmodules b/.gitmodules index c4212e3f..0d4e4e8d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "googletest"] path = googletest url = https://github.com/google/googletest.git -[submodule "ZipLib"] - path = ZipLib - url = https://github.com/ParadoxGameConverters/ZipLib.git [submodule "imageMagick"] path = imageMagick url = https://github.com/ParadoxGameConverters/imageMagick.git diff --git a/CK3toEU4.sln b/CK3toEU4.sln index 460fa442..609e3b8f 100644 --- a/CK3toEU4.sln +++ b/CK3toEU4.sln @@ -16,13 +16,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CK3ToEU4Tests", "CK3ToEU4Te EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fronter", "Fronter\Fronter.vcxproj", "{D4E43E3D-E131-466D-9AA7-704C2298EACC}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "ZipLib\extlibs\bzip2\bzip2.vcxproj", "{DBBF348D-C221-4F2E-8A0D-24EFA0D98E71}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZipLib", "commonItems\ZipLib\ZipLib.vcxproj", "{5C9FD859-DDF9-4510-8397-B329B0AE8C48}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzma", "ZipLib\extlibs\lzma\lzma.vcxproj", "{7EAD1358-3E72-4FB6-A212-25D462B5C1E9}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "commonItems\ZipLib\extlibs\bzip2\bzip2.vcxproj", "{DBBF348D-C221-4F2E-8A0D-24EFA0D98E71}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "ZipLib\extlibs\zlib\zlib.vcxproj", "{BAEB16B3-DB4C-432F-9E6A-2ACADEA0691D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzma", "commonItems\ZipLib\extlibs\lzma\lzma.vcxproj", "{7EAD1358-3E72-4FB6-A212-25D462B5C1E9}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZipLib", "ZipLib\ZipLib.vcxproj", "{5C9FD859-DDF9-4510-8397-B329B0AE8C48}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "commonItems\ZipLib\extlibs\zlib\zlib.vcxproj", "{BAEB16B3-DB4C-432F-9E6A-2ACADEA0691D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -42,6 +42,10 @@ Global {D4E43E3D-E131-466D-9AA7-704C2298EACC}.Debug|x64.Build.0 = Debug|x64 {D4E43E3D-E131-466D-9AA7-704C2298EACC}.Release|x64.ActiveCfg = Release|x64 {D4E43E3D-E131-466D-9AA7-704C2298EACC}.Release|x64.Build.0 = Release|x64 + {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Debug|x64.ActiveCfg = Debug|x64 + {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Debug|x64.Build.0 = Debug|x64 + {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Release|x64.ActiveCfg = Release|x64 + {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Release|x64.Build.0 = Release|x64 {DBBF348D-C221-4F2E-8A0D-24EFA0D98E71}.Debug|x64.ActiveCfg = Debug|x64 {DBBF348D-C221-4F2E-8A0D-24EFA0D98E71}.Debug|x64.Build.0 = Debug|x64 {DBBF348D-C221-4F2E-8A0D-24EFA0D98E71}.Release|x64.ActiveCfg = Release|x64 @@ -54,10 +58,6 @@ Global {BAEB16B3-DB4C-432F-9E6A-2ACADEA0691D}.Debug|x64.Build.0 = Debug|x64 {BAEB16B3-DB4C-432F-9E6A-2ACADEA0691D}.Release|x64.ActiveCfg = Release|x64 {BAEB16B3-DB4C-432F-9E6A-2ACADEA0691D}.Release|x64.Build.0 = Release|x64 - {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Debug|x64.ActiveCfg = Debug|x64 - {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Debug|x64.Build.0 = Debug|x64 - {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Release|x64.ActiveCfg = Release|x64 - {5C9FD859-DDF9-4510-8397-B329B0AE8C48}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CK3toEU4/CK3toEU4.vcxproj b/CK3toEU4/CK3toEU4.vcxproj index 1a1a3a81..4aec1050 100644 --- a/CK3toEU4/CK3toEU4.vcxproj +++ b/CK3toEU4/CK3toEU4.vcxproj @@ -55,13 +55,13 @@ WIN32;NDEBUG;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_CONSOLE;_SILENCE_CXX20_U8PATH_DEPRECATION_WARNING;%(PreprocessorDefinitions) stdcpplatest - ..\commonItems;..\ZipLib;..\imageMagick\include-windows + ..\commonItems;..\commonItems\ZipLib;..\imageMagick\include-windows true Console ..\imageMagick\lib-windows;%(AdditionalLibraryDirectories) - Resources\rakaly.dll.lib;CORE_RL_aom_.lib;CORE_RL_bzlib_.lib;CORE_RL_cairo_.lib;CORE_RL_croco_.lib;CORE_RL_exr_.lib;CORE_RL_ffi_.lib;CORE_RL_flif_.lib;CORE_RL_freetype_.lib;CORE_RL_fribidi_.lib;CORE_RL_glib_.lib;CORE_RL_harfbuzz_.lib;CORE_RL_jbig_.lib;CORE_RL_jp2_.lib;CORE_RL_jpeg_.lib;CORE_RL_lcms_.lib;CORE_RL_libde265_.lib;CORE_RL_libheif_.lib;CORE_RL_liblzma_.lib;CORE_RL_libraw_.lib;CORE_RL_librsvg_.lib;CORE_RL_libxml_.lib;CORE_RL_libzip_.lib;CORE_RL_lqr_.lib;CORE_RL_Magick++_.lib;CORE_RL_MagickCore_.lib;CORE_RL_MagickWand_.lib;CORE_RL_openjpeg_.lib;CORE_RL_pango_.lib;CORE_RL_pixman_.lib;CORE_RL_png_.lib;CORE_RL_tiff_.lib;CORE_RL_webp_.lib;CORE_RL_zlib_.lib;FILTER_analyze_.lib;ImageMagickObject.lib;%(AdditionalDependencies) + Resources\rakaly.dll.lib;CORE_RL_aom_.lib;CORE_RL_bzlib_.lib;CORE_RL_cairo_.lib;CORE_RL_croco_.lib;CORE_RL_exr_.lib;CORE_RL_ffi_.lib;CORE_RL_flif_.lib;CORE_RL_freetype_.lib;CORE_RL_fribidi_.lib;CORE_RL_glib_.lib;CORE_RL_harfbuzz_.lib;CORE_RL_jbig_.lib;CORE_RL_jp2_.lib;CORE_RL_jpeg_.lib;CORE_RL_lcms_.lib;CORE_RL_libde265_.lib;CORE_RL_libheif_.lib;CORE_RL_liblzma_.lib;CORE_RL_libraw_.lib;CORE_RL_librsvg_.lib;CORE_RL_libxml_.lib;CORE_RL_libzip_.lib;CORE_RL_lqr_.lib;CORE_RL_Magick++_.lib;CORE_RL_MagickCore_.lib;CORE_RL_MagickWand_.lib;CORE_RL_openjpeg_.lib;CORE_RL_pango_.lib;CORE_RL_pixman_.lib;CORE_RL_png_.lib;CORE_RL_tiff_.lib;CORE_RL_webp_.lib;CORE_RL_zlib_.lib;FILTER_analyze_.lib;ImageMagickObject.lib;$(SolutionDir)$(Platform)\$(Configuration)\ZipLib.lib;$(SolutionDir)$(Platform)\$(Configuration)\bzip2.lib;$(SolutionDir)$(Platform)\$(Configuration)\lzma.lib;$(SolutionDir)$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) Copy_Files.bat @@ -94,6 +94,8 @@ + + @@ -117,8 +119,6 @@ - - @@ -192,6 +192,8 @@ + + @@ -216,8 +218,6 @@ - - @@ -282,11 +282,6 @@ - - - {5c9fd859-ddf9-4510-8397-b329b0ae8c48} - - diff --git a/CK3toEU4/CK3toEU4.vcxproj.filters b/CK3toEU4/CK3toEU4.vcxproj.filters index 8578a9dc..c7cda874 100644 --- a/CK3toEU4/CK3toEU4.vcxproj.filters +++ b/CK3toEU4/CK3toEU4.vcxproj.filters @@ -40,9 +40,6 @@ {b8f0c17a-bba5-4e2c-a35c-29da525cc60e} - - {f149b03a-69e9-4ef6-a116-0b0ab2d38af7} - {2a9ce57e-33f2-4d14-b582-8c566644af3b} @@ -112,6 +109,9 @@ {d10185d1-0fad-4d18-8a4c-249ea6deb425} + + {55ecf61d-6900-4f6d-95e7-715012a9d5cb} + @@ -208,12 +208,6 @@ CK3World\Titles - - CK3World\Mods - - - CK3World\Mods - CK3World\Flags @@ -400,6 +394,12 @@ CommonItems + + CommonItems\ModLoader + + + CommonItems\ModLoader + @@ -497,12 +497,6 @@ CK3World\Titles - - CK3World\Mods - - - CK3World\Mods - CK3World\Flags @@ -689,5 +683,11 @@ CommonItems + + CommonItems\ModLoader + + + CommonItems\ModLoader + \ No newline at end of file diff --git a/CK3toEU4/CMakeLists.txt b/CK3toEU4/CMakeLists.txt index 3db208db..4e38bfb0 100644 --- a/CK3toEU4/CMakeLists.txt +++ b/CK3toEU4/CMakeLists.txt @@ -17,11 +17,11 @@ add_compile_options("-pthread") add_link_options(-no-pie) include_directories("../commonItems") -include_directories("../ZipLib") +include_directories("../commonItems/ZipLib") include_directories("/usr/local/include/ImageMagick-7/") include_directories("${PROJECT_SOURCE_DIR}") link_directories(${CMAKE_SOURCE_DIR}/Resources /usr/local/lib) -add_subdirectory(../ZipLib [binary_dir]) +add_subdirectory(../commonItems/ZipLib [binary_dir]) set(MAIN_SOURCES ${MAIN_SOURCES} "${PROJECT_SOURCE_DIR}/CK3ToEU4Converter.cpp") set(MAIN_SOURCES ${MAIN_SOURCES} "${PROJECT_SOURCE_DIR}/main.cpp") @@ -46,8 +46,6 @@ set(CK3WORLD_GEOGRAPHY_SOURCES ${CK3WORLD_GEOGRAPHY_SOURCES} "${PROJECT_SOURCE_D set(CK3WORLD_GEOGRAPHY_SOURCES ${CK3WORLD_GEOGRAPHY_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Geography/ProvinceHolding.cpp") set(CK3WORLD_GEOGRAPHY_SOURCES ${CK3WORLD_GEOGRAPHY_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Geography/CountyDetails.cpp") set(CK3WORLD_GEOGRAPHY_SOURCES ${CK3WORLD_GEOGRAPHY_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Geography/CountyDetail.cpp") -set(CK3WORLD_MODS_SOURCES ${CK3WORLD_MODS_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Mods/Mod.cpp") -set(CK3WORLD_MODS_SOURCES ${CK3WORLD_MODS_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Mods/Mods.cpp") set(CK3WORLD_RELIGIONS_SOURCES ${CK3WORLD_RELIGIONS_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Religions/Faith.cpp") set(CK3WORLD_RELIGIONS_SOURCES ${CK3WORLD_RELIGIONS_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Religions/Faiths.cpp") set(CK3WORLD_RELIGIONS_SOURCES ${CK3WORLD_RELIGIONS_SOURCES} "${PROJECT_SOURCE_DIR}/CK3World/Religions/Religion.cpp") @@ -120,6 +118,8 @@ set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/Date.cpp") set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/GameVersion.cpp") set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/LinuxUtils.cpp") set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/Log.cpp") +set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/ModLoader/ModLoader.cpp") +set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/ModLoader/ModParser.cpp") set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/OSCommonLayer.cpp") set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/Parser.cpp") set(COMMON_SOURCES ${COMMON_SOURCES} "../commonItems/ParserHelpers.cpp") @@ -137,7 +137,6 @@ add_executable(CK3toEU4 ${CK3WORLD_DYNASTIES_SOURCES} ${CK3WORLD_FLAGS_SOURCES} ${CK3WORLD_GEOGRAPHY_SOURCES} - ${CK3WORLD_MODS_SOURCES} ${CK3WORLD_RELIGIONS_SOURCES} ${CK3WORLD_TITLES_SOURCES} diff --git a/CK3toEU4/Source/CK3World/Mods/Mod.cpp b/CK3toEU4/Source/CK3World/Mods/Mod.cpp deleted file mode 100644 index 158c7e07..00000000 --- a/CK3toEU4/Source/CK3World/Mods/Mod.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "Mod.h" -#include "Log.h" -#include "ParserHelpers.h" -#include "CommonRegexes.h" - -CK3::Mod::Mod(std::istream& theStream) -{ - registerKeyword("name", [this](const std::string& unused, std::istream& theStream) { - const commonItems::singleString nameString(theStream); - name = nameString.getString(); - }); - registerRegex("path|archive", [this](const std::string& unused, std::istream& theStream) { - const commonItems::singleString pathString(theStream); - path = pathString.getString(); - }); - registerRegex(commonItems::catchallRegex, commonItems::ignoreItem); - - parseStream(theStream); - clearRegisteredKeywords(); - - if (!path.empty()) - { - const auto lastDot = path.find_last_of('.'); - if (lastDot != std::string::npos) - { - const auto ending = path.substr(lastDot + 1, path.size()); - compressed = ending == "zip" || ending == "bin"; - } - } -} diff --git a/CK3toEU4/Source/CK3World/Mods/Mod.h b/CK3toEU4/Source/CK3World/Mods/Mod.h deleted file mode 100644 index 9077aebf..00000000 --- a/CK3toEU4/Source/CK3World/Mods/Mod.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef CK3_MOD_H -#define CK3_MOD_H - -#include "Parser.h" - -namespace CK3 -{ -class Mod: commonItems::parser -{ - public: - explicit Mod(std::istream& theStream); - - [[nodiscard]] const auto& getName() const { return name; } - [[nodiscard]] const auto& getPath() const { return path; } - [[nodiscard]] auto looksValid() const { return !name.empty() && !path.empty(); } - [[nodiscard]] auto isCompressed() const { return compressed; } - - void setPath(const std::string& thePath) { path = thePath; } - - private: - bool compressed = false; - - std::string name; - std::string path; -}; -} // namespace CK3 - -#endif // CK3_MOD_H \ No newline at end of file diff --git a/CK3toEU4/Source/CK3World/Mods/Mods.cpp b/CK3toEU4/Source/CK3World/Mods/Mods.cpp deleted file mode 100644 index 6ae0d712..00000000 --- a/CK3toEU4/Source/CK3World/Mods/Mods.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include "Mods.h" -#include "../../Configuration/Configuration.h" -#include "CommonFunctions.h" -#include "Log.h" -#include "Mod.h" -#include "OSCompatibilityLayer.h" -#include "ZipFile.h" -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; - -void CK3::Mods::loadModDirectory(const Configuration& theConfiguration) -{ - if (theConfiguration.getModFileNames().empty()) - { - Log(LogLevel::Info) << "No mods were detected in savegame. Skipping mod processing."; - return; - } - - loadCK3ModDirectory(theConfiguration); - - Log(LogLevel::Info) << "\tDetermining Mod Usability"; - auto allMods = possibleMods; - allMods.insert(possibleCompressedMods.begin(), possibleCompressedMods.end()); - for (const auto& usedMod: allMods) - { - auto possibleModPath = getModPath(usedMod.first); - if (possibleModPath) - { - if (!commonItems::DoesFolderExist(*possibleModPath) && !commonItems::DoesFileExist(*possibleModPath)) - { - Log(LogLevel::Warning) << usedMod.first + " could not be found in the specified mod directory " + - "- a valid mod directory must be specified. Tried " + *possibleModPath; - continue; - } - - LOG(LogLevel::Info) << "\t\t->> Found potentially usable [" << usedMod.first << "]: " << *possibleModPath + "/"; - usableMods.insert(std::pair(usedMod.first, *possibleModPath + "/")); - } - else - { - Log(LogLevel::Warning) << "No path could be found for " + usedMod.first + - ". Check that the mod is present and that the .mod file specifies the path for the mod"; - } - } -} - -void CK3::Mods::loadCK3ModDirectory(const Configuration& theConfiguration) -{ - const auto& CK3ModsPath = theConfiguration.getCK3DocPath() + "/mod"; - if (!commonItems::DoesFolderExist(CK3ModsPath)) - throw std::invalid_argument("Crusader Kings 3 mods directory path is invalid! Is it at: " + theConfiguration.getCK3DocPath() + "/mod/ ?"); - - LOG(LogLevel::Info) << "\tCK3 mods directory is " << CK3ModsPath; - - const auto diskModNames = commonItems::GetAllFilesInFolder(CK3ModsPath); - for (const auto& usedModFileName: theConfiguration.getModFileNames()) - { - const auto trimmedModFileName = trimPath(usedModFileName); - if (!diskModNames.contains(trimmedModFileName)) - { - Log(LogLevel::Warning) << "Savegame uses mod at " << usedModFileName - << " which is not present on disk. Skipping at your risk, but this can greatly affect conversion."; - continue; - } - if (getExtension(trimmedModFileName) != "mod") - continue; // shouldn't be necessary but just in case. - try - { - std::ifstream modFile(fs::u8path(CK3ModsPath + "/" + trimmedModFileName)); - Mod theMod(modFile); - modFile.close(); - - if (theMod.looksValid()) - { - if (!theMod.isCompressed()) - { - if (!commonItems::DoesFolderExist(theMod.getPath())) - { - // Maybe we have a relative path - if (commonItems::DoesFolderExist(theConfiguration.getCK3DocPath() + "/" + theMod.getPath())) - { - // fix this. - theMod.setPath(theConfiguration.getCK3DocPath() + "/" + theMod.getPath()); - } - else - { - Log(LogLevel::Warning) << "Mod file " + usedModFileName + " points to " + theMod.getPath() + - " which does not exist! Skipping at your risk, but this can greatly affect conversion."; - continue; - } - } - - possibleMods.insert(std::make_pair(theMod.getName(), theMod.getPath())); - Log(LogLevel::Info) << "\t\tFound potential mod named " << theMod.getName() << " with a mod file at " << CK3ModsPath + "/" + trimmedModFileName - << " and itself at " << theMod.getPath(); - } - else - { - if (!commonItems::DoesFileExist(theMod.getPath())) - { - Log(LogLevel::Warning) << "Mod file " + usedModFileName + " points to " + theMod.getPath() + - " which does not exist! Skipping at your risk, but this can greatly affect conversion."; - continue; - } - - possibleCompressedMods.insert(std::make_pair(theMod.getName(), theMod.getPath())); - Log(LogLevel::Info) << "\t\tFound a compressed mod named " << theMod.getName() << " with a mod file at " << CK3ModsPath << "/" - << trimmedModFileName << " and itself at " << theMod.getPath(); - } - } - else - { - Log(LogLevel::Warning) << "Mod at " << CK3ModsPath + "/" + trimmedModFileName << " does not look valid."; - } - } - catch (std::exception&) - { - LOG(LogLevel::Warning) << "Error while reading " << CK3ModsPath << "/" << trimmedModFileName << "! Mod will not be useable for conversions."; - } - } -} - -std::optional CK3::Mods::getModPath(const std::string& modName) const -{ - const auto& mod = possibleMods.find(modName); - if (mod != possibleMods.end()) - { - return mod->second; - } - - const auto& compressedMod = possibleCompressedMods.find(modName); - if (compressedMod != possibleCompressedMods.end()) - { - const auto archivePath = compressedMod->second; - const auto uncompressedName = trimPath(trimExtension(archivePath)); - - commonItems::TryCreateFolder("mods/"); - - if (!commonItems::DoesFolderExist("mods/" + uncompressedName)) - { - LOG(LogLevel::Info) << "\t\tUncompressing: " << archivePath; - if (!extractZip(archivePath, "mods/" + uncompressedName)) - { - LOG(LogLevel::Warning) << "We're having trouble automatically uncompressing your mod."; - LOG(LogLevel::Warning) << "Please, manually uncompress: " << archivePath; - LOG(LogLevel::Warning) << "Into: CK3toEU4/mods/" << uncompressedName; - LOG(LogLevel::Warning) << "Then run the converter again. Thank you and good luck."; - return std::nullopt; - } - } - - if (commonItems::DoesFolderExist("mods/" + uncompressedName)) - { - return "mods/" + uncompressedName; - } - } - - return std::nullopt; -} - -bool CK3::Mods::extractZip(const std::string& archive, const std::string& path) const -{ - commonItems::TryCreateFolder(path); - auto modfile = ZipFile::Open(archive); - if (!modfile) - return false; - for (size_t entryNum = 0; entryNum < modfile->GetEntriesCount(); ++entryNum) - { - const auto& entry = modfile->GetEntry(static_cast(entryNum)); - const auto& inpath = entry->GetFullName(); - const auto& name = entry->GetName(); - if (entry->IsDirectory()) - continue; - - // Does target directory exist? - const auto dirnamepos = inpath.find(name); - const auto dirname = path + "/" + inpath.substr(0, dirnamepos); - if (!commonItems::DoesFolderExist(dirname)) - { - // we need to craft our way through to target directory. - auto remainder = inpath; - auto currentpath = path; - while (remainder != name) - { - const auto pos = remainder.find_first_of('/'); - if (pos != std::string::npos) - { - auto makedirname = remainder.substr(0, pos); - currentpath += "/" + makedirname; - commonItems::TryCreateFolder(currentpath); - remainder = remainder.substr(pos + 1, remainder.length()); - } - else - break; - } - } - ZipFile::ExtractFile(archive, inpath, path + "/" + inpath); - } - return true; -} \ No newline at end of file diff --git a/CK3toEU4/Source/CK3World/Mods/Mods.h b/CK3toEU4/Source/CK3World/Mods/Mods.h deleted file mode 100644 index 2e7f78e8..00000000 --- a/CK3toEU4/Source/CK3World/Mods/Mods.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef CK3_MODS_H -#define CK3_MODS_H - -#include -#include -#include - -class Configuration; -namespace CK3 -{ -class Mods -{ - public: - Mods() = default; - void loadModDirectory(const Configuration& theConfiguration); - - [[nodiscard]] const auto& getMods() const { return usableMods; } - - private: - void loadCK3ModDirectory(const Configuration& theConfiguration); - - [[nodiscard]] bool extractZip(const std::string& archive, const std::string& path) const; - [[nodiscard]] std::optional getModPath(const std::string& modName) const; - - std::map possibleMods; // name, absolute path to mod directory - std::map possibleCompressedMods; // name, absolute path to zip file - std::map usableMods; // name, absolute path for directories, relative for unpacked -}; -} // namespace CK3 - -#endif // CK3_MODS_H \ No newline at end of file diff --git a/CK3toEU4/Source/CK3World/World.cpp b/CK3toEU4/Source/CK3World/World.cpp index 8c2dd3da..a14b8959 100644 --- a/CK3toEU4/Source/CK3World/World.cpp +++ b/CK3toEU4/Source/CK3World/World.cpp @@ -18,11 +18,14 @@ CK3::World::World(const std::shared_ptr& theConfiguration, const LOG(LogLevel::Info) << "*** Hello CK3, Deus Vult! ***"; registerRegex("SAV.*", [](const std::string& unused, std::istream& theStream) { }); - registerKeyword("mods", [theConfiguration](const std::string& unused, std::istream& theStream) { + registerKeyword("mods", [this, theConfiguration](std::istream& theStream) { Log(LogLevel::Info) << "-> Detecting used mods."; - const auto modsList = commonItems::stringList(theStream).getStrings(); - theConfiguration->setModFileNames(std::set(modsList.begin(), modsList.end())); - Log(LogLevel::Info) << "<> Savegame claims " << theConfiguration->getModFileNames().size() << " mods used."; + for (const auto& path: commonItems::getStrings(theStream)) + mods.emplace_back(Mod("", path)); + Log(LogLevel::Info) << "<> Savegame claims " << mods.size() << " mods used."; + commonItems::ModLoader modLoader; + modLoader.loadMods(theConfiguration->getCK3DocPath(), mods); + mods = modLoader.getMods(); }); registerKeyword("date", [this](const std::string& unused, std::istream& theStream) { const commonItems::singleString dateString(theStream); @@ -115,7 +118,6 @@ CK3::World::World(const std::shared_ptr& theConfiguration, const Log(LogLevel::Progress) << "10 %"; LOG(LogLevel::Info) << "* Priming Converter Components *"; - mods.loadModDirectory(*theConfiguration); primeLaFabricaDeColor(*theConfiguration); loadLandedTitles(*theConfiguration); loadCharacterTraits(*theConfiguration); @@ -347,16 +349,16 @@ void CK3::World::primeLaFabricaDeColor(const Configuration& theConfiguration) continue; namedColors.loadColors(theConfiguration.getCK3Path() + "common/named_colors/" + file); } - for (const auto& mod: mods.getMods()) + for (const auto& mod: mods) { - if (!commonItems::DoesFolderExist(mod.second + "common/named_colors")) + if (!commonItems::DoesFolderExist(mod.path + "common/named_colors")) continue; - Log(LogLevel::Info) << "<> Loading some colors from " << mod.first; - for (const auto& file: commonItems::GetAllFilesInFolder(mod.second + "common/named_colors")) + Log(LogLevel::Info) << "<> Loading some colors from [" << mod.name << "]"; + for (const auto& file: commonItems::GetAllFilesInFolder(mod.path + "common/named_colors")) { if (file.find(".txt") == std::string::npos) continue; - namedColors.loadColors(mod.second + "common/named_colors/" + file); + namedColors.loadColors(mod.path + "common/named_colors/" + file); } } Log(LogLevel::Info) << "<> Loaded " << laFabricaDeColor.getRegisteredColors().size() << " colors."; @@ -371,16 +373,16 @@ void CK3::World::loadLandedTitles(const Configuration& theConfiguration) continue; landedTitles.loadTitles(theConfiguration.getCK3Path() + "common/landed_titles/" + file); } - for (const auto& mod: mods.getMods()) + for (const auto& mod: mods) { - if (!commonItems::DoesFolderExist(mod.second + "common/landed_titles")) + if (!commonItems::DoesFolderExist(mod.path + "common/landed_titles")) continue; - Log(LogLevel::Info) << "<> Loading some landed titles from " << mod.first; - for (const auto& file: commonItems::GetAllFilesInFolder(mod.second + "common/landed_titles")) + Log(LogLevel::Info) << "<> Loading some landed titles from [" << mod.name << "]"; + for (const auto& file: commonItems::GetAllFilesInFolder(mod.path + "common/landed_titles")) { if (file.find(".txt") == std::string::npos) continue; - landedTitles.loadTitles(mod.second + "common/landed_titles/" + file); + landedTitles.loadTitles(mod.path + "common/landed_titles/" + file); } } Log(LogLevel::Info) << "<> Loaded " << landedTitles.getFoundTitles().size() << " landed titles."; @@ -395,16 +397,16 @@ void CK3::World::loadCharacterTraits(const Configuration& theConfiguration) continue; traitScraper.loadTraits(theConfiguration.getCK3Path() + "common/traits/" + file); } - for (const auto& mod: mods.getMods()) + for (const auto& mod: mods) { - if (!commonItems::DoesFolderExist(mod.second + "common/traits")) + if (!commonItems::DoesFolderExist(mod.path + "common/traits")) continue; - Log(LogLevel::Info) << "<> Loading some character traits from " << mod.first; - for (const auto& file: commonItems::GetAllFilesInFolder(mod.second + "common/traits")) + Log(LogLevel::Info) << "<> Loading some character traits from [" << mod.name << "]"; + for (const auto& file: commonItems::GetAllFilesInFolder(mod.path + "common/traits")) { if (file.find(".txt") == std::string::npos) continue; - traitScraper.loadTraits(mod.second + "common/traits/" + file); + traitScraper.loadTraits(mod.path + "common/traits/" + file); } } LOG(LogLevel::Info) << ">> " << traitScraper.getTraits().size() << " personalities scrutinized."; diff --git a/CK3toEU4/Source/CK3World/World.h b/CK3toEU4/Source/CK3World/World.h index bbd8dc43..f5dbc49c 100644 --- a/CK3toEU4/Source/CK3World/World.h +++ b/CK3toEU4/Source/CK3World/World.h @@ -14,7 +14,7 @@ #include "GameVersion.h" #include "Geography/CountyDetails.h" #include "Geography/ProvinceHoldings.h" -#include "Mods/Mods.h" +#include "ModLoader/ModLoader.h" #include "Parser.h" #include "Religions/Faiths.h" #include "Religions/Religions.h" diff --git a/CK3toEU4/Source/Configuration/Configuration.cpp b/CK3toEU4/Source/Configuration/Configuration.cpp index 4e922758..01f7e102 100644 --- a/CK3toEU4/Source/Configuration/Configuration.cpp +++ b/CK3toEU4/Source/Configuration/Configuration.cpp @@ -110,12 +110,6 @@ void Configuration::registerKeys() development = DEVELOPMENT(std::stoi(developmentString.getString())); Log(LogLevel::Info) << "Development set to: " << developmentString.getString(); }); - registerKeyword("selectedMods", [this](const std::string& unused, std::istream& theStream) { - const commonItems::stringList modsList(theStream); - const auto& theList = modsList.getStrings(); - modFileNames.insert(theList.begin(), theList.end()); - Log(LogLevel::Info) << modFileNames.size() << " mods selected by configuration. Deselected mods will be ignored."; - }); registerRegex(commonItems::catchallRegex, commonItems::ignoreItem); } diff --git a/CK3toEU4/Source/Configuration/Configuration.h b/CK3toEU4/Source/Configuration/Configuration.h index 9f3eca89..39dd74b4 100644 --- a/CK3toEU4/Source/Configuration/Configuration.h +++ b/CK3toEU4/Source/Configuration/Configuration.h @@ -2,7 +2,6 @@ #define CONFIGURATION_H #include "ConverterVersion.h" #include "Parser.h" -#include class Configuration: commonItems::parser { @@ -88,11 +87,8 @@ class Configuration: commonItems::parser [[nodiscard]] const auto& getSunset() const { return sunset; } [[nodiscard]] const auto& getDynamicInstitutions() const { return dynamicInstitutions; } [[nodiscard]] const auto& getDevelopment() const { return development; } - [[nodiscard]] const auto& getModFileNames() const { return modFileNames; } [[nodiscard]] const auto& getSplitVassals() const { return splitVassals; } - void setModFileNames(const std::set& mods) { modFileNames = mods; } - private: void registerKeys(); void setOutputName(); @@ -118,8 +114,6 @@ class Configuration: commonItems::parser DEVELOPMENT development = DEVELOPMENT::IMPORT; DEJURE dejure = DEJURE::ENABLED; SPLITVASSALS splitVassals = SPLITVASSALS::YES; - - std::set modFileNames; }; #endif // CONFIGURATION_H diff --git a/CK3toEU4/Source/EU4World/EU4World.cpp b/CK3toEU4/Source/EU4World/EU4World.cpp index 3d15d740..d483035d 100644 --- a/CK3toEU4/Source/EU4World/EU4World.cpp +++ b/CK3toEU4/Source/EU4World/EU4World.cpp @@ -21,7 +21,7 @@ EU4::World::World(const CK3::World& sourceWorld, const Configuration& theConfigu LOG(LogLevel::Info) << "*** Hello EU4, let's get painting. ***"; // Scraping localizations from CK3 so we may know proper names for our countries and people. LOG(LogLevel::Info) << "-> Reading Words"; - localizationMapper.scrapeLocalizations(theConfiguration, sourceWorld.getMods().getMods()); + localizationMapper.scrapeLocalizations(theConfiguration, sourceWorld.getMods()); Log(LogLevel::Progress) << "50 %"; // Scrape Primary Tags for nationalities diff --git a/CK3toEU4/Source/EU4World/EU4World.h b/CK3toEU4/Source/EU4World/EU4World.h index 348336e9..1afee55e 100644 --- a/CK3toEU4/Source/EU4World/EU4World.h +++ b/CK3toEU4/Source/EU4World/EU4World.h @@ -86,7 +86,7 @@ class World void outputReligions(const Configuration& theConfiguration, const std::vector& generatedReligions, const std::vector& reformedReligions) const; - void outputReligionIcons(const Configuration& theConfiguration, const std::vector& generatedReligions, const CK3::Mods& mods) const; + void outputReligionIcons(const Configuration& theConfiguration, const std::vector& generatedReligions, const Mods& mods) const; std::map> provinces; std::map> countries; diff --git a/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.cpp b/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.cpp index 50298b49..c31bf3d7 100644 --- a/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.cpp +++ b/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.cpp @@ -1,7 +1,6 @@ #include "FlagFoundry.h" #include "../../CK3World/CoatsOfArms/CoatOfArms.h" #include "../../CK3World/Dynasties/House.h" -#include "../../CK3World/Mods/Mods.h" #include "../../CK3World/Titles/Title.h" #include "../../Configuration/Configuration.h" #include "../Country/Country.h" @@ -20,24 +19,24 @@ EU4::FlagFoundry::FlagFoundry() flagCrafter.loadWarehouse(warehouse); } -void EU4::FlagFoundry::loadImageFolders(const Configuration& theConfiguration, const CK3::Mods& mods) const +void EU4::FlagFoundry::loadImageFolders(const Configuration& theConfiguration, const Mods& mods) const { std::set folders; folders.insert(theConfiguration.getCK3Path() + "gfx/coat_of_arms/"); - for (const auto& [modName, modPath]: mods.getMods()) + for (const auto& mod: mods) { - if (!commonItems::DoesFolderExist(modPath + "/gfx/coat_of_arms/")) + if (!commonItems::DoesFolderExist(mod.path + "/gfx/coat_of_arms/")) continue; - Log(LogLevel::Info) << "<> Loading some garments from " << modName; - folders.insert(modPath + "/gfx/coat_of_arms/"); + Log(LogLevel::Info) << "<> Loading some garments from [" << mod.name << "]"; + folders.insert(mod.path + "/gfx/coat_of_arms/"); } warehouse->loadImageFolders(folders); } void EU4::FlagFoundry::generateFlags(const std::map>& countries, const Configuration& theConfiguration, - const std::vector& religions, - const CK3::Mods& mods) const + const std::vector& religions, + const Mods& mods) const { // prep the battleground. if (!commonItems::DeleteFolder("flags.tmp")) @@ -117,7 +116,7 @@ void EU4::FlagFoundry::craftFlag(const std::shared_ptr& country) const } } -void EU4::FlagFoundry::craftRebelFlag(const Configuration& theConfiguration, const GeneratedReligion& religion, const CK3::Mods& mods) const +void EU4::FlagFoundry::craftRebelFlag(const Configuration& theConfiguration, const GeneratedReligion& religion, const Mods& mods) const { // Import the generic Rebel Flag if (!commonItems::DoesFileExist("blankMod/output/gfx/flags/generic_rebels.tga")) @@ -143,10 +142,10 @@ void EU4::FlagFoundry::craftRebelFlag(const Configuration& theConfiguration, con } if (!foundIcon) { - for (const auto& modDir: mods.getMods() | std::ranges::views::values) + for (const auto& mod: mods) { - path1 = modDir + "/" + religion.iconPath; - path2 = modDir + "/gfx/interface/icons/faith/" + religion.iconPath + ".dds"; + path1 = mod.path + "/" + religion.iconPath; + path2 = mod.path + "/gfx/interface/icons/faith/" + religion.iconPath + ".dds"; if (commonItems::DoesFileExist(path1)) { foundIcon = true; @@ -187,7 +186,7 @@ void EU4::FlagFoundry::craftRebelFlag(const Configuration& theConfiguration, con baseFlag.write("flags.tmp/" + religion.name + "_rebels.tga"); } -void EU4::FlagFoundry::extendReligionStrips(const Configuration& theConfiguration, const std::vector& religions, const CK3::Mods& mods) const +void EU4::FlagFoundry::extendReligionStrips(const Configuration& theConfiguration, const std::vector& religions, const Mods& mods) const { std::set targetStrips = {"country_icon_religion.dds", "icon_religion.dds", "icon_religion_small.dds", "province_view_religion.dds"}; for (const auto& religion: religions) @@ -211,10 +210,10 @@ void EU4::FlagFoundry::extendReligionStrips(const Configuration& theConfiguratio } if (!foundIcon) { - for (const auto& modDir: mods.getMods() | std::ranges::views::values) + for (const auto& mod: mods) { - path1 = modDir + "/" + religion.iconPath; - path2 = modDir + "/gfx/interface/icons/faith/" + religion.iconPath + ".dds"; + path1 = mod.path + "/" + religion.iconPath; + path2 = mod.path + "/gfx/interface/icons/faith/" + religion.iconPath + ".dds"; if (commonItems::DoesFileExist(path1)) { foundIcon = true; diff --git a/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.h b/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.h index 259c440d..0094c09a 100644 --- a/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.h +++ b/CK3toEU4/Source/EU4World/FlagFoundry/FlagFoundry.h @@ -5,6 +5,7 @@ #include #include #include +#include "ModLoader/ModLoader.h" class Configuration; @@ -32,14 +33,14 @@ class FlagFoundry FlagFoundry(); void generateFlags(const std::map>& countries, const Configuration& theConfiguration, - const std::vector& religions, - const CK3::Mods& mods) const; - void loadImageFolders(const Configuration& theConfiguration, const CK3::Mods& mods) const; - void extendReligionStrips(const Configuration& theConfiguration, const std::vector& religions, const CK3::Mods& mods) const; + const std::vector& religions, + const Mods& mods) const; + void loadImageFolders(const Configuration& theConfiguration, const Mods& mods) const; + void extendReligionStrips(const Configuration& theConfiguration, const std::vector& religions, const Mods& mods) const; private: void craftFlag(const std::shared_ptr& country) const; - void craftRebelFlag(const Configuration& theConfiguration, const GeneratedReligion& religion, const CK3::Mods& mods) const; + void craftRebelFlag(const Configuration& theConfiguration, const GeneratedReligion& religion, const Mods& mods) const; [[nodiscard]] Magick::Image extendReligionStrip(const Magick::Image& sourceStrip, const Magick::Image& icon) const; FlagCrafter flagCrafter; // image processor diff --git a/CK3toEU4/Source/EU4World/Output/outWorld.cpp b/CK3toEU4/Source/EU4World/Output/outWorld.cpp index bff656aa..258f47f4 100644 --- a/CK3toEU4/Source/EU4World/Output/outWorld.cpp +++ b/CK3toEU4/Source/EU4World/Output/outWorld.cpp @@ -114,7 +114,7 @@ void EU4::World::output(const commonItems::ConverterVersion& converterVersion, c void EU4::World::outputReligionIcons(const Configuration& theConfiguration, const std::vector& generatedReligions, - const CK3::Mods& mods) const + const Mods& mods) const { // edit the strips flagFoundry.extendReligionStrips(theConfiguration, generatedReligions, mods); diff --git a/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.cpp b/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.cpp index 1a1b557c..a94bf288 100644 --- a/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.cpp +++ b/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.cpp @@ -5,7 +5,7 @@ #include #include -void mappers::LocalizationMapper::scrapeLocalizations(const Configuration& theConfiguration, const std::map& mods) +void mappers::LocalizationMapper::scrapeLocalizations(const Configuration& theConfiguration, const Mods& mods) { scrapeLanguage("english", theConfiguration.getCK3Path() + "localization"); scrapeLanguage("french", theConfiguration.getCK3Path() + "localization"); @@ -14,17 +14,17 @@ void mappers::LocalizationMapper::scrapeLocalizations(const Configuration& theCo for (const auto& mod: mods) { - if (commonItems::DoesFolderExist(mod.second + "localization")) + if (commonItems::DoesFolderExist(mod.path + "localization")) { - Log(LogLevel::Info) << "\t>> Found some words in: " << mod.second + "/localization"; - scrapeLanguage("english", mod.second + "/localization"); - scrapeLanguage("french", mod.second + "/localization"); - scrapeLanguage("german", mod.second + "/localization"); - scrapeLanguage("spanish", mod.second + "/localization"); - scrapeLanguage("english", mod.second + "/localization/replace"); - scrapeLanguage("french", mod.second + "/localization/replace"); - scrapeLanguage("german", mod.second + "/localization/replace"); - scrapeLanguage("spanish", mod.second + "/localization/replace"); + Log(LogLevel::Info) << "\t>> Found some words in: [" << mod.name + "]"; + scrapeLanguage("english", mod.path + "/localization"); + scrapeLanguage("french", mod.path + "/localization"); + scrapeLanguage("german", mod.path + "/localization"); + scrapeLanguage("spanish", mod.path + "/localization"); + scrapeLanguage("english", mod.path + "/localization/replace"); + scrapeLanguage("french", mod.path + "/localization/replace"); + scrapeLanguage("german", mod.path + "/localization/replace"); + scrapeLanguage("spanish", mod.path + "/localization/replace"); } } diff --git a/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.h b/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.h index 238ccf5b..846e27f0 100644 --- a/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.h +++ b/CK3toEU4/Source/Mappers/LocalizationMapper/LocalizationMapper.h @@ -3,6 +3,7 @@ #include #include #include +#include "ModLoader/ModLoader.h" class Configuration; namespace mappers @@ -19,7 +20,7 @@ class LocalizationMapper { public: LocalizationMapper() = default; - void scrapeLocalizations(const Configuration& theConfiguration, const std::map& mods); + void scrapeLocalizations(const Configuration& theConfiguration, const Mods& mods); void scrapeStream(std::istream& theStream, const std::string& language); [[nodiscard]] std::optional getLocBlockForKey(const std::string& key) const; diff --git a/Fronter b/Fronter index 0ba60e16..0f5208a3 160000 --- a/Fronter +++ b/Fronter @@ -1 +1 @@ -Subproject commit 0ba60e16fe8388c8fed073149754857349923cda +Subproject commit 0f5208a36a9cbafd8d6177b5f8e5985a19038edd diff --git a/ZipLib b/ZipLib deleted file mode 160000 index 1a0fbd70..00000000 --- a/ZipLib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1a0fbd703b11b92cc1723cc0ab44005428438d69 diff --git a/commonItems b/commonItems index 69d972d0..35cb428e 160000 --- a/commonItems +++ b/commonItems @@ -1 +1 @@ -Subproject commit 69d972d0db136a55e32549885523466b60d47604 +Subproject commit 35cb428e82d2fa45fcf9d59083fb6870e23317ce