7502018d20
There is an asset in the store I grabbed. the coding is WAY above my head, I got about half of it and integrated and adapted what I can to it. im going as far as I can with it and ill come back in a few month when I understand t better.
219 lines
8.6 KiB
C#
219 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
namespace UnityEngine.AddressableAssets.Utility
|
|
{
|
|
internal static class SerializationUtilities
|
|
{
|
|
internal enum ObjectType
|
|
{
|
|
AsciiString,
|
|
UnicodeString,
|
|
UInt16,
|
|
UInt32,
|
|
Int32,
|
|
Hash128,
|
|
Type,
|
|
JsonObject
|
|
}
|
|
|
|
internal static int ReadInt32FromByteArray(byte[] data, int offset)
|
|
{
|
|
return data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24);
|
|
}
|
|
|
|
internal static int WriteInt32ToByteArray(byte[] data, int val, int offset)
|
|
{
|
|
data[offset] = (byte)(val & 0xFF);
|
|
data[offset + 1] = (byte)((val >> 8) & 0xFF);
|
|
data[offset + 2] = (byte)((val >> 16) & 0xFF);
|
|
data[offset + 3] = (byte)((val >> 24) & 0xFF);
|
|
return offset + 4;
|
|
}
|
|
/*
|
|
internal static ushort ReadUInt16FromByteArray(byte[] data, int offset)
|
|
{
|
|
return (ushort)(data[offset] | (data[offset + 1] << 8));
|
|
}
|
|
|
|
internal static int WriteUInt16ToByteArray(byte[] data, ushort val, int offset)
|
|
{
|
|
data[offset] = (byte)(val & 0xFF);
|
|
data[offset + 1] = (byte)((val >> 8) & 0xFF);
|
|
return offset + 2;
|
|
}*/
|
|
/// <summary>
|
|
/// Deserializes an object from an array at a specified index. Supported types are ASCIIString, UnicodeString, UInt16, UInt32, Int32, Hash128, JsonObject
|
|
/// </summary>
|
|
/// <param name="keyData">The array of bytes for the object. The first byte is the ObjectType. The rest depends on the type.</param>
|
|
/// <param name="dataIndex">The index of the first byte of the data.</param>
|
|
/// <returns>The deserialized object.</returns>
|
|
internal static object ReadObjectFromByteArray(byte[] keyData, int dataIndex)
|
|
{
|
|
try
|
|
{
|
|
ObjectType keyType = (ObjectType)keyData[dataIndex];
|
|
dataIndex++;
|
|
switch (keyType)
|
|
{
|
|
case ObjectType.UnicodeString:
|
|
{
|
|
var dataLength = BitConverter.ToInt32(keyData, dataIndex);
|
|
return Encoding.Unicode.GetString(keyData, dataIndex + 4, dataLength);
|
|
}
|
|
case ObjectType.AsciiString:
|
|
{
|
|
var dataLength = BitConverter.ToInt32(keyData, dataIndex);
|
|
return Encoding.ASCII.GetString(keyData, dataIndex + 4, dataLength);
|
|
}
|
|
case ObjectType.UInt16: return BitConverter.ToUInt16(keyData, dataIndex);
|
|
case ObjectType.UInt32: return BitConverter.ToUInt32(keyData, dataIndex);
|
|
case ObjectType.Int32: return BitConverter.ToInt32(keyData, dataIndex);
|
|
case ObjectType.Hash128: return Hash128.Parse(Encoding.ASCII.GetString(keyData, dataIndex + 1, keyData[dataIndex]));
|
|
case ObjectType.Type: return Type.GetTypeFromCLSID(new Guid(Encoding.ASCII.GetString(keyData, dataIndex + 1, keyData[dataIndex])));
|
|
case ObjectType.JsonObject:
|
|
{
|
|
int assemblyNameLength = keyData[dataIndex];
|
|
dataIndex++;
|
|
string assemblyName = Encoding.ASCII.GetString(keyData, dataIndex, assemblyNameLength);
|
|
dataIndex += assemblyNameLength;
|
|
|
|
int classNameLength = keyData[dataIndex];
|
|
dataIndex++;
|
|
string className = Encoding.ASCII.GetString(keyData, dataIndex, classNameLength);
|
|
dataIndex += classNameLength;
|
|
int jsonLength = BitConverter.ToInt32(keyData, dataIndex);
|
|
dataIndex += 4;
|
|
string jsonText = Encoding.Unicode.GetString(keyData, dataIndex, jsonLength);
|
|
var assembly = Assembly.Load(assemblyName);
|
|
var t = assembly.GetType(className);
|
|
return JsonUtility.FromJson(jsonText, t);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogException(ex);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write an object to a byte array
|
|
/// </summary>
|
|
/// <param name="obj">The object to write.</param>
|
|
/// <param name="buffer">The list of bytes to write to.</param>
|
|
/// <returns>The number of bytes written.</returns>
|
|
internal static int WriteObjectToByteList(object obj, List<byte> buffer)
|
|
{
|
|
var objectType = obj.GetType();
|
|
if (objectType == typeof(string))
|
|
{
|
|
string str = obj as string;
|
|
if (str == null)
|
|
str = string.Empty;
|
|
byte[] tmp = Encoding.Unicode.GetBytes(str);
|
|
byte[] tmp2 = Encoding.ASCII.GetBytes(str);
|
|
if (Encoding.Unicode.GetString(tmp) == Encoding.ASCII.GetString(tmp2))
|
|
{
|
|
buffer.Add((byte)ObjectType.AsciiString);
|
|
buffer.AddRange(BitConverter.GetBytes(tmp2.Length));
|
|
buffer.AddRange(tmp2);
|
|
return tmp2.Length + 5;
|
|
}
|
|
|
|
buffer.Add((byte)ObjectType.UnicodeString);
|
|
buffer.AddRange(BitConverter.GetBytes(tmp.Length));
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 5;
|
|
}
|
|
|
|
if (objectType == typeof(UInt32))
|
|
{
|
|
byte[] tmp = BitConverter.GetBytes((UInt32)obj);
|
|
buffer.Add((byte)ObjectType.UInt32);
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 1;
|
|
}
|
|
|
|
if (objectType == typeof(UInt16))
|
|
{
|
|
byte[] tmp = BitConverter.GetBytes((UInt16)obj);
|
|
buffer.Add((byte)ObjectType.UInt16);
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 1;
|
|
}
|
|
|
|
if (objectType == typeof(Int32))
|
|
{
|
|
byte[] tmp = BitConverter.GetBytes((Int32)obj);
|
|
buffer.Add((byte)ObjectType.Int32);
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 1;
|
|
}
|
|
|
|
if (objectType == typeof(int))
|
|
{
|
|
byte[] tmp = BitConverter.GetBytes((UInt32)obj);
|
|
buffer.Add((byte)ObjectType.UInt32);
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 1;
|
|
}
|
|
|
|
if (objectType == typeof(Hash128))
|
|
{
|
|
var guid = (Hash128)obj;
|
|
byte[] tmp = Encoding.ASCII.GetBytes(guid.ToString());
|
|
buffer.Add((byte)ObjectType.Hash128);
|
|
buffer.Add((byte)tmp.Length);
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 2;
|
|
}
|
|
|
|
if (objectType == typeof(Type))
|
|
{
|
|
byte[] tmp = objectType.GUID.ToByteArray();
|
|
buffer.Add((byte)ObjectType.Type);
|
|
buffer.Add((byte)tmp.Length);
|
|
buffer.AddRange(tmp);
|
|
return tmp.Length + 2;
|
|
}
|
|
|
|
var attrs = objectType.GetCustomAttributes(typeof(SerializableAttribute), true);
|
|
if (attrs.Length == 0)
|
|
return 0;
|
|
int length = 0;
|
|
buffer.Add((byte)ObjectType.JsonObject);
|
|
length++;
|
|
|
|
//write assembly name
|
|
byte[] tmpAssemblyName = Encoding.ASCII.GetBytes(objectType.Assembly.FullName);
|
|
buffer.Add((byte)tmpAssemblyName.Length);
|
|
length++;
|
|
buffer.AddRange(tmpAssemblyName);
|
|
length += tmpAssemblyName.Length;
|
|
|
|
//write class name
|
|
var objName = objectType.FullName;
|
|
if (objName == null)
|
|
objName = string.Empty;
|
|
byte[] tmpClassName = Encoding.ASCII.GetBytes(objName);
|
|
buffer.Add((byte)tmpClassName.Length);
|
|
length++;
|
|
buffer.AddRange(tmpClassName);
|
|
length += tmpClassName.Length;
|
|
|
|
//write json data
|
|
byte[] tmpJson = Encoding.Unicode.GetBytes(JsonUtility.ToJson(obj));
|
|
buffer.AddRange(BitConverter.GetBytes(tmpJson.Length));
|
|
length += 4;
|
|
buffer.AddRange(tmpJson);
|
|
length += tmpJson.Length;
|
|
return length;
|
|
}
|
|
}
|
|
}
|