Beispiel #1
0
        private async Task rebuildExports()
        {
            Dictionary <ExportedObjectViewEntity, List <ExportedObjectViewEntity> > filesToMod = viewModel.ExportsTree?.Traverse(e => Path.HasExtension(e.Filename) && e.IsChecked)
                                                                                                 .GroupBy(e => e.Parent)
                                                                                                 .ToDictionary(g => g.Key, g => g.ToList());

            if (filesToMod == null || !filesToMod.Any())
            {
                return;
            }

            LoadProgressMessage message = new LoadProgressMessage {
                Text = "Rebuilding...", Total = filesToMod.Count
            };

            foreach (KeyValuePair <ExportedObjectViewEntity, List <ExportedObjectViewEntity> > pair in filesToMod)
            {
                string gameFilename = $"{pair.Key.Filename.Replace(settings.ExportPath, null)}.upk";

                DomainUpkFile file = allFiles.SingleOrDefault(f => f.GameFilename.Equals(gameFilename));

                if (file == null)
                {
                    continue;
                }

                DomainHeader header = await repository.LoadUpkFile(Path.Combine(settings.PathToGame, file.GameFilename));

                await header.ReadHeaderAsync(null);

                message.Current++;

                foreach (ExportedObjectViewEntity entity in pair.Value)
                {
                    DomainExportTableEntry export = header.ExportTable.SingleOrDefault(ex => ex.NameTableIndex.Name.Equals(Path.GetFileNameWithoutExtension(entity.Filename), StringComparison.CurrentCultureIgnoreCase));

                    if (export == null)
                    {
                        continue;
                    }

                    await export.ParseDomainObject(header, false, false);

                    int compressor = menuViewModel.IsCompressorClusterFit ? 0 : menuViewModel.IsCompressorRangeFit ? 1 : 2;

                    int errorMetric = menuViewModel.IsErrorMetricPerceptual ? 0 : 1;

                    FileFormat fileFormat = menuViewModel.IsDdsDefault ? FileFormat.Unknown :
                                            menuViewModel.IsDdsFormat1 ? FileFormat.DXT1    :
                                            menuViewModel.IsDdsFormat5 ? FileFormat.DXT5    : FileFormat.A8R8G8B8;

                    DdsSaveConfig config = new DdsSaveConfig(fileFormat, compressor, errorMetric, menuViewModel.IsWeightColorByAlpha, false);

                    await export.DomainObject.SetObject(entity.Filename, header.NameTable, config);

                    message.StatusText = entity.Filename;

                    messenger.Send(message);
                }

                string directory = Path.Combine(settings.PathToGame, Path.GetDirectoryName(file.GameFilename), "mod");

                string filename = Path.Combine(directory, Path.GetFileName(file.GameFilename));

                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                await repository.SaveUpkFile(header, filename);

                DomainUpkFile upkFile = new DomainUpkFile {
                    GameFilename = filename.Replace(settings.PathToGame, null), FileSize = new FileInfo(filename).Length, Package = GetFileNameWithoutExtension(filename).ToLowerInvariant()
                };

                messenger.Send(new ModFileBuiltMessage {
                    UpkFile = upkFile
                });
            }

            message.IsComplete = true;
            message.StatusText = null;

            messenger.Send(message);
        }
        private async Task exportFileObjects(List <DomainUpkFile> files)
        {
            LoadProgressMessage message = new LoadProgressMessage {
                Text = "Exporting...", Total = files.Count
            };

            int compressor = menuViewModel.IsCompressorClusterFit ? 0 : menuViewModel.IsCompressorRangeFit ? 1 : 2;

            int errorMetric = menuViewModel.IsErrorMetricPerceptual ? 0 : 1;

            DdsSaveConfig config = new DdsSaveConfig(FileFormat.Unknown, compressor, errorMetric, menuViewModel.IsWeightColorByAlpha, false);

            foreach (DomainUpkFile file in files)
            {
                FileViewEntity fileEntity = viewModel.Files.Single(fe => fe.Id == file.Id);

                string directory = Path.Combine(settings.ExportPath, Path.GetDirectoryName(file.GameFilename), Path.GetFileNameWithoutExtension(file.GameFilename));

                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                DomainHeader header = file.Header;

                if (header == null)
                {
                    try {
                        header = await repository.LoadUpkFile(Path.Combine(settings.PathToGame, file.GameFilename));

                        await Task.Run(() => header.ReadHeaderAsync(null));
                    }
                    catch (Exception ex) {
                        messenger.Send(new ApplicationErrorMessage {
                            HeaderText = "Error Loading UPK File", ErrorMessage = $"Filename: {file.GameFilename}", Exception = ex
                        });

                        fileEntity.IsErrored = true;

                        continue;
                    }
                }

                message.Current++;

                foreach (DomainExportTableEntry export in header.ExportTable)
                {
                    if (export.DomainObject == null)
                    {
                        try {
                            await export.ParseDomainObject(header, false, false);
                        }
                        catch (Exception ex) {
                            messenger.Send(new ApplicationErrorMessage {
                                HeaderText = "Error Parsing Object", ErrorMessage = $"Filename: {header.Filename}\nExport Name: {export.NameTableIndex.Name}\nType: {export.TypeReferenceNameIndex.Name}", Exception = ex
                            });

                            fileEntity.IsErrored = true;

                            continue;
                        }
                    }

                    if (!export.DomainObject.IsExportable)
                    {
                        continue;
                    }

                    string filename = Path.Combine(directory, $"{export.NameTableIndex.Name}{export.DomainObject.FileExtension}");

                    message.StatusText = filename;

                    messenger.Send(message);

                    await export.DomainObject.SaveObject(filename, config);
                }

                file.Header = null;
            }

            message.IsComplete = true;
            message.StatusText = null;

            messenger.Send(message);
        }