static int GetFieldLength(TextWriter writer, MapField field) { switch (field.Type) { case FieldType.BOOL: case FieldType.U8: case FieldType.S8: return(1); case FieldType.U16: case FieldType.S16: case FieldType.IPPORT: return(2); case FieldType.U32: case FieldType.S32: case FieldType.F32: case FieldType.IPADDR: return(4); case FieldType.U64: case FieldType.F64: return(8); case FieldType.LLVector3: case FieldType.LLQuaternion: return(12); case FieldType.LLUUID: case FieldType.LLVector4: //case FieldType.LLQuaternion: return(16); case FieldType.LLVector3d: return(24); case FieldType.Fixed: return(field.Count); case FieldType.Variable: return(0); default: writer.WriteLine("!!! ERROR: Unhandled FieldType " + field.Type.ToString() + " !!!"); return(0); } }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <returns></returns> public int CompareTo(object obj) { MapField temp = (MapField)obj; if (KeywordPosition > temp.KeywordPosition) { return(1); } else { if (temp.KeywordPosition == KeywordPosition) { return(0); } else { return(-1); } } }
static int GetFieldLength(TextWriter writer, MapField field) { switch (field.Type) { case FieldType.BOOL: case FieldType.U8: case FieldType.S8: return 1; case FieldType.U16: case FieldType.S16: case FieldType.IPPORT: return 2; case FieldType.U32: case FieldType.S32: case FieldType.F32: case FieldType.IPADDR: return 4; case FieldType.U64: case FieldType.F64: return 8; case FieldType.LLVector3: case FieldType.LLQuaternion: return 12; case FieldType.LLUUID: case FieldType.LLVector4: return 16; case FieldType.LLVector3d: return 24; case FieldType.Fixed: return field.Count; case FieldType.Variable: return 0; default: writer.WriteLine("!!! ERROR: Unhandled FieldType " + field.Type.ToString() + " !!!"); return 0; } }
/// <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; } }
/// <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 WriteFieldToBytes(TextWriter writer, MapField field) { writer.Write(" "); switch (field.Type) { case FieldType.BOOL: writer.WriteLine("bytes[i++] = (byte)((" + field.Name + ") ? 1 : 0);"); break; case FieldType.F32: writer.WriteLine("Utils.FloatToBytes(" + field.Name + ", bytes, i); i += 4;"); break; case FieldType.F64: writer.WriteLine("Utils.DoubleToBytes(" + field.Name + ", bytes, i); i += 8;"); break; case FieldType.Fixed: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Count + ");" + "i += " + field.Count + ";"); break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 is little endian. Go figure writer.WriteLine("bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)(" + field.Name + " % 256);"); break; case FieldType.U16: case FieldType.S16: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); break; case FieldType.LLQuaternion: case FieldType.LLVector3: writer.WriteLine(field.Name + ".ToBytes(bytes, i); i += 12;"); break; case FieldType.LLUUID: case FieldType.LLVector4: writer.WriteLine(field.Name + ".ToBytes(bytes, i); i += 16;"); break; case FieldType.LLVector3d: writer.WriteLine(field.Name + ".ToBytes(bytes, i); i += 24;"); break; case FieldType.U8: writer.WriteLine("bytes[i++] = " + field.Name + ";"); break; case FieldType.S8: writer.WriteLine("bytes[i++] = (byte)" + field.Name + ";"); break; case FieldType.IPADDR: case FieldType.U32: writer.WriteLine("Utils.UIntToBytes(" + field.Name + ", bytes, i); i += 4;"); break; case FieldType.S32: writer.WriteLine("Utils.IntToBytes(" + field.Name + ", bytes, i); i += 4;"); break; case FieldType.U64: writer.WriteLine("Utils.UInt64ToBytes(" + field.Name + ", bytes, i); i += 8;"); break; case FieldType.Variable: //writer.WriteLine("if(" + field.Name + " == null) { Console.WriteLine(\"Warning: " + field.Name + " is null, in \" + this.GetType()); }"); //writer.Write(" "); if (field.Count == 1) { writer.WriteLine("bytes[i++] = (byte)" + field.Name + ".Length;"); } else { writer.WriteLine("bytes[i++] = (byte)(" + field.Name + ".Length % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + ".Length >> 8) % 256);"); } writer.WriteLine(" Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Name + ".Length); " + "i += " + field.Name + ".Length;"); break; default: writer.WriteLine("!!! ERROR: Unhandled FieldType: " + field.Type.ToString() + " !!!"); break; } }
static void WriteFieldMember(TextWriter writer, MapField field) { string type = String.Empty; switch (field.Type) { case FieldType.BOOL: type = "bool"; break; case FieldType.F32: type = "float"; break; case FieldType.F64: type = "double"; break; case FieldType.IPPORT: case FieldType.U16: type = "ushort"; break; case FieldType.IPADDR: case FieldType.U32: type = "uint"; break; case FieldType.LLQuaternion: type = "Quaternion"; break; case FieldType.LLUUID: type = "UUID"; break; case FieldType.LLVector3: type = "Vector3"; break; case FieldType.LLVector3d: type = "Vector3d"; break; case FieldType.LLVector4: type = "Vector4"; break; case FieldType.S16: type = "short"; break; case FieldType.S32: type = "int"; break; case FieldType.S8: type = "sbyte"; break; case FieldType.U64: type = "ulong"; break; case FieldType.U8: type = "byte"; break; case FieldType.Fixed: type = "byte[]"; break; } if (field.Type != FieldType.Variable) { //writer.WriteLine(" /// <summary>" + field.Name + " field</summary>"); writer.WriteLine(" public " + type + " " + field.Name + ";"); } else { writer.WriteLine(" public byte[] " + field.Name + ";"); //writer.WriteLine(" private byte[] _" + field.Name.ToLower() + ";"); ////writer.WriteLine(" /// <summary>" + field.Name + " field</summary>"); //writer.WriteLine(" public byte[] " + field.Name + Environment.NewLine + " {"); //writer.WriteLine(" get { return _" + field.Name.ToLower() + "; }"); //writer.WriteLine(" set" + Environment.NewLine + " {"); //writer.WriteLine(" if (value == null) { _" + // field.Name.ToLower() + " = null; return; }"); //writer.WriteLine(" if (value.Length > " + // ((field.Count == 1) ? "255" : "1100") + ") { throw new OverflowException(" + // "\"Value exceeds " + ((field.Count == 1) ? "255" : "1100") + " characters\"); }"); //writer.WriteLine(" else { _" + field.Name.ToLower() + // " = new byte[value.Length]; Buffer.BlockCopy(value, 0, _" + // field.Name.ToLower() + ", 0, value.Length); }"); //writer.WriteLine(" }" + Environment.NewLine + " }"); } }
static void WriteFieldFromBytes(TextWriter writer, MapField field) { switch (field.Type) { case FieldType.BOOL: writer.WriteLine(" " + field.Name + " = (bytes[i++] != 0) ? (bool)true : (bool)false;"); break; case FieldType.F32: writer.WriteLine(" " + field.Name + " = Utils.BytesToFloat(bytes, i); i += 4;"); break; case FieldType.F64: writer.WriteLine(" " + field.Name + " = Utils.BytesToDouble(bytes, i); i += 8;"); break; case FieldType.Fixed: writer.WriteLine(" " + field.Name + " = new byte[" + field.Count + "];"); writer.WriteLine(" Buffer.BlockCopy(bytes, i, " + field.Name + ", 0, " + field.Count + "); i += " + field.Count + ";"); break; case FieldType.IPADDR: case FieldType.U32: writer.WriteLine(" " + field.Name + " = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));"); break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 are little endian. Go figure writer.WriteLine(" " + field.Name + " = (ushort)((bytes[i++] << 8) + bytes[i++]);"); break; case FieldType.U16: writer.WriteLine(" " + field.Name + " = (ushort)(bytes[i++] + (bytes[i++] << 8));"); break; case FieldType.LLQuaternion: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i, true); i += 12;"); break; case FieldType.LLUUID: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 16;"); break; case FieldType.LLVector3: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 12;"); break; case FieldType.LLVector3d: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 24;"); break; case FieldType.LLVector4: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 16;"); break; case FieldType.S16: writer.WriteLine(" " + field.Name + " = (short)(bytes[i++] + (bytes[i++] << 8));"); break; case FieldType.S32: writer.WriteLine(" " + field.Name + " = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));"); break; case FieldType.S8: writer.WriteLine(" " + field.Name + " = (sbyte)bytes[i++];"); break; case FieldType.U64: writer.WriteLine(" " + field.Name + " = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + " + "((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + " + "((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + " + "((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));"); break; case FieldType.U8: writer.WriteLine(" " + field.Name + " = (byte)bytes[i++];"); break; case FieldType.Variable: if (field.Count == 1) { writer.WriteLine(" length = bytes[i++];"); } else { writer.WriteLine(" length = (bytes[i++] + (bytes[i++] << 8));"); } writer.WriteLine(" " + field.Name + " = new byte[length];"); writer.WriteLine(" Buffer.BlockCopy(bytes, i, " + field.Name + ", 0, length); i += length;"); break; default: writer.WriteLine("!!! ERROR: Unhandled FieldType: " + field.Type.ToString() + " !!!"); break; } }
static void WriteFieldMember(TextWriter writer, MapField field) { string type = String.Empty; switch (field.Type) { case FieldType.BOOL: type = "bool"; break; case FieldType.F32: type = "float"; break; case FieldType.F64: type = "double"; break; case FieldType.IPPORT: case FieldType.U16: type = "ushort"; break; case FieldType.IPADDR: case FieldType.U32: type = "uint"; break; case FieldType.LLQuaternion: type = "Quaternion"; break; case FieldType.LLUUID: type = "UUID"; break; case FieldType.LLVector3: type = "Vector3"; break; case FieldType.LLVector3d: type = "Vector3d"; break; case FieldType.LLVector4: type = "Vector4"; break; case FieldType.S16: type = "short"; break; case FieldType.S32: type = "int"; break; case FieldType.S8: type = "sbyte"; break; case FieldType.U64: type = "ulong"; break; case FieldType.U8: type = "byte"; break; case FieldType.Fixed: type = "byte[]"; break; } if (field.Type != FieldType.Variable) { //writer.WriteLine(" /// <summary>" + field.Name + " field</summary>"); writer.WriteLine(" public " + type + " " + field.Name + ";"); } else { writer.WriteLine(" private byte[] _" + field.Name.ToLower() + ";"); //writer.WriteLine(" /// <summary>" + field.Name + " field</summary>"); writer.WriteLine(" public byte[] " + field.Name + Environment.NewLine + " {"); writer.WriteLine(" get { return _" + field.Name.ToLower() + "; }"); writer.WriteLine(" set" + Environment.NewLine + " {"); writer.WriteLine(" if (value == null) { _" + field.Name.ToLower() + " = null; return; }"); writer.WriteLine(" if (value.Length > " + ((field.Count == 1) ? "255" : "1100") + ") { throw new OverflowException(" + "\"Value exceeds " + ((field.Count == 1) ? "255" : "1100") + " characters\"); }"); writer.WriteLine(" else { _" + field.Name.ToLower() + " = new byte[value.Length]; Buffer.BlockCopy(value, 0, _" + field.Name.ToLower() + ", 0, value.Length); }"); 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 WriteFieldToBytes(TextWriter writer, MapField field) { writer.Write(" "); switch (field.Type) { case FieldType.BOOL: writer.WriteLine("bytes[i++] = (byte)((" + field.Name + ") ? 1 : 0);"); break; case FieldType.F32: writer.WriteLine("Utils.FloatToBytes(" + field.Name + ", bytes, i); i += 4;"); break; case FieldType.F64: writer.WriteLine("Utils.DoubleToBytes(" + field.Name + ", bytes, i); i += 8;"); break; case FieldType.Fixed: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Count + ");" + "i += " + field.Count + ";"); break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 is little endian. Go figure writer.WriteLine("bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)(" + field.Name + " % 256);"); break; case FieldType.U16: case FieldType.S16: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); break; case FieldType.LLUUID: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 16); i += 16;"); break; case FieldType.LLVector4: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 16); i += 16;"); break; case FieldType.LLQuaternion: case FieldType.LLVector3: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 12); i += 12;"); break; case FieldType.LLVector3d: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 24); i += 24;"); break; case FieldType.U8: writer.WriteLine("bytes[i++] = " + field.Name + ";"); break; case FieldType.S8: writer.WriteLine("bytes[i++] = (byte)" + field.Name + ";"); break; case FieldType.IPADDR: case FieldType.U32: writer.WriteLine("Utils.UIntToBytes(" + field.Name + ", bytes, i); i += 4;"); break; case FieldType.S32: writer.WriteLine("Utils.IntToBytes(" + field.Name + ", bytes, i); i += 4;"); break; case FieldType.U64: writer.WriteLine("Utils.UInt64ToBytes(" + field.Name + ", bytes, i); i += 8;"); break; case FieldType.Variable: writer.WriteLine("if(" + field.Name + " == null) { Console.WriteLine(\"Warning: " + field.Name + " is null, in \" + this.GetType()); }"); writer.Write(" "); if (field.Count == 1) { writer.WriteLine("bytes[i++] = (byte)" + field.Name + ".Length;"); } else { writer.WriteLine("bytes[i++] = (byte)(" + field.Name + ".Length % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + ".Length >> 8) % 256);"); } writer.WriteLine(" Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Name + ".Length); " + "i += " + field.Name + ".Length;"); break; default: writer.WriteLine("!!! ERROR: Unhandled FieldType: " + field.Type.ToString() + " !!!"); break; } }
static void WriteFieldFromBytes(TextWriter writer, MapField field) { switch (field.Type) { case FieldType.BOOL: writer.WriteLine(" " + field.Name + " = (bytes[i++] != 0) ? (bool)true : (bool)false;"); break; case FieldType.F32: writer.WriteLine(" " + field.Name + " = Utils.BytesToFloat(bytes, i); i += 4;"); break; case FieldType.F64: writer.WriteLine(" " + field.Name + " = Utils.BytesToDouble(bytes, i); i += 8;"); break; case FieldType.Fixed: writer.WriteLine(" " + field.Name + " = new byte[" + field.Count + "];"); writer.WriteLine(" Buffer.BlockCopy(bytes, i, " + field.Name + ", 0, " + field.Count + "); i += " + field.Count + ";"); break; case FieldType.IPADDR: case FieldType.U32: writer.WriteLine(" " + field.Name + " = (uint)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));"); break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 are little endian. Go figure writer.WriteLine(" " + field.Name + " = (ushort)((bytes[i++] << 8) + bytes[i++]);"); break; case FieldType.U16: writer.WriteLine(" " + field.Name + " = (ushort)(bytes[i++] + (bytes[i++] << 8));"); break; case FieldType.LLQuaternion: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i, true); i += 12;"); break; case FieldType.LLUUID: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 16;"); break; case FieldType.LLVector3: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 12;"); break; case FieldType.LLVector3d: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 24;"); break; case FieldType.LLVector4: writer.WriteLine(" " + field.Name + ".FromBytes(bytes, i); i += 16;"); break; case FieldType.S16: writer.WriteLine(" " + field.Name + " = (short)(bytes[i++] + (bytes[i++] << 8));"); break; case FieldType.S32: writer.WriteLine(" " + field.Name + " = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));"); break; case FieldType.S8: writer.WriteLine(" " + field.Name + " = (sbyte)bytes[i++];"); break; case FieldType.U64: writer.WriteLine(" " + field.Name + " = (ulong)((ulong)bytes[i++] + ((ulong)bytes[i++] << 8) + " + "((ulong)bytes[i++] << 16) + ((ulong)bytes[i++] << 24) + " + "((ulong)bytes[i++] << 32) + ((ulong)bytes[i++] << 40) + " + "((ulong)bytes[i++] << 48) + ((ulong)bytes[i++] << 56));"); break; case FieldType.U8: writer.WriteLine(" " + field.Name + " = (byte)bytes[i++];"); break; case FieldType.Variable: if (field.Count == 1) { writer.WriteLine(" length = (ushort)bytes[i++];"); } else { writer.WriteLine(" length = (ushort)(bytes[i++] + (bytes[i++] << 8));"); } writer.WriteLine(" _" + field.Name.ToLower() + " = new byte[length];"); writer.WriteLine(" Buffer.BlockCopy(bytes, i, _" + field.Name.ToLower() + ", 0, length); i += length;"); break; default: writer.WriteLine("!!! ERROR: Unhandled FieldType: " + field.Type.ToString() + " !!!"); break; } }
static void WriteFieldToBytes(TextWriter writer, MapField field) { writer.Write(" "); switch (field.Type) { case FieldType.BOOL: writer.WriteLine("bytes[i++] = (byte)((" + field.Name + ") ? 1 : 0);"); break; case FieldType.F32: writer.WriteLine("ba = BitConverter.GetBytes(" + field.Name + ");" + Environment.NewLine + " if(!BitConverter.IsLittleEndian) { Array.Reverse(ba, 0, 4); }" + Environment.NewLine + " Array.Copy(ba, 0, bytes, i, 4); i += 4;"); break; case FieldType.F64: writer.WriteLine("ba = BitConverter.GetBytes(" + field.Name + ");" + Environment.NewLine + " if(!BitConverter.IsLittleEndian) { Array.Reverse(ba, 0, 8); }" + Environment.NewLine + " Array.Copy(ba, 0, bytes, i, 8); i += 8;"); break; case FieldType.Fixed: writer.WriteLine(" Array.Copy(" + field.Name + ", 0, bytes, i, " + field.Count + ");" + "i += " + field.Count + ";"); break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 is little endian. Go figure writer.WriteLine("bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)(" + field.Name + " % 256);"); break; case FieldType.U16: case FieldType.S16: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); break; case FieldType.LLUUID: writer.WriteLine("if(" + field.Name + " == null) { Console.WriteLine(\"Warning: " + field.Name + " is null, in \" + this.GetType()); }"); writer.Write(" "); writer.WriteLine("Array.Copy(" + field.Name + ".GetBytes(), 0, bytes, i, 16); i += 16;"); break; case FieldType.LLVector4: writer.WriteLine("Array.Copy(" + field.Name + ".GetBytes(), 0, bytes, i, 16); i += 16;"); break; case FieldType.LLQuaternion: case FieldType.LLVector3: writer.WriteLine("Array.Copy(" + field.Name + ".GetBytes(), 0, bytes, i, 12); i += 12;"); break; case FieldType.LLVector3d: writer.WriteLine("Array.Copy(" + field.Name + ".GetBytes(), 0, bytes, i, 24); i += 24;"); break; case FieldType.U8: writer.WriteLine("bytes[i++] = " + field.Name + ";"); break; case FieldType.S8: writer.WriteLine("bytes[i++] = (byte)" + field.Name + ";"); break; case FieldType.IPADDR: case FieldType.U32: case FieldType.S32: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 16) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 24) % 256);"); break; case FieldType.U64: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 16) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 24) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 32) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 40) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 48) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 56) % 256);"); break; case FieldType.Variable: writer.WriteLine("if(" + field.Name + " == null) { Console.WriteLine(\"Warning: " + field.Name + " is null, in \" + this.GetType()); }"); writer.Write(" "); if (field.Count == 1) { writer.WriteLine("bytes[i++] = (byte)" + field.Name + ".Length;"); } else { writer.WriteLine("bytes[i++] = (byte)(" + field.Name + ".Length % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + ".Length >> 8) % 256);"); } writer.WriteLine(" Array.Copy(" + field.Name + ", 0, bytes, i, " + field.Name + ".Length); " + "i += " + field.Name + ".Length;"); break; default: writer.WriteLine("!!! ERROR: Unhandled FieldType: " + field.Type.ToString() + " !!!"); break; } }
static void WriteFieldToBytes(TextWriter writer, MapField field) { writer.Write(" "); switch (field.Type) { case FieldType.BOOL: writer.WriteLine("bytes[i++] = (byte)((" + field.Name + ") ? 1 : 0);"); break; case FieldType.F32: writer.WriteLine("ba = BitConverter.GetBytes(" + field.Name + ");" + Environment.NewLine + " if(!BitConverter.IsLittleEndian) { Array.Reverse(ba, 0, 4); }" + Environment.NewLine + " Buffer.BlockCopy(ba, 0, bytes, i, 4); i += 4;"); break; case FieldType.F64: writer.WriteLine("ba = BitConverter.GetBytes(" + field.Name + ");" + Environment.NewLine + " if(!BitConverter.IsLittleEndian) { Array.Reverse(ba, 0, 8); }" + Environment.NewLine + " Buffer.BlockCopy(ba, 0, bytes, i, 8); i += 8;"); break; case FieldType.Fixed: writer.WriteLine(" Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Count + ");" + "i += " + field.Count + ";"); break; case FieldType.IPPORT: // IPPORT is big endian while U16/S16 is little endian. Go figure writer.WriteLine("bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)(" + field.Name + " % 256);"); break; case FieldType.U16: case FieldType.S16: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); break; case FieldType.LLUUID: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 16); i += 16;"); break; case FieldType.LLVector4: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 16); i += 16;"); break; case FieldType.LLQuaternion: case FieldType.LLVector3: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 12); i += 12;"); break; case FieldType.LLVector3d: writer.WriteLine("Buffer.BlockCopy(" + field.Name + ".GetBytes(), 0, bytes, i, 24); i += 24;"); break; case FieldType.U8: writer.WriteLine("bytes[i++] = " + field.Name + ";"); break; case FieldType.S8: writer.WriteLine("bytes[i++] = (byte)" + field.Name + ";"); break; case FieldType.IPADDR: case FieldType.U32: case FieldType.S32: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 16) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 24) % 256);"); break; case FieldType.U64: writer.WriteLine("bytes[i++] = (byte)(" + field.Name + " % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 8) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 16) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 24) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 32) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 40) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 48) % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + " >> 56) % 256);"); break; case FieldType.Variable: writer.WriteLine("if(" + field.Name + " == null) { Console.WriteLine(\"Warning: " + field.Name + " is null, in \" + this.GetType()); }"); writer.Write(" "); if (field.Count == 1) { writer.WriteLine("bytes[i++] = (byte)" + field.Name + ".Length;"); } else { writer.WriteLine("bytes[i++] = (byte)(" + field.Name + ".Length % 256);"); writer.WriteLine(" bytes[i++] = (byte)((" + field.Name + ".Length >> 8) % 256);"); } writer.WriteLine(" Buffer.BlockCopy(" + field.Name + ", 0, bytes, i, " + field.Name + ".Length); " + "i += " + field.Name + ".Length;"); break; default: writer.WriteLine("!!! ERROR: Unhandled FieldType: " + field.Type.ToString() + " !!!"); break; } }