mirror of
https://github.com/MilkBarModding/MilkBarLauncher.git
synced 2025-06-16 20:20:56 +00:00
319 lines
11 KiB
C#
319 lines
11 KiB
C#
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<byte> ByteData;
|
|
|
|
public Tuple<MessageType, object> 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<ClientDTO>(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>(messageType, Object);
|
|
}
|
|
|
|
public byte[] BuildArrayOfBytes(object original, bool debug = false)
|
|
{
|
|
ByteData = new List<byte>();
|
|
|
|
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<object> result = new List<object>();
|
|
|
|
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<object, object> result = new Dictionary<object, object>();
|
|
|
|
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<ModelDataDTO>(Encoding.UTF8.GetString(Data));
|
|
|
|
value = result;
|
|
}
|
|
else
|
|
{
|
|
|
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
|
|
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<T>(object original)
|
|
{
|
|
|
|
List<T> OriginalList = (List<T>)original;
|
|
|
|
ByteData.Add((byte)OriginalList.Count);
|
|
|
|
for (int i = 0; i < OriginalList.Count; i++)
|
|
{
|
|
GetByteData(OriginalList[i]);
|
|
}
|
|
|
|
}
|
|
|
|
public void AddDictData<K, V>(object original)
|
|
{
|
|
Dictionary<K, V> OriginalDict = (Dictionary<K, V>)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);
|
|
}
|
|
}
|
|
}
|