コード例 #1
0
        public GeneratingWadFilesDialog(ModFile mod, LeagueFileIndex index)
        {
            this.DataContext = this;
            this._mod        = mod;
            this._index      = index;

            this.GeneratingString = string.Format("Generating WAD files for {0}...", mod.GetID());

            InitializeComponent();
        }
コード例 #2
0
        public static async Task <ModFile> ShowCreateModDialog(LeagueFileIndex index)
        {
            CreateModDialogViewModel dialogModel = new CreateModDialogViewModel(index);
            CreateModDialog          dialog      = new CreateModDialog(index, dialogModel);

            object result = await DialogHost.Show(dialog, "RootDialog", (dialog.DataContext as CreateModDialogViewModel).ClosingEventHandler);

            if ((bool)result)
            {
                return(dialogModel.GetCreatedMod());
            }
            else
            {
                return(null);
            }
        }
コード例 #3
0
        public ModFile(LeagueFileIndex index, IEnumerable <string> wadFilePaths, IEnumerable <string> wadFolderPaths, ModInfo info, Image image)
        {
            this._file = string.Format(@"{0}\{1}.fantome", ModManager.MOD_FOLDER, info.CreateID());

            using (FileStream fileStream = new FileStream(this._file, FileMode.Create))
            {
                using (this.Content = new ZipArchive(fileStream, ZipArchiveMode.Update))
                {
                    this._info  = info;
                    this._image = image;

                    foreach (string wadFolderPath in wadFolderPaths)
                    {
                        //Check if we want to pack the WAD folder into a WAD file
                        if (Config.Get <bool>("PackWadFolders"))
                        {
                            PackWadFolder(wadFolderPath);
                        }
                        else
                        {
                            AddFolder("WAD", wadFolderPath);
                        }
                    }

                    foreach (string wadFilePath in wadFilePaths)
                    {
                        string wadFileName = Path.GetFileName(wadFilePath);
                        string wadPath     = index.FindWADPath(wadFileName);

                        AddFile($"WAD/{wadFileName}", File.ReadAllBytes(wadFilePath));
                    }

                    AddFile("META/info.json", Encoding.ASCII.GetBytes(info.Serialize()));

                    if (image != null)
                    {
                        using (MemoryStream imageStream = new MemoryStream())
                        {
                            image.Save(imageStream, ImageFormat.Png);
                            AddFile("META/image.png", imageStream.ToArray());
                        }
                    }
                }
            }

            this.Content = ZipFile.OpenRead(string.Format(@"{0}\{1}.fantome", ModManager.MOD_FOLDER, this.GetID()));
        }
