using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using Unity.Netcode;
using UnityEngine;
using Unity.Collections;
using System.Threading.Tasks;
namespace TcgEngine
{
///
/// Useful network static function
///
public class NetworkTool
{
//Serialize a [System.Serializable] into bytes
public static byte[] Serialize(T obj) where T : class
{
try
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
byte[] bytes = ms.ToArray();
ms.Close();
return bytes;
}
catch (Exception e)
{
Debug.LogError("Serialization error: " + e.Message);
return new byte[0];
}
}
//Deserialize a [System.Serializable] from bytes
public static T Deserialize(byte[] bytes) where T : class
{
try
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
ms.Write(bytes, 0, bytes.Length);
ms.Seek(0, SeekOrigin.Begin);
T obj = (T)bf.Deserialize(ms);
ms.Close();
return obj;
}
catch (Exception e)
{
Debug.LogError("Deserialization error: " + e.Message);
return null;
}
}
//Serialize a INetworkSerializable to bytes
public static byte[] NetSerialize(T obj, int size = 128) where T : INetworkSerializable, new()
{
if (obj == null)
return new byte[0];
try
{
FastBufferWriter writer = new FastBufferWriter(size, Allocator.Temp, TcgNetwork.MsgSizeMax);
writer.WriteNetworkSerializable(obj);
byte[] bytes = writer.ToArray();
writer.Dispose();
return bytes;
}
catch (Exception e)
{
Debug.LogError("Serialization error: " + e.Message);
return new byte[0];
}
}
//Deserialize a INetworkSerializable from bytes
public static T NetDeserialize(byte[] bytes) where T : INetworkSerializable, new()
{
if (bytes == null || bytes.Length == 0)
return default(T);
try
{
FastBufferReader reader = new FastBufferReader(bytes, Allocator.Temp);
reader.ReadNetworkSerializable(out T obj);
reader.Dispose();
return obj;
}
catch (Exception e)
{
Debug.LogError("Deserialization error: " + e.Message);
return default(T);
}
}
//Serialize an array using Netcode
public static void NetSerializeArray(BufferSerializer serializer, ref string[] array) where TS : IReaderWriter
{
if (serializer.IsReader)
{
int size = 0;
serializer.SerializeValue(ref size);
array = new string[size];
for (int i = 0; i < size; i++)
{
string val = "";
serializer.SerializeValue(ref val);
array[i] = val;
}
}
if (serializer.IsWriter)
{
int size = array.Length;
serializer.SerializeValue(ref size);
for (int i = 0; i < size; i++)
serializer.SerializeValue(ref array[i]);
}
}
//Serialize an array using Netcode
public static void NetSerializeArray(BufferSerializer serializer, ref T[] array) where T : INetworkSerializable, new() where TS : IReaderWriter
{
if (serializer.IsReader)
{
int size = 0;
serializer.SerializeValue(ref size);
array = new T[size];
for(int i=0; i 0)
return System.BitConverter.ToInt32(bytes, 0);
return 0;
}
public static byte[] SerializeUInt64(ulong data)
{
return System.BitConverter.GetBytes(data);
}
public static ulong DeserializeUInt64(byte[] bytes)
{
if (bytes != null && bytes.Length > 0)
return System.BitConverter.ToUInt64(bytes, 0);
return 0;
}
public static byte[] SerializeString(string data)
{
if(data != null)
return System.Text.Encoding.UTF8.GetBytes(data);
return new byte[0];
}
public static string DeserializeString(byte[] bytes)
{
if (bytes != null)
return System.Text.Encoding.UTF8.GetString(bytes);
return null;
}
public static string SerializeToString(T obj) where T : class
{
byte[] bytes = Serialize(obj);
return Convert.ToBase64String(bytes);
}
public static T DeserializeFromString(string str) where T : class
{
byte[] bytes = Convert.FromBase64String(str);
return Deserialize(bytes);
}
public static void SerializeObject(BufferSerializer serializer, ref T1 data) where T : IReaderWriter where T1 : class
{
string sdata = "";
if (serializer.IsWriter)
{
sdata = SerializeToString(data);
}
serializer.SerializeValue(ref sdata, true);
if (serializer.IsReader)
{
data = DeserializeFromString(sdata);
}
}
public static void SerializeDictionary(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T1 : unmanaged, IComparable, IConvertible, IComparable, IEquatable where T2 : unmanaged, IComparable, IConvertible, IComparable, IEquatable
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
T1 key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
T1 key = new T1();
T2 val = new T2();
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionaryEnum(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T1 : unmanaged, Enum where T2 : unmanaged, IComparable, IConvertible, IComparable, IEquatable
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
T1 key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
T1 key = new T1();
T2 val = new T2();
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionary(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T2 : unmanaged, IComparable, IConvertible, IComparable, IEquatable
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
string key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
string key = "";
T2 val = new T2();
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionary(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
string key = pair.Key;
string val = pair.Value;
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
string key = "";
string val = "";
serializer.SerializeValue(ref key);
serializer.SerializeValue(ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionaryNetObject(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T2 : INetworkSerializable, new()
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
string key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
serializer.SerializeNetworkSerializable(ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
string key = "";
T2 val = new T2();
serializer.SerializeValue(ref key);
serializer.SerializeNetworkSerializable(ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionaryNetObject(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T1 : unmanaged, IComparable, IConvertible, IComparable, IEquatable where T2 : INetworkSerializable, new()
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
T1 key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
serializer.SerializeNetworkSerializable(ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
T1 key = new T1();
T2 val = new T2();
serializer.SerializeValue(ref key);
serializer.SerializeNetworkSerializable(ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionaryObject(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T2 : class, new()
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
string key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
SerializeObject(serializer, ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
string key = "";
T2 val = new T2();
serializer.SerializeValue(ref key);
SerializeObject(serializer, ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionaryObject(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T1 : unmanaged, IComparable, IConvertible, IComparable, IEquatable where T2 : class, new()
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
T1 key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
SerializeObject(serializer, ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
T1 key = new T1();
T2 val = new T2();
serializer.SerializeValue(ref key);
SerializeObject(serializer, ref val);
data.Add(key, val);
}
}
}
public static void SerializeDictionaryEnumObject(BufferSerializer serializer, ref Dictionary data)
where T : IReaderWriter where T1 : unmanaged, Enum where T2 : class, new()
{
int count = data != null ? data.Count : 0;
serializer.SerializeValue(ref count);
if (serializer.IsWriter)
{
foreach (KeyValuePair pair in data)
{
T1 key = pair.Key;
T2 val = pair.Value;
serializer.SerializeValue(ref key);
SerializeObject(serializer, ref val);
}
}
if (serializer.IsReader)
{
data = new Dictionary();
for (int i = 0; i < count; i++)
{
T1 key = new T1();
T2 val = new T2();
serializer.SerializeValue(ref key);
SerializeObject(serializer, ref val);
data.Add(key, val);
}
}
}
public static ushort Hash16(string string_id)
{
return (ushort) string_id.GetHashCode();
}
public static uint Hash32(string string_id)
{
return (uint) string_id.GetHashCode();
}
public static ulong Hash64(string string_id)
{
string s1 = string_id.Substring(0, string_id.Length / 2);
string s2 = string_id.Substring(string_id.Length / 2);
ulong id = (uint)s1.GetHashCode();
id = id << 32;
id = id | (uint)s2.GetHashCode();
return id;
}
public static IPAddress ResolveDns(string url)
{
#if !UNITY_WEBGL
IPAddress[] ips = Dns.GetHostAddresses(url);
if (ips != null && ips.Length > 0)
return ips[0];
#else
Debug.LogWarning("Dns.GetHostAddresses not working on WebGL, try using direct IP address instead of host url");
#endif
return null;
}
//Converts a host (either domain or IP) into an IP
public static string HostToIP(string host)
{
bool success = IPAddress.TryParse(host, out IPAddress address);
if (success)
return address.ToString(); //Already an IP
IPAddress ip = ResolveDns(host); //Not an IP, resolve DNS
if (ip != null)
return ip.ToString();
return "";
}
public static string GetLocalIp()
{
//Get Internal IP
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in hostEntry.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return "";
}
public static async Task GetOnlineIp()
{
//Get External IP
WebResponse res = await WebTool.SendRequest("https://api.ipify.org");
if (res.success)
return res.data;
else
return null;
}
}
}