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> stack = new Stack>(); 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> stack = new Stack>(); 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); } } }