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

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