Files
better-genshin-impact/BetterGenshinImpact/Helpers/ScriptObjectConverter.cs
2025-09-02 01:18:37 +08:00

85 lines
2.7 KiB
C#

using Microsoft.ClearScript;
using System;
using System.Reflection;
namespace BetterGenshinImpact.Helpers;
public class ScriptObjectConverter
{
public static T ConvertTo<T>(ScriptObject source)
{
T result = Activator.CreateInstance<T>();
Type type = typeof(T);
foreach (PropertyInfo property in type.GetProperties())
{
// 支持 PascalCase 和 camelCase
DealWithProperty(source, property, char.ToLower(property.Name[0]) + property.Name[1..], result);
DealWithProperty(source, property, char.ToUpper(property.Name[0]) + property.Name[1..], result);
}
return result;
}
private static void DealWithProperty<T>(ScriptObject source, PropertyInfo property, string propertyName, T result)
{
if (source[propertyName] is not Undefined && source[propertyName] != null)
{
object value = source.GetProperty(propertyName);
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
{
property.SetValue(result, Convert.ChangeType(value, property.PropertyType));
}
else
{
MethodInfo method = typeof(ScriptObjectConverter).GetMethod("ConvertTo")!.MakeGenericMethod(property.PropertyType);
object? nestedValue = method.Invoke(null, [value]);
property.SetValue(result, nestedValue);
}
}
}
public static T GetValue<T>(ScriptObject source, string propertyName, T defaultValue)
{
if (source[propertyName] is not Undefined && source[propertyName] != null)
{
object value = source.GetProperty(propertyName);
Type type = typeof(T);
type = Nullable.GetUnderlyingType(type) ?? type;
if (type.IsEnum)
{
// 处理数字
if (value is int intValue)
{
if (Enum.IsDefined(type, intValue))
{
return (T)Enum.ToObject(type, intValue);
}
else
{
return defaultValue;
}
}
// 处理字符串
else if (value is string strValue)
{
if (Enum.TryParse(type, strValue, ignoreCase: true, out object? parsedEnum))
{
return (T)parsedEnum;
}
else
{
return defaultValue;
}
}
}
return (T)value;
}
return defaultValue;
}
}