Exemple #1
0
        public static TagInstance ConvertTag(TagInstance srcTag, OpenTagCache srcInfo, Stream srcStream, ResourceDataManager srcResources, OpenTagCache destInfo, Stream destStream, ResourceDataManager destResources, TagCacheMap tagMap)
        {
            TagPrinter.PrintTagShort(srcTag);

            // Deserialize the tag from the source cache
            var structureType = TagStructureTypes.FindByGroupTag(srcTag.Group.Tag);
            var srcContext    = new TagSerializationContext(srcStream, srcInfo.Cache, srcInfo.StringIDs, srcTag);
            var tagData       = srcInfo.Deserializer.Deserialize(srcContext, structureType);

            // Acquire the destination tag
            var destTag = destInfo.Cache.AllocateTag(srcTag.Group);

            tagMap.Add(srcInfo.CacheFile.FullName, srcTag.Index, destInfo.CacheFile.FullName, destTag.Index);

            if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd "))
            {
                IsDecalShader = true;
            }

            // Convert the source tag
            tagData = Convert(tagData, srcInfo, srcStream, srcResources, destInfo, destStream, destResources, tagMap);

            if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd "))
            {
                IsDecalShader = false;
            }

            // Re-serialize into the destination cache
            var destContext = new TagSerializationContext(destStream, destInfo.Cache, destInfo.StringIDs, destTag);

            destInfo.Serializer.Serialize(destContext, tagData);

            return(destTag);
        }
Exemple #2
0
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            var groupTag = ArgumentParser.ParseGroupTag(Info.StringIDs, args[0]);

            if (groupTag == null || !TagGroup.Instances.ContainsKey(groupTag))
            {
                return(false);
            }

            TagInstance instance;

            using (var stream = Info.OpenCacheReadWrite())
            {
                instance = Info.Cache.AllocateTag(TagGroup.Instances[groupTag]);
                var context = new TagSerializationContext(stream, Info.Cache, Info.StringIDs, instance);
                var data    = Activator.CreateInstance(TagStructureTypes.FindByGroupTag(groupTag));
                Info.Serializer.Serialize(context, data);
            }

            var tagName = Info.TagNames.ContainsKey(instance.Index) ?
                          Info.TagNames[instance.Index] :
                          $"0x{instance.Index:X4}";

            Console.WriteLine($"[Index: 0x{instance.Index:X4}, Offset: 0x{instance.HeaderOffset:X8}, Size: 0x{instance.TotalSize:X4}] {tagName}.{Info.StringIDs.GetString(instance.Group.Name)}");

            return(true);
        }
Exemple #3
0
        private TagInstance ConvertTag(TagInstance srcTag, OpenTagCache srcInfo, Stream srcStream, ResourceDataManager srcResources, OpenTagCache destInfo, Stream destStream, ResourceDataManager destResources, TagVersionMap tagMap)
        {
            TagPrinter.PrintTagShort(srcTag);

            // Uncomment this to use 0x101F for all shaders

            /*if (srcTag.IsClass("rm  "))
             *  return destInfo.Cache.Tags[0x101F];*/

            // Check if the tag is in the map, and just return the translated tag if so
            var destIndex = tagMap.Translate(srcInfo.Version, srcTag.Index, destInfo.Version);

            if (destIndex >= 0)
            {
                Console.WriteLine("- Using already-known index {0:X4}", destIndex);
                return(destInfo.Cache.Tags[destIndex]);
            }

            // Deserialize the tag from the source cache
            var structureType = TagStructureTypes.FindByGroupTag(srcTag.Group.Tag);
            var srcContext    = new TagSerializationContext(srcStream, srcInfo.Cache, srcInfo.StringIDs, srcTag);
            var tagData       = srcInfo.Deserializer.Deserialize(srcContext, structureType);

            // Uncomment this to use 0x101F in place of shaders that need conversion

            /*if (tagData is RenderMethod)
             * {
             *  var rm = (RenderMethod)tagData;
             *  foreach (var prop in rm.ShaderProperties)
             *  {
             *      if (tagMap.Translate(srcInfo.Version, prop.Template.Index, destInfo.Version) < 0)
             *          return destInfo.Cache.Tags[0x101F];
             *  }
             * }*/

            // Allocate a new tag and create a mapping for it
            var newTag = destInfo.Cache.AllocateTag(srcTag.Group);

            tagMap.Add(srcInfo.Version, srcTag.Index, destInfo.Version, newTag.Index);

            if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd "))
            {
                _isDecalShader = true;
            }

            // Convert it
            tagData = Convert(tagData, srcInfo, srcStream, srcResources, destInfo, destStream, destResources, tagMap);

            if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd "))
            {
                _isDecalShader = false;
            }

            // Re-serialize into the destination cache
            var destContext = new TagSerializationContext(destStream, destInfo.Cache, destInfo.StringIDs, newTag);

            destInfo.Serializer.Serialize(destContext, tagData);
            return(newTag);
        }
