You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
9.8 KiB
259 lines
9.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using ProtoCSStruct;
|
|
using static System.Int32;
|
|
|
|
namespace Sog
|
|
{
|
|
public static class RoleDataHelper
|
|
{
|
|
/**
|
|
* example:
|
|
* RaceData.RaceBase.PvpData.DefaultStrategy
|
|
*/
|
|
public static void UpdateNoArrayData(ref DBRoleData roleData, string[] subNameList, object newValue)
|
|
{
|
|
var fistName = subNameList[0];
|
|
var baseType = typeof(DBRoleData);
|
|
var baseField = baseType.GetField(fistName);
|
|
if (baseField == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TypedReference roleDataRef = __makeref(roleData);
|
|
var currentObject = baseField.GetValue(roleData);
|
|
var exist = HaveSubFields(currentObject.GetType());
|
|
if (!exist)
|
|
{
|
|
var fieldType = baseField.FieldType;
|
|
var target = Convert.ChangeType(newValue, fieldType);
|
|
baseField.SetValueDirect(roleDataRef, target);
|
|
return;
|
|
}
|
|
|
|
var baseDataRef = __makeref(currentObject);
|
|
var currentType = currentObject.GetType();
|
|
Stack<Tuple<object, FieldInfo>> stack = new Stack<Tuple<object, FieldInfo>>();
|
|
for (int i = 1; i < subNameList.Length - 1; i++)
|
|
{
|
|
var subName = subNameList[i];
|
|
if (string.IsNullOrEmpty(subName))
|
|
{
|
|
break;
|
|
}
|
|
|
|
var currentField = currentType.GetField(subName);
|
|
//父obj,子方法名
|
|
stack.Push(Tuple.Create(currentObject, currentField));
|
|
currentObject = currentField.GetValue(currentObject);
|
|
baseDataRef = __makeref(currentObject);
|
|
currentType = currentObject.GetType();
|
|
}
|
|
|
|
var tailField = currentType.GetField(subNameList[^1]); //取最后一个属性
|
|
var targetValue = Convert.ChangeType(newValue, tailField.FieldType);
|
|
tailField.SetValueDirect(baseDataRef, targetValue);
|
|
while (stack.Count > 0) //回淑
|
|
{
|
|
var tv = stack.Pop();
|
|
var parentObject = tv.Item1;
|
|
var parentField = tv.Item2;
|
|
var parentRef = __makeref(parentObject);
|
|
parentField.SetValueDirect(parentRef, currentObject);
|
|
currentObject = parentObject;
|
|
}
|
|
|
|
baseField.SetValueDirect(roleDataRef, currentObject);
|
|
}
|
|
|
|
|
|
/**
|
|
* example :
|
|
* //string sub = "Mate.MateList[0].PropList[0].Value.";
|
|
//string sub = "Mythics.Levels[0].";
|
|
//string sub = "Mate.MateList[0].PropList[0].Value.";
|
|
//string sub = "Mate.PetHouse.PetHouseList[0].PetHouseLevel.";
|
|
//string sub = "ActivityInfo[0].EndTime.";
|
|
*/
|
|
public static void UpdateExistArrayData(ref DBRoleData roleData, string[] subNameList, object newValue)
|
|
{
|
|
var fistName = subNameList[0];
|
|
var baseType = typeof(DBRoleData);
|
|
var baseIsArray = false;
|
|
var baseIndex = -1;
|
|
if (fistName.Contains('['))
|
|
{
|
|
baseIndex = GetIndexBySubName(ref fistName);
|
|
baseIsArray = true;
|
|
}
|
|
var baseField = baseType.GetField(fistName);
|
|
if (baseField == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
Stack<ValueTuple<int, object, FieldInfo>> stack = new Stack<ValueTuple<int, object, FieldInfo>>();
|
|
|
|
var roleDataRef = __makeref(roleData);
|
|
var currentObject = baseField.GetValue(roleData);
|
|
var baseDataRef = __makeref(currentObject);
|
|
var currentField = baseField;
|
|
var currentType = currentObject.GetType();
|
|
if (baseIsArray)
|
|
{
|
|
//数组中的数据
|
|
var currentSubType = currentObject.GetType();
|
|
var method = currentSubType.GetMethod("Get");
|
|
var currentSubObject = method.Invoke(currentObject, new object[] { baseIndex });
|
|
var tempType = currentSubObject.GetType();
|
|
var existSub = HaveSubFields(tempType);
|
|
if (!existSub)
|
|
{
|
|
return;
|
|
}
|
|
|
|
stack.Push(ValueTuple.Create(baseIndex, currentObject, currentField));
|
|
stack.Push(ValueTuple.Create(-1, currentSubObject, currentField));
|
|
currentObject = currentSubObject;
|
|
baseDataRef = __makeref(currentObject);
|
|
currentType = currentObject.GetType();
|
|
}
|
|
else
|
|
{
|
|
var exist = HaveSubFields(currentObject.GetType());
|
|
if (!exist)
|
|
{
|
|
var fieldType = baseField.FieldType;
|
|
var target = Convert.ChangeType(newValue, fieldType);
|
|
baseField.SetValueDirect(roleDataRef, target);
|
|
return;
|
|
}
|
|
|
|
baseDataRef = __makeref(currentObject);
|
|
currentType = currentObject.GetType();
|
|
currentField = baseField;
|
|
stack.Push(ValueTuple.Create(-1, currentObject, currentField));
|
|
}
|
|
for (int i = 1; i < subNameList.Length - 1; i++)
|
|
{
|
|
var subName = subNameList[i];
|
|
if (string.IsNullOrEmpty(subName))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (subName.Contains("["))
|
|
{
|
|
//数组中的数据
|
|
var index = GetIndexBySubName(ref subName);
|
|
currentField = currentType.GetField(subName);
|
|
currentObject = currentField.GetValue(currentObject);
|
|
var currentSubType = currentObject.GetType();
|
|
var method = currentSubType.GetMethod("Get");
|
|
var currentSubObject = method.Invoke(currentObject, new object[] { index });
|
|
var tempType = currentSubObject.GetType();
|
|
var existSub = HaveSubFields(tempType);
|
|
if (!existSub)
|
|
{
|
|
break;
|
|
}
|
|
|
|
stack.Push(ValueTuple.Create(index, currentObject, currentField));
|
|
stack.Push(ValueTuple.Create(-1, currentSubObject, currentField));
|
|
currentObject = currentSubObject;
|
|
baseDataRef = __makeref(currentObject);
|
|
currentType = currentObject.GetType();
|
|
}
|
|
else
|
|
{
|
|
currentField = currentType.GetField(subName);
|
|
//父obj,子方法名
|
|
currentObject = currentField.GetValue(currentObject);
|
|
baseDataRef = __makeref(currentObject);
|
|
currentType = currentObject.GetType();
|
|
stack.Push(ValueTuple.Create(-1, currentObject, currentField));
|
|
}
|
|
}
|
|
|
|
var tailName = subNameList[^1];
|
|
if (tailName.Contains("["))
|
|
{
|
|
//最后是数组
|
|
var index = GetIndexBySubName(ref tailName);
|
|
currentField = currentType.GetField(tailName);
|
|
currentObject = currentField.GetValue(currentObject);
|
|
var currentSubType = currentObject.GetType();
|
|
var setter = currentSubType.GetMethod("Set");
|
|
if (setter != null)
|
|
{
|
|
var paramType = setter.GetParameters()[1].ParameterType.GetElementType();
|
|
var targetValue = Convert.ChangeType(newValue, paramType);
|
|
setter.Invoke(currentObject, new[] { index, targetValue });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var tailField = currentType.GetField(tailName); //取最后一个属性
|
|
var targetValue = Convert.ChangeType(newValue, tailField.FieldType);
|
|
tailField.SetValueDirect(baseDataRef, targetValue);
|
|
}
|
|
|
|
if (stack.Count > 1)
|
|
{
|
|
stack.Pop();
|
|
}
|
|
|
|
while (stack.Count > 0) //回溯
|
|
{
|
|
var tv = stack.Pop();
|
|
var index = tv.Item1;
|
|
var parentObject = tv.Item2;
|
|
var parentField = tv.Item3;
|
|
var parentObjectType = parentObject.GetType();
|
|
|
|
var parentRef = __makeref(parentObject);
|
|
var setter = parentObjectType.GetMethod("Set");
|
|
if (index > -1 || setter != null)
|
|
{
|
|
if (setter != null)
|
|
{
|
|
setter.Invoke(parentObject, new[] { index, currentObject });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
currentField.SetValueDirect(parentRef, currentObject);
|
|
}
|
|
|
|
currentObject = parentObject;
|
|
currentField = parentField;
|
|
}
|
|
|
|
baseField.SetValueDirect(roleDataRef, currentObject);
|
|
}
|
|
|
|
private static int GetIndexBySubName(ref string name)
|
|
{
|
|
var sp = name.Split("[");
|
|
var index = sp[1].Split("]")[0];
|
|
name = sp[0];
|
|
TryParse(index, out var u);
|
|
return u;
|
|
}
|
|
|
|
private static bool HaveSubFields(Type type)
|
|
{
|
|
if (type == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var interfaceType = typeof(IStructMessage);
|
|
return interfaceType.IsAssignableFrom(type);
|
|
}
|
|
}
|
|
}
|