Initial commit: Client Doc docs Server Tools

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ud18010
2026-07-10 10:24:29 +08:00
co-authored by Cursor
commit 7e35d8da31
3374 changed files with 680813 additions and 0 deletions
@@ -0,0 +1,526 @@
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
namespace XGame
{
public class Type_Null
{
public static int Reserve = 0;
}
public static partial class Utility
{
//private static float FLOAT_PRECISION = 1e-5f;
private static Dictionary<string, int> sActorIdDic = new Dictionary<string, int>();
private static Dictionary<string, Type> sTypeDic = new Dictionary<string, Type>();
private static Dictionary<string, Assembly> Asms = new Dictionary<string, Assembly>();
private static Type typeNull = typeof(Type_Null);
public static int GenClientNameId(string actorTypeName)
{
if (sActorIdDic.ContainsKey(actorTypeName) == false)
{
sActorIdDic.Add(actorTypeName, 0);
}
++sActorIdDic[actorTypeName];
return sActorIdDic[actorTypeName];
}
static Type SuperGetType(string sTypeName)
{
Type typeValue;
if (sTypeDic.TryGetValue(sTypeName, out typeValue))
{
if (typeValue == typeNull)
return null;
else
return typeValue;
}
else
{
typeValue = Type.GetType(sTypeName);//底包的类型有就不用下面的麻烦代码
if (typeValue != null)
{
sTypeDic[sTypeName] = typeValue;
//Debug.Log($"SuperGetType sTypeDic 1 : {sTypeName}");
return typeValue;
}
Assembly[] foundAsms = null;
if (Asms.Count == 0)
{
foundAsms = AppDomain.CurrentDomain.GetAssemblies();
foreach (var asm in foundAsms)
{
//只检查GYFramework 和Assembly-CSharp 热更相关的dll
//Debug.Log($"SuperGetType : {sTypeName} ({asm.GetName().Name})");
string asmName = asm.GetName().Name;
if (asmName == "GYFramework" || asmName == "Assembly-CSharp")
{
Asms[asmName] = asm;
}
}
}
foreach (var asm in Asms)
{
typeValue = asm.Value.GetType(sTypeName);
if (typeValue != null)
{
sTypeDic[sTypeName] = typeValue;
//Debug.Log($"SuperGetType sTypeDic 2 : {sTypeName}");
return typeValue;
}
}
//最后全量查找
if (null == foundAsms)
{
foundAsms = AppDomain.CurrentDomain.GetAssemblies();
}
foreach (var asm in foundAsms)
{
string asmName = asm.GetName().Name;
typeValue = asm.GetType(sTypeName);
if (typeValue != null)
{
Asms[asmName] = asm;
sTypeDic[sTypeName] = typeValue;
//Debug.Log($"SuperGetType sTypeDic 3: {sTypeName}");
return typeValue;
}
}
sTypeDic[sTypeName] = typeNull;
//Debug.Log($"SuperGetType Error : {sTypeName} == null");
}
return null;
}
public static Type GetTypeByTypeName(string typeName)
{
System.Type type = SuperGetType(typeName);//Type.GetType(typeName);//
if (null == type)
{
string newTypeName = "XGame" + "." + typeName;
type = SuperGetType(newTypeName); //Type.GetType(newTypeName);//
//if (null == type)
//{
// newTypeName = "XGame" + "." + typeName;
// type = SuperGetType(newTypeName); //Type.GetType(newTypeName);//
//}
}
return type;
}
public static Type GetTypeByTypeName<BaseType>(string typeName) where BaseType : class
{
System.Type type = Type.GetType(typeName);
if (type == null)
{
string newTypeName = "XGame" + "." + typeName;
type = Type.GetType(newTypeName);
//if (type == null)
//{
// newTypeName = "XGame" + "." + typeName;
// type = Type.GetType(newTypeName);
//}
}
if (type == null)
{
Debug.LogError("GetTypeByTypeName typeName:{0} get type return null");
return null;
}
if (!typeof(BaseType).IsAssignableFrom(type))
{
Debug.LogError($"GetTypeByTypeName typeName:{typeName} is not subclass of {typeof(BaseType).FullName}");
return null;
}
return type;
}
/// <summary>
/// 判断指定的类型 <paramref name="type"/> 是否是指定泛型类型的子类型,或实现了指定泛型接口。
/// </summary>
/// <param name="type">需要测试的类型。</param>
/// <param name="generic">泛型接口类型,传入 typeof(IXxx)</param>
/// <returns>如果是泛型接口的子类型,则返回 true,否则返回 false。</returns>
public static bool HasImplementedRawGeneric(this Type type, Type generic)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (generic == null) throw new ArgumentNullException(nameof(generic));
// 测试接口。
var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
if (isTheRawGenericType) return true;
// 测试类型。
while (type != null && type != typeof(object))
{
isTheRawGenericType = IsTheRawGenericType(type);
if (isTheRawGenericType) return true;
type = type.BaseType;
}
// 没有找到任何匹配的接口或类型。
return false;
// 测试某个类型是否是指定的原始接口。
bool IsTheRawGenericType(Type test)
=> generic == (test.IsGenericType ? test.GetGenericTypeDefinition() : test);
}
public static object GetPropValue(object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null)
{
return null;
}
obj = info.GetValue(obj, null);
}
return obj;
}
public static T GetPropValue<T>(object obj, String name)
{
object retval = GetPropValue(obj, name);
if (retval == null)
{
return default(T);
}
// throws InvalidCastException if types are incompatible
return (T)retval;
}
public static object GetFieldValue(object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
FieldInfo info = type.GetField(part);
if (info == null)
{
return null;
}
obj = info.GetValue(obj);
}
return obj;
}
public static T GetFieldValue<T>(object obj, String name)
{
object retval = GetFieldValue(obj, name);
if (retval == null)
{
return default(T);
}
// throws InvalidCastException if types are incompatible
return (T)retval;
}
public static T CreateInstance<T>(string typeName, params object[] args) where T : class
{
if (string.IsNullOrEmpty(typeName) || typeName == "")
{
typeName = typeof(T).FullName;
}
Type type = Type.GetType(typeName);
if (type == null)
{
Debug.LogError($"Get Type from type name:{type} return null");
return null;
}
if (typeof(T).IsAssignableFrom(type) == false)
{
Debug.LogError($"{type} is not assignable from {typeof(T).Name}");
return null;
}
T instance = Activator.CreateInstance(type, args) as T;
return instance;
}
public static object CopyObject(object srcObject)
{
Type type = srcObject.GetType();
object newObject = Activator.CreateInstance(type);
FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < fields.Length; ++i)
{
FieldInfo fi = fields[i];
fi.SetValue(newObject, fi.GetValue(srcObject));
}
PropertyInfo[] props = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < props.Length; ++i)
{
PropertyInfo fi = props[i];
fi.SetValue(newObject, fi.GetValue(srcObject));
}
return newObject;
}
public static bool CopyObject(object srcObject, object targetObject)
{
Type srcType = srcObject.GetType();
Type targetType = targetObject.GetType();
if (srcType != targetType)
{
return false;
}
FieldInfo[] fields = srcType.GetFields(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < fields.Length; ++i)
{
FieldInfo fi = fields[i];
fi.SetValue(targetObject, fi.GetValue(srcObject));
}
PropertyInfo[] props = srcType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < props.Length; ++i)
{
PropertyInfo fi = props[i];
fi.SetValue(targetObject, fi.GetValue(srcObject));
}
return true;
}
public static object CopyFields(object src)
{
Type t = src.GetType();
object res = Activator.CreateInstance(t);
FieldInfo[] list = t.GetFields();
for (int i = 0; i < list.Length; ++i)
{
FieldInfo fi = list[i];
fi.SetValue(res, fi.GetValue(src));
}
return res;
}
public static T ParseEnum<T>(string value, T defaultValue) where T : struct
{
T v;
return Enum.TryParse<T>(value, true, out v) ? v : defaultValue;
}
public static void ThrowError(string fmt, params object[] args)
{
string msg = String.Format(fmt, args);
throw new Exception(msg);
}
/// <summary>
/// 计算字符串的MD5值
/// </summary>
public static string GetStringMd5(string source)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.UTF8.GetBytes(source);
byte[] md5Data = md5.ComputeHash(data, 0, data.Length);
md5.Clear();
string destString = "";
for (int i = 0; i < md5Data.Length; i++)
{
destString += System.Convert.ToString(md5Data[i], 16).PadLeft(2, '0');
}
destString = destString.PadLeft(32, '0');
return destString.ToUpper();
}
/// <summary>
/// 计算文件的MD5值
/// </summary>
public static string GetFileMd5(string file)
{
try
{
FileStream fs = new FileStream(file, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(fs);
fs.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception ex)
{
throw new Exception("md5file() fail, error:" + ex.Message);
}
}
public static string GetBytesMd5(byte[] bytes)
{
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
public static long GetTimeTick()
{
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalMilliseconds);
}
public static double XWorldGetTime()
{
return Time.realtimeSinceStartupAsDouble;
}
public static bool IsPossibleSimulator()
{
if (Application.isEditor)
{
return false;
}
bool isSimulator = false;
isSimulator = isSimulator || SystemInfo.graphicsDeviceName == "Netease";
isSimulator = isSimulator || SystemInfo.deviceModel == "Netease MuMu";
string processorType = SystemInfo.processorType.ToLower();
isSimulator = isSimulator || processorType.Contains("intel") || processorType.Contains("amd");
return isSimulator;
}
// 格式化文件大小
private static string[] sSuffix = { "B", "KB", "MB", "GB", "TB" };
public static string FormatBytesStr(long bytes)
{
float size = Convert.ToSingle(bytes);
int sufIdx = 0;
for(sufIdx = 0; sufIdx < sSuffix.Length; sufIdx++)
{
if(size >= 1024)
{
size = Mathf.Ceil(size / 1024);
continue;
}
else
{
break;
}
}
string format = size + sSuffix[sufIdx];
return format;
}
public static bool Contains<T>(T[] array, T value) where T : class
{
for (int i = 0; i < array.Length; ++i)
{
if (array[i] == value)
{
return true;
}
}
return false;
}
public static bool Contains(string[] array, string value)
{
for (int i = 0; i < array.Length; ++i)
{
if (array[i].CompareTo(value) == 0)
{
return true;
}
}
return false;
}
public static int RandomRangeToInt(int min,int max)
{
return UnityEngine.Random.Range(min,max);
}
public static void CreateMulDirectory(string path)
{
if (Directory.Exists(path))
return;
int n = path.LastIndexOf('/');
if(n == -1)
n = path.LastIndexOf('\\');
if (n == -1)
{
Directory.CreateDirectory(path);
return;
}
string subpath = path.Substring(0, n);
if (Directory.Exists(subpath))
{
Directory.CreateDirectory(path);
}
else
{
CreateMulDirectory(subpath);
Directory.CreateDirectory(path);
}
}
}
}