Exemple #4
0
        public static Tag ParseGroupTag(StringIDCache stringIDs, string groupName)
        {
            if (TagStructureTypes.IsGroupTag(groupName))
            {
                return(new Tag(groupName));
            }

            foreach (var pair in TagGroup.Instances)
            {
                if (groupName == stringIDs.GetString(pair.Value.Name))
                {
                    return(pair.Value.Tag);
                }
            }

            return(Tag.Null);
        }
        private void SetGameObjectName(Stream stream, TagInstance tag, ref Dictionary <int, string> tagNames)
        {
            var context    = new TagSerializationContext(stream, Info.Cache, Info.StringIds, tag);
            var definition = (GameObject)Info.Deserializer.Deserialize(context, TagStructureTypes.FindByGroupTag(tag.Group.Tag));

            if (definition.Model == null)
            {
                return;
            }

            context = new TagSerializationContext(stream, Info.Cache, Info.StringIds, definition.Model);
            var modelDefinition = Info.Deserializer.Deserialize <Model>(context);

            if (modelDefinition.RenderModel == null)
            {
                return;
            }

            context = new TagSerializationContext(stream, Info.Cache, Info.StringIds, modelDefinition.RenderModel);
            var renderModelDefinition = Info.Deserializer.Deserialize <RenderModel>(context);

            var objectName = Info.StringIds.GetString(renderModelDefinition.Name);

            if (tag.Group.Tag == new Tag("bipd"))
            {
                var biped = (Biped)definition;

                var isMultiplayer = objectName.StartsWith("mp_");
                var isMonitor     = objectName.StartsWith("monitor");

                var objectRootName = isMultiplayer ?
                                     objectName.Substring(3) :
                                     objectName;

                var objectGenericName = $"objects\\characters\\{objectRootName}\\{objectRootName}";

                if (objectRootName != objectName)
                {
                    objectName = $"objects\\characters\\{objectRootName}\\{objectName}\\{objectName}";
                }
                else if (isMonitor)
                {
                    objectName = $"{objectGenericName}_editor";
                }
                else
                {
                    objectName = objectGenericName;
                }

                tagNames[definition.Model.Index] = objectName;

                if (modelDefinition.RenderModel != null)
                {
                    tagNames[modelDefinition.RenderModel.Index] = objectName;
                }

                if (modelDefinition.CollisionModel != null)
                {
                    tagNames[modelDefinition.CollisionModel.Index] = objectGenericName;
                }

                if (modelDefinition.PhysicsModel != null)
                {
                    tagNames[modelDefinition.PhysicsModel.Index] = objectGenericName;
                }

                if (modelDefinition.Animation != null)
                {
                    tagNames[modelDefinition.Animation.Index] = objectGenericName;
                }

                if (biped.CollisionDamage != null && !tagNames.ContainsKey(biped.CollisionDamage.Index))
                {
                    tagNames[biped.CollisionDamage.Index] = isMonitor ?
                                                            "globals\\collision_damage\\invulnerable_harmless" :
                                                            "globals\\collision_damage\\biped_player";
                }

                if (biped.MaterialEffects != null && !tagNames.ContainsKey(biped.MaterialEffects.Index))
                {
                    tagNames[biped.MaterialEffects.Index] =
                        $"fx\\material_effects\\objects\\characters\\{objectRootName}";
                }

                if (biped.MeleeImpact != null && !tagNames.ContainsKey(biped.MeleeImpact.Index))
                {
                    tagNames[biped.MeleeImpact.Index] =
                        "sounds\\materials\\soft\\organic_flesh\\melee_impact";
                }

                if (biped.CameraTracks.Count != 0 && biped.CameraTracks[0].Track != null && !tagNames.ContainsKey(biped.CameraTracks[0].Track.Index))
                {
                    tagNames[biped.CameraTracks[0].Track.Index] = isMonitor ?
                                                                  "camera\\biped_follow_camera" :
                                                                  "camera\\biped_support_camera";
                }

                if (biped.MeleeDamage != null && !tagNames.ContainsKey(biped.MeleeDamage.Index))
                {
                    tagNames[biped.MeleeDamage.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_melee";
                }

                if (biped.BoardingMeleeDamage != null && !tagNames.ContainsKey(biped.BoardingMeleeDamage.Index))
                {
                    tagNames[biped.BoardingMeleeDamage.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_boarding_melee";
                }

                if (biped.BoardingMeleeResponse != null && !tagNames.ContainsKey(biped.BoardingMeleeResponse.Index))
                {
                    tagNames[biped.BoardingMeleeResponse.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_boarding_melee_response";
                }

                if (biped.EjectionMeleeDamage != null && !tagNames.ContainsKey(biped.EjectionMeleeDamage.Index))
                {
                    tagNames[biped.EjectionMeleeDamage.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_ejection_melee";
                }

                if (biped.EjectionMeleeResponse != null && !tagNames.ContainsKey(biped.EjectionMeleeResponse.Index))
                {
                    tagNames[biped.EjectionMeleeResponse.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_ejection_melee_response";
                }

                if (biped.LandingMeleeDamage != null && !tagNames.ContainsKey(biped.LandingMeleeDamage.Index))
                {
                    tagNames[biped.LandingMeleeDamage.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_landing_melee";
                }

                if (biped.FlurryMeleeDamage != null && !tagNames.ContainsKey(biped.FlurryMeleeDamage.Index))
                {
                    tagNames[biped.FlurryMeleeDamage.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_flurry_melee";
                }

                if (biped.ObstacleSmashMeleeDamage != null && !tagNames.ContainsKey(biped.ObstacleSmashMeleeDamage.Index))
                {
                    tagNames[biped.ObstacleSmashMeleeDamage.Index] =
                        $"objects\\characters\\{objectRootName}\\damage_effects\\{objectRootName}_obstacle_smash";
                }

                if (biped.AreaDamageEffect != null && !tagNames.ContainsKey(biped.AreaDamageEffect.Index))
                {
                    tagNames[biped.AreaDamageEffect.Index] =
                        $"fx\\material_effects\\objects\\characters\\contact\\collision\\blood_aoe_{objectRootName}";
                }
            }
            else if (tag.Group.Tag == new Tag("weap"))
            {
                var weapon = (Weapon)definition;

                if (weapon.HudInterface != null && !tagNames.ContainsKey(weapon.HudInterface.Index))
                {
                    tagNames[weapon.HudInterface.Index] = $"ui\\chud\\{objectName}";
                }

                if (weapon.FirstPerson.Count > 0)
                {
                    var spartanJmadTag = weapon.FirstPerson[0].FirstPersonAnimations;
                    if (spartanJmadTag != null)
                    {
                        tagNames[spartanJmadTag.Index] = $"objects\\characters\\mp_masterchief\\fp\\weapons\\fp_{objectName}\\fp_{objectName}";
                    }
                }

                if (weapon.FirstPerson.Count > 1)
                {
                    var eliteJmadTag = weapon.FirstPerson[1].FirstPersonAnimations;
                    if (eliteJmadTag != null)
                    {
                        tagNames[eliteJmadTag.Index] = $"objects\\characters\\mp_elite\\fp\\weapons\\fp_{objectName}\\fp_{objectName}";
                    }
                }

                var weaponClassName =
                    // HUNTER WEAPONS
                    objectName.StartsWith("flak_cannon") ?
                    "hunter\\hunter_flak_cannon" :
                    // MELEE WEAPONS
                    objectName.StartsWith("energy_blade") ?
                    "melee\\energy_blade" :
                    objectName.StartsWith("gravity_hammer") ?
                    "melee\\gravity_hammer" :
                    // MULTIPLAYER WEAPONS
                    objectName.StartsWith("assault_bomb") ?
                    "multiplayer\\assault_bomb" :
                    objectName.StartsWith("ball") ?
                    "multiplayer\\ball" :
                    objectName.StartsWith("flag") ?
                    "multiplayer\\flag" :
                    // PISTOL WEAPONS
                    objectName.StartsWith("excavator") ?
                    "pistol\\excavator" :
                    objectName.StartsWith("magnum") ?
                    "pistol\\magnum" :
                    objectName.StartsWith("needler") ?
                    "pistol\\needler" :
                    objectName.StartsWith("plasma_pistol") ?
                    "pistol\\plasma_pistol" :
                    // RIFLE WEAPONS
                    (objectName.StartsWith("assault_rifle") || objectName.StartsWith("ar_variant")) ?
                    "rifle\\assault_rifle" :
                    (objectName.StartsWith("battle_rifle") || objectName.StartsWith("br_variant")) ?
                    "rifle\\battle_rifle" :
                    objectName.StartsWith("beam_rifle") ?
                    "rifle\\beam_rifle" :
                    objectName.StartsWith("covenant_carbine") ?
                    "rifle\\covenant_carbine" :
                    objectName.StartsWith("dmr") ?
                    "rifle\\dmr" :
                    objectName.StartsWith("needle_rifle") ?
                    "rifle\\needle_rifle" :
                    objectName.StartsWith("plasma_rifle") ?
                    "rifle\\plasma_rifle" :
                    objectName.StartsWith("shotgun") ?
                    "rifle\\shotgun" :
                    objectName.StartsWith("smg") ?
                    "rifle\\smg" :
                    objectName.StartsWith("sniper_rifle") ?
                    "rifle\\sniper_rifle" :
                    objectName.StartsWith("spike_rifle") ?
                    "rifle\\spike_rifle" :
                    // SUPPORT WEAPONS
                    objectName.StartsWith("rocket_launcher") ?
                    "support_high\\rocket_launcher" :
                    objectName.StartsWith("spartan_laser") ?
                    "support_high\\spartan_laser" :
                    objectName.StartsWith("brute_shot") ?
                    "support_low\\brute_shot" :
                    objectName.StartsWith("sentinel_gun") ?
                    "support_low\\sentinel_gun" :
                    // OTHER WEAPONS
                    objectName;

                objectName = $"objects\\weapons\\{weaponClassName}\\{objectName}";

                if (objectName.EndsWith("energy_blade") && definition.WaterDensity == GameObject.WaterDensityValue.Default)
                {
                    objectName += "_useless";
                }

                tagNames[definition.Model.Index] = objectName;

                if (modelDefinition.RenderModel != null)
                {
                    tagNames[modelDefinition.RenderModel.Index] = objectName;
                }

                if (modelDefinition.CollisionModel != null)
                {
                    tagNames[modelDefinition.CollisionModel.Index] = objectName;
                }

                if (modelDefinition.PhysicsModel != null)
                {
                    tagNames[modelDefinition.PhysicsModel.Index] = objectName;
                }

                if (modelDefinition.Animation != null)
                {
                    tagNames[modelDefinition.Animation.Index] = objectName;
                }
            }
            else if (tag.Group.Tag == new Tag("eqip"))
            {
                var equipment = (Equipment)definition;

                var equipmentClassName =
                    (objectName.StartsWith("health_pack") || objectName.EndsWith("ammo")) ?
                    $"powerups\\{objectName}" :
                    objectName.StartsWith("powerup") ?
                    $"multi\\powerups\\{objectName}" :
                    objectName.EndsWith("grenade") ?
                    $"weapons\\grenade\\{objectName}" :
                    $"equipment\\{objectName}";

                objectName = $"objects\\{equipmentClassName}\\{objectName}";
            }
            else if (tag.Group.Tag == new Tag("vehi"))
            {
            }
            else if (tag.Group.Tag == new Tag("armr"))
            {
                // TODO: figure out spartan/elite armor name differences

                objectName = $"objects\\characters\\masterchief\\mp_masterchief\\armor\\{objectName}";

                tagNames[definition.Model.Index] = objectName;

                if (modelDefinition.RenderModel != null)
                {
                    tagNames[modelDefinition.RenderModel.Index] = objectName;
                }

                if (modelDefinition.CollisionModel != null)
                {
                    tagNames[modelDefinition.CollisionModel.Index] = objectName;
                }

                if (modelDefinition.PhysicsModel != null)
                {
                    tagNames[modelDefinition.PhysicsModel.Index] = objectName;
                }

                if (modelDefinition.Animation != null)
                {
                    tagNames[modelDefinition.Animation.Index] = objectName;
                }
            }

            tagNames[tag.Index] = objectName;
        }
        public override bool Execute(List <string> args)
        {
            if (args.Count < 2)
            {
                return(false);
            }
            var outputPath = args[0];

            // Load each file and do version detection
            var infos = new List <OpenTagCache>();

            foreach (var path in args.Skip(1))
            {
                Console.WriteLine("Loading {0}...", path);

                // Load the cache file
                var info = new OpenTagCache {
                    CacheFile = new FileInfo(path)
                };
                using (var stream = info.OpenCacheRead())
                    info.Cache = new TagCache(stream);

                // Do version detection, and don't accept the closest version
                // because that might not work
                EngineVersion closestVersion;
                info.Version = VersionDetection.DetectVersion(info.Cache, out closestVersion);
                if (info.Version == EngineVersion.Unknown)
                {
                    Console.WriteLine("- Unrecognized version! Ignoring.");
                    continue;
                }
                info.Deserializer = new TagDeserializer(info.Version);
                infos.Add(info);
            }

            var result = new TagVersionMap();

            using (var baseStream = _info.OpenCacheRead())
            {
                // Get the scenario tags for this cache
                Console.WriteLine("Finding base scenario tags...");
                var baseScenarios = FindScenarios(_info, baseStream);
                var baseVersion   = _info.Version;
                var baseTagData   = new Dictionary <int, object>();
                foreach (var scenario in baseScenarios)
                {
                    baseTagData[scenario.Tag.Index] = scenario.Data;
                }

                // Now compare with each of the other caches
                foreach (var info in infos)
                {
                    using (var stream = info.OpenCacheRead())
                    {
                        Console.WriteLine("Finding scenario tags in {0}...", info.CacheFile.FullName);

                        // Get the scenario tags and connect them to the base tags
                        var scenarios     = FindScenarios(info, stream);
                        var tagsToCompare = new Queue <QueuedTag>();
                        for (var i = 0; i < scenarios.Count; i++)
                        {
                            tagsToCompare.Enqueue(scenarios[i]);
                            if (i < baseScenarios.Count)
                            {
                                result.Add(baseVersion, baseScenarios[i].Tag.Index, info.Version, scenarios[i].Tag.Index);
                            }
                        }

                        // Process each tag in the queue, enqueuing all of its dependencies as well
                        while (tagsToCompare.Count > 0)
                        {
                            // Get the tag and its data
                            var tag = tagsToCompare.Dequeue();
                            TagPrinter.PrintTagShort(tag.Tag);
                            var data = tag.Data;
                            if (data == null)
                            {
                                // No data yet - deserialize it
                                var context = new TagSerializationContext(stream, info.Cache, info.StringIds, tag.Tag);
                                var type    = TagStructureTypes.FindByGroupTag(tag.Tag.Group.Tag);
                                data = info.Deserializer.Deserialize(context, type);
                            }

                            // Now get the data for the base tag
                            var baseTag = result.Translate(info.Version, tag.Tag.Index, baseVersion);
                            if (baseTag == -1 || _info.Cache.Tags[baseTag].Group.Tag != tag.Tag.Group.Tag)
                            {
                                continue;
                            }
                            object baseData;
                            if (!baseTagData.TryGetValue(baseTag, out baseData))
                            {
                                // No data yet - deserialize it
                                var context = new TagSerializationContext(baseStream, _info.Cache, _info.StringIds, _info.Cache.Tags[baseTag]);
                                var type    = TagStructureTypes.FindByGroupTag(tag.Tag.Group.Tag);
                                baseData             = _info.Deserializer.Deserialize(context, type);
                                baseTagData[baseTag] = baseData;
                            }

                            // Compare the two blocks
                            CompareBlocks(baseData, baseVersion, data, info.Version, result, tagsToCompare);
                        }
                    }
                }
            }

            // Write out the CSV
            Console.WriteLine("Writing results...");
            using (var writer = new StreamWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write)))
                result.WriteCsv(writer);

            Console.WriteLine("Done!");
            return(true);
        }
Exemple #7
0
        public static CommandContext Create(CommandContextStack stack, OpenTagCache info, TagInstance tag)
        {
            var groupName = info.StringIDs.GetString(tag.Group.Name);

            var tagName = $"0x{tag.Index:X4}";

            if (info.TagNames.ContainsKey(tag.Index))
            {
                tagName = info.TagNames[tag.Index];
                tagName = $"(0x{tag.Index:X4}) {tagName.Substring(tagName.LastIndexOf('\\') + 1)}";
            }

            var context = new CommandContext(stack.Context,
                                             string.Format("{0}.{1}", tagName, groupName));

            switch (tag.Group.Tag.ToString())
            {
            case "vfsl":     // vfiles_list
                EditVFilesList(context, info, tag);
                break;

            case "unic":     // multilingual_unicode_string_list
                EditMultilingualUnicodeStringList(context, info, tag);
                break;

            case "bitm":     // bitmap
                EditBitmap(context, info, tag);
                break;

            case "hlmt":     // model
                EditModel(context, info, tag);
                break;

            case "mode":     // render_model
                EditRenderModel(context, info, tag);
                break;

            case "jmad":
                EditAnimation(context, info, tag);
                break;

            case "rm  ":     // render_method
            case "rmsh":     // shader
            case "rmd ":     // shader_decal
            case "rmfl":     // shader_foliage
            case "rmhg":     // shader_halogram
            case "rmss":     // shader_screen
            case "rmtr":     // shader_terrain
            case "rmw ":     // shader_water
            case "rmzo":     // shader_zonly
            case "rmcs":     // shader_custom
                EditRenderMethod(context, info, tag);
                break;

            case "scnr":
                EditScenario(context, info, tag);
                break;
            }

            object value = null;

            using (var stream = info.OpenCacheRead())
                value = info.Deserializer.Deserialize(
                    new TagSerializationContext(stream, info.Cache, info.StringIDs, tag),
                    TagStructureTypes.FindByGroupTag(tag.Group.Tag));

            var structure = new TagStructureInfo(
                TagStructureTypes.FindByGroupTag(tag.Group.Tag));

            context.AddCommand(new ListFieldsCommand(info, structure, value));
            context.AddCommand(new SetFieldCommand(stack, info, tag, structure, value));
            context.AddCommand(new EditBlockCommand(stack, info, tag, value));
            context.AddCommand(new AddToCommand(stack, info, tag, structure, value));
            context.AddCommand(new RemoveFromCommand(stack, info, tag, structure, value));
            context.AddCommand(new CopyElementsCommand(stack, info, tag, structure, value));
            context.AddCommand(new PasteElementsCommand(stack, info, tag, structure, value));
            context.AddCommand(new SaveChangesCommand(info, tag, value));
            context.AddCommand(new ExitToCommand(stack));

            return(context);
        }