예제 #1
0
        private bool ImportModelResource(TagInstance tagIndex, string cachePath, string dataPath)
        {
            RenderModel   renderModel;
            ResourceCache resourceCache;
            uint          compressedSize = 0;
            var           data           = File.ReadAllBytes(dataPath);

            using (var cacheStream = _info.OpenCacheReadWrite())
            {
                var tagContext = new TagSerializationContext(cacheStream, _info.Cache, _info.StringIDs, tagIndex);
                renderModel = _info.Deserializer.Deserialize <RenderModel>(tagContext);
            }
            using (var stream = File.Open(_info.CacheFile.DirectoryName + "\\" + cachePath, FileMode.Open, FileAccess.ReadWrite))
            {
                resourceCache = new ResourceCache(stream);
                renderModel.Geometry.Resource.Index          = resourceCache.Add(stream, data, out compressedSize);
                renderModel.Geometry.Resource.CompressedSize = compressedSize;
            }
            using (var cacheStream = _fileInfo.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                var context = new TagSerializationContext(cacheStream, _cache, _stringIds, tagIndex);
                _info.Serializer.Serialize(context, renderModel);
            }
            Console.WriteLine("{1}: Imported 0x{0}.", compressedSize, tagIndex);
            return(true);
        }
예제 #2
0
        public static void FixDecalSystems(OpenTagCache destInfo, int firstNewIndex)
        {
            // decs tags need to be updated to use the old rmdf for decals,
            // because the decal planes seem to be generated by the engine and
            // therefore need to use the old vertex format.
            //
            // This could probably be done as a post-processing step in
            // ConvertStructure to avoid the extra deserialize-reserialize
            // pass, but we'd have to store the rmdf somewhere and frankly I'm
            // too lazy to do that...

            var firstDecalSystemTag = destInfo.Cache.Tags.FindFirstInGroup("decs");

            if (firstDecalSystemTag == null)
            {
                return;
            }
            using (var stream = destInfo.OpenCacheReadWrite())
            {
                var firstDecalSystemContext = new TagSerializationContext(stream, destInfo.Cache, destInfo.StringIDs, firstDecalSystemTag);
                var firstDecalSystem        = destInfo.Deserializer.Deserialize <DecalSystem>(firstDecalSystemContext);
                foreach (var decalSystemTag in destInfo.Cache.Tags.FindAllInGroup("decs").Where(t => t.Index >= firstNewIndex))
                {
                    TagPrinter.PrintTagShort(decalSystemTag);
                    var context     = new TagSerializationContext(stream, destInfo.Cache, destInfo.StringIDs, decalSystemTag);
                    var decalSystem = destInfo.Deserializer.Deserialize <DecalSystem>(context);
                    foreach (var system in decalSystem.DecalSystem2)
                    {
                        system.BaseRenderMethod = firstDecalSystem.DecalSystem2[0].BaseRenderMethod;
                    }
                    destInfo.Serializer.Serialize(context, decalSystem);
                }
            }
        }
예제 #3
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }
            var imagePath = args[0];

            Console.WriteLine("Loading textures.dat...");
            var resourceManager = new ResourceDataManager();

            resourceManager.LoadCacheFromDirectory(_info.CacheFile.DirectoryName, ResourceLocation.Textures);

            Console.WriteLine("Importing image...");
            var bitmap = new TagStructures.Bitmap
            {
                Flags     = TagStructures.Bitmap.RuntimeFlags.UseResource,
                Sequences = new List <TagStructures.Bitmap.Sequence>
                {
                    new TagStructures.Bitmap.Sequence
                    {
                        FirstBitmapIndex = 0,
                        BitmapCount      = 1
                    }
                },
                Images = new List <TagStructures.Bitmap.Image>
                {
                    new TagStructures.Bitmap.Image
                    {
                        Signature = new Tag("bitm").Value,
                        Unknown28 = -1,
                    }
                },
                Resources = new List <TagStructures.Bitmap.BitmapResource>
                {
                    new TagStructures.Bitmap.BitmapResource()
                }
            };

            using (var imageStream = File.OpenRead(imagePath))
            {
                var injector = new BitmapDdsInjector(resourceManager);
                injector.InjectDds(_info.Serializer, _info.Deserializer, bitmap, 0, imageStream);
            }

            Console.WriteLine("Creating a new tag...");
            var tag = _info.Cache.AllocateTag();

            using (var tagsStream = _info.OpenCacheReadWrite())
            {
                var tagContext = new TagSerializationContext(tagsStream, _info.Cache, _info.StringIds, tag);
                _info.Serializer.Serialize(tagContext, bitmap);
            }

            Console.WriteLine();
            Console.WriteLine("All done! The new bitmap tag is:");
            TagPrinter.PrintTagShort(tag);
            return(true);
        }
