public static void AddName(string type, string name, string direction) { if (direction == "C2S") { ListAdds.AppendLine("C2SMessageTable.Add({0}, (reader) => new {1}(reader));", type, name); } else if (direction == "S2C") { ListAdds.AppendLine("S2CMessageTable.Add({0}, (reader) => new {1}(reader));", type, name); } }
void WriteWriterString(TypeInfo typeInfo, string name, CodeStringBuilder builder) { if (typeInfo.IsPrimitive) { builder.AppendLine(Util.CreateWriterString(typeInfo, name) + ";"); } else if (typeInfo.IsEnum) { EnumInfo enumType = (EnumInfo)typeInfo; builder.AppendLine(Util.CreateWriterString(enumType, name) + ";"); } else { builder.AppendLine("{0}.Pack(writer);", name); } }
void BuildEnumItem(XElement node, CodeStringBuilder returnText, EnumInfo myInfo) { string itemValue = node.GetAttribute("value"); string itemName = node.GetAttribute("name"); if (String.IsNullOrWhiteSpace(itemName)) { itemName = "Unknown" + BlankCounter++; } myInfo.ValueMap.Add(itemName, itemValue); var itemText = node.Attribute("text"); if (itemText != null && itemText.IsValid()) { returnText.AppendLine(); returnText.AppendSummary(itemText.Value); } returnText.AppendLine("{0} = {1},", itemName, itemValue); }
void WriteReaderString(TypeInfo typeInfo, string name, CodeStringBuilder builder, bool field = true) { if (typeInfo.IsPrimitive) { if (!field) { builder.AppendLine("var {0} = {1};", name, Util.CreateReaderString(typeInfo)); } else { builder.AppendLine("{0} = {1};", name, Util.CreateReaderString(typeInfo)); } } else if (typeInfo.IsEnum) { EnumInfo enumType = (EnumInfo)typeInfo; if (!field) { builder.AppendLine("var {0} = {1};", name, Util.CreateReaderString(enumType)); } else { builder.AppendLine("{0} = {1};", name, Util.CreateReaderString(enumType)); } } else { if (!field) { builder.AppendLine("var {0} = new {1}();", name, typeInfo.UsableType); } builder.AppendLine("{0}.Unpack(reader);", name); } }
void ProcessField(XElement node, bool output = true) { string name = node.GetAttribute("name").Capitalize(); string type = node.GetAttribute("type"); var typeInfo = TypeTable.GetType(type); string staticValue = node.GetAttribute("staticValue", false); if (node.CheckAttribute("unused", "true") || !String.IsNullOrWhiteSpace(staticValue)) { if (String.IsNullOrWhiteSpace(staticValue)) { staticValue = "0"; } if (typeInfo != null && typeInfo.UsableType == "string") { staticValue = "\"" + staticValue + "\""; } string temp = "temp" + tempCount++; unpack.AppendLine("var {0} = {1}; // Unused value", temp, Util.CreateReaderString(typeInfo)); unpack.AppendLineRaw("#if NETWORKVALIDATION"); unpack.AppendLine("if({0} != {1})", temp, staticValue); unpack.OpenBlock(); unpack.AppendLine("throw new Exception(\"Recieved value different from static on {0}, expected: {1}, actual \" + {2});", baseName, staticValue.Replace("\"", ""), temp); unpack.CloseBlock(); unpack.AppendLineRaw("#endif"); pack.AppendLine(Util.CreateStaticWriterString(typeInfo, staticValue) + "; // Unused value"); return; } string defaultValue = node.GetAttribute("defaultValue", false); bool propertyExists = propertyMap.ContainsKey(name); if (!propertyExists) { propertyMap.Add(name, type); } if (node.HasElements) { unpack.AppendVariable(type, name, Util.CreateReaderString(typeInfo)); if (output) { pack.AppendVariable(type, name, "0"); } foreach (var childNode in node.Elements()) { if (childNode.Name == "submember" || childNode.Name == "subfield") { ProcessSubfield(name, type, childNode, output); } } pack.AppendLine(Util.CreateWriterString(typeInfo, name) + ";"); } else { if (!propertyExists) { string text = node.GetAttribute("text", false); if (!String.IsNullOrWhiteSpace(text)) { properties.AppendSummary(text); } } if (node.CheckAttribute("isArray", "true")) { string length = node.GetAttribute("length").Capitalize(); if (!propertyExists) { properties.AppendReadWriteProperty(typeInfo.UsableType + "[]", name); } unpack.AppendLine("{0} = new {1}[{2}];", name, typeInfo.UsableType, length); unpack.AppendLine("for(int i = 0; i < {0}; i++)", length); unpack.OpenBlock(); unpack.AppendLine("{0}[i] = {1};", name, Util.CreateReaderString(typeInfo)); unpack.CloseBlock(); if (output) { pack.AppendLine("for(int i = 0; i < {0}; i++)", length); pack.OpenBlock(); pack.AppendLine(Util.CreateWriterString(typeInfo, name) + ";"); pack.CloseBlock(); } } else if (type == "List") { string genericType = node.GetAttribute("genericType"); TypeInfo genericTypeInfo = TypeTable.GetType(genericType); string length = node.GetAttribute("length").Capitalize(); if (!propertyExists) { properties.AppendReadOnlyGenericProperty(type, genericTypeInfo.UsableType, name); } unpack.AppendLine(String.Format("{0}.Clear();", name)); unpack.AppendLine("for(int i = 0; i < {0}; i++)", length); unpack.OpenBlock(); WriteListReadString(genericType, name); unpack.CloseBlock(); if (output) { pack.AppendLine("for(int i = 0; i < {0}; i++)", length); pack.OpenBlock(); WriteListWriteString(genericType, name + "[i]"); pack.CloseBlock(); } } else if (typeInfo.IsPrimitive) { if (!propertyExists) { properties.AppendReadWriteProperty(typeInfo.UsableType, name, defaultValue); } unpack.AppendLine("{0} = {1};", name, Util.CreateReaderString(typeInfo)); if (output) { pack.AppendLine(Util.CreateWriterString(typeInfo, name) + ";"); } } else if (typeInfo.IsEnum) { if (!propertyExists) { properties.AppendReadWriteProperty(typeInfo.Name, name, defaultValue); } var streamType = node.GetAttribute("streamType", false); EnumInfo enumType = (EnumInfo)typeInfo; if (String.IsNullOrEmpty(streamType)) { unpack.AppendLine("{0} = {1};", name, Util.CreateReaderString(enumType)); if (output) { pack.AppendLine(Util.CreateWriterString(enumType, name) + ";"); } } else { TypeInfo streamInfoType = TypeTable.GetType(streamType); unpack.AppendLine("{0} = {1};", name, Util.CreateReaderString(enumType, streamInfoType)); if (output) { pack.AppendLine(Util.CreateWriterString(streamInfoType, name, true) + ";"); } } } else { if (typeInfo.BaseType == "List") { var genericType = node.GetAttribute("genericType"); var genericTypeInfo = TypeTable.GetType(genericType); string readFunc = "Read" + name; string writeFunc = "Write" + name; if (!propertyExists) { collectionFunctions.AppendLine("static {0} {1}(BinaryReader reader)", genericTypeInfo.UsableType, readFunc); collectionFunctions.OpenBlock(); WriteReaderString(genericTypeInfo, "item", collectionFunctions, false); collectionFunctions.AppendLine("return item;", genericTypeInfo.UsableType); collectionFunctions.CloseBlock(); collectionFunctions.AppendLine(); collectionFunctions.AppendLine("static void {1}(BinaryWriter writer, {0} item)", genericTypeInfo.UsableType, writeFunc); collectionFunctions.OpenBlock(); WriteWriterString(genericTypeInfo, "item", collectionFunctions); collectionFunctions.CloseBlock(); collectionFunctions.AppendLine(); properties.AppendReadOnlyGenericProperty(type, genericTypeInfo.UsableType, name, readFunc, writeFunc); } } else if (typeInfo.BaseType == "Dictionary") { var genericKey = node.GetAttribute("genericKey"); var genericKeyInfo = TypeTable.GetType(genericKey); var genericValue = node.GetAttribute("genericValue"); var genericValueInfo = TypeTable.GetType(genericValue); string readFunc = "Read" + name; string writeFunc = "Write" + name; if (!propertyExists) { collectionFunctions.AppendLine("static KeyValuePair<{0}, {1}> {2}(BinaryReader reader)", genericKeyInfo.UsableType, genericValueInfo.UsableType, readFunc); collectionFunctions.OpenBlock(); WriteReaderString(genericKeyInfo, "key", collectionFunctions, false); WriteReaderString(genericValueInfo, "val", collectionFunctions, false); collectionFunctions.AppendLine("return new KeyValuePair<{0}, {1}>(key, val);", genericKeyInfo.UsableType, genericValueInfo.UsableType); collectionFunctions.CloseBlock(); collectionFunctions.AppendLine(); collectionFunctions.AppendLine("static void {2}(BinaryWriter writer, KeyValuePair<{0}, {1}> pair)", genericKeyInfo.UsableType, genericValueInfo.UsableType, writeFunc); collectionFunctions.OpenBlock(); WriteWriterString(genericKeyInfo, "pair.Key", collectionFunctions); WriteWriterString(genericValueInfo, "pair.Value", collectionFunctions); collectionFunctions.CloseBlock(); collectionFunctions.AppendLine(); properties.AppendReadOnlyKeyValueProperty(type, genericKeyInfo.UsableType, genericValueInfo.UsableType, name, readFunc, writeFunc); } } else { if (!propertyExists) { properties.AppendReadOnlyProperty(type, name); } } unpack.AppendLine("{0}.Unpack(reader);", name); if (output) { pack.AppendLine("{0}.Pack(writer);", name); } } } }
void ProcessSubfield(string supername, string supertype, XElement node, bool output = true) { string type = node.GetAttribute("type"); string name = node.GetAttribute("name").Capitalize(); TypeInfo typeInfo = TypeTable.GetType(type); bool propertyExists = propertyMap.ContainsKey(name); if (!propertyExists) { propertyMap.Add(name, type); string text = node.GetAttribute("text", false); if (!String.IsNullOrWhiteSpace(text)) { properties.AppendSummary(text); } } if (!output) { name = "Unused" + name; } if (!propertyExists) { properties.AppendReadWriteProperty(type, name); properties.AppendLine(); } string and = node.GetAttribute("and", false); string shift = node.GetAttribute("shift", false); if (!String.IsNullOrEmpty(and) && !String.IsNullOrEmpty(shift)) { if (typeInfo.IsSignedType || supertype != type) { unpack.AppendLine("{0} = ({4})({1} >> {2} & {3});", name, supername, shift, and, type); pack.AppendLine("{0} |= ({4})({1} & {2} << {3});", supername, name, and, shift, supertype); } else { unpack.AppendLine("{0} = ({4})({1} >> {2} & {3});", name, supername, shift, and, type); pack.AppendLine("{0} |= ({4})({1} & {2} << {3});", supername, name, and, shift, supertype); } } else if (!String.IsNullOrEmpty(shift)) { if (typeInfo.IsSignedType || supertype != type) { unpack.AppendLine("{0} = ({3})({1} >> {2});", name, supername, shift, type); pack.AppendLine("{0} |= ({3})({1} << {2});", supername, name, shift, supertype); } else { unpack.AppendLine("{0} = ({3})({1} >> {2});", name, supername, shift, type); pack.AppendLine("{0} |= ({3})({1} << {2});", supername, name, shift, supertype); } } else if (!String.IsNullOrEmpty(and)) { if (typeInfo.IsSignedType) { var andInt = Convert.ToInt32(and, 16); BitArray ba = new BitArray(new int[] { andInt }); int pos; for (pos = 0; pos < ba.Length; pos++) { if (!ba[pos]) { break; } } uint negCheck = (uint)Math.Pow(2, pos - 1); string negativeCheck = String.Format("0x{0:X}", negCheck); int size = negativeCheck.Replace("0x", "").Length; int sizediff = Util.GetHexLength(type) - size; string negativeOr = "0x" + new string('F', sizediff) + new string('0', size); unpack.AppendLine("if(({0} & {1}) != 0) // Is the subvalue negative?", supername, negativeCheck); unpack.Indent(); unpack.AppendLine("{0} = ({4})({1} & {2} | {3});", name, supername, and, negativeOr, type); unpack.Unindent(); unpack.AppendLine("else"); unpack.Indent(); unpack.AppendLine("{0} = ({3})({1} & {2});", name, supername, and, type); unpack.Unindent(); } else { unpack.AppendLine("{0} = ({3})({1} & {2});", name, supername, and, type); pack.AppendLine("{0} |= ({3})({1} & {2});", supername, name, and, supertype); } } }