using BOTWM.Server.DataTypes; using BOTWM.Server.DTO; using Newtonsoft.Json; using System.Text; namespace JSONCompressor { public enum MessageType { error, ping, connect, update, disconnect } public class JSONBuilder { byte[] Data; List ByteData; public Tuple BuildFromBytes(byte[] data) { Data = data; MessageType messageType = (MessageType)(int)GetArray(1)[0]; object Object = null; if (messageType == MessageType.connect) { Object = GetJson(typeof(ConnectDTO)); } else if (messageType == MessageType.update) { string SerializedJson = JsonConvert.SerializeObject(GetJson(typeof(ClientDTO))); Object = JsonConvert.DeserializeObject(SerializedJson); } else if (messageType == MessageType.ping) { Object = Encoding.UTF8.GetString(Data).Replace("\0", ""); } else if (messageType == MessageType.disconnect) { Object = Encoding.UTF8.GetString(Data).Replace("\0", ""); } return new Tuple(messageType, Object); } public byte[] BuildArrayOfBytes(object original, bool debug = false) { ByteData = new List(); GetByteData(original); if (!debug) ByteData.InsertRange(0, BitConverter.GetBytes((short)ByteData.Count)); return ByteData.ToArray(); } private object GetJson(Type original) { object value = null; if (original == typeof(int)) value = BitConverter.ToInt32(GetArray(4), 0); else if (original == typeof(float)) value = BitConverter.ToSingle(GetArray(4), 0); else if (original == typeof(bool)) value = GetArray(1)[0] == 0x0 ? false : true; else if (original == typeof(byte)) value = GetArray(1)[0]; else if (original == typeof(short)) value = BitConverter.ToInt16(GetArray(2), 0); else if (original == typeof(string)) { int stringSize = GetArray(1)[0]; value = Encoding.UTF8.GetString(GetArray(stringSize)); } else if (original == typeof(Vec3f)) { Vec3f result = new Vec3f(); result.x = BitConverter.ToSingle(GetArray(4), 0); result.y = BitConverter.ToSingle(GetArray(4), 0); result.z = BitConverter.ToSingle(GetArray(4), 0); value = result; } else if (original == typeof(Quaternion)) { Quaternion result = new Quaternion(); result.q1 = BitConverter.ToSingle(GetArray(4), 0); result.q2 = BitConverter.ToSingle(GetArray(4), 0); result.q3 = BitConverter.ToSingle(GetArray(4), 0); result.q4 = BitConverter.ToSingle(GetArray(4), 0); value = result; } else if (original == typeof(CharacterLocation)) { CharacterLocation result = new CharacterLocation(); result.Map = GetArray(1)[0]; result.Section = GetArray(1)[0]; value = result; } else if (original == typeof(CharacterEquipment)) { CharacterEquipment result = new CharacterEquipment(); result.WType = GetArray(1)[0]; result.Sword = BitConverter.ToInt16(GetArray(2), 0); result.Shield = BitConverter.ToInt16(GetArray(2), 0); result.Bow = BitConverter.ToInt16(GetArray(2), 0); result.Head = BitConverter.ToInt16(GetArray(2), 0); result.Upper = BitConverter.ToInt16(GetArray(2), 0); result.Lower = BitConverter.ToInt16(GetArray(2), 0); value = result; } else if (original.IsGenericType && typeof(System.Collections.IList).IsAssignableFrom(original)) { int ListSize = GetArray(1)[0]; List result = new List(); for (int i = 0; i < ListSize; i++) { result.Add(GetJson(original.GetGenericArguments()[0])); } value = result; } else if (original.IsGenericType && typeof(System.Collections.IDictionary).IsAssignableFrom(original)) { int DictionarySize = GetArray(1)[0]; Dictionary result = new Dictionary(); for (int i = 0; i < DictionarySize; i++) { object Key = GetJson(original.GetGenericArguments()[0]); object Value = GetJson(original.GetGenericArguments()[1]); result.Add(Key, Value); } value = result; } else if (original == typeof(ConnectDTO)) { ConnectDTO result = new ConnectDTO(); int stringSize = GetArray(1)[0]; result.Name = Encoding.UTF8.GetString(GetArray(stringSize)); stringSize = GetArray(1)[0]; result.Password = Encoding.UTF8.GetString(GetArray(stringSize)); result.ModelData = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(Data)); value = result; } else { Dictionary result = new Dictionary(); foreach (var item in original.GetFields()) { if (item.Name == "Schedule") continue; var res = GetJson(item.FieldType); result.Add(item.Name, res); } value = result; } return value; } private void GetByteData(object original) { if (original.GetType() == typeof(int)) AddBytes(BitConverter.GetBytes((int)original)); else if (original.GetType() == typeof(float)) AddBytes(BitConverter.GetBytes((float)original)); else if (original.GetType() == typeof(bool)) ByteData.Add((bool)original ? (byte)1 : (byte)0); else if (original.GetType() == typeof(byte)) ByteData.Add((byte)original); else if (original.GetType() == typeof(short)) AddBytes(BitConverter.GetBytes((short)original)); else if (original.GetType() == typeof(string)) { ByteData.Add((byte)((string)original).Length); AddBytes(Encoding.UTF8.GetBytes((string)original), false); } else if (original.GetType() == typeof(Vec3f)) { Vec3f originalVec3f = (Vec3f)original; AddBytes(BitConverter.GetBytes(originalVec3f.x)); AddBytes(BitConverter.GetBytes(originalVec3f.y)); AddBytes(BitConverter.GetBytes(originalVec3f.z)); } else if (original.GetType() == typeof(Quaternion)) { Quaternion originalQuaternion = (Quaternion)original; AddBytes(BitConverter.GetBytes(originalQuaternion.q1)); AddBytes(BitConverter.GetBytes(originalQuaternion.q2)); AddBytes(BitConverter.GetBytes(originalQuaternion.q3)); AddBytes(BitConverter.GetBytes(originalQuaternion.q4)); } else if (original.GetType() == typeof(CharacterLocation)) { CharacterLocation originalLocation = (CharacterLocation)original; ByteData.Add((byte)originalLocation.Map); ByteData.Add((byte)originalLocation.Section); } else if (original.GetType() == typeof(CharacterEquipment)) { CharacterEquipment originalEquipment = (CharacterEquipment)original; //AddBytes(BitConverter.GetBytes(originalEquipment.WType)); ByteData.Add((byte)originalEquipment.WType); AddBytes(BitConverter.GetBytes(originalEquipment.Sword)); AddBytes(BitConverter.GetBytes(originalEquipment.Shield)); AddBytes(BitConverter.GetBytes(originalEquipment.Bow)); AddBytes(BitConverter.GetBytes(originalEquipment.Head)); AddBytes(BitConverter.GetBytes(originalEquipment.Upper)); AddBytes(BitConverter.GetBytes(originalEquipment.Lower)); } else if (original.GetType().IsGenericType && typeof(System.Collections.IList).IsAssignableFrom(original.GetType())) { typeof(JSONBuilder).GetMethod("AddListData").MakeGenericMethod(original.GetType().GenericTypeArguments).Invoke(this, new[] { original }); } else if (original.GetType().IsGenericType && typeof(System.Collections.IDictionary).IsAssignableFrom(original.GetType())) { typeof(JSONBuilder).GetMethod("AddDictData").MakeGenericMethod(original.GetType().GenericTypeArguments).Invoke(this, new[] { original }); } else { foreach (var item in original.GetType().GetFields()) GetByteData(item.GetValue(original)); } } private byte[] GetArray(int length, bool Reverse = true) { byte[] bytes = Data.Take(length).ToArray(); Data = Data.Skip(length).ToArray(); return bytes; } public void AddListData(object original) { List OriginalList = (List)original; ByteData.Add((byte)OriginalList.Count); for (int i = 0; i < OriginalList.Count; i++) { GetByteData(OriginalList[i]); } } public void AddDictData(object original) { Dictionary OriginalDict = (Dictionary)original; ByteData.Add((byte)OriginalDict.Count); for (int i = 0; i < OriginalDict.Count; i++) { GetByteData(OriginalDict.ElementAt(i).Key); GetByteData(OriginalDict.ElementAt(i).Value); } } private void AddBytes(byte[] bytes, bool Reverse = true) { ByteData.AddRange(bytes); } } }