예제 #4
0
        public static void Populate(CommandContext context, OpenTagCache info, TagInstance tag)
        {
            RenderMethod renderMethod = null;

            using (var cacheStream = info.OpenCacheReadWrite())
            {
                var tagContext = new TagSerializationContext(cacheStream, info.Cache, info.StringIDs, tag);

                switch (tag.Group.Tag.ToString())
                {
                case "rm  ":     // render_method
                    renderMethod = info.Deserializer.Deserialize <RenderMethod>(tagContext);
                    break;

                case "rmsh":     // shader
                    renderMethod = info.Deserializer.Deserialize <Shader>(tagContext);
                    break;

                case "rmd ":     // shader_decal
                    renderMethod = info.Deserializer.Deserialize <ShaderDecal>(tagContext);
                    break;

                case "rmfl":     // shader_foliage
                    renderMethod = info.Deserializer.Deserialize <ShaderFoliage>(tagContext);
                    break;

                case "rmhg":     // shader_halogram
                    renderMethod = info.Deserializer.Deserialize <ShaderHalogram>(tagContext);
                    break;

                case "rmss":     // shader_screen
                    renderMethod = info.Deserializer.Deserialize <ShaderScreen>(tagContext);
                    break;

                case "rmtr":     // shader_terrain
                    renderMethod = info.Deserializer.Deserialize <ShaderTerrain>(tagContext);
                    break;

                case "rmw ":     // shader_water
                    renderMethod = info.Deserializer.Deserialize <ShaderWater>(tagContext);
                    break;

                case "rmzo":     // shader_zonly
                    renderMethod = info.Deserializer.Deserialize <ShaderZonly>(tagContext);
                    break;

                case "rmcs":     // shader_custom
                    renderMethod = info.Deserializer.Deserialize <ShaderCustom>(tagContext);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            context.AddCommand(new ListArgumentsCommand(info, tag, renderMethod));
            context.AddCommand(new ListBitmapsCommand(info, tag, renderMethod));
            context.AddCommand(new SpecifyBitmapsCommand(info, tag, renderMethod));
        }
        public static void Populate(CommandContext context, OpenTagCache info, TagInstance tag)
        {
            RenderMethod renderMethod = null;

            using (var cacheStream = info.OpenCacheReadWrite())
            {
                var tagContext = new TagSerializationContext(cacheStream, info.Cache, info.StringIds, tag);

                switch (tag.Group.Tag.ToString())
                {
                    case "rm  ": // render_method
                        renderMethod = info.Deserializer.Deserialize<RenderMethod>(tagContext);
                        break;

                    case "rmsh": // shader
                        renderMethod = info.Deserializer.Deserialize<Shader>(tagContext);
                        break;

                    case "rmd ": // shader_decal
                        renderMethod = info.Deserializer.Deserialize<ShaderDecal>(tagContext);
                        break;

                    case "rmfl": // shader_foliage
                        renderMethod = info.Deserializer.Deserialize<ShaderFoliage>(tagContext);
                        break;

                    case "rmhg": // shader_halogram
                        renderMethod = info.Deserializer.Deserialize<ShaderHalogram>(tagContext);
                        break;

                    case "rmss": // shader_screen
                        renderMethod = info.Deserializer.Deserialize<ShaderScreen>(tagContext);
                        break;

                    case "rmtr": // shader_terrain
                        renderMethod = info.Deserializer.Deserialize<ShaderTerrain>(tagContext);
                        break;

                    case "rmw ": // shader_water
                        renderMethod = info.Deserializer.Deserialize<ShaderWater>(tagContext);
                        break;

                    case "rmzo": // shader_zonly
                        renderMethod = info.Deserializer.Deserialize<ShaderZonly>(tagContext);
                        break;

                    case "rmcs": // shader_custom
                        renderMethod = info.Deserializer.Deserialize<ShaderCustom>(tagContext);
                        break;

                    default:
                        throw new NotImplementedException();
                }
            }
            
            context.AddCommand(new ListArgumentsCommand(info, tag, renderMethod));
            context.AddCommand(new ListBitmapsCommand(info, tag, renderMethod));
            context.AddCommand(new SpecifyBitmapsCommand(info, tag, renderMethod));
        }
예제 #6
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 2)
            {
                return(false);
            }
            int imageIndex;

            if (!int.TryParse(args[0], NumberStyles.HexNumber, null, out imageIndex))
            {
                return(false);
            }
            if (imageIndex < 0 || imageIndex >= _bitmap.Images.Count)
            {
                Console.Error.WriteLine("Invalid image index.");
                return(true);
            }
            var imagePath = args[1];

            Console.WriteLine("Loading resource caches...");
            var resourceManager = new ResourceDataManager();

            try
            {
                resourceManager.LoadCachesFromDirectory(_info.CacheFile.DirectoryName);
            }
            catch
            {
                Console.WriteLine("Unable to load the resource .dat files.");
                Console.WriteLine("Make sure that they all exist and are valid.");
                return(true);
            }
            Console.WriteLine("Importing image data...");
            try
            {
                using (var imageStream = File.OpenRead(imagePath))
                {
                    var injector = new BitmapDdsInjector(resourceManager);
                    injector.InjectDds(_info.Serializer, _info.Deserializer, _bitmap, imageIndex, imageStream);
                }
                using (var tagsStream = _info.OpenCacheReadWrite())
                {
                    var tagContext = new TagSerializationContext(tagsStream, _info.Cache, _info.StringIds, _tag);
                    _info.Serializer.Serialize(tagContext, _bitmap);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Importing image data failed: " + ex.Message);
                return(true);
            }
            Console.WriteLine("Done!");
            return(true);
        }
        private bool ExecuteAddRemove(TagInstance tag, List <string> args)
        {
            if (args.Count < 3)
            {
                return(false);
            }
            var dependencies = args.Skip(2).Select(a => ArgumentParser.ParseTagIndex(_cache, a)).ToList();

            if (dependencies.Count == 0 || dependencies.Any(d => d == null))
            {
                return(false);
            }
            using (var stream = _info.OpenCacheReadWrite())
            {
                var data = _cache.ExtractTag(stream, tag);
                if (args[0] == "add")
                {
                    foreach (var dependency in dependencies)
                    {
                        if (data.Dependencies.Add(dependency.Index))
                        {
                            Console.WriteLine("Added dependency on tag {0:X8}.", dependency.Index);
                        }
                        else
                        {
                            Console.Error.WriteLine("Tag {0:X8} already depends on tag {1:X8}.", tag.Index,
                                                    dependency.Index);
                        }
                    }
                }
                else
                {
                    foreach (var dependency in dependencies)
                    {
                        if (data.Dependencies.Remove(dependency.Index))
                        {
                            Console.WriteLine("Removed dependency on tag {0:X8}.", dependency.Index);
                        }
                        else
                        {
                            Console.Error.WriteLine("Tag {0:X8} does not depend on tag {1:X8}.", tag.Index,
                                                    dependency.Index);
                        }
                    }
                }
                _cache.SetTagData(stream, tag, data);
            }
            return(true);
        }
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }
            var tag = ArgumentParser.ParseTagIndex(_info.Cache, args[0]);

            if (tag == null)
            {
                return(false);
            }

            TagInstance newTag;

            using (var stream = _info.OpenCacheReadWrite())
                newTag = _info.Cache.DuplicateTag(stream, tag);

            Console.WriteLine("Tag duplicated successfully!");
            Console.Write("New tag: ");
            TagPrinter.PrintTagShort(newTag);
            return(true);
        }