コード例 #4
0
        public Dictionary <string, WadBuilder> GetWadFiles(LeagueFileIndex index)
        {
            if (this._wadFiles != null)
            {
                return(this._wadFiles);
            }

            Dictionary <string, WadBuilder> modWadFiles = new ();

            //Collect WAD files in WAD folder
            CollectWADFiles();

            //Pack WAD folders files into WAD files
            CollectWADFolders();

            //Collect files from the RAW folder
            CollectRAWFiles();

            this._wadFiles = modWadFiles;

            return(modWadFiles);

            void CollectWADFiles()
            {
                foreach (ZipArchiveEntry zipEntry in GetEntries(@"^WAD[\\/][\w.]+.wad.client$"))
                {
                    char   ps      = Pathing.GetPathSeparator(zipEntry.FullName);
                    string wadPath = index.FindWADPath(zipEntry.FullName.Split(ps)[1]);

                    zipEntry.ExtractToFile("wadtemp", true);
                    modWadFiles.Add(wadPath, new WadBuilder(Wad.Mount(new MemoryStream(File.ReadAllBytes("wadtemp")), false)));
                    File.Delete("wadtemp");

                    //We need to check each entry to see if they're shared across any other WAD files
                    //if they are, we need to also modify those WADs
                    foreach (var entry in modWadFiles[wadPath].Entries)
                    {
                        //Check if the entry is present in the game files or if it's new
                        if (index.Game.ContainsKey(entry.Key))
                        {
                            foreach (string additionalWadPath in index.Game[entry.Key].Where(x => x != wadPath))
                            {
                                if (!modWadFiles.ContainsKey(additionalWadPath))
                                {
                                    modWadFiles.Add(additionalWadPath, new WadBuilder());
                                }

                                modWadFiles[additionalWadPath].WithEntry(entry.Value);
                            }
                        }
                    }
                }
            }

            void CollectWADFolders()
            {
                List <string> wadPaths = new List <string>();

                foreach (ZipArchiveEntry zipEntry in GetEntries(@"^WAD[\\/][\w.]+.wad.client[\\/].*"))
                {
                    char   ps      = Pathing.GetPathSeparator(zipEntry.FullName);
                    string wadName = zipEntry.FullName.Split(ps)[1];
                    string wadPath = index.FindWADPath(wadName);
                    string path    = zipEntry.FullName.Replace(string.Format("WAD{0}{1}{0}", ps, wadName), "").Replace('\\', '/');
                    ulong  hash    = XXHash.XXH64(Encoding.ASCII.GetBytes(path.ToLower()));

                    if (!modWadFiles.ContainsKey(wadPath))
                    {
                        modWadFiles.Add(wadPath, new WadBuilder());
                        wadPaths.Add(wadPath);
                    }

                    WadEntryBuilder entryBuilder = new();

                    entryBuilder
                    .WithPathXXHash(hash)
                    .WithGenericDataStream(path, zipEntry.Open());

                    modWadFiles[wadPath].WithEntry(entryBuilder);
                }

                //Shared Entry Check
                foreach (string wadPath in wadPaths)
                {
                    foreach (var entry in modWadFiles[wadPath].Entries)
                    {
                        //Check if the entry is present in the game files or if it's new
                        if (index.Game.ContainsKey(entry.Key))
                        {
                            foreach (string additionalWadPath in index.Game[entry.Key].Where(x => x != wadPath))
                            {
                                if (!modWadFiles.ContainsKey(additionalWadPath))
                                {
                                    modWadFiles.Add(additionalWadPath, new WadBuilder());
                                }

                                WadEntryBuilder entryBuilder = new ();

                                entryBuilder
                                .WithPathXXHash(entry.Key)
                                .WithZstdDataStream(entry.Value.DataStream, entry.Value.CompressedSize, entry.Value.UncompressedSize);

                                modWadFiles[additionalWadPath].WithEntry(entryBuilder);
                            }
                        }
                    }
                }
            }

            void CollectRAWFiles()
            {
                foreach (ZipArchiveEntry zipEntry in GetEntries(@"^RAW[\\/].*"))
                {
                    char   ps   = Pathing.GetPathSeparator(zipEntry.FullName);
                    string path = zipEntry.FullName.Replace(@"RAW" + ps, "").Replace('\\', '/');
                    ulong  hash = XXHash.XXH64(Encoding.ASCII.GetBytes(path.ToLower()));

                    //Check if file exists, if not, we discard it
                    if (index.Game.ContainsKey(hash))
                    {
                        List <string> fileWadFiles = index.Game[hash];
                        foreach (string wadFilePath in fileWadFiles)
                        {
                            if (!modWadFiles.ContainsKey(wadFilePath))
                            {
                                modWadFiles.Add(wadFilePath, new WadBuilder());
                            }

                            WadEntryBuilder entryBuilder = new();

                            entryBuilder
                            .WithPathXXHash(hash)
                            .WithGenericDataStream(path, zipEntry.Open());

                            modWadFiles[wadFilePath].WithEntry(entryBuilder);
                        }
                    }
                }
            }
        }
コード例 #5
0
 public void GenerateWadFiles(LeagueFileIndex index)
 {
     this._wadFiles = GetWadFiles(index);
 }
