public override bool Execute(List <string> args) { if (args.Count > 1) { return(false); } var match = (args.Count == 1); var token = match ? args[0].ToLower() : ""; var enumerator = new TagFieldEnumerator(Structure); while (enumerator.Next()) { var nameString = enumerator.Field.Name; if (match && !nameString.ToLower().Contains(token)) { continue; } var fieldType = enumerator.Field.FieldType; var fieldValue = enumerator.Field.GetValue(Value); var typeString = fieldType.IsGenericType ? $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" : fieldType.Name; string valueString; if (fieldValue == null) { valueString = "null"; } else if (fieldType.GetInterface(typeof(IList).Name) != null) { valueString = ((IList)fieldValue).Count != 0 ? $"{{...}}[{((IList)fieldValue).Count}]" : "null"; } else if (fieldType == typeof(StringID)) { valueString = Info.StringIDs.GetString((StringID)fieldValue); } else if (fieldType == typeof(TagInstance)) { valueString = $"[0x{((TagInstance)fieldValue).Index:X4}] {Info.TagNames[((TagInstance)fieldValue).Index]}.{Info.StringIDs.GetString(((TagInstance)fieldValue).Group.Name)}"; } else { valueString = fieldValue.ToString(); } Console.WriteLine("{0}: {1} = {2}", nameString, typeString, valueString); } return(true); }
private object CreateElement(Type elementType) { var element = Activator.CreateInstance(elementType); var isTagStructure = Attribute.IsDefined(elementType, typeof(TagStructureAttribute)); if (isTagStructure) { var enumerator = new TagFieldEnumerator( new TagStructureInfo(elementType)); while (enumerator.Next()) { var fieldType = enumerator.Field.FieldType; if (fieldType.IsArray && enumerator.Attribute.Count > 0) { var array = (IList)Activator.CreateInstance(enumerator.Field.FieldType, new object[] { enumerator.Attribute.Count }); for (var i = 0; i < enumerator.Attribute.Count; i++) { array[i] = CreateElement(fieldType.GetElementType()); } } else { try { enumerator.Field.SetValue(element, CreateElement(enumerator.Field.FieldType)); } catch { enumerator.Field.SetValue(element, null); } } } } return(element); }
public static object ConvertStructure(object data, Type type, OpenTagCache srcInfo, Stream srcStream, ResourceDataManager srcResources, OpenTagCache destInfo, Stream destStream, ResourceDataManager destResources, TagCacheMap tagMap) { // Convert each field var enumerator = new TagFieldEnumerator(new TagStructureInfo(type, destInfo.Version)); while (enumerator.Next()) { var oldValue = enumerator.Field.GetValue(data); var newValue = Convert(oldValue, srcInfo, srcStream, srcResources, destInfo, destStream, destResources, tagMap); enumerator.Field.SetValue(data, newValue); } // Perform fixups FixObjectTypes(data, type, srcInfo); FixShaders(data, srcInfo); var scenario = data as Scenario; if (scenario != null) { FixScenario(scenario); } return(data); }
private static void CompareBlocks(object leftData, EngineVersion leftVersion, object rightData, EngineVersion rightVersion, TagVersionMap result, Queue <QueuedTag> tagQueue) { if (leftData == null || rightData == null) { return; } var type = leftData.GetType(); if (type == typeof(TagInstance)) { // If the objects are tags, then we've found a match var leftTag = (TagInstance)leftData; var rightTag = (TagInstance)rightData; if (leftTag.Group.Tag != rightTag.Group.Tag) { return; } if (leftTag.IsInGroup("rmt2") || leftTag.IsInGroup("rmdf") || leftTag.IsInGroup("vtsh") || leftTag.IsInGroup("pixl") || leftTag.IsInGroup("rm ") || leftTag.IsInGroup("bitm")) { return; } var translated = result.Translate(leftVersion, leftTag.Index, rightVersion); if (translated >= 0) { return; } result.Add(leftVersion, leftTag.Index, rightVersion, rightTag.Index); tagQueue.Enqueue(new QueuedTag { Tag = rightTag }); } else if (type.IsArray) { if (type.GetElementType().IsPrimitive) { return; } // If the objects are arrays, then loop through each element var leftArray = (Array)leftData; var rightArray = (Array)rightData; if (leftArray.Length != rightArray.Length) { return; // If the sizes are different, we probably can't compare them } for (var i = 0; i < leftArray.Length; i++) { CompareBlocks(leftArray.GetValue(i), leftVersion, rightArray.GetValue(i), rightVersion, result, tagQueue); } } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>)) { if (type.GenericTypeArguments[0].IsPrimitive) { return; } // If the objects are lists, then loop through each element var countProperty = type.GetProperty("Count"); var leftCount = (int)countProperty.GetValue(leftData); var rightCount = (int)countProperty.GetValue(rightData); if (leftCount != rightCount) { return; // If the sizes are different, we probably can't compare them } var getItem = type.GetMethod("get_Item"); for (var i = 0; i < leftCount; i++) { var leftItem = getItem.Invoke(leftData, new object[] { i }); var rightItem = getItem.Invoke(rightData, new object[] { i }); CompareBlocks(leftItem, leftVersion, rightItem, rightVersion, result, tagQueue); } } else if (type.GetCustomAttributes(typeof(TagStructureAttribute), false).Length > 0) { // The objects are structures var left = new TagFieldEnumerator(new TagStructureInfo(leftData.GetType(), leftVersion)); var right = new TagFieldEnumerator(new TagStructureInfo(rightData.GetType(), rightVersion)); while (left.Next() && right.Next()) { // Keep going on the left until the field is on the right while (!VersionDetection.IsBetween(rightVersion, left.MinVersion, left.MaxVersion)) { if (!left.Next()) { return; } } // Keep going on the right until the field is on the left while (!VersionDetection.IsBetween(leftVersion, right.MinVersion, right.MaxVersion)) { if (!right.Next()) { return; } } if (left.Field.MetadataToken != right.Field.MetadataToken) { throw new InvalidOperationException("WTF, left and right fields don't match!"); } // Process the fields var leftFieldData = left.Field.GetValue(leftData); var rightFieldData = right.Field.GetValue(rightData); CompareBlocks(leftFieldData, leftVersion, rightFieldData, rightVersion, result, tagQueue); } } }
public override bool Execute(List <string> args) { if (args.Count < 1 || args.Count > 2) { return(false); } if (CopyElementsCommand.Elements == null) { Console.WriteLine("ERROR: No elements are available in the clipboard."); return(false); } var fieldName = args[0]; var fieldNameLow = fieldName.ToLower(); var previousContext = Stack.Context; var previousOwner = Owner; var previousStructure = Structure; if (fieldName.Contains(".")) { var lastIndex = fieldName.LastIndexOf('.'); var blockName = fieldName.Substring(0, lastIndex); fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1); fieldNameLow = fieldName.ToLower(); var command = new EditBlockCommand(Stack, Info, Tag, Owner); if (!command.Execute(new List <string> { blockName })) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } command = (Stack.Context.GetCommand("Edit") as EditBlockCommand); Owner = command.Owner; Structure = command.Structure; if (Owner == null) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } } var index = -1; if (args.Count > 1) { if (args[1] != "*" && (!int.TryParse(args[1], out index) || index < 0)) { Console.WriteLine($"Invalid index specified: {args[1]}"); return(false); } } var enumerator = new TagFieldEnumerator(Structure); var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow); var fieldType = field.FieldType; if ((field == null) || (!fieldType.IsGenericType) || (fieldType.GetInterface("IList") == null)) { Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]); while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } var elementType = field.FieldType.GenericTypeArguments[0]; if (elementType != CopyElementsCommand.ElementType) { Console.WriteLine("Invalid block element type!"); return(false); } var blockValue = field.GetValue(Owner) as IList; if (blockValue == null) { blockValue = Activator.CreateInstance(field.FieldType) as IList; field.SetValue(Owner, blockValue); } if (index > blockValue.Count) { Console.WriteLine($"Invalid index specified: {args[2]}"); return(false); } for (var i = 0; i < CopyElementsCommand.Elements.Count; i++) { var element = CopyElementsCommand.Elements[i]; if (index == -1) { blockValue.Add(element); } else { blockValue.Insert(index + i, element); } } field.SetValue(Owner, blockValue); var typeString = fieldType.IsGenericType ? $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" : fieldType.Name; var itemString = CopyElementsCommand.Elements.Count < 2 ? "element" : "elements"; var valueString = ((IList)blockValue).Count != 0 ? $"{{...}}[{((IList)blockValue).Count}]" : "null"; Console.WriteLine($"Successfully pasted {CopyElementsCommand.Elements.Count} {itemString} to {field.Name}: {typeString}"); Console.WriteLine(valueString); while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(true); }
public override bool Execute(List <string> args) { if (args.Count < 2) { return(false); } var fieldName = args[0]; var fieldNameLow = fieldName.ToLower(); var previousContext = Stack.Context; var previousOwner = Owner; var previousStructure = Structure; if (fieldName.Contains(".")) { var lastIndex = fieldName.LastIndexOf('.'); var blockName = fieldName.Substring(0, lastIndex); fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1); fieldNameLow = fieldName.ToLower(); var command = new EditBlockCommand(Stack, Info, Tag, Owner); if (!command.Execute(new List <string> { blockName })) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } command = (Stack.Context.GetCommand("Edit") as EditBlockCommand); Owner = command.Owner; Structure = command.Structure; if (Owner == null) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } } var enumerator = new TagFieldEnumerator(Structure); var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow); if (field == null) { Console.WriteLine("ERROR: {0} does not contain a field named \"{1}\".", Structure.Types[0].Name, fieldName); while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } var fieldType = field.FieldType; var fieldValue = ParseArgs(field.FieldType, args.Skip(1).ToList()); if (fieldValue != null && fieldValue.Equals(false)) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } field.SetValue(Owner, fieldValue); var typeString = fieldType.IsGenericType ? $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" : fieldType.Name; var valueString = fieldType == typeof(StringId) ? Info.StringIds.GetString((StringId)fieldValue) : fieldType.GetInterface(typeof(IList).Name) != null ? (((IList)fieldValue).Count != 0 ? $"{{...}}[{((IList)fieldValue).Count}]" : "null") : fieldValue == null ? "null" : fieldValue.ToString(); Console.WriteLine("{0}: {1} = {2}", field.Name, typeString, valueString); while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(true); }
public override bool Execute(List <string> args) { if (args.Count < 1 || args.Count > 2) { return(false); } var blockName = args[0]; var ownerType = Owner.GetType(); var enumerator = new TagFieldEnumerator(Structure); var deferredNames = new List <string>(); var deferredArgs = new List <string>(); if (blockName.Contains(".")) { deferredNames.AddRange(blockName.Split('.')); blockName = deferredNames[0]; deferredNames = deferredNames.Skip(1).ToList(); deferredArgs.AddRange(args.Skip(1)); args = new List <string> { blockName }; } if (blockName.Contains("]")) { var openBracketIndex = blockName.IndexOf('['); var closeBracketIndex = blockName.IndexOf(']'); var name = blockName.Substring(0, openBracketIndex); var index = blockName.Substring(openBracketIndex + 1, (closeBracketIndex - openBracketIndex) - 1); blockName = name; args = new List <string> { name, index }; } var blockNameLow = blockName.ToLower(); var field = enumerator.Find(f => f.Name == blockName || f.Name.ToLower() == blockNameLow); if (field == null) { Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, blockName); return(false); } var contextName = ""; object blockValue = null; var structureAttribute = field.FieldType.CustomAttributes.ToList().Find(a => a.AttributeType == typeof(TagStructureAttribute)); if (structureAttribute != null) { if (args.Count != 1) { return(false); } blockValue = field.GetValue(Owner); contextName = $"{blockName}"; } else { if (args.Count != 2) { return(false); } IList fieldValue = null; if (field.FieldType.GetInterface("IList") == null || (fieldValue = (IList)field.GetValue(Owner)) == null) { Console.WriteLine("{0} does not contain a block named \"{1}\"", ownerType.Name, blockName); return(false); } int blockIndex = 0; if (args[1] == "*") { blockIndex = fieldValue.Count - 1; } else if (!int.TryParse(args[1], out blockIndex)) { Console.WriteLine("Invalid index requested from block {0}: {1}", blockName, blockIndex); return(false); } if (blockIndex >= fieldValue.Count || blockIndex < 0) { Console.WriteLine("Invalid index requested from block {0}: {1}", blockName, blockIndex); return(false); } blockValue = fieldValue[blockIndex]; contextName = $"{blockName}[{blockIndex}]"; } var blockStructure = new TagStructureInfo(blockValue.GetType()); var blockContext = new CommandContext(Stack.Context, contextName); blockContext.AddCommand(new ListFieldsCommand(Info, blockStructure, blockValue)); blockContext.AddCommand(new SetFieldCommand(Stack, Info, Tag, blockStructure, blockValue)); blockContext.AddCommand(new EditBlockCommand(Stack, Info, Tag, blockValue)); blockContext.AddCommand(new AddToBlockCommand(Stack, Info, Tag, blockStructure, blockValue)); blockContext.AddCommand(new RemoveFromBlockCommand(Stack, Info, Tag, blockStructure, blockValue)); blockContext.AddCommand(new ExitToCommand(Stack)); Stack.Push(blockContext); if (deferredNames.Count != 0) { var name = deferredNames[0]; deferredNames = deferredNames.Skip(1).ToList(); foreach (var deferredName in deferredNames) { name += '.' + deferredName; } args = new List <string> { name }; args.AddRange(deferredArgs); var command = new EditBlockCommand(Stack, Info, Tag, blockValue); return(command.Execute(args)); } return(true); }
public override bool Execute(List<string> args) { if (args.Count < 1 || args.Count > 3) return false; var fieldName = args[0]; var fieldNameLow = fieldName.ToLower(); var previousContext = Stack.Context; var previousOwner = Owner; var previousStructure = Structure; if (fieldName.Contains(".")) { var lastIndex = fieldName.LastIndexOf('.'); var blockName = fieldName.Substring(0, lastIndex); fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1); fieldNameLow = fieldName.ToLower(); var command = new EditBlockCommand(Stack, Info, Tag, Owner); if (!command.Execute(new List<string> { blockName })) { while (Stack.Context != previousContext) Stack.Pop(); Owner = previousOwner; Structure = previousStructure; return false; } command = (Stack.Context.GetCommand("Edit") as EditBlockCommand); Owner = command.Owner; Structure = command.Structure; if (Owner == null) { while (Stack.Context != previousContext) Stack.Pop(); Owner = previousOwner; Structure = previousStructure; return false; } } var enumerator = new TagFieldEnumerator(Structure); var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow); var fieldType = field.FieldType; if ((field == null) || (!fieldType.IsGenericType) || (fieldType.GetInterface("IList") == null)) { Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]); while (Stack.Context != previousContext) Stack.Pop(); Owner = previousOwner; Structure = previousStructure; return false; } var blockValue = field.GetValue(Owner) as IList; if (blockValue == null) { blockValue = Activator.CreateInstance(field.FieldType) as IList; field.SetValue(Owner, blockValue); } var elementType = field.FieldType.GenericTypeArguments[0]; var index = blockValue.Count - 1; var count = 1; var genericIndex = false; var genericCount = false; if (args.Count == 1) { count = 1; } else { if (args.Count >= 2) { if (args[1] == "*") { genericIndex = true; index = blockValue.Count - 1; } else if (!int.TryParse(args[1], out index) || index < 0 || index >= blockValue.Count) { Console.WriteLine($"Invalid index specified: {args[1]}"); return false; } } if (args.Count == 3) { if (args[2] == "*") { genericCount = true; count = blockValue.Count - index; } else if (!int.TryParse(args[2], out count) || count < 1) { Console.WriteLine($"Invalid number specified: {args[2]}"); return false; } } } if (genericIndex && genericCount) { index = 0; count = blockValue.Count; } else if (genericIndex) { index -= count; if (index < 0) index = 0; } if (index + count > blockValue.Count) { Console.WriteLine($"ERROR: Too many block elements specified to be removed: {count}. Maximum at index {index} can be {blockValue.Count - index}"); return false; } for (var i = 0; i < count; i++) blockValue.RemoveAt(index); field.SetValue(Owner, blockValue); var typeString = fieldType.IsGenericType ? $"{fieldType.Name}<{fieldType.GenericTypeArguments[0].Name}>" : fieldType.Name; var itemString = count < 2 ? "element" : "elements"; var valueString = ((IList)blockValue).Count != 0 ? $"{{...}}[{((IList)blockValue).Count}]" : "null"; Console.WriteLine($"Successfully removed {count} {itemString} from {field.Name} at index {index}: {typeString}"); Console.WriteLine(valueString); while (Stack.Context != previousContext) Stack.Pop(); Owner = previousOwner; Structure = previousStructure; return true; }
public override bool Execute(List <string> args) { if (args.Count > 4) { return(false); } if (args.Count < 1 || args.Count > 3) { return(false); } var fieldName = args[0]; var fieldNameLow = fieldName.ToLower(); var previousContext = Stack.Context; var previousOwner = Owner; var previousStructure = Structure; if (fieldName.Contains(".")) { var lastIndex = fieldName.LastIndexOf('.'); var blockName = fieldName.Substring(0, lastIndex); fieldName = fieldName.Substring(lastIndex + 1, (fieldName.Length - lastIndex) - 1); fieldNameLow = fieldName.ToLower(); var command = new EditBlockCommand(Stack, Info, Tag, Owner); if (!command.Execute(new List <string> { blockName })) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } command = (Stack.Context.GetCommand("Edit") as EditBlockCommand); Owner = command.Owner; Structure = command.Structure; if (Owner == null) { while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } } var count = -1; if (args.Count > 1 && args[1] != "*") { if (!int.TryParse(args[1], out count) || count < 0) { Console.WriteLine($"Invalid count specified: {args[1]}"); return(false); } } var index = 0; if (args.Count > 2) { if (!int.TryParse(args[2], out index) || index < 1) { Console.WriteLine($"Invalid index specified: {args[2]}"); return(false); } } var enumerator = new TagFieldEnumerator(Structure); var field = enumerator.Find(f => f.Name == fieldName || f.Name.ToLower() == fieldNameLow); var fieldType = field.FieldType; if ((field == null) || (!fieldType.IsGenericType) || (fieldType.GetInterface("IList") == null)) { Console.WriteLine("ERROR: {0} does not contain a tag block named \"{1}\".", Structure.Types[0].Name, args[0]); while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(false); } var blockValue = field.GetValue(Owner) as IList; if (blockValue == null) { Console.WriteLine($"Invalid index specified: {args[0]}"); return(false); } if (count < 0) { count = blockValue.Count; } if ((index + count) < 0 || (index + count) > blockValue.Count) { Console.WriteLine($"Invalid index: {index}, and count: {count}"); return(false); } ElementType = field.FieldType.GenericTypeArguments[0]; Elements = new List <object>(); for (var i = index; i < (index + count); i++) { Elements.Add(blockValue[i]); } var itemString = index < 2 ? "element" : "elements"; Console.WriteLine($"Successfully copied {count} {itemString}."); while (Stack.Context != previousContext) { Stack.Pop(); } Owner = previousOwner; Structure = previousStructure; return(true); }