예제 #9
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            var destDir = new DirectoryInfo(args[0]);

            if (!destDir.Exists)
            {
                Write("Destination directory does not exist. Create it? [y/n] ");
                var answer = ReadLine().ToLower();

                if (answer.Length == 0 || !(answer.StartsWith("y") || answer.StartsWith("n")))
                {
                    return(false);
                }

                if (answer.StartsWith("y"))
                {
                    destDir.Create();
                }
                else
                {
                    return(false);
                }
            }

            WriteLine($"Generating cache files in \"{destDir.FullName}\"...");

            var destTagsFile = new FileInfo(Combine(destDir.FullName, "tags.dat"));

            Write($"Generating {destTagsFile.FullName}...");
            using (var tagCacheStream = destTagsFile.Create())
                using (var writer = new BinaryWriter(tagCacheStream))
                {
                    writer.Write((int)0);                   // padding
                    writer.Write((int)0);                   // tag list offset
                    writer.Write((int)0);                   // tag count
                    writer.Write((int)0);                   // padding
                    writer.Write((long)130713360239499012); // timestamp
                    writer.Write((long)0);                  // padding
                }
            WriteLine("done.");

            var destStringIDsFile = new FileInfo(Combine(destDir.FullName, "string_ids.dat"));

            Write($"Generating {destStringIDsFile.FullName}...");
            using (var stringIDCacheStream = destStringIDsFile.Create())
                using (var writer = new BinaryWriter(stringIDCacheStream))
                {
                    writer.Write((int)0); // string count
                    writer.Write((int)0); // data size
                }
            WriteLine("done.");

            var resourceCachePaths = new string[]
            {
                Combine(destDir.FullName, "audio.dat"),
                Combine(destDir.FullName, "resources.dat"),
                Combine(destDir.FullName, "textures.dat"),
                Combine(destDir.FullName, "textures_b.dat"),
                Combine(destDir.FullName, "video.dat")
            };

            foreach (var resourceCachePath in resourceCachePaths)
            {
                Write($"Generating {resourceCachePath}...");
                using (var resourceCacheStream = File.Create(resourceCachePath))
                    using (var writer = new BinaryWriter(resourceCacheStream))
                    {
                        writer.Write((int)0); // padding
                        writer.Write((int)0); // table offset
                        writer.Write((int)0); // resource count
                        writer.Write((int)0); // padding
                    }
                WriteLine("done.");
            }

            var dependencies = new Dictionary <int, TagInstance>();

            LoadTagDependencies(0, ref dependencies);
            LoadTagDependencies(0x16, ref dependencies);
            LoadTagDependencies(0x27D7, ref dependencies);

            var destResourcesFile = new FileInfo(Combine(destDir.FullName, "resources.dat"));

            if (!destResourcesFile.Exists)
            {
                WriteLine($"Destination resource cache file does not exist: {destResourcesFile.FullName}");
                return(false);
            }

            var destTexturesFile = new FileInfo(Combine(destDir.FullName, "textures.dat"));

            if (!destTexturesFile.Exists)
            {
                WriteLine($"Destination texture cache file does not exist: {destTexturesFile.FullName}");
                return(false);
            }

            var destTexturesBFile = new FileInfo(Combine(destDir.FullName, "textures_b.dat"));

            if (!destTexturesBFile.Exists)
            {
                WriteLine($"Destination texture cache file does not exist: {destTexturesBFile.FullName}");
                return(false);
            }

            var destAudioFile = new FileInfo(Combine(destDir.FullName, "audio.dat"));

            if (!destAudioFile.Exists)
            {
                WriteLine($"Destination audio cache file does not exist: {destAudioFile.FullName}");
                return(false);
            }

            TagCache destTagCache;

            using (var stream = destTagsFile.OpenRead())
                destTagCache = new TagCache(stream);

            DefinitionSet guessedVersion;
            var           destVersion = Detect(destTagCache, out guessedVersion);

            if (destVersion == Unknown)
            {
                WriteLine($"Unrecognized target version! (guessed {GetVersionString(guessedVersion)})");
                return(true);
            }

            WriteLine($"Destination cache version: {GetVersionString(destVersion)}");

            StringIDCache destStringIDCache;

            using (var stream = destStringIDsFile.OpenRead())
                destStringIDCache = new StringIDCache(stream, Create(destVersion));

            var destResources = new ResourceDataManager();

            destResources.LoadCachesFromDirectory(destDir.FullName);

            var srcResources = new ResourceDataManager();

            srcResources.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);

            var destSerializer   = new TagSerializer(destVersion);
            var destDeserializer = new TagDeserializer(destVersion);

            var destInfo = new OpenTagCache
            {
                Cache         = destTagCache,
                CacheFile     = destTagsFile,
                StringIDs     = destStringIDCache,
                StringIDsFile = destStringIDsFile,
                Version       = destVersion,
                Serializer    = destSerializer,
                Deserializer  = destDeserializer
            };

            using (Stream srcStream = Info.OpenCacheRead(), destStream = destInfo.OpenCacheReadWrite())
            {
                var maxDependency = dependencies.Keys.Max();
                for (var i = 0; i <= maxDependency; i++)
                {
                    var srcTag = Info.Cache.Tags[i];
                    if (srcTag == null)
                    {
                        destInfo.Cache.AllocateTag();
                        continue;
                    }

                    var srcData = Info.Cache.ExtractTagRaw(srcStream, srcTag);

                    var destTag = destInfo.Cache.AllocateTag(srcTag.Group);
                    destInfo.Cache.SetTagDataRaw(destStream, destTag, srcData);

                    srcData = new byte[0];
                }
            }

            WriteLine($"Done generating cache files in \"{destDir.FullName}\".");

            return(true);
        }
