Example #1
0
        public static bool ImportFromDirectory(out Mod mod, out string message)
        {
            mod     = null;
            message = "";

            CommonOpenFileDialog openDialog = new CommonOpenFileDialog
            {
                IsFolderPicker = true,
                Title          = "Open mod folder",
                Multiselect    = false
            };

            if (openDialog.ShowDialog() != CommonFileDialogResult.Ok)
            {
                return(false);
            }

            CommonSaveFileDialog saveDialog = new CommonSaveFileDialog
            {
                Filters = { new CommonFileDialogFilter("Compressed mod", "*.zipmod"), new CommonFileDialogFilter("Compressed folder", "*.zip") },
                Title   = "Save new .zip file",
                AlwaysAppendDefaultExtension = true
            };

            if (saveDialog.ShowDialog() != CommonFileDialogResult.Ok)
            {
                return(false);
            }

            string sourceDir = openDialog.FileName;
            string savePath  = saveDialog.FileName;

            if (!savePath.ToLower().EndsWith(".zipmod") && (saveDialog.SelectedFileTypeIndex == 1))
            {
                savePath += ".zipmod";
            }

            if (!savePath.ToLower().EndsWith(".zip") && (saveDialog.SelectedFileTypeIndex == 2))
            {
                savePath += ".zip";
            }

            if (File.Exists(savePath))
            {
                File.Delete(savePath);
            }

            ZipFile file = new ZipFile(savePath, Encoding.UTF8);
            //file.CompressionLevel = Ionic.Zlib.CompressionLevel.None;

            Manifest manifest = new Manifest
            {
                Guid = "<not set>"
            };

            //check for root abdata folder
            string rootDir = "";

            if (Path.GetFileName(sourceDir).ToLower() == "abdata")
            {
                rootDir = Path.GetDirectoryName(sourceDir);
            }
            else if (Directory.Exists(Path.Combine(sourceDir, "abdata")))
            {
                rootDir = sourceDir;
            }
            else
            {
                //we have to try and find abdata
                string potentialDirectory =
                    Directory.EnumerateDirectories(sourceDir, "abdata", SearchOption.AllDirectories).FirstOrDefault() ?? "";

                if (potentialDirectory != "")
                {
                    rootDir = Path.GetDirectoryName(potentialDirectory);
                }
                else
                {
                    //no abdata folder exists
                    message = "Cannot find \"abdata\" folder!";

                    file.Save();
                    file.Dispose();
                    File.Delete(savePath);

                    return(false);
                }
            }

            string GetNewPath(string FullPath)
            {
                string newPath = FullPath.Remove(0, rootDir.Length).Trim('\\', '/').Replace('\\', '/');

                newPath = newPath.Remove(newPath.LastIndexOf('/') + 1);
                return(newPath);
            }

            void TryAddFolderFromRoot(string prefix)
            {
                string totalPath = Path.Combine(rootDir, prefix);

                if (Directory.Exists(totalPath))
                {
                    file.AddDirectoryByName(prefix + "/");

                    foreach (string subFilePath in Directory.GetFiles(Path.Combine(rootDir, prefix), "*", SearchOption.AllDirectories))
                    {
                        file.AddFile(subFilePath, GetNewPath(subFilePath));
                    }

                    foreach (string subDirPath in Directory.GetDirectories(Path.Combine(rootDir, prefix), "*", SearchOption.AllDirectories))
                    {
                        file.AddDirectoryByName(subDirPath.Remove(0, rootDir.Length).Trim('\\', '/').Replace('\\', '/') + "/");
                    }
                }
            }

            //need to add abdata with special care
            file.AddDirectoryByName("abdata/");
            TryAddFolderFromRoot("UserData");

            //Export csv files
            if (Directory.Exists(Path.Combine(rootDir, "abdata/list/characustom/")))
            {
                AssetsManager assetsManager = new AssetsManager();
                assetsManager.LoadFolder(Path.Combine(rootDir, "abdata/list/characustom/"));
                foreach (var assetFile in assetsManager.assetsFileList)
                {
                    bool hasOtherAssets = false;

                    foreach (var asset in assetFile.Objects.Select(x => x.Value))
                    {
                        switch (asset)
                        {
                        case TextAsset textAsset:
                            string FileName = $"abdata/list/characustom/{Path.GetFileNameWithoutExtension(assetFile.originalPath)}_{textAsset.m_Name}.csv";
                            file.AddFileWithName(__tempMakeFile(ExportCSV(textAsset.m_Script)), FileName);
                            break;

                        case AssetBundle ab:
                            break;

                        default:
                            hasOtherAssets = true;
                            break;
                        }
                    }

                    //If the list file has assets other than just text lists add it too. It may be necessary for the mod to work.
                    if (hasOtherAssets)
                    {
                        file.AddFile(assetFile.originalPath, GetNewPath(assetFile.originalPath));
                    }
                }
            }

            //Export studio csv files
            if (Directory.Exists(Path.Combine(rootDir, "abdata/studio/info/")))
            {
                AssetsManager assetsManager = new AssetsManager();
                assetsManager.LoadFolder(Path.Combine(rootDir, "abdata/studio/info/"));
                foreach (var assetFile in assetsManager.assetsFileList)
                {
                    bool hasOtherAssets = false;
                    bool directoryAdded = false;

                    foreach (var asset in assetFile.Objects.Select(x => x.Value))
                    {
                        switch (asset)
                        {
                        case MonoBehaviour monoBehaviour:
                            if (monoBehaviour.m_Script.TryGet(out var monoScript) && monoScript.m_Name == "ExcelData")
                            {
                                if (!directoryAdded)
                                {
                                    file.AddDirectoryByName($"abdata/studio/info/{Path.GetFileNameWithoutExtension(assetFile.originalPath)}/");
                                    directoryAdded = true;
                                }
                                string FileName = $"abdata/studio/info/{Path.GetFileNameWithoutExtension(assetFile.originalPath)}/{monoBehaviour.m_Name}.csv";

                                monoBehaviour.reader.Reset();
                                file.AddFileWithName(__tempMakeFile(ExportStudioCSV(monoBehaviour.serializedType.m_Nodes, monoBehaviour.reader)), FileName);
                            }
                            break;

                        case AssetBundle ab:
                        case MonoScript ms:
                            break;

                        default:
                            hasOtherAssets = true;
                            break;
                        }
                    }

                    if (hasOtherAssets)
                    {
                        file.AddFile(assetFile.originalPath, GetNewPath(assetFile.originalPath));
                    }
                }
            }

            //Add the rest of the unity3d files
            foreach (string subFilePath in Directory.GetFiles(Path.Combine(rootDir, "abdata"), "*", SearchOption.AllDirectories))
            {
                string newPath = GetNewPath(subFilePath);

                //These are handled elsewhere
                if (newPath.ToLower().StartsWith("abdata/list/characustom/") || newPath.ToLower().StartsWith("abdata/studio/info/"))
                {
                    continue;
                }

                if (subFilePath.EndsWith(".unity3d"))
                {
                    file.AddFile(subFilePath, newPath);
                }
            }

            //Add all directories
            foreach (string subDirPath in Directory.GetDirectories(Path.Combine(rootDir, "abdata"), "*", SearchOption.AllDirectories))
            {
                string newPath = subDirPath.Remove(0, rootDir.Length).Trim('\\', '/').Replace('\\', '/') + "/";
                file.AddDirectoryByName(newPath);
            }


            //Add manifest
            file.AddFileWithName(__tempMakeFile(manifest.Export()), "manifest.xml");

            file.Save();
            file.Dispose();

            __deleteAllTempPaths();

            mod = new Mod(savePath);
            return(true);
        }