private static void ExportExpressionFunction( string itemName, uint pointer, ProcessMemory memory, TextWriter writer) { var sb = new StringBuilder(); var func = memory.ReadStructure <Natives.ExpressionFunction>(pointer); sb.AppendFormat("[{0:X8}] ", func.Handler); var funcName = memory.ReadStringZ(func.NamePointer); var codeName = memory.ReadStringZ(func.ExprCodeNamePointer); var tags = new string[12]; for (int i = 0; i < 12; i++) { tags[i] = memory.ReadStringZ(func.Tags[i]); } var validTags = tags .Where(t => string.IsNullOrWhiteSpace(t) == false) .ToArray(); if (validTags.Length > 0) { sb.AppendFormat("{0} : ", string.Join(", ", validTags)); } sb.AppendFormat("{0} {1}(", TranslateArgumentType(func.ReturnType, memory), funcName); for (int i = 0; i < func.ArgumentCount; i++) { if (i > 0) { sb.Append(", "); } sb.AppendFormat("{0} {1}", TranslateArgumentType(func.Arguments[i], memory), memory.ReadStringZ(func.Arguments[i].NamePointer)); } sb.Append(")"); writer.WriteLine(sb.ToString()); }
public static uint HashTable(ProcessMemory memory, uint address, uint hash) { var columns = new List <KeyValuePair <Natives.ParserColumn, string> >(); var currentAddress = address; while (true) { var column = memory.ReadStructure <Natives.ParserColumn>(currentAddress); currentAddress += 40; var name = memory.ReadStringZ(column.NamePointer); if (column.Type == 0) { if (string.IsNullOrEmpty(name) == true) { break; } } columns.Add(new KeyValuePair <Natives.ParserColumn, string>(column, name)); } foreach (var kv in columns) { var column = kv.Key; if (column.Flags.HasAnyOptions(Parser.ColumnFlags.REDUNDANTNAME | Parser.ColumnFlags.UNOWNED) == true) { continue; } var name = kv.Value; if (string.IsNullOrEmpty(name) == false) { hash = Adler32.Hash(name, hash); } hash = Adler32.Hash(column.Type, hash); var token = Parser.GlobalTokens.GetToken(column.Token); switch (token.GetParameter(column.Flags, 0)) { case Parser.ColumnParameter.NumberOfElements: case Parser.ColumnParameter.Default: case Parser.ColumnParameter.StringLength: case Parser.ColumnParameter.Size: { hash = Adler32.Hash(column.Parameter0, hash); break; } case Parser.ColumnParameter.BitOffset: { hash = Adler32.Hash(column.Parameter0 >> 16, hash); break; } case Parser.ColumnParameter.DefaultString: case Parser.ColumnParameter.CommandString: { if (column.Parameter0 != 0) { hash = Adler32.Hash(memory.ReadStringZ(column.Parameter0), hash); } break; } } var param1 = token.GetParameter(column.Flags, 1); if (column.Parameter1 != 0 && (column.Token == 20 || column.Token == 21) && address != column.Parameter1 && column.Flags.HasAnyOptions(Parser.ColumnFlags.STRUCT_NORECURSE) == false) { hash = HashTable(memory, column.Parameter1, hash); } if (column.Parameter1 != 0 && param1 == Parser.ColumnParameter.StaticDefineList) { hash = HashStaticDefineList(memory, column.Parameter1, hash); } if (column.Token == 23) { var formatString = memory.ReadStringZ(column.FormatStringPointer); if (string.IsNullOrEmpty(formatString) == false) { hash = Adler32.Hash(formatString, hash); } } } return(hash); }
private static void ExportParserTable( ProcessMemory memory, uint address, XmlWriter xml, List <KeyValuePair <string, uint> > parsers, List <KeyValuePair <string, uint> > enums) { /*xml.WriteComment(string.Format(" {0:X8} ", * 0x00400000u + (address - (uint)memory.MainModuleAddress.ToInt32())));*/ var currentAddress = address; var columns = new List <KeyValuePair <Natives.ParserColumn, string> >(); while (true) { var column = memory.ReadStructure <Natives.ParserColumn>(currentAddress); currentAddress += 40; var name = memory.ReadStringZ(column.NamePointer); if (column.Type == 0) { if (string.IsNullOrEmpty(name) == true) { break; } } columns.Add(new KeyValuePair <Natives.ParserColumn, string>(column, name)); } foreach (var kv in columns) { var column = kv.Key; var name = kv.Value; xml.WriteStartElement("column"); if (string.IsNullOrEmpty(name) == false) { xml.WriteAttributeString("name", name); } var token = Parser.GlobalTokens.GetToken(column.Token); Parser.ColumnFlags flags; var tokenName = GetTokenName(column, out flags); xml.WriteAttributeString("type", tokenName); if (column.Token != 0 && column.Token != 1 && column.Token != 2) { xml.WriteElementString("offset", column.Offset.ToString(CultureInfo.InvariantCulture)); } var values = new List <string>(); if (column.Flags.HasAnyOptions(Parser.ColumnFlags.PARSETABLE_INFO) == true) { xml.WriteStartElement("flags"); xml.WriteElementString("flag", "PARSETABLE_INFO"); xml.WriteEndElement(); /* Star Trek Online replaces its format string with a * stash table of parsed tokens. */ string formatString = null; if (column.FormatStringPointer != 0) { if (memory.ReadU32(column.FormatStringPointer) == 33) { formatString = memory.ReadStringZ(memory.ReadU32(column.FormatStringPointer + 4)); } else { formatString = memory.ReadStringZ(column.FormatStringPointer); } } if (string.IsNullOrEmpty(formatString) == false) { xml.WriteStartElement("format_strings"); ExportFormatStrings(xml, formatString); xml.WriteEndElement(); } } else { if ((flags & _ColumnFlagsMask) != 0) { xml.WriteStartElement("flags"); foreach (var flag in _ColumnFlagNames) { if ((flags & flag.Key) != 0) { xml.WriteElementString("flag", flag.Value); } } xml.WriteEndElement(); } if (column.Flags.HasAnyOptions(Parser.ColumnFlags.REDUNDANTNAME) == true) { var aliased = columns .Where(c => c.Key != column) .Where(c => c.Key.Flags.HasAnyOptions(Parser.ColumnFlags.REDUNDANTNAME) == false) .Where(c => c.Key.Offset == column.Offset) .Where(c => c.Key.Token == column.Token) .FirstOrDefault(c => c.Key.Token != 23 || c.Key.Parameter0 == column.Parameter0); if (aliased.Key != null) { xml.WriteElementString("redundant_name", aliased.Value); } } //else { if (column.MinBits != 0) { if (column.Token == 7) { xml.WriteElementString("float_rounding", _FloatRounding[column.MinBits]); } else { xml.WriteElementString("min_bits", column.MinBits.ToString(CultureInfo.InvariantCulture)); } } switch (token.GetParameter(column.Flags, 0)) { case Parser.ColumnParameter.NumberOfElements: { xml.WriteElementString( "num_elements", ((int)column.Parameter0).ToString(CultureInfo.InvariantCulture)); break; } case Parser.ColumnParameter.Default: { if (column.Parameter0 != 0) { xml.WriteElementString( "default", ((int)column.Parameter0).ToString(CultureInfo.InvariantCulture)); } break; } case Parser.ColumnParameter.StringLength: { xml.WriteElementString( "string_length", ((int)column.Parameter0).ToString(CultureInfo.InvariantCulture)); break; } case Parser.ColumnParameter.DefaultString: { if (column.Parameter0 != 0) { xml.WriteElementString("default_string", memory.ReadStringZ(column.Parameter0) ?? ""); } break; } case Parser.ColumnParameter.CommandString: { if (column.Parameter0 != 0) { xml.WriteElementString("command_string", memory.ReadStringZ(column.Parameter0) ?? ""); } break; } case Parser.ColumnParameter.Size: { xml.WriteElementString( "size", ((int)column.Parameter0).ToString(CultureInfo.InvariantCulture)); break; } case Parser.ColumnParameter.BitOffset: { xml.WriteElementString( "bit_offset", ((int)column.Parameter0).ToString(CultureInfo.InvariantCulture)); break; } } switch (token.GetParameter(column.Flags, 1)) { case Parser.ColumnParameter.StaticDefineList: { if (column.Parameter1 != 0) { xml.WriteStartElement("static_define_list"); var possibleEnum = enums.SingleOrDefault(e => e.Value == column.Parameter1); if (possibleEnum.Key == null) { xml.WriteComment(" dynamic enum? "); /*xml.WriteStartElement("enum"); * ExportEnum(memory, column.Parameter1, xml); * xml.WriteEndElement();*/ } else { xml.WriteAttributeString("external", possibleEnum.Key); } //xml.WriteComment(string.Format(" {0:X8} ", column.Parameter1)); xml.WriteEndElement(); } break; } case Parser.ColumnParameter.DictionaryName: { if (column.Parameter1 != 0) { xml.WriteElementString("dictionary_name", memory.ReadStringZ(column.Parameter1) ?? ""); } break; } case Parser.ColumnParameter.Subtable: { if (column.Parameter1 == 0) { xml.WriteElementString("subtable", "NULL?"); } else { xml.WriteStartElement("subtable"); var parser = parsers.SingleOrDefault(p => p.Value == column.Parameter1); if (parser.Key == null) { //xml.WriteElementString("subtable", "NOT FOUND? " + column.Parameter1.ToString("X*")); xml.WriteStartElement("table"); ExportParserTable(memory, column.Parameter1, xml, parsers, enums); xml.WriteEndElement(); } else { xml.WriteAttributeString("external", parser.Key); } xml.WriteEndElement(); } break; } } var format = column.Format & 0xFF; if (format != 0) { if (format < _FormatNames.Length && _FormatNames[format] != null) { xml.WriteElementString("format", _FormatNames[format]); } else { xml.WriteElementString("format_raw", format.ToString(CultureInfo.InvariantCulture)); } } /* Star Trek Online replaces its format string with a * stash table of parsed tokens. */ string formatString = null; if (column.FormatStringPointer != 0) { if (memory.ReadU32(column.FormatStringPointer) == 33) { formatString = memory.ReadStringZ(memory.ReadU32(column.FormatStringPointer + 4)); } else { formatString = memory.ReadStringZ(column.FormatStringPointer); } } if (string.IsNullOrEmpty(formatString) == false) { xml.WriteStartElement("format_strings"); ExportFormatStrings(xml, formatString); xml.WriteEndElement(); } } } xml.WriteEndElement(); } }