该项目的目的是同时测试和演示来自 Unity DOTS 技术堆栈的多个新包。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

230 行
7.0 KiB

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Unity.Sample.Core;
using UnityEngine;
public static class NetworkUtils
{
public static float UInt32ToFloat(uint value) { return new UIntFloat() { intValue = value }.floatValue; }
public static uint FloatToUInt32(float value) { return new UIntFloat() { floatValue = value }.intValue; }
public static Color32 Uint32ToColor32(uint value) { return new Color32((byte)(value & 0xff), (byte)((value >> 8) & 0xff), (byte)((value >> 16) & 0xff), (byte)((value >> 24) & 0xff)); }
public static UInt32 Color32ToUInt32(Color32 value) { return (uint)value.r | (uint)(value.g << 8) | (uint)(value.b << 16) | (uint)(value.a << 24); }
public static double DoubleToUInt64(ulong value) { return new ULongDouble() { longValue = value }.doubleValue; }
public static ulong UInt64ToDouble(double value) { return new ULongDouble() { doubleValue = value }.longValue; }
static readonly string hexdigits = "0123456789ABCDEF";
public static string HexString(byte[] values, int count)
{
var d = new char[count * 2];
for (int i = 0; i < count; i++)
{
d[i * 2 + 0] = hexdigits[values[i] >> 4];
d[i * 2 + 1] = hexdigits[values[i] & 0xf];
}
return new string(d) + " (" + count + ")";
}
static NetworkUtils()
{
stopwatch.Start();
}
public static System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
[StructLayout(LayoutKind.Explicit)]
struct UIntFloat
{
[FieldOffset(0)]
public float floatValue;
[FieldOffset(0)]
public uint intValue;
}
[StructLayout(LayoutKind.Explicit)]
struct ULongDouble
{
[FieldOffset(0)]
public double doubleValue;
[FieldOffset(0)]
public ulong longValue;
}
public static int CalculateRequiredBits(long min, long max)
{
return (min == max) ? 0 : (int)Math.Log(max - min, 2) + 1;
}
public static void MemCopy(byte[] src, int srcIndex, byte[] dst, int dstIndex, int count)
{
for (int i = 0; i < count; ++i)
dst[dstIndex++] = src[srcIndex++];
}
public static int MemCmp(byte[] a, int aIndex, byte[] b, int bIndex, int count)
{
for (int i = 0; i < count; ++i)
{
var diff = b[bIndex++] - a[aIndex++];
if (diff != 0)
return diff;
}
return 0;
}
public static int MemCmp(uint[] a, int aIndex, uint[] b, int bIndex, int count)
{
for (int i = 0; i < count; ++i)
{
var diff = b[bIndex++] - a[aIndex++];
if (diff != 0)
return (int)diff;
}
return 0;
}
public static uint SimpleHash(uint[] array, int count)
{
uint hash = 0;
for (int i = 0; i < count; i++)
{
hash = hash * 179 + array[i] + 1;
}
return hash;
}
public static uint SimpleHashStreaming(uint old_hash, uint value)
{
return old_hash * 179 + value + 1;
}
public static bool EndpointParse(string endpoint, out IPAddress address, out int port, int defaultPort)
{
string address_part;
address = null;
port = 0;
if (endpoint.Contains(":"))
{
int.TryParse(endpoint.AfterLast(":"), out port);
address_part = endpoint.BeforeFirst(":");
}
else
address_part = endpoint;
if (port == 0)
port = defaultPort;
// Resolve in case we got a hostname
var resolvedAddress = System.Net.Dns.GetHostAddresses(address_part);
foreach (var r in resolvedAddress)
{
if (r.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
// Pick first ipv4
address = r;
return true;
}
}
return false;
}
public static List<string> GetLocalInterfaceAddresses()
{
// Useful to print 'best guess' for local ip, so...
List<NetworkInterface> interfaces = new List<NetworkInterface>();
List<string> addresses = new List<string>();
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.OperationalStatus != OperationalStatus.Up)
continue;
var type = item.NetworkInterfaceType;
if (type != NetworkInterfaceType.Ethernet && type != NetworkInterfaceType.Wireless80211)
continue;
interfaces.Add(item);
}
// Sort interfaces so those with most gateways are first. Attempting to guess what is the 'main' ip address
interfaces.Sort((a, b) => { return b.GetIPProperties().GatewayAddresses.Count.CompareTo(a.GetIPProperties().GatewayAddresses.Count); });
foreach (NetworkInterface item in interfaces)
{
try
{
foreach (UnicastIPAddressInformation addr in item.GetIPProperties().UnicastAddresses)
{
if (addr.Address.AddressFamily != AddressFamily.InterNetwork)
continue;
addresses.Add(addr.Address.ToString());
}
}
catch (System.Exception e)
{
// NOTE : For some reason this can throw marshal exception in the interop
// to native network code on some computers (when running player but not in editor)?
GameDebug.Log("Error " + e.Message + " while getting IP properties for " + item.Description);
}
}
return addresses;
}
}
class ByteArrayComp : IEqualityComparer<byte[]>, IComparer<byte[]>
{
public static readonly ByteArrayComp instance = new ByteArrayComp();
public int Compare(byte[] x, byte[] y)
{
if (x == null || y == null)
throw new ArgumentNullException("Trying to compare array with null");
var xl = x.Length;
var yl = y.Length;
if (xl != yl)
return yl - xl;
for (int i = 0; i < xl; i++)
{
var d = y[i] - x[i];
if (d != 0)
return d;
}
return 0;
}
public bool Equals(byte[] x, byte[] y)
{
return Compare(x, y) == 0;
}
public int GetHashCode(byte[] x)
{
if (x == null)
throw new ArgumentNullException("Trying to get hash of null");
var xl = x.Length;
if (xl >= 4)
return (int)(x[0] + (x[1] << 8) + (x[2] << 16) + (x[3] << 24));
else
return 0;
}
}
public class Aggregator
{
const int k_WindowSize = 120;
public float previousValue;
public FloatRollingAverage graph = new FloatRollingAverage(k_WindowSize);
public void Update(float value)
{
graph.Update(value - previousValue);
previousValue = value;
}
}