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; } } }