예제 #10
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 4)
            {
                return(false);
            }
            var srcTag = ArgumentParser.ParseTagIndex(_info, args[0]);

            if (srcTag == null)
            {
                return(false);
            }
            var csvPath    = args[1];
            var csvOutPath = args[2];
            var targetDir  = args[3];

            // Load the CSV
            Console.WriteLine("Reading {0}...", csvPath);
            TagVersionMap tagMap;

            using (var reader = new StreamReader(File.OpenRead(csvPath)))
                tagMap = TagVersionMap.ParseTagVersionMap(reader);

            // Load destination files
            Console.WriteLine("Loading the target tags.dat...");
            var destCachePath = Path.Combine(targetDir, "tags.dat");
            var destInfo      = new OpenTagCache {
                CacheFile = new FileInfo(destCachePath)
            };

            using (var stream = destInfo.OpenCacheRead())
                destInfo.Cache = new TagCache(stream);

            // Do version detection
            DefinitionSet guessedVersion;

            destInfo.Version = Definition.Detect(destInfo.Cache, out guessedVersion);
            if (destInfo.Version == DefinitionSet.Unknown)
            {
                Console.WriteLine("Unrecognized target version!");
                return(true);
            }
            Console.WriteLine("- Detected version {0}", Definition.GetVersionString(destInfo.Version));

            if (_info.Version != DefinitionSet.HaloOnline498295 && destInfo.Version != DefinitionSet.HaloOnline106708)
            {
                Console.Error.WriteLine("Conversion is only supported from 11.1.498295 Live to 1.106708 cert_ms23.");
                return(true);
            }

            // Set up version-specific objects
            destInfo.Serializer   = new TagSerializer(destInfo.Version);
            destInfo.Deserializer = new TagDeserializer(destInfo.Version);

            // Load stringIDs
            Console.WriteLine("Loading the target string_ids.dat...");

            var resolver = StringIDResolverFactory.Create(destInfo.Version);

            var destStringIDsPath = Path.Combine(targetDir, "string_ids.dat");

            destInfo.StringIDsFile = new FileInfo(destStringIDsPath);

            using (var stream = destInfo.StringIDsFile.OpenRead())
                destInfo.StringIDs = new StringIDCache(stream, resolver);

            // Load resources for the target build
            Console.WriteLine("Loading target resources...");
            var destResources = new ResourceDataManager();

            destResources.LoadCachesFromDirectory(destInfo.CacheFile.DirectoryName);

            // Load resources for our build
            Console.WriteLine("Loading source resources...");
            var srcResources = new ResourceDataManager();

            srcResources.LoadCachesFromDirectory(_info.CacheFile.DirectoryName);

            Console.WriteLine();
            Console.WriteLine("CONVERTING FROM VERSION {0} TO {1}", Definition.GetVersionString(_info.Version), Definition.GetVersionString(destInfo.Version));
            Console.WriteLine();

            TagInstance resultTag;

            using (Stream srcStream = _info.OpenCacheRead(), destStream = destInfo.OpenCacheReadWrite())
                resultTag = ConvertTag(srcTag, _info, srcStream, srcResources, destInfo, destStream, destResources, tagMap);

            Console.WriteLine();
            Console.WriteLine("Repairing decal systems...");
            FixDecalSystems(destInfo, resultTag.Index);

            Console.WriteLine();
            Console.WriteLine("Saving stringIDs...");
            using (var stream = destInfo.StringIDsFile.Open(FileMode.Open, FileAccess.ReadWrite))
                destInfo.StringIDs.Save(stream);

            Console.WriteLine("Writing {0}...", csvOutPath);
            using (var stream = new StreamWriter(File.Open(csvOutPath, FileMode.Create, FileAccess.ReadWrite)))
                tagMap.WriteCsv(stream);

            // Uncomment this to add the new tag as a dependency to cfgt to make testing easier

            /*using (var stream = destInfo.OpenCacheReadWrite())
             * {
             *  destInfo.Cache.Tags[0].Dependencies.Add(resultTag.Index);
             *  destInfo.Cache.UpdateTag(stream, destInfo.Cache.Tags[0]);
             * }*/

            Console.WriteLine();
            Console.WriteLine("All done! The converted tag is:");
            TagPrinter.PrintTagShort(resultTag);
            return(true);
        }
