186 lines
5.7 KiB
C#
186 lines
5.7 KiB
C#
#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<string, INetMessageReader> netReaders = new();
|
|
#if NET5_0_OR_GREATER
|
|
public static readonly List<Type> 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<INetMessageReader>())
|
|
{
|
|
var typeName = x.GetMessageType().FullName;
|
|
if (typeName == null) continue;
|
|
netReaders.Add(typeName, x);
|
|
BIT4Log.Log<BITBinary>($"已注册类型:{typeName}");
|
|
}
|
|
#if NET5_0_OR_GREATER
|
|
var serializes = await ReflectionHelper.GetInstances<IBinarySerialize>();
|
|
#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<BITBinary>($"已注册类型:{x.GetType().FullName}");
|
|
// }
|
|
}
|
|
|
|
public static object Read<T>(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<BITBinary>($"反序列化失败,类型:{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<T>() => 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;
|
|
}
|
|
}
|
|
} |