#if NET5_0_OR_GREATER #else using UnityEngine; #endif using System; using System.Collections.Generic; using System.IO; using System.Linq; using Cysharp.Threading.Tasks; #if NET5_0_OR_GREATER using Microsoft.SqlServer.Server; #endif using Newtonsoft.Json; namespace BITKit { public class BITBinary { private static readonly Dictionary netReaders = new(); #if NET5_0_OR_GREATER public static readonly List serializableTypes = new(); #endif public static async UniTask Start() { netReaders.Clear(); #if NET5_0_OR_GREATER serializableTypes.Clear(); #endif foreach (var x in await ReflectionHelper.GetInstances()) { var typeName = x.GetMessageType().FullName; if (typeName == null) continue; netReaders.Add(typeName, x); BIT4Log.Log($"已注册类型:{typeName}"); } #if NET5_0_OR_GREATER var serializes = await ReflectionHelper.GetInstances(); #else #endif // #if NET5_0_OR_GREATER // #else // serializes = serializes.Where(x => x is not UnityEngine.Object); // #endif // foreach (var x in serializes) // { // serializableTypes.Add(x.GetType()); // BIT4Log.Log($"已注册类型:{x.GetType().FullName}"); // } } public static object 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) { var isObjects = reader.ReadBoolean(); if (isObjects) { var objs = new object[reader.ReadInt32()]; for (var i = 0; i < objs.Length; i++) { objs[i] = Read(reader); } return objs.ToArray(); } var typeName = reader.ReadString(); if (netReaders.TryGetValue(typeName, out var netReader)) return netReader.ReadBinaryAsObject(reader); var json = reader.ReadString(); if (string.IsNullOrEmpty(json)) { throw new Exception($"从二进制中读取的json值为空"); } try { if (BITSharp.TryGetTypeFromFullName(typeName, out var 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) { if (value is object[] objects) { if (objects.Length is 1) { writer.Write(false); value = objects[0]; } else { writer.Write(true); writer.Write(objects.Length); foreach (var obj in objects) { Write(writer,obj); } } } else { writer.Write(false); } var typeName = value.GetType().FullName; writer.Write(typeName!); if (netReaders.TryGetValue(typeName, out var netReader)) { netReader.WriteBinaryAsObject(writer,value); } else { writer.Write(JsonConvert.SerializeObject(value)); } } 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) { if (netReaders.ContainsKey(typeName)) { return true; } #if NET5_0_OR_GREATER else if (serializableTypes.Any(x => x.FullName == typeName)) { return true; } #endif return false; } 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; } } }