예제 #11
0
        public override bool Execute(List<string> args)
        {
            if (args.Count != 1)
                return false;

            var destDir = new DirectoryInfo(args[0]);
            if (!destDir.Exists)
            {
                Write("Destination directory does not exist. Create it? [y/n] ");
                var answer = ReadLine().ToLower();

                if (answer.Length == 0 || !(answer.StartsWith("y") || answer.StartsWith("n")))
                    return false;

                if (answer.StartsWith("y"))
                    destDir.Create();
                else
                    return false;
            }

            WriteLine($"Generating cache files in \"{destDir.FullName}\"...");

            var destTagsFile = new FileInfo(Combine(destDir.FullName, "tags.dat"));

            Write($"Generating {destTagsFile.FullName}...");
            using (var tagCacheStream = destTagsFile.Create())
            using (var writer = new BinaryWriter(tagCacheStream))
            {
                writer.Write((int)0); // padding
                writer.Write((int)0); // tag list offset
                writer.Write((int)0); // tag count
                writer.Write((int)0); // padding
                writer.Write((long)130713360239499012); // timestamp
                writer.Write((long)0); // padding
            }
            WriteLine("done.");

            var destStringIDsFile = new FileInfo(Combine(destDir.FullName, "string_ids.dat"));

            Write($"Generating {destStringIDsFile.FullName}...");
            using (var stringIDCacheStream = destStringIDsFile.Create())
            using (var writer = new BinaryWriter(stringIDCacheStream))
            {
                writer.Write((int)0); // string count
                writer.Write((int)0); // data size
            }
            WriteLine("done.");

            var resourceCachePaths = new string[]
            {
                Combine(destDir.FullName, "audio.dat"),
                Combine(destDir.FullName, "resources.dat"),
                Combine(destDir.FullName, "textures.dat"),
                Combine(destDir.FullName, "textures_b.dat"),
                Combine(destDir.FullName, "video.dat")
            };

            foreach (var resourceCachePath in resourceCachePaths)
            {
                Write($"Generating {resourceCachePath}...");
                using (var resourceCacheStream = File.Create(resourceCachePath))
                using (var writer = new BinaryWriter(resourceCacheStream))
                {
                    writer.Write((int)0); // padding
                    writer.Write((int)0); // table offset
                    writer.Write((int)0); // resource count
                    writer.Write((int)0); // padding
                }
                WriteLine("done.");
            }

            var dependencies = new Dictionary<int, TagInstance>();
            LoadTagDependencies(0, ref dependencies);
            LoadTagDependencies(0x16, ref dependencies);
            LoadTagDependencies(0x27D7, ref dependencies);
            
            var destResourcesFile = new FileInfo(Combine(destDir.FullName, "resources.dat"));
            if (!destResourcesFile.Exists)
            {
                WriteLine($"Destination resource cache file does not exist: {destResourcesFile.FullName}");
                return false;
            }

            var destTexturesFile = new FileInfo(Combine(destDir.FullName, "textures.dat"));
            if (!destTexturesFile.Exists)
            {
                WriteLine($"Destination texture cache file does not exist: {destTexturesFile.FullName}");
                return false;
            }

            var destTexturesBFile = new FileInfo(Combine(destDir.FullName, "textures_b.dat"));
            if (!destTexturesBFile.Exists)
            {
                WriteLine($"Destination texture cache file does not exist: {destTexturesBFile.FullName}");
                return false;
            }

            var destAudioFile = new FileInfo(Combine(destDir.FullName, "audio.dat"));
            if (!destAudioFile.Exists)
            {
                WriteLine($"Destination audio cache file does not exist: {destAudioFile.FullName}");
                return false;
            }
            
            TagCache destTagCache;
            using (var stream = destTagsFile.OpenRead())
                destTagCache = new TagCache(stream);

            DefinitionSet guessedVersion;
            var destVersion = Detect(destTagCache, out guessedVersion);
            if (destVersion == Unknown)
            {
                WriteLine($"Unrecognized target version! (guessed {GetVersionString(guessedVersion)})");
                return true;
            }

            WriteLine($"Destination cache version: {GetVersionString(destVersion)}");

            StringIDCache destStringIDCache;
            using (var stream = destStringIDsFile.OpenRead())
                destStringIDCache = new StringIDCache(stream, Create(destVersion));

            var destResources = new ResourceDataManager();
            destResources.LoadCachesFromDirectory(destDir.FullName);

            var srcResources = new ResourceDataManager();
            srcResources.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);

            var destSerializer = new TagSerializer(destVersion);
            var destDeserializer = new TagDeserializer(destVersion);

            var destInfo = new OpenTagCache
            {
                Cache = destTagCache,
                CacheFile = destTagsFile,
                StringIDs = destStringIDCache,
                StringIDsFile = destStringIDsFile,
                Version = destVersion,
                Serializer = destSerializer,
                Deserializer = destDeserializer
            };

            using (Stream srcStream = Info.OpenCacheRead(), destStream = destInfo.OpenCacheReadWrite())
            {
                var maxDependency = dependencies.Keys.Max();
                for (var i = 0; i <= maxDependency; i++)
                {
                    var srcTag = Info.Cache.Tags[i];
                    if (srcTag == null)
                    {
                        destInfo.Cache.AllocateTag();
                        continue;
                    }

                    var srcData = Info.Cache.ExtractTagRaw(srcStream, srcTag);

                    var destTag = destInfo.Cache.AllocateTag(srcTag.Group);
                    destInfo.Cache.SetTagDataRaw(destStream, destTag, srcData);

                    srcData = new byte[0];
                }
            }
            
            WriteLine($"Done generating cache files in \"{destDir.FullName}\".");

            return true;
        }
