#if NET5_0_OR_GREATER #else using UnityEngine; #endif using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Cysharp.Threading.Tasks; using MemoryPack; using Microsoft.SqlServer.Server; #if NET5_0_OR_GREATER using Microsoft.SqlServer.Server; #endif using Newtonsoft.Json; namespace BITKit { public class BITBinary { private static readonly Dictionary netReaders = new(); public static readonly List serializableTypes = new(); public static async UniTask Start() { netReaders.Clear(); #if NET5_0_OR_GREATER serializableTypes.Clear(); #endif var stringBuilder = new StringBuilder(); foreach (var x in await ReflectionHelper.GetInstances()) { var typeName = x.GetMessageType().FullName; if (typeName == null) continue; netReaders.Add(typeName, x); stringBuilder.AppendLine(typeName); } var serializes = await ReflectionHelper.GetInstances(); #if NET5_0_OR_GREATER #else serializes = serializes.Where(x => x.GetType().IsAssignableFrom(typeof(UnityEngine.Object)) is false); #endif foreach (var x in serializes) { serializableTypes.Add(x.GetType()); //BIT4Log.Log($"已注册类型:{x.GetType().FullName}"); stringBuilder.AppendLine(x.GetType().FullName); } BIT4Log.Log($"已注册类型:\n{stringBuilder}"); } public static T Read(byte[] buffer) => (T)ReadAsValue(buffer); public static object ReadAsValue(byte[] buffer) { using var ms = new MemoryStream(buffer); using var reader = new BinaryReader(ms); return Read(reader); } public static object Read(BinaryReader reader) { // 检测是否为数组 if (reader.ReadBoolean()) { //读取数组类型的名称 var arrayTypeName = reader.ReadString(); //获取数组类型 var arrayType = BITSharp.GetTypeFromFullName(arrayTypeName); if(string.IsNullOrEmpty(arrayTypeName) || arrayType is null) throw new Exception($"未找到类型:{arrayTypeName}"); //创建数组实例 var arrayLength = reader.ReadInt32(); var array = Array.CreateInstance(arrayType, arrayLength); //循环Reader for (var i = 0; i < array.Length; i++) { //设置值 array.SetValue(ReadInternel(reader),i); } //返回数组 return array; } return ReadInternel(reader); object ReadInternel(BinaryReader reader) { if (reader.ReadBoolean() is false) { return null; } var typeName = reader.ReadString(); if (netReaders.TryGetValue(typeName, out var netReader)) return netReader.ReadBinaryAsObject(reader); var type = BITSharp.GetTypeFromFullName(typeName); if (type is null) { throw new Exception($"反序列化时未找到类型:{typeName}"); } var instance = System.Activator.CreateInstance(type); if (instance is IBinarySerialize serialize) { serialize.Read(reader); return instance; } if (BITSharp.TryGetTypeFromFullName(typeName, out type)) { return MemoryPackSerializer.Deserialize(type, reader.ReadBytes(reader.ReadInt32())); } // var json = reader.ReadString(); // if (string.IsNullOrEmpty(json)) // { // throw new Exception($"从二进制中读取的json值为空"); // } // // try // { // if (BITSharp.TryGetTypeFromFullName(typeName, out type)) // return JsonConvert.DeserializeObject(json, type); // } // catch (Exception e) // { // BIT4Log.Warning($"反序列化失败,类型:{typeName},值:\n{json}"); // BIT4Log.LogException(e); // } throw new Exception("未找到读取该二进制的BinaryReader"); } } public static byte[] WriteAsBytes(object value) { using var ms = new MemoryStream(); using var writer = new BinaryWriter(ms); Write(writer, value); return ms.ToArray(); } public static void Write(BinaryWriter writer, object value) { try { if (value is not string && value is IList enumerable) { var pars = enumerable.Cast().ToArray(); writer.Write(true); writer.Write(value.GetType().GetElementType()!.FullName!); writer.Write(pars.Length); foreach (var obj in pars) { WriteInterel(writer, obj); } } else { writer.Write(false); WriteInterel(writer,value); } return; void WriteInterel(BinaryWriter writer, object value) { if (value is null) { writer.Write(false); return; } var typeName = value.GetType().FullName; writer.Write(typeName!); if (netReaders.TryGetValue(typeName, out var netReader)) { netReader.WriteBinaryAsObject(writer,value); } else if (value is IBinarySerialize serialize) { serialize.Write(writer); } else { try { var bytes = MemoryPackSerializer.Serialize(value.GetType(),value); writer.Write(bytes.Length); writer.Write(bytes); //writer.Write(JsonConvert.SerializeObject(value)); } catch (Exception) { BIT4Log.Warning(typeName); throw; } } } } catch (Exception e) { throw; } } public static bool IsSupport(object obj) => IsSupport(obj.GetType().FullName); public static bool IsSupport(Type type) => IsSupport(type.FullName); public static bool IsSupport() => IsSupport(typeof(T).FullName); public static bool IsSupport(string typeName) { return netReaders.ContainsKey(typeName) || serializableTypes.Any(x => x.FullName == typeName); } public static bool TryWrite(object obj, out byte[] bytes) { bytes = null; if (IsSupport(obj)) { bytes = WriteAsBytes(obj); return true; } else { using var ms = new MemoryStream(); using var writer = new BinaryWriter(ms); try { writer.Write(obj!.GetType()!.FullName!); var json = JsonHelper.Get(obj); writer.Write(json); } catch (Exception e) { BIT4Log.Log(e); return false; } } return true; //bytes = null; //return false; } } }