コード例 #6
0
        public string Validate(LeagueFileIndex index)
        {
            string validationError = "";

            //Check for RAW, WAD and META folders, and collect entries from RAW and WAD
            ZipArchiveEntry[] wadEntries  = GetEntries(@"^WAD[\\/].+").ToArray();
            ZipArchiveEntry[] rawEntries  = GetEntries(@"^RAW[\\/].+").ToArray();
            ZipArchiveEntry[] metaEntries = GetEntries(@"^META[\\/].*").ToArray();

            validationError = ValidateBaseFolders();
            if (!string.IsNullOrEmpty(validationError))
            {
                return(validationError);
            }

            validationError = ValidateBaseFoldersContent();
            if (!string.IsNullOrEmpty(validationError))
            {
                return(validationError);
            }

            return(string.Empty);

            string ValidateBaseFolders()
            {
                if (wadEntries.Length == 0 && rawEntries.Length == 0)
                {
                    return(string.Format("{0} contains no files in either WAD or RAW folder", GetID()));
                }

                //Check if META folder exists
                if (metaEntries.Length != 0)
                {
                    //If it does then we check if it contains info.json
                    if (!metaEntries.Any(x => x.Name == "info.json"))
                    {
                        return(string.Format("The META folder of {0} does not contain a META/info.json file", GetID()));
                    }
                }
                else
                {
                    return(string.Format("{0} does not contain a META folder", GetID()));
                }

                return(string.Empty);
            }

            string ValidateBaseFoldersContent()
            {
                bool isInvalid = false;

                //Get all files in the WAD folder
                validationError = string.Format("The WAD folder of {0} contains invalid entries:\n", GetID());
                foreach (ZipArchiveEntry entry in wadEntries)
                {
                    if (!entry.FullName.Contains(".wad.client"))
                    {
                        isInvalid        = true;
                        validationError += entry.FullName + '\n';
                    }
                    else
                    {
                        //See if the WAD file exists in the game
                        string wadName = entry.FullName.Split(Pathing.GetPathSeparator(entry.FullName))[1];
                        if (string.IsNullOrEmpty(index.FindWADPath(wadName)))
                        {
                            isInvalid        = true;
                            validationError += entry.FullName + '\n';
                        }
                    }
                }
                if (isInvalid)
                {
                    return(validationError);
                }


                //Get all files in RAW folder and see if they contain a reference to WAD files
                validationError = string.Format("The RAW folder of {0} contains invalid entries:\n", GetID());
                foreach (ZipArchiveEntry entry in rawEntries)
                {
                    if (entry.FullName.Contains(".wad.client"))
                    {
                        isInvalid        = true;
                        validationError += entry.FullName + '\n';
                    }
                }
                if (isInvalid)
                {
                    return(validationError);
                }

                return(string.Empty);
            }
        }
コード例 #7
0
        public static async Task <object> ShowGenerateWadFilesDialog(ModFile mod, LeagueFileIndex index)
        {
            GeneratingWadFilesDialog dialog = new GeneratingWadFilesDialog(mod, index);

            return(await DialogHost.Show(dialog, "OperationDialog", dialog.StartGeneration, null));
        }