예제 #12
0
        public override bool Execute(List <string> args)
        {
            //Arguments needed: filepath, <new>|<tagIndex>
            if (args.Count < 2)
            {
                return(false);
            }

            TagInstance tag = null;
            bool        b_duplicate;
            // optional argument: forces overwriting of tags that are not type: phmo
            bool b_force = (args.Count >= 3 && args[2].ToLower().Equals("force"));

            if (args[1].ToLower().Equals("new"))
            {
                b_duplicate = true;
            }
            else
            {
                tag = ArgumentParser.ParseTagIndex(_info.Cache, args[1]);
                if (tag == null)
                {
                    return(false);
                }
                b_duplicate = false;
            }

            if (!b_force && !b_duplicate && !tag.IsInGroup("phmo"))
            {
                Console.WriteLine("Tag to override was not of class- 'phmo'. Use third argument- 'force' to inject.");
                return(false);
            }

            var filename = args[0];

            var modelbuilder = new PhysicsModelBuilder();

            if (!modelbuilder.ParseFromFile(filename))
            {
                return(false);
            }
            //modelbuilder must also make a node for the physics model
            var phmo = modelbuilder.Build();

            if (phmo == null)
            {
                return(false);
            }

            using (var stream = _info.OpenCacheReadWrite())
            {
                if (b_duplicate)
                {
                    //duplicate an existing tag, trashcan phmo
                    tag = _info.Cache.DuplicateTag(stream, _info.Cache.Tags[0x4436]);
                    if (tag == null)
                    {
                        Console.WriteLine("Failed tag duplication.");
                        return(false);
                    }
                }

                var context = new TagSerializationContext(stream, _info.Cache, _info.StringIds, tag);
                _info.Serializer.Serialize(context, phmo);
            }

            Console.Write("Successfully imported phmo to: ");
            TagPrinter.PrintTagShort(tag);

            return(true);
        }