public void Serialize(Stream stream, CachedTagHaloOnline instance, object definition) { if (!ModifiedTags.Contains(instance.Index)) { SignalModifiedTag(instance.Index); } Serializer.Serialize(new HaloOnlineSerializationContext(stream, this, instance), definition); }
private bool ExecuteAddRemove(CachedTagHaloOnline tag, List <string> args) { if (args.Count < 3) { return(false); } var dependencies = args.Skip(2).Select(name => Cache.GetTag(name)).ToList(); if (dependencies.Count == 0 || dependencies.Any(d => d == null)) { return(false); } using (var stream = Cache.OpenCacheReadWrite()) { var data = Cache.TagCacheGenHO.ExtractTag(stream, tag); if (args[0].ToLower() == "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.TagCacheGenHO.SetTagData(stream, tag, data); } return(true); }
private bool ExecuteListDependsOn(CachedTagHaloOnline tag) { var dependsOn = Cache.TagCacheGenHO.NonNull().Where(t => ((CachedTagHaloOnline)t).Dependencies.Contains(tag.Index)); foreach (var dependency in dependsOn) { var tagName = dependency?.Name ?? $"0x{dependency.Index:X4}"; Console.WriteLine($"[Index: 0x{dependency.Index:X4}, Offset: 0x{dependency.DefinitionOffset:X8}] {tagName}.{Cache.StringTable.GetString(dependency.Group.Name)}"); } return(true); }
public PokeTagChangesCommand(GameCacheHaloOnlineBase cache, CachedTagHaloOnline tag, object value) : base(true, "PokeTagChanges", $"Pokes changes made to the current {cache.StringTable.GetString(tag.Group.Name)} definition to a running game's memory.", "PokeTagChanges [process id]", $"Pokes changes made to the current {cache.StringTable.GetString(tag.Group.Name)} definition to a running game's memory.") { Cache = cache; Tag = tag; Value = value; }
private bool ExecuteList(CachedTagHaloOnline tag, bool all, params string[] groups) { if (tag.Dependencies.Count == 0) { Console.Error.WriteLine("Tag {0:X8} has no dependencies.", tag.Index); return(true); } IEnumerable <CachedTagHaloOnline> dependencies; if (all) { dependencies = Cache.TagCacheGenHO.FindDependencies(tag); } else { dependencies = tag.Dependencies.Where(i => i >= 0 && i <= Cache.TagCache.Count).Select(i => Cache.TagCacheGenHO.Tags[i]); } var groupTags = groups.Select(group => Cache.ParseGroupTag(group)).ToArray(); foreach (var dependency in dependencies) { if (groupTags.Length != 0 && !dependency.IsInGroup(groupTags)) { continue; } var tagName = dependency?.Name ?? $"0x{dependency.Index:X4}"; Console.WriteLine($"[Index: 0x{dependency.Index:X4}, Offset: 0x{dependency.HeaderOffset:X8}, Size: 0x{dependency.TotalSize:X4}] {tagName}.{Cache.StringTable.GetString(dependency.Group.Name)}"); } foreach (var instance in tag.Dependencies) { if (instance < 0 || instance >= Cache.TagCache.Count) { Console.WriteLine($"WARNING: dependency is an inexistent tag: 0x{instance:X4}"); } } return(true); }
private CachedTagHaloOnline ConvertTag(CachedTagHaloOnline srcTag, GameCacheContextHaloOnline srcCacheContext, Stream srcStream, GameCacheContextHaloOnline destCacheContext, Stream destStream, TagVersionMap tagMap) { TagPrinter.PrintTagShort(srcTag); // Uncomment this to use 0x101F for all shaders /*if (srcTag.IsClass("rm ")) * return destCacheContext.Cache.Tags[0x101F];*/ // Check if the tag is in the map, and just return the translated tag if so var destIndex = tagMap.Translate(srcCacheContext.Version, srcTag.Index, destCacheContext.Version); if (destIndex >= 0) { Console.WriteLine("- Using already-known index {0:X4}", destIndex); return(destCacheContext.TagCache.Index[destIndex]); } // Deserialize the tag from the source cache var tagData = srcCacheContext.Deserialize(srcStream, srcTag); // 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(srcCacheContext.Version, prop.Template.Index, destCacheContext.Version) < 0) * return destCacheContext.Cache.Tags[0x101F]; * } * }*/ // Allocate a new tag and create a mapping for it CachedTagHaloOnline instance = null; if (srcCacheContext.Version != destCacheContext.Version) { for (var i = 0; i < destCacheContext.TagCache.Index.Count; i++) { if (destCacheContext.TagCache.Index[i] == null) { destCacheContext.TagCache.Index[i] = instance = new CachedTagHaloOnline(i, TagGroup.Instances[srcTag.Group.Tag]); break; } } } else { if (destCacheContext.TagCache.Index[srcTag.Index] != null) { if (destCacheContext.TagCache.Index[srcTag.Index].IsInGroup(srcTag.Group)) { return(destCacheContext.TagCache.Index[srcTag.Index]); } } else { destCacheContext.TagCache.Index[srcTag.Index] = instance = new CachedTagHaloOnline(srcTag.Index, TagGroup.Instances[srcTag.Group.Tag], srcTag.Name); } } if (instance == null) { instance = destCacheContext.TagCache.AllocateTag(srcTag.Group); } tagMap.Add(srcCacheContext.Version, srcTag.Index, destCacheContext.Version, instance.Index); if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd ")) { IsDecalShader = true; } // Convert it tagData = Convert(tagData, srcCacheContext, srcStream, destCacheContext, destStream, tagMap); if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd ")) { IsDecalShader = false; } // Re-serialize into the destination cache destCacheContext.Serialize(destStream, instance, tagData); return(instance); }
public object Deserialize(Stream stream, CachedTagHaloOnline instance) => Deserialize(new HaloOnlineSerializationContext(stream, this, instance), TagDefinition.Find(instance.Group.Tag));
public T Deserialize <T>(Stream stream, CachedTagHaloOnline instance) => Deserialize <T>(new HaloOnlineSerializationContext(stream, this, instance));
/// <summary> /// Creates a tag serialization context which serializes data into a tag. /// </summary> /// <param name="stream">The stream to write to.</param> /// <param name="context">The game cache context.</param> /// <param name="tag">The tag to overwrite.</param> public HaloOnlineSerializationContext(Stream stream, GameCacheHaloOnlineBase context, CachedTagHaloOnline tag) { Stream = stream; Context = context; Tag = tag; }
public ModPackageTagSerializationContext(Stream stream, GameCacheHaloOnlineBase context, ModPackage package, CachedTagHaloOnline tag) : base(stream, context, tag) { Package = package; }