/// <summary> /// /// </summary> /// <param name="map"></param> /// <param name="frequency"></param> private void PrintOneMap(TextWriter writer, MapPacket[] map, string frequency) { int i; for (i = 0; i < map.Length; ++i) { if (map[i] != null) { writer.WriteLine("{0} {1,5} - {2} - {3} - {4}", frequency, i, map[i].Name, map[i].Trusted ? "Trusted" : "Untrusted", map[i].Encoded ? "Unencoded" : "Zerocoded"); foreach (MapBlock block in map[i].Blocks) { if (block.Count == -1) { writer.WriteLine("\t{0,4} {1} (Variable)", block.KeywordPosition, block.Name); } else { writer.WriteLine("\t{0,4} {1} ({2})", block.KeywordPosition, block.Name, block.Count); } foreach (MapField field in block.Fields) { writer.WriteLine("\t\t{0,4} {1} ({2} / {3})", field.KeywordPosition, field.Name, field.Type, field.Count); } } } } }
/// <summary> /// /// </summary> /// <param name="mapFile"></param> private void LoadMapFile(string mapFile) { FileStream map; // Load the protocol map file try { map = new FileStream(mapFile, FileMode.Open, FileAccess.Read); } catch(Exception e) { throw new Exception("Map file error", e); } try { StreamReader r = new StreamReader(map); r.BaseStream.Seek(0, SeekOrigin.Begin); string newline; string trimmedline; bool inPacket = false; bool inBlock = false; MapPacket currentPacket = null; MapBlock currentBlock = null; char[] trimArray = new char[] {' ', '\t'}; // While not at the end of the file while (r.Peek() > -1) { #region ParseMap newline = r.ReadLine(); trimmedline = System.Text.RegularExpressions.Regex.Replace(newline, @"\s+", " "); trimmedline = trimmedline.Trim(trimArray); if (!inPacket) { // Outside of all packet blocks if (trimmedline == "{") { inPacket = true; } } else { // Inside of a packet block if (!inBlock) { // Inside a packet block, outside of the blocks if (trimmedline == "{") { inBlock = true; } else if (trimmedline == "}") { // Reached the end of the packet // currentPacket.Blocks.Sort(); inPacket = false; } else { // The packet header #region ParsePacketHeader // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] {' ', '\t'}); if (tokens.Length > 3) { //Hash packet name to insure correct keyword ordering KeywordPosition(tokens[0]); uint packetID; // Remove the leading "0x" if (tokens[2].Length > 2 && tokens[2].Substring(0, 2) == "0x") { tokens[2] = tokens[2].Substring(2, tokens[2].Length - 2); packetID = UInt32.Parse(tokens[2], System.Globalization.NumberStyles.HexNumber); } else { packetID = UInt32.Parse(tokens[2]); } if (tokens[1] == "Fixed") { // Truncate the id to a short packetID &= 0xFFFF; LowMaps[packetID] = new MapPacket(); LowMaps[packetID].ID = (ushort)packetID; LowMaps[packetID].Frequency = PacketFrequency.Low; LowMaps[packetID].Name = tokens[0]; LowMaps[packetID].Trusted = (tokens[3] == "Trusted"); LowMaps[packetID].Encoded = (tokens[4] == "Zerocoded"); LowMaps[packetID].Blocks = new List<MapBlock>(); currentPacket = LowMaps[packetID]; } else if (tokens[1] == "Low") { LowMaps[packetID] = new MapPacket(); LowMaps[packetID].ID = (ushort)packetID; LowMaps[packetID].Frequency = PacketFrequency.Low; LowMaps[packetID].Name = tokens[0]; LowMaps[packetID].Trusted = (tokens[2] == "Trusted"); LowMaps[packetID].Encoded = (tokens[3] == "Zerocoded"); LowMaps[packetID].Blocks = new List<MapBlock>(); currentPacket = LowMaps[packetID]; } else if (tokens[1] == "Medium") { MediumMaps[packetID] = new MapPacket(); MediumMaps[packetID].ID = (ushort)packetID; MediumMaps[packetID].Frequency = PacketFrequency.Medium; MediumMaps[packetID].Name = tokens[0]; MediumMaps[packetID].Trusted = (tokens[2] == "Trusted"); MediumMaps[packetID].Encoded = (tokens[3] == "Zerocoded"); MediumMaps[packetID].Blocks = new List<MapBlock>(); currentPacket = MediumMaps[packetID]; } else if (tokens[1] == "High") { HighMaps[packetID] = new MapPacket(); HighMaps[packetID].ID = (ushort)packetID; HighMaps[packetID].Frequency = PacketFrequency.High; HighMaps[packetID].Name = tokens[0]; HighMaps[packetID].Trusted = (tokens[2] == "Trusted"); HighMaps[packetID].Encoded = (tokens[3] == "Zerocoded"); HighMaps[packetID].Blocks = new List<MapBlock>(); currentPacket = HighMaps[packetID]; } else { //Client.Log("Unknown packet frequency", Helpers.LogLevel.Error); throw new Exception("Unknown packet frequency"); } } #endregion } } else { if (trimmedline.Length > 0 && trimmedline.Substring(0, 1) == "{") { // A field #region ParseField MapField field = new MapField(); // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] {' ', '\t'}); field.Name = tokens[1]; field.KeywordPosition = KeywordPosition(field.Name); field.Type = (FieldType)Enum.Parse(typeof(FieldType), tokens[2], true); if (tokens[3] != "}") { field.Count = Int32.Parse(tokens[3]); } else { field.Count = 1; } // Save this field to the current block currentBlock.Fields.Add(field); #endregion } else if (trimmedline == "}") { // currentBlock.Fields.Sort(); inBlock = false; } else if (trimmedline.Length != 0 && trimmedline.Substring(0, 2) != "//") { // The block header #region ParseBlockHeader currentBlock = new MapBlock(); // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] {' ', '\t'}); currentBlock.Name = tokens[0]; currentBlock.KeywordPosition = KeywordPosition(currentBlock.Name); currentBlock.Fields = new List<MapField>(); currentPacket.Blocks.Add(currentBlock); if (tokens[1] == "Single") { currentBlock.Count = 1; } else if (tokens[1] == "Multiple") { currentBlock.Count = Int32.Parse(tokens[2]); } else if (tokens[1] == "Variable") { currentBlock.Count = -1; } else { //Client.Log("Unknown block frequency", Helpers.LogLevel.Error); throw new Exception("Unknown block frequency"); } #endregion } } } #endregion } r.Close(); map.Close(); } catch (Exception e) { throw e; } }
static void WriteToBytesMultiple(TextWriter writer, MapPacket packet) { writer.WriteLine( " public override byte[][] ToBytesMultiple()" + Environment.NewLine + " {"); // Check if there are any variable blocks bool hasVariable = false; bool cannotSplit = false; foreach (MapBlock block in packet.Blocks) { if (block.Count == -1) { hasVariable = true; } else if (hasVariable) { // A fixed or single block showed up after a variable count block. // Our automatic splitting algorithm won't work for this packet cannotSplit = true; break; } } if (hasVariable && !cannotSplit) { writer.WriteLine( " System.Collections.Generic.List<byte[]> packets = new System.Collections.Generic.List<byte[]>();"); writer.WriteLine( " int i = 0;"); writer.Write( " int fixedLength = "); if (packet.Frequency == PacketFrequency.Low) { writer.WriteLine("10;"); } else if (packet.Frequency == PacketFrequency.Medium) { writer.WriteLine("8;"); } else { writer.WriteLine("7;"); } writer.WriteLine(); // ACK serialization writer.WriteLine(" byte[] ackBytes = null;"); writer.WriteLine(" int acksLength = 0;"); writer.WriteLine(" if (Header.AckList != null && Header.AckList.Length > 0) {"); writer.WriteLine(" Header.AppendedAcks = true;"); writer.WriteLine(" ackBytes = new byte[Header.AckList.Length * 4 + 1];"); writer.WriteLine(" Header.AcksToBytes(ackBytes, ref acksLength);"); writer.WriteLine(" }"); writer.WriteLine(); // Count fixed blocks foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" fixedLength += " + sanitizedName + ".Length;"); } else if (block.Count > 0) { // Fixed count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { fixedLength += " + sanitizedName + "[j].Length; }"); } } // Serialize fixed blocks writer.WriteLine( " byte[] fixedBytes = new byte[fixedLength];"); writer.WriteLine( " Header.ToBytes(fixedBytes, ref i);"); foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".ToBytes(fixedBytes, ref i);"); } else if (block.Count > 0) { // Fixed count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { " + sanitizedName + "[j].ToBytes(fixedBytes, ref i); }"); } } int variableCountBlock = 0; foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block ++variableCountBlock; } } writer.WriteLine(" fixedLength += " + variableCountBlock + ";"); writer.WriteLine(); foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" int " + sanitizedName + "Start = 0;"); } } writer.WriteLine(" do"); writer.WriteLine(" {"); // Count how many variable blocks can go in this packet writer.WriteLine(" int variableLength = 0;"); foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" int " + sanitizedName + "Count = 0;"); } } writer.WriteLine(); foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" i = " + sanitizedName + "Start;"); writer.WriteLine(" while (fixedLength + variableLength + acksLength < Packet.MTU && i < " + sanitizedName + ".Length) {"); writer.WriteLine(" int blockLength = " + sanitizedName + "[i].Length;"); writer.WriteLine(" if (fixedLength + variableLength + blockLength + acksLength <= MTU) {"); writer.WriteLine(" variableLength += blockLength;"); writer.WriteLine(" ++" + sanitizedName + "Count;"); writer.WriteLine(" }"); writer.WriteLine(" else { break; }"); writer.WriteLine(" ++i;"); writer.WriteLine(" }"); writer.WriteLine(); } } // Create the packet writer.WriteLine(" byte[] packet = new byte[fixedLength + variableLength + acksLength];"); writer.WriteLine(" int length = fixedBytes.Length;"); writer.WriteLine(" Buffer.BlockCopy(fixedBytes, 0, packet, 0, length);"); // Remove the appended ACKs flag from subsequent packets writer.WriteLine(" if (packets.Count > 0) { packet[0] = (byte)(packet[0] & ~0x10); }"); writer.WriteLine(); foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { writer.WriteLine(" packet[length++] = (byte)" + sanitizedName + "Count;"); writer.WriteLine(" for (i = " + sanitizedName + "Start; i < " + sanitizedName + "Start + " + sanitizedName + "Count; i++) { " + sanitizedName + "[i].ToBytes(packet, ref length); }"); writer.WriteLine(" " + sanitizedName + "Start += " + sanitizedName + "Count;"); writer.WriteLine(); } } // ACK appending writer.WriteLine(" if (acksLength > 0) {"); writer.WriteLine(" Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength);"); writer.WriteLine(" acksLength = 0;"); writer.WriteLine(" }"); writer.WriteLine(); writer.WriteLine(" packets.Add(packet);"); writer.WriteLine(" } while ("); bool first = true; foreach (MapBlock block in packet.Blocks) { string sanitizedName; if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { if (first) first = false; else writer.WriteLine(" ||"); // Variable count block writer.Write(" " + sanitizedName + "Start < " + sanitizedName + ".Length"); } } writer.WriteLine(");"); writer.WriteLine(); writer.WriteLine(" return packets.ToArray();"); writer.WriteLine(" }"); } else { writer.WriteLine(" return new byte[][] { ToBytes() };"); writer.WriteLine(" }"); } }
/// <summary> /// /// </summary> /// <param name="mapFile"></param> private void LoadMapFile(string mapFile) { FileStream map; // Load the protocol map file try { map = new FileStream(mapFile, FileMode.Open, FileAccess.Read); } catch (Exception e) { throw new Exception("Map file error", e); } try { StreamReader r = new StreamReader(map); r.BaseStream.Seek(0, SeekOrigin.Begin); string newline; string trimmedline; bool inPacket = false; bool inBlock = false; MapPacket currentPacket = null; MapBlock currentBlock = null; char[] trimArray = new char[] { ' ', '\t' }; // While not at the end of the file while (r.Peek() > -1) { #region ParseMap newline = r.ReadLine(); trimmedline = System.Text.RegularExpressions.Regex.Replace(newline, @"\s+", " "); trimmedline = trimmedline.Trim(trimArray); if (!inPacket) { // Outside of all packet blocks if (trimmedline == "{") { inPacket = true; } } else { // Inside of a packet block if (!inBlock) { // Inside a packet block, outside of the blocks if (trimmedline == "{") { inBlock = true; } else if (trimmedline == "}") { // Reached the end of the packet // currentPacket.Blocks.Sort(); inPacket = false; } else { // Skip comments if (trimmedline.StartsWith("//")) { continue; } // The packet header #region ParsePacketHeader // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] { ' ', '\t' }); if (tokens.Length > 3) { //Hash packet name to insure correct keyword ordering KeywordPosition(tokens[0]); uint packetID; // Remove the leading "0x" if (tokens[2].Length > 2 && tokens[2].Substring(0, 2) == "0x") { tokens[2] = tokens[2].Substring(2, tokens[2].Length - 2); packetID = UInt32.Parse(tokens[2], System.Globalization.NumberStyles.HexNumber); } else { packetID = UInt32.Parse(tokens[2]); } if (tokens[1] == "Fixed") { // Truncate the id to a short packetID &= 0xFFFF; LowMaps[packetID] = new MapPacket { ID = (ushort)packetID, Frequency = PacketFrequency.Low, Name = tokens[0], Trusted = (tokens[3] == "Trusted"), Encoded = (tokens[4] == "Zerocoded"), Blocks = new List <MapBlock>() }; currentPacket = LowMaps[packetID]; } else if (tokens[1] == "Low") { LowMaps[packetID] = new MapPacket { ID = (ushort)packetID, Frequency = PacketFrequency.Low, Name = tokens[0], Trusted = (tokens[2] == "Trusted"), Encoded = (tokens[4] == "Zerocoded"), Blocks = new List <MapBlock>() }; currentPacket = LowMaps[packetID]; } else if (tokens[1] == "Medium") { MediumMaps[packetID] = new MapPacket { ID = (ushort)packetID, Frequency = PacketFrequency.Medium, Name = tokens[0], Trusted = (tokens[2] == "Trusted"), Encoded = (tokens[4] == "Zerocoded"), Blocks = new List <MapBlock>() }; currentPacket = MediumMaps[packetID]; } else if (tokens[1] == "High") { HighMaps[packetID] = new MapPacket { ID = (ushort)packetID, Frequency = PacketFrequency.High, Name = tokens[0], Trusted = (tokens[2] == "Trusted"), Encoded = (tokens[4] == "Zerocoded"), Blocks = new List <MapBlock>() }; currentPacket = HighMaps[packetID]; } else { //Client.Log("Unknown packet frequency", Helpers.LogLevel.Error); throw new Exception("Unknown packet frequency"); } } #endregion } } else { if (trimmedline.Length > 0 && trimmedline.Substring(0, 1) == "{") { // A field #region ParseField MapField field = new MapField(); // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] { ' ', '\t' }); field.Name = tokens[1]; field.KeywordPosition = KeywordPosition(field.Name); field.Type = (FieldType)Enum.Parse(typeof(FieldType), tokens[2], true); field.Count = tokens[3] != "}" ? Int32.Parse(tokens[3]) : 1; // Save this field to the current block currentBlock.Fields.Add(field); #endregion } else if (trimmedline == "}") { // currentBlock.Fields.Sort(); inBlock = false; } else if (trimmedline.Length != 0 && trimmedline.Substring(0, 2) != "//") { // The block header #region ParseBlockHeader currentBlock = new MapBlock(); // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] { ' ', '\t' }); currentBlock.Name = tokens[0]; currentBlock.KeywordPosition = KeywordPosition(currentBlock.Name); currentBlock.Fields = new List <MapField>(); currentPacket.Blocks.Add(currentBlock); if (tokens[1] == "Single") { currentBlock.Count = 1; } else if (tokens[1] == "Multiple") { currentBlock.Count = Int32.Parse(tokens[2]); } else if (tokens[1] == "Variable") { currentBlock.Count = -1; } else { //Client.Log("Unknown block frequency", Helpers.LogLevel.Error); throw new Exception("Unknown block frequency"); } #endregion } } } #endregion } r.Close(); map.Close(); } catch (Exception e) { throw e; } }
static void WriteBlockClass(TextWriter writer, MapBlock block, MapPacket packet) { int variableFieldCountBytes = 0; //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" public sealed class " + block.Name + "Block : PacketBlock" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldMember(writer, field); if (field.Type == FieldType.Variable) { variableFieldCountBytes += field.Count; } } // Length property writer.WriteLine(""); //writer.WriteLine(" /// <summary>Length of this block serialized in bytes</summary>"); writer.WriteLine(" public override int Length" + Environment.NewLine + " {" + Environment.NewLine + " get" + Environment.NewLine + " {"); int length = variableFieldCountBytes; // Figure out the length of this block foreach (MapField field in block.Fields) { length += GetFieldLength(writer, field); } if (variableFieldCountBytes == 0) { writer.WriteLine(" return " + length + ";"); } else { writer.WriteLine(" int length = " + length + ";"); foreach (MapField field in block.Fields) { if (field.Type == FieldType.Variable) { writer.WriteLine(" if (" + field.Name + " != null) { length += " + field.Name + ".Length; }"); } } writer.WriteLine(" return length;"); } writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + block.Name + "Block() { }"); // Constructor for building the class from bytes //writer.WriteLine(" /// <summary>Constructor for building the block from a byte array</summary>"); writer.WriteLine(" public " + block.Name + "Block(byte[] bytes, ref int i)" + Environment.NewLine + " {" + Environment.NewLine + " FromBytes(bytes, ref i);" + Environment.NewLine + " }" + Environment.NewLine); // Initiates instance variables from a byte message writer.WriteLine(" public override void FromBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); // Declare a length variable if we need it for variable fields in this constructor if (variableFieldCountBytes > 0) { writer.WriteLine(" int length;"); } // Start of the try catch block writer.WriteLine(" try" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldFromBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine + " catch (Exception)" + Environment.NewLine + " {" + Environment.NewLine + " throw new MalformedDataException();" + Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine); // ToBytes() function //writer.WriteLine(" /// <summary>Serialize this block to a byte array</summary>"); writer.WriteLine(" public override void ToBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldToBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine); writer.WriteLine(" }" + Environment.NewLine); }
static void WritePacketClass(TextWriter writer, MapPacket packet) { bool hasVariableBlocks = false; string sanitizedName; //writer.WriteLine(" /// <summary>" + packet.Name + " packet</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" public sealed class " + packet.Name + "Packet : Packet" + Environment.NewLine + " {"); // Write out each block class foreach (MapBlock block in packet.Blocks) { WriteBlockClass(writer, block, packet); } // Length member writer.WriteLine(" public override int Length" + Environment.NewLine + " {" + Environment.NewLine + " get" + Environment.NewLine + " {"); int length = 0; if (packet.Frequency == PacketFrequency.Low) { length = 10; } else if (packet.Frequency == PacketFrequency.Medium) { length = 8; } else { length = 7; } foreach (MapBlock block in packet.Blocks) { if (block.Count == -1) { hasVariableBlocks = true; ++length; } } writer.WriteLine(" int length = " + length + ";"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++)"); writer.WriteLine(" length += " + sanitizedName + "[j].Length;"); } else if (block.Count == 1) { writer.WriteLine(" length += " + sanitizedName + ".Length;"); } else { // Multiple count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" length += " + sanitizedName + "[j].Length;"); } } writer.WriteLine(" return length;"); writer.WriteLine(" }" + Environment.NewLine + " }"); // Block members foreach (MapBlock block in packet.Blocks) { // TODO: More thorough name blacklisting if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" public " + block.Name + "Block" + ((block.Count != 1) ? "[]" : "") + " " + sanitizedName + ";"); } writer.WriteLine(""); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + packet.Name + "Packet()" + Environment.NewLine + " {"); writer.WriteLine(" HasVariableBlocks = " + hasVariableBlocks.ToString().ToLowerInvariant() + ";"); writer.WriteLine(" Type = PacketType." + packet.Name + ";"); writer.WriteLine(" Header = new Header();"); writer.WriteLine(" Header.Frequency = PacketFrequency." + packet.Frequency + ";"); writer.WriteLine(" Header.ID = " + packet.ID + ";"); writer.WriteLine(" Header.Reliable = true;"); // Turn the reliable flag on by default if (packet.Encoded) { writer.WriteLine(" Header.Zerocoded = true;"); } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block();"); } else if (block.Count == -1) { // Variable count block writer.WriteLine(" " + sanitizedName + " = null;"); } else { // Multiple count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); } } writer.WriteLine(" }" + Environment.NewLine); // Constructor that takes a byte array and beginning position only (no prebuilt header) bool seenVariable = false; //writer.WriteLine(" /// <summary>Constructor that takes a byte array and beginning position (no prebuilt header)</summary>"); writer.WriteLine(" public " + packet.Name + "Packet(byte[] bytes, ref int i) : this()" + Environment.NewLine + " {" + Environment.NewLine + " int packetEnd = bytes.Length - 1;" + Environment.NewLine + " FromBytes(bytes, ref i, ref packetEnd, null);" + Environment.NewLine + " }" + Environment.NewLine); writer.WriteLine(" override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + " {"); writer.WriteLine(" Header.FromBytes(bytes, ref i, ref packetEnd);"); writer.WriteLine(" if (Header.Zerocoded && zeroBuffer != null)"); writer.WriteLine(" {"); writer.WriteLine(" packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;"); writer.WriteLine(" bytes = zeroBuffer;"); writer.WriteLine(" }"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".FromBytes(bytes, ref i);"); } else if (block.Count == -1) { // Variable count block if (!seenVariable) { writer.WriteLine(" int count = (int)bytes[i++];"); seenVariable = true; } else { writer.WriteLine(" count = (int)bytes[i++];"); } writer.WriteLine(" if(" + sanitizedName + " == null || " + sanitizedName + ".Length != " + block.Count + ") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[count];"); writer.WriteLine(" for(int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j] = new " + block.Name + "Block(); }"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } else { // Multiple count block writer.WriteLine(" if(" + sanitizedName + " == null || " + sanitizedName + ".Length != " + block.Count + ") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); writer.WriteLine(" for(int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j] = new " + block.Name + "Block(); }"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } } writer.WriteLine(" }" + Environment.NewLine); seenVariable = false; // Constructor that takes a byte array and a prebuilt header //writer.WriteLine(" /// <summary>Constructor that takes a byte array and a prebuilt header</summary>"); writer.WriteLine(" public " + packet.Name + "Packet(Header head, byte[] bytes, ref int i): this()" + Environment.NewLine + " {" + Environment.NewLine + " int packetEnd = bytes.Length - 1;" + Environment.NewLine + " FromBytes(head, bytes, ref i, ref packetEnd);" + Environment.NewLine + " }" + Environment.NewLine); writer.WriteLine(" override public void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd)" + Environment.NewLine + " {"); writer.WriteLine(" Header = header;"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".FromBytes(bytes, ref i);"); } else if (block.Count == -1) { // Variable count block if (!seenVariable) { writer.WriteLine(" int count = (int)bytes[i++];"); seenVariable = true; } else { writer.WriteLine(" count = (int)bytes[i++];"); } writer.WriteLine(" if(" + sanitizedName + " == null || " + sanitizedName + ".Length != count) {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[count];"); writer.WriteLine(" for(int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j] = new " + block.Name + "Block(); }"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } else { // Multiple count block writer.WriteLine(" if(" + sanitizedName + " == null || " + sanitizedName + ".Length != " + block.Count + ") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); writer.WriteLine(" for(int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j] = new " + block.Name + "Block(); }"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } } writer.WriteLine(" }" + Environment.NewLine); #region ToBytes() Function //writer.WriteLine(" /// <summary>Serialize this packet to a byte array</summary><returns>A byte array containing the serialized packet</returns>"); writer.WriteLine(" public override byte[] ToBytes()" + Environment.NewLine + " {"); writer.Write(" int length = "); if (packet.Frequency == PacketFrequency.Low) { writer.WriteLine("10;"); } else if (packet.Frequency == PacketFrequency.Medium) { writer.WriteLine("8;"); } else { writer.WriteLine("7;"); } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" length += " + sanitizedName + ".Length;"); } } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { writer.WriteLine(" length++;"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { length += " + sanitizedName + "[j].Length; }"); } else if (block.Count > 1) { writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { length += " + sanitizedName + "[j].Length; }"); } } writer.WriteLine(" if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }"); writer.WriteLine(" byte[] bytes = new byte[length];"); writer.WriteLine(" int i = 0;"); writer.WriteLine(" Header.ToBytes(bytes, ref i);"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" bytes[i++] = (byte)" + sanitizedName + ".Length;"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } else if (block.Count == 1) { writer.WriteLine(" " + sanitizedName + ".ToBytes(bytes, ref i);"); } else { // Multiple count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } } writer.WriteLine(" if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }"); writer.WriteLine(" return bytes;" + Environment.NewLine + " }" + Environment.NewLine); #endregion ToBytes() Function WriteToBytesMultiple(writer, packet); writer.WriteLine(" }" + Environment.NewLine); }
static void WritePacketClass(TextWriter writer, MapPacket packet) { string sanitizedName; //writer.WriteLine(" /// <summary>" + packet.Name + " packet</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" public class " + packet.Name + "Packet : Packet" + Environment.NewLine + " {"); // Write out each block class foreach (MapBlock block in packet.Blocks) { WriteBlockClass(writer, block, packet); } // Header member writer.WriteLine(" private Header header;"); //writer.WriteLine(" /// <summary>The header for this packet</summary>"); writer.WriteLine(" public override Header Header { get { return header; } set { header = value; } }"); // PacketType member //writer.WriteLine(" /// <summary>Will return PacketType." + packet.Name+ "</summary>"); writer.WriteLine(" public override PacketType Type { get { return PacketType." + packet.Name + "; } }"); // Block members foreach (MapBlock block in packet.Blocks) { // TODO: More thorough name blacklisting if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" public " + block.Name + "Block" + ((block.Count != 1) ? "[]" : "") + " " + sanitizedName + ";"); } writer.WriteLine(""); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + packet.Name + "Packet()" + Environment.NewLine + " {"); writer.WriteLine(" Header = new " + packet.Frequency.ToString() + "Header();"); writer.WriteLine(" Header.ID = " + packet.ID + ";"); writer.WriteLine(" Header.Reliable = true;"); // Turn the reliable flag on by default if (packet.Encoded) { writer.WriteLine(" Header.Zerocoded = true;"); } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block();"); } else if (block.Count == -1) { // Variable count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[0];"); } else { // Multiple count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); } } writer.WriteLine(" }" + Environment.NewLine); // Constructor that takes a byte array and beginning position only (no prebuilt header) bool seenVariable = false; //writer.WriteLine(" /// <summary>Constructor that takes a byte array and beginning position (no prebuilt header)</summary>"); writer.WriteLine(" public " + packet.Name + "Packet(byte[] bytes, ref int i) : this()" + Environment.NewLine + " {" + Environment.NewLine + " int packetEnd = bytes.Length - 1;" + Environment.NewLine + " FromBytes(bytes, ref i, ref packetEnd, null);" + Environment.NewLine + " }" + Environment.NewLine); writer.WriteLine(" override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + " {"); writer.WriteLine(" header.FromBytes(bytes, ref i, ref packetEnd);"); writer.WriteLine(" if (header.Zerocoded && zeroBuffer != null)"); writer.WriteLine(" {"); writer.WriteLine(" packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;"); writer.WriteLine(" bytes = zeroBuffer;"); writer.WriteLine(" }"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".FromBytes(bytes, ref i);"); } else if (block.Count == -1) { // Variable count block if (!seenVariable) { writer.WriteLine(" int count = (int)bytes[i++];"); seenVariable = true; } else { writer.WriteLine(" count = (int)bytes[i++];"); } writer.WriteLine(" if(" + sanitizedName + ".Length < count) {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[count];"); writer.WriteLine(" for(int j = 0; j < count; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } else { // Multiple count block writer.WriteLine(" if(" + sanitizedName + ".Length < " + block.Count+") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); writer.WriteLine(" for(int j = 0; j < " + block.Count + "; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } } writer.WriteLine(" }" + Environment.NewLine); seenVariable = false; // Constructor that takes a byte array and a prebuilt header //writer.WriteLine(" /// <summary>Constructor that takes a byte array and a prebuilt header</summary>"); writer.WriteLine(" public " + packet.Name + "Packet(Header head, byte[] bytes, ref int i): this()" + Environment.NewLine + " {" + Environment.NewLine + " int packetEnd = bytes.Length - 1;" + Environment.NewLine + " FromBytes(head, bytes, ref i, ref packetEnd, null);" + Environment.NewLine + " }" + Environment.NewLine); writer.WriteLine(" override public void FromBytes(Header head, byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + " {"); writer.WriteLine(" Header = head;"); writer.WriteLine(" if (head.Zerocoded && zeroBuffer != null)"); writer.WriteLine(" {"); writer.WriteLine(" packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;"); writer.WriteLine(" bytes = zeroBuffer;"); writer.WriteLine(" }"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".FromBytes(bytes, ref i);"); } else if (block.Count == -1) { // Variable count block if (!seenVariable) { writer.WriteLine(" int count = (int)bytes[i++];"); seenVariable = true; } else { writer.WriteLine(" count = (int)bytes[i++];"); } writer.WriteLine(" if(" + sanitizedName + ".Length < count) {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[count];"); writer.WriteLine(" for(int j = 0; j < count; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } else { // Multiple count block writer.WriteLine(" if(" + sanitizedName + ".Length < " + block.Count+") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); writer.WriteLine(" for(int j = 0; j < " + block.Count + "; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } } writer.WriteLine(" }" + Environment.NewLine); // ToBytes() function //writer.WriteLine(" /// <summary>Serialize this packet to a byte array</summary><returns>A byte array containing the serialized packet</returns>"); writer.WriteLine(" public override byte[] ToBytes()" + Environment.NewLine + " {"); writer.Write(" int length = "); if (packet.Frequency == PacketFrequency.Low) { writer.WriteLine("10;"); } else if (packet.Frequency == PacketFrequency.Medium) { writer.WriteLine("8;"); } else { writer.WriteLine("7;"); } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.Write(" length += " + sanitizedName + ".Length;"); } } writer.WriteLine(";"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { writer.WriteLine(" length++;"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { length += " + sanitizedName + "[j].Length; }"); } else if (block.Count > 1) { writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { length += " + sanitizedName + "[j].Length; }"); } } writer.WriteLine(" if (header.AckList.Length > 0) { length += header.AckList.Length * 4 + 1; }"); writer.WriteLine(" byte[] bytes = new byte[length];"); writer.WriteLine(" int i = 0;"); writer.WriteLine(" header.ToBytes(bytes, ref i);"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" bytes[i++] = (byte)" + sanitizedName + ".Length;"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } else if (block.Count == 1) { writer.WriteLine(" " + sanitizedName + ".ToBytes(bytes, ref i);"); } else { // Multiple count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } } writer.WriteLine(" if (header.AckList.Length > 0) { header.AcksToBytes(bytes, ref i); }"); writer.WriteLine(" return bytes;" + Environment.NewLine + " }" + Environment.NewLine); // ToString() function //writer.WriteLine(" /// <summary>Serialize this packet to a string</summary><returns>A string containing the serialized packet</returns>"); writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {"); writer.WriteLine(" string output = \"--- " + packet.Name + " ---\" + Environment.NewLine;"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++)" + Environment.NewLine + " {"); writer.WriteLine(" output += " + sanitizedName + "[j].ToString() + Environment.NewLine;" + Environment.NewLine + " }"); } else if (block.Count == 1) { writer.WriteLine(" output += " + sanitizedName + ".ToString() + Environment.NewLine;"); } else { // Multiple count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)" + Environment.NewLine + " {"); writer.WriteLine(" output += " + sanitizedName + "[j].ToString() + Environment.NewLine;" + Environment.NewLine + " }"); } } writer.WriteLine(" return output;" + Environment.NewLine + " }" + Environment.NewLine); // Closing function bracket writer.WriteLine(" }" + Environment.NewLine); }
static void WriteBlockClass(TextWriter writer, MapBlock block, MapPacket packet) { bool variableFields = false; //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" public class " + block.Name + "Block : PacketBlock" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldMember(writer, field); if (field.Type == FieldType.Variable) { variableFields = true; } } // Length property writer.WriteLine(""); //writer.WriteLine(" /// <summary>Length of this block serialized in bytes</summary>"); writer.WriteLine(" public override int Length" + Environment.NewLine + " {" + Environment.NewLine + " get" + Environment.NewLine + " {"); int length = 0; // Figure out the length of this block foreach (MapField field in block.Fields) { length += GetFieldLength(writer, field); } if (!variableFields) { writer.WriteLine(" return " + length + ";"); } else { writer.WriteLine(" int length = " + length + ";"); foreach (MapField field in block.Fields) { if (field.Type == FieldType.Variable) { writer.WriteLine(" if (" + field.Name + " != null) { length += " + field.Count + " + " + field.Name + ".Length; }"); } } writer.WriteLine(" return length;"); } writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + block.Name + "Block() { }"); // Constructor for building the class from bytes //writer.WriteLine(" /// <summary>Constructor for building the block from a byte array</summary>"); writer.WriteLine(" public " + block.Name + "Block(byte[] bytes, ref int i)" + Environment.NewLine + " {" + Environment.NewLine + " FromBytes(bytes, ref i);" + Environment.NewLine + " }" + Environment.NewLine); // Initiates instance variables from a byte message writer.WriteLine(" public override void FromBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); // Declare a length variable if we need it for variable fields in this constructor if (variableFields) { writer.WriteLine(" int length;"); } // Start of the try catch block writer.WriteLine(" try" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldFromBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine + " catch (Exception)" + Environment.NewLine + " {" + Environment.NewLine + " throw new MalformedDataException();" + Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine); // ToBytes() function //writer.WriteLine(" /// <summary>Serialize this block to a byte array</summary>"); writer.WriteLine(" public override void ToBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldToBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine); // ToString() function writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {"); writer.WriteLine(" StringBuilder output = new StringBuilder();"); writer.WriteLine(" output.AppendLine(\"-- " + block.Name + " --\");"); for (int i = 0; i < block.Fields.Count; i++) { MapField field = block.Fields[i]; if (field.Type == FieldType.Variable || field.Type == FieldType.Fixed) { writer.WriteLine(" Helpers.FieldToString(output, " + field.Name + ", \"" + field.Name + "\");"); if (i != block.Fields.Count - 1) writer.WriteLine(" output.Append(Environment.NewLine);"); } else { if (i != block.Fields.Count - 1) writer.WriteLine(" output.AppendLine(String.Format(\"" + field.Name + ": {0}\", " + field.Name + "));"); else writer.WriteLine(" output.Append(String.Format(\"" + field.Name + ": {0}\", " + field.Name + "));"); } } writer.WriteLine(" return output.ToString();" + Environment.NewLine + " }"); writer.WriteLine(" }" + Environment.NewLine); }
static void WritePacketClass(TextWriter writer, MapPacket packet) { string sanitizedName; //writer.WriteLine(" /// <summary>" + packet.Name + " packet</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" public class " + packet.Name + "Packet : Packet" + Environment.NewLine + " {"); // Write out each block class foreach (MapBlock block in packet.Blocks) { WriteBlockClass(writer, block, packet); } // Header member writer.WriteLine(" private Header header;"); //writer.WriteLine(" /// <summary>The header for this packet</summary>"); writer.WriteLine(" public override Header Header { get { return header; } set { header = value; } }"); // PacketType member //writer.WriteLine(" /// <summary>Will return PacketType." + packet.Name+ "</summary>"); writer.WriteLine(" public override PacketType Type { get { return PacketType." + packet.Name + "; } }"); // Block members foreach (MapBlock block in packet.Blocks) { // TODO: More thorough name blacklisting if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" public " + block.Name + "Block" + ((block.Count != 1) ? "[]" : "") + " " + sanitizedName + ";"); } writer.WriteLine(""); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + packet.Name + "Packet()" + Environment.NewLine + " {"); writer.WriteLine(" Header = new " + packet.Frequency.ToString() + "Header();"); writer.WriteLine(" Header.ID = " + packet.ID + ";"); writer.WriteLine(" Header.Reliable = true;"); // Turn the reliable flag on by default if (packet.Encoded) { writer.WriteLine(" Header.Zerocoded = true;"); } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block();"); } else if (block.Count == -1) { // Variable count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[0];"); } else { // Multiple count block writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); } } writer.WriteLine(" }" + Environment.NewLine); // Constructor that takes a byte array and beginning position only (no prebuilt header) bool seenVariable = false; //writer.WriteLine(" /// <summary>Constructor that takes a byte array and beginning position (no prebuilt header)</summary>"); writer.WriteLine(" public " + packet.Name + "Packet(byte[] bytes, ref int i) : this()" + Environment.NewLine + " {" + Environment.NewLine + " int packetEnd = bytes.Length - 1;" + Environment.NewLine + " FromBytes(bytes, ref i, ref packetEnd, null);" + Environment.NewLine + " }" + Environment.NewLine); writer.WriteLine(" override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + " {"); writer.WriteLine(" header.FromBytes(bytes, ref i, ref packetEnd);"); writer.WriteLine(" if (header.Zerocoded && zeroBuffer != null)"); writer.WriteLine(" {"); writer.WriteLine(" packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;"); writer.WriteLine(" bytes = zeroBuffer;"); writer.WriteLine(" }"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".FromBytes(bytes, ref i);"); } else if (block.Count == -1) { // Variable count block if (!seenVariable) { writer.WriteLine(" int count = (int)bytes[i++];"); seenVariable = true; } else { writer.WriteLine(" count = (int)bytes[i++];"); } writer.WriteLine(" if(" + sanitizedName + ".Length < count) {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[count];"); writer.WriteLine(" for(int j = 0; j < count; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } else { // Multiple count block writer.WriteLine(" if(" + sanitizedName + ".Length < " + block.Count + ") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); writer.WriteLine(" for(int j = 0; j < " + block.Count + "; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } } writer.WriteLine(" }" + Environment.NewLine); seenVariable = false; // Constructor that takes a byte array and a prebuilt header //writer.WriteLine(" /// <summary>Constructor that takes a byte array and a prebuilt header</summary>"); writer.WriteLine(" public " + packet.Name + "Packet(Header head, byte[] bytes, ref int i): this()" + Environment.NewLine + " {" + Environment.NewLine + " int packetEnd = bytes.Length - 1;" + Environment.NewLine + " FromBytes(head, bytes, ref i, ref packetEnd, null);" + Environment.NewLine + " }" + Environment.NewLine); writer.WriteLine(" override public void FromBytes(Header head, byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + " {"); writer.WriteLine(" Header = head;"); writer.WriteLine(" if (head.Zerocoded && zeroBuffer != null)"); writer.WriteLine(" {"); writer.WriteLine(" packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;"); writer.WriteLine(" bytes = zeroBuffer;"); writer.WriteLine(" }"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.WriteLine(" " + sanitizedName + ".FromBytes(bytes, ref i);"); } else if (block.Count == -1) { // Variable count block if (!seenVariable) { writer.WriteLine(" int count = (int)bytes[i++];"); seenVariable = true; } else { writer.WriteLine(" count = (int)bytes[i++];"); } writer.WriteLine(" if(" + sanitizedName + ".Length < count) {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[count];"); writer.WriteLine(" for(int j = 0; j < count; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < count; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } else { // Multiple count block writer.WriteLine(" if(" + sanitizedName + ".Length < " + block.Count + ") {"); writer.WriteLine(" " + sanitizedName + " = new " + block.Name + "Block[" + block.Count + "];"); writer.WriteLine(" for(int j = 0; j < " + block.Count + "; j++) " + sanitizedName + "[j] = new " + block.Name + "Block();"); writer.WriteLine(" }"); writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)"); writer.WriteLine(" { " + sanitizedName + "[j].FromBytes(bytes, ref i); }"); } } writer.WriteLine(" }" + Environment.NewLine); // ToBytes() function //writer.WriteLine(" /// <summary>Serialize this packet to a byte array</summary><returns>A byte array containing the serialized packet</returns>"); writer.WriteLine(" public override byte[] ToBytes()" + Environment.NewLine + " {"); writer.Write(" int length = "); if (packet.Frequency == PacketFrequency.Low) { writer.WriteLine("10;"); } else if (packet.Frequency == PacketFrequency.Medium) { writer.WriteLine("8;"); } else { writer.WriteLine("7;"); } foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == 1) { // Single count block writer.Write(" length += " + sanitizedName + ".Length;"); } } writer.WriteLine(";"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { writer.WriteLine(" length++;"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { length += " + sanitizedName + "[j].Length; }"); } else if (block.Count > 1) { writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { length += " + sanitizedName + "[j].Length; }"); } } writer.WriteLine(" if (header.AckList.Length > 0) { length += header.AckList.Length * 4 + 1; }"); writer.WriteLine(" byte[] bytes = new byte[length];"); writer.WriteLine(" int i = 0;"); writer.WriteLine(" header.ToBytes(bytes, ref i);"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" bytes[i++] = (byte)" + sanitizedName + ".Length;"); writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } else if (block.Count == 1) { writer.WriteLine(" " + sanitizedName + ".ToBytes(bytes, ref i);"); } else { // Multiple count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++) { " + sanitizedName + "[j].ToBytes(bytes, ref i); }"); } } writer.WriteLine(" if (header.AckList.Length > 0) { header.AcksToBytes(bytes, ref i); }"); writer.WriteLine(" return bytes;" + Environment.NewLine + " }" + Environment.NewLine); // ToString() function //writer.WriteLine(" /// <summary>Serialize this packet to a string</summary><returns>A string containing the serialized packet</returns>"); writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {"); writer.WriteLine(" string output = \"--- " + packet.Name + " ---\" + Environment.NewLine;"); foreach (MapBlock block in packet.Blocks) { if (block.Name == "Header") { sanitizedName = "_" + block.Name; } else { sanitizedName = block.Name; } if (block.Count == -1) { // Variable count block writer.WriteLine(" for (int j = 0; j < " + sanitizedName + ".Length; j++)" + Environment.NewLine + " {"); writer.WriteLine(" output += " + sanitizedName + "[j].ToString() + Environment.NewLine;" + Environment.NewLine + " }"); } else if (block.Count == 1) { writer.WriteLine(" output += " + sanitizedName + ".ToString() + Environment.NewLine;"); } else { // Multiple count block writer.WriteLine(" for (int j = 0; j < " + block.Count + "; j++)" + Environment.NewLine + " {"); writer.WriteLine(" output += " + sanitizedName + "[j].ToString() + Environment.NewLine;" + Environment.NewLine + " }"); } } writer.WriteLine(" return output;" + Environment.NewLine + " }" + Environment.NewLine); // Closing function bracket writer.WriteLine(" }" + Environment.NewLine); }
static void WriteBlockClass(TextWriter writer, MapBlock block, MapPacket packet) { bool variableFields = false; //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" public class " + block.Name + "Block : PacketBlock" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldMember(writer, field); if (field.Type == FieldType.Variable) { variableFields = true; } } // Length property writer.WriteLine(""); //writer.WriteLine(" /// <summary>Length of this block serialized in bytes</summary>"); writer.WriteLine(" public override int Length" + Environment.NewLine + " {" + Environment.NewLine + " get" + Environment.NewLine + " {"); int length = 0; // Figure out the length of this block foreach (MapField field in block.Fields) { length += GetFieldLength(writer, field); } if (!variableFields) { writer.WriteLine(" return " + length + ";"); } else { writer.WriteLine(" int length = " + length + ";"); foreach (MapField field in block.Fields) { if (field.Type == FieldType.Variable) { writer.WriteLine(" if (" + field.Name + " != null) { length += " + field.Count + " + " + field.Name + ".Length; }"); } } writer.WriteLine(" return length;"); } writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + block.Name + "Block() { }"); // Constructor for building the class from bytes //writer.WriteLine(" /// <summary>Constructor for building the block from a byte array</summary>"); writer.WriteLine(" public " + block.Name + "Block(byte[] bytes, ref int i)" + Environment.NewLine + " {" + Environment.NewLine + " FromBytes(bytes, ref i);" + Environment.NewLine + " }" + Environment.NewLine); // Initiates instance variables from a byte message writer.WriteLine(" public override void FromBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); // Declare a length variable if we need it for variable fields in this constructor if (variableFields) { writer.WriteLine(" int length;"); } // Start of the try catch block writer.WriteLine(" try" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldFromBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine + " catch (Exception)" + Environment.NewLine + " {" + Environment.NewLine + " throw new MalformedDataException();" + Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine); // ToBytes() function //writer.WriteLine(" /// <summary>Serialize this block to a byte array</summary>"); writer.WriteLine(" public override void ToBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldToBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine); // ToString() function writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {"); writer.WriteLine(" StringBuilder output = new StringBuilder();"); writer.WriteLine(" output.AppendLine(\"-- " + block.Name + " --\");"); for (int i = 0; i < block.Fields.Count; i++) { MapField field = block.Fields[i]; if (field.Type == FieldType.Variable || field.Type == FieldType.Fixed) { writer.WriteLine(" Helpers.FieldToString(output, " + field.Name + ", \"" + field.Name + "\");"); if (i != block.Fields.Count - 1) { writer.WriteLine(" output.Append(Environment.NewLine);"); } } else { if (i != block.Fields.Count - 1) { writer.WriteLine(" output.AppendLine(String.Format(\"" + field.Name + ": {0}\", " + field.Name + "));"); } else { writer.WriteLine(" output.Append(String.Format(\"" + field.Name + ": {0}\", " + field.Name + "));"); } } } writer.WriteLine(" return output.ToString();" + Environment.NewLine + " }"); writer.WriteLine(" }" + Environment.NewLine); }
static void WriteBlockClass(TextWriter writer, MapBlock block, MapPacket packet) { bool variableFields = false; bool floatFields = false; //writer.WriteLine(" /// <summary>" + block.Name + " block</summary>"); writer.WriteLine(" /// <exclude/>"); writer.WriteLine(" [XmlType(\"" + packet.Name.ToLower() + "_" + block.Name.ToLower() + "\")]"); writer.WriteLine(" public class " + block.Name + "Block" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldMember(writer, field); if (field.Type == FieldType.Variable) { variableFields = true; } if (field.Type == FieldType.F32 || field.Type == FieldType.F64) { floatFields = true; } } // Length property writer.WriteLine(""); //writer.WriteLine(" /// <summary>Length of this block serialized in bytes</summary>"); writer.WriteLine(" [XmlIgnore]" + Environment.NewLine + " public int Length" + Environment.NewLine + " {" + Environment.NewLine + " get" + Environment.NewLine + " {"); int length = 0; // Figure out the length of this block foreach (MapField field in block.Fields) { length += GetFieldLength(writer, field); } if (!variableFields) { writer.WriteLine(" return " + length + ";"); } else { writer.WriteLine(" int length = " + length + ";"); foreach (MapField field in block.Fields) { if (field.Type == FieldType.Variable) { writer.WriteLine(" if (" + field.Name + " != null) { length += " + field.Count + " + " + field.Name + ".Length; }"); } } writer.WriteLine(" return length;"); } writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine); // Default constructor //writer.WriteLine(" /// <summary>Default constructor</summary>"); writer.WriteLine(" public " + block.Name + "Block() { }"); // Constructor for building the class from bytes //writer.WriteLine(" /// <summary>Constructor for building the block from a byte array</summary>"); writer.WriteLine(" public " + block.Name + "Block(byte[] bytes, ref int i)" + Environment.NewLine + " {"); // Declare a length variable if we need it for variable fields in this constructor if (variableFields) { writer.WriteLine(" int length;"); } // Start of the try catch block writer.WriteLine(" try" + Environment.NewLine + " {"); foreach (MapField field in block.Fields) { WriteFieldFromBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine + " catch (Exception)" + Environment.NewLine + " {" + Environment.NewLine + " throw new MalformedDataException();" + Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine); // ToBytes() function //writer.WriteLine(" /// <summary>Serialize this block to a byte array</summary>"); writer.WriteLine(" public void ToBytes(byte[] bytes, ref int i)" + Environment.NewLine + " {"); // Declare a byte[] variable if we need it for floating point field conversions if (floatFields) { writer.WriteLine(" byte[] ba;"); } foreach (MapField field in block.Fields) { WriteFieldToBytes(writer, field); } writer.WriteLine(" }" + Environment.NewLine); // ToString() function //writer.WriteLine(" /// <summary>Serialize this block to a string</summary><returns>A string containing the serialized block</returns>"); writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {"); writer.WriteLine(" string output = \"-- " + block.Name + " --\" + Environment.NewLine;"); foreach (MapField field in block.Fields) { if (field.Type == FieldType.Variable || field.Type == FieldType.Fixed) { writer.WriteLine(" output += Helpers.FieldToString(" + field.Name + ", \"" + field.Name + "\") + \"\" + Environment.NewLine;"); } else { writer.WriteLine(" output += \"" + field.Name + ": \" + " + field.Name + ".ToString() + \"\" + Environment.NewLine;"); } } writer.WriteLine(" output = output.Trim();" + Environment.NewLine + " return output;" + Environment.NewLine + " }"); writer.WriteLine(" }" + Environment.NewLine); }