コード例 #8
0
        public Dictionary <string, WADFile> GetWadFiles(LeagueFileIndex index)
        {
            if (this._wadFiles != null)
            {
                return(this._wadFiles);
            }

            Dictionary <string, WADFile> modWadFiles = new Dictionary <string, WADFile>();

            //Collect WAD files in WAD folder
            CollectWADFiles();

            //Pack WAD folders files into WAD files
            CollectWADFolders();

            //Collect files from the RAW folder
            CollectRAWFiles();

            this._wadFiles = modWadFiles;

            return(modWadFiles);

            void CollectWADFiles()
            {
                foreach (ZipArchiveEntry zipEntry in GetEntries(@"^WAD[\\/][\w.]+.wad.client(?![\\/])"))
                {
                    char   ps      = Pathing.GetPathSeparator(zipEntry.FullName);
                    string wadPath = index.FindWADPath(zipEntry.FullName.Split(ps)[1]);

                    zipEntry.ExtractToFile("wadtemp", true);
                    modWadFiles.Add(wadPath, new WADFile(new MemoryStream(File.ReadAllBytes("wadtemp"))));
                    File.Delete("wadtemp");

                    //We need to check each entry to see if they're shared across any other WAD files
                    //if they are, we need to also modify those WADs
                    foreach (WADEntry entry in modWadFiles[wadPath].Entries)
                    {
                        //Check if the entry is present in the game files or if it's new
                        if (index.Game.ContainsKey(entry.XXHash))
                        {
                            foreach (string additionalWadPath in index.Game[entry.XXHash].Where(x => x != wadPath))
                            {
                                if (!modWadFiles.ContainsKey(additionalWadPath))
                                {
                                    modWadFiles.Add(additionalWadPath, new WADFile(3, 0));
                                }

                                if (entry.Type == EntryType.Uncompressed)
                                {
                                    modWadFiles[additionalWadPath].AddEntry(entry.XXHash, entry.GetContent(false), false);
                                }
                                else if (entry.Type == EntryType.Compressed || entry.Type == EntryType.ZStandardCompressed)
                                {
                                    modWadFiles[additionalWadPath].AddEntryCompressed(entry.XXHash, entry.GetContent(false), entry.UncompressedSize, entry.Type);
                                }
                            }
                        }
                    }
                }
            }

            void CollectWADFolders()
            {
                List <string> wadPaths = new List <string>();

                foreach (ZipArchiveEntry zipEntry in GetEntries(@"^WAD[\\/][\w.]+.wad.client[\\/].*"))
                {
                    char   ps      = Pathing.GetPathSeparator(zipEntry.FullName);
                    string wadName = zipEntry.FullName.Split(ps)[1];
                    string wadPath = index.FindWADPath(wadName);
                    string path    = zipEntry.FullName.Replace(string.Format("WAD{0}{1}{0}", ps, wadName), "").Replace('\\', '/');
                    ulong  hash    = XXHash.XXH64(Encoding.ASCII.GetBytes(path.ToLower()));

                    if (!modWadFiles.ContainsKey(wadPath))
                    {
                        modWadFiles.Add(wadPath, new WADFile(3, 0));
                        wadPaths.Add(wadPath);
                    }

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        zipEntry.Open().CopyTo(memoryStream);
                        if (Path.GetExtension(path) == ".wpk")
                        {
                            modWadFiles[wadPath].AddEntry(hash, memoryStream.ToArray(), false);
                        }
                        else
                        {
                            modWadFiles[wadPath].AddEntry(hash, memoryStream.ToArray(), true);
                        }
                    }
                }

                //Shared Entry Check
                foreach (string wadPath in wadPaths)
                {
                    foreach (WADEntry entry in modWadFiles[wadPath].Entries)
                    {
                        //Check if the entry is present in the game files or if it's new
                        if (index.Game.ContainsKey(entry.XXHash))
                        {
                            foreach (string additionalWadPath in index.Game[entry.XXHash].Where(x => x != wadPath))
                            {
                                if (!modWadFiles.ContainsKey(additionalWadPath))
                                {
                                    modWadFiles.Add(additionalWadPath, new WADFile(3, 0));
                                }

                                modWadFiles[additionalWadPath].AddEntryCompressed(entry.XXHash, entry.GetContent(false), entry.UncompressedSize, EntryType.ZStandardCompressed);
                            }
                        }
                    }
                }
            }

            void CollectRAWFiles()
            {
                foreach (ZipArchiveEntry zipEntry in GetEntries(@"^RAW[\\/].*"))
                {
                    char          ps           = Pathing.GetPathSeparator(zipEntry.FullName);
                    string        path         = zipEntry.FullName.Replace(@"RAW" + ps, "").Replace('\\', '/');
                    ulong         hash         = XXHash.XXH64(Encoding.ASCII.GetBytes(path.ToLower()));
                    List <string> fileWadFiles = new List <string>();

                    //Check if file exists, if not, we discard it
                    if (index.Game.ContainsKey(hash))
                    {
                        fileWadFiles = index.Game[hash];
                        foreach (string wadFilePath in fileWadFiles)
                        {
                            if (!modWadFiles.ContainsKey(wadFilePath))
                            {
                                modWadFiles.Add(wadFilePath, new WADFile(3, 0));
                            }

                            using (MemoryStream memoryStream = new MemoryStream())
                            {
                                zipEntry.Open().CopyTo(memoryStream);
                                modWadFiles[wadFilePath].AddEntry(hash, memoryStream.ToArray(), true);
                            }
                        }
                    }
                }
            }
        }