private bool SetDefFieldAtPath(Type defType, string path, object value, Type ensureFieldType, bool errorOnDefNotFound, string fileSource, bool isPlaceholder, out string normalizedPath, out string suggestedPath, out string replacedString, out IEnumerable <string> replacedStringsList) { replacedString = null; replacedStringsList = null; normalizedPath = path; suggestedPath = path; string text = path.Split(new char[] { '.' })[0]; text = BackCompatibility.BackCompatibleDefName(defType, text, true); if (GenDefDatabase.GetDefSilentFail(defType, text, false) == null) { if (errorOnDefNotFound) { this.loadErrors.Add(string.Concat(new object[] { "Found no ", defType, " named ", text, " to match ", path, " (", fileSource, ")" })); } return(false); } bool flag = false; int num = 0; bool result; try { List <string> list = path.Split(new char[] { '.' }).ToList <string>(); object obj = GenGeneric.InvokeStaticMethodOnGenericType(typeof(DefDatabase <>), defType, "GetNamedSilentFail", new object[] { list[0] }); if (obj == null) { throw new InvalidOperationException("Def named " + list[0] + " not found."); } list.RemoveAt(0); num++; string text2; int num2; DefInjectionPathPartKind defInjectionPathPartKind; FieldInfo field; int num3; int num4; while (true) { text2 = list[0]; num2 = -1; if (int.TryParse(text2, out num2)) { defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; } else if (this.GetFieldNamed(obj.GetType(), text2) != null) { defInjectionPathPartKind = DefInjectionPathPartKind.Field; } else if (obj.GetType().GetProperty("Count") != null) { if (text2.Contains('-')) { defInjectionPathPartKind = DefInjectionPathPartKind.ListHandleWithIndex; string[] array = text2.Split(new char[] { '-' }); text2 = array[0]; num2 = (int)ParseHelper.FromString(array[1], typeof(int)); } else { defInjectionPathPartKind = DefInjectionPathPartKind.ListHandle; } } else { defInjectionPathPartKind = DefInjectionPathPartKind.Field; } if (list.Count == 1) { break; } if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { field = obj.GetType().GetField(text2, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { goto Block_41; } if (field.HasAttribute <NoTranslateAttribute>()) { goto Block_42; } if (field.HasAttribute <UnsavedAttribute>()) { goto Block_43; } if (field.HasAttribute <TranslationCanChangeCountAttribute>()) { flag = true; } if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { obj = field.GetValue(obj); } else { object value2 = field.GetValue(obj); PropertyInfo property = value2.GetType().GetProperty("Item"); if (property == null) { goto Block_46; } num3 = (int)value2.GetType().GetProperty("Count").GetValue(value2, null); if (num2 < 0 || num2 >= num3) { goto IL_ADC; } obj = property.GetValue(value2, new object[] { num2 }); } } else if (defInjectionPathPartKind == DefInjectionPathPartKind.ListIndex || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandle || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandleWithIndex) { object obj2 = obj; PropertyInfo property2 = obj2.GetType().GetProperty("Item"); if (property2 == null) { goto Block_50; } bool flag2; if (defInjectionPathPartKind == DefInjectionPathPartKind.ListHandle || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandleWithIndex) { num2 = TranslationHandleUtility.GetElementIndexByHandle(obj2, text2, num2); defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; flag2 = true; } else { flag2 = false; } num4 = (int)obj2.GetType().GetProperty("Count").GetValue(obj2, null); if (num2 < 0 || num2 >= num4) { goto IL_BB7; } obj = property2.GetValue(obj2, new object[] { num2 }); if (flag2) { string[] array2 = normalizedPath.Split(new char[] { '.' }); array2[num] = num2.ToString(); normalizedPath = string.Join(".", array2); } else { string bestHandleWithIndexForListElement = TranslationHandleUtility.GetBestHandleWithIndexForListElement(obj2, obj); if (!bestHandleWithIndexForListElement.NullOrEmpty()) { string[] array3 = suggestedPath.Split(new char[] { '.' }); array3[num] = bestHandleWithIndexForListElement; suggestedPath = string.Join(".", array3); } } } else { this.loadErrors.Add(string.Concat(new object[] { "Can't enter node ", text2, " at path ", path, ", element kind is ", defInjectionPathPartKind, ". (", fileSource, ")" })); } list.RemoveAt(0); num++; } bool flag3 = false; foreach (KeyValuePair <string, DefInjectionPackage.DefInjection> current in this.injections) { if (!(current.Key == path)) { if (current.Value.injected && current.Value.normalizedPath == normalizedPath) { string text3 = string.Concat(new string[] { "Duplicate def-injected translation key. Both ", current.Value.path, " and ", path, " refer to the same field (", suggestedPath, ")" }); if (current.Value.path != current.Value.nonBackCompatiblePath) { string text4 = text3; text3 = string.Concat(new string[] { text4, " (", current.Value.nonBackCompatiblePath, " was auto-renamed to ", current.Value.path, ")" }); } text3 = text3 + " (" + current.Value.fileSource + ")"; this.loadErrors.Add(text3); flag3 = true; break; } } } bool flag4 = false; if (!flag3) { if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { FieldInfo fieldNamed = this.GetFieldNamed(obj.GetType(), text2); if (fieldNamed == null) { throw new InvalidOperationException(string.Concat(new object[] { "Field ", text2, " does not exist in type ", obj.GetType(), "." })); } if (fieldNamed.HasAttribute <NoTranslateAttribute>()) { this.loadErrors.Add(string.Concat(new object[] { "Translated untranslatable field ", fieldNamed.Name, " of type ", fieldNamed.FieldType, " at path ", path, ". Translating this field will break the game. (", fileSource, ")" })); } else if (fieldNamed.HasAttribute <UnsavedAttribute>()) { this.loadErrors.Add(string.Concat(new object[] { "Translated untranslatable field (UnsavedAttribute) ", fieldNamed.Name, " of type ", fieldNamed.FieldType, " at path ", path, ". Translating this field will break the game. (", fileSource, ")" })); } else if (!isPlaceholder && fieldNamed.FieldType != ensureFieldType) { this.loadErrors.Add(string.Concat(new object[] { "Translated non-", ensureFieldType, " field ", fieldNamed.Name, " of type ", fieldNamed.FieldType, " at path ", path, ". Expected ", ensureFieldType, ". (", fileSource, ")" })); } else if (!isPlaceholder && ensureFieldType != typeof(string) && !fieldNamed.HasAttribute <TranslationCanChangeCountAttribute>()) { this.loadErrors.Add(string.Concat(new object[] { "Tried to translate field ", fieldNamed.Name, " of type ", fieldNamed.FieldType, " at path ", path, ", but this field doesn't have [TranslationCanChangeCount] attribute so it doesn't allow this type of translation. (", fileSource, ")" })); } else if (!isPlaceholder) { if (ensureFieldType == typeof(string)) { replacedString = (string)fieldNamed.GetValue(obj); } else { replacedStringsList = (fieldNamed.GetValue(obj) as IEnumerable <string>); } fieldNamed.SetValue(obj, value); flag4 = true; } } else if (defInjectionPathPartKind == DefInjectionPathPartKind.ListIndex || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandle || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandleWithIndex) { object obj3 = obj; if (obj3 == null) { throw new InvalidOperationException("Tried to use index on null list at " + path); } Type type = obj3.GetType(); PropertyInfo property3 = type.GetProperty("Count"); if (property3 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Count' property)."); } if (defInjectionPathPartKind == DefInjectionPathPartKind.ListHandle || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandleWithIndex) { num2 = TranslationHandleUtility.GetElementIndexByHandle(obj3, text2, num2); defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; } int num5 = (int)property3.GetValue(obj3, null); if (num2 >= num5) { throw new InvalidOperationException(string.Concat(new object[] { "Trying to translate ", defType, ".", path, " at index ", num2, " but the list only has ", num5, " entries (so max index is ", (num5 - 1).ToString(), ")." })); } PropertyInfo property4 = type.GetProperty("Item"); if (property4 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } Type propertyType = property4.PropertyType; if (!isPlaceholder && propertyType != ensureFieldType) { this.loadErrors.Add(string.Concat(new object[] { "Translated non-", ensureFieldType, " list item of type ", propertyType, " at path ", path, ". Expected ", ensureFieldType, ". (", fileSource, ")" })); } else if (!isPlaceholder && ensureFieldType != typeof(string) && !flag) { this.loadErrors.Add(string.Concat(new object[] { "Tried to translate field of type ", propertyType, " at path ", path, ", but this field doesn't have [TranslationCanChangeCount] attribute so it doesn't allow this type of translation. (", fileSource, ")" })); } else if (num2 < 0 || num2 >= (int)type.GetProperty("Count").GetValue(obj3, null)) { this.loadErrors.Add("Index out of bounds (max index is " + ((int)type.GetProperty("Count").GetValue(obj3, null) - 1) + ")"); } else if (!isPlaceholder) { replacedString = (string)property4.GetValue(obj3, new object[] { num2 }); property4.SetValue(obj3, value, new object[] { num2 }); flag4 = true; } } else { this.loadErrors.Add(string.Concat(new object[] { "Translated ", text2, " at path ", path, " but it's not a field, it's ", defInjectionPathPartKind, ". (", fileSource, ")" })); } } if (path != suggestedPath) { IList <string> list2 = value as IList <string>; string text5; if (list2 != null) { text5 = list2.ToStringSafeEnumerable(); } else { text5 = value.ToString(); } this.loadSyntaxSuggestions.Add(string.Concat(new string[] { "Consider using ", suggestedPath, " instead of ", path, " for translation '", text5, "' (", fileSource, ")" })); } result = flag4; return(result); Block_41: throw new InvalidOperationException("Field " + text2 + " does not exist."); Block_42: throw new InvalidOperationException(string.Concat(new object[] { "Translated untranslatable field ", field.Name, " of type ", field.FieldType, " at path ", path, ". Translating this field will break the game." })); Block_43: throw new InvalidOperationException(string.Concat(new object[] { "Translated untranslatable field ([Unsaved] attribute) ", field.Name, " of type ", field.FieldType, " at path ", path, ". Translating this field will break the game." })); Block_46: throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); IL_ADC: throw new InvalidOperationException("Index out of bounds (max index is " + (num3 - 1) + ")"); Block_50: throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); IL_BB7: throw new InvalidOperationException("Index out of bounds (max index is " + (num4 - 1) + ")"); } catch (Exception ex) { string text6 = string.Concat(new object[] { "Couldn't inject ", path, " into ", defType, " (", fileSource, "): ", ex.Message }); if (ex.InnerException != null) { text6 = text6 + " -> " + ex.InnerException.Message; } this.loadErrors.Add(text6); result = false; } return(result); }
public static object Convert(object obj, Type to, object defaultValue) { if (obj == null) { return(defaultValue); } if (to.IsAssignableFrom(obj.GetType())) { return(obj); } if (to == typeof(string)) { return(obj.ToString()); } string text = obj as string; if (text != null && !to.IsPrimitive && ParseHelper.CanParse(to, (string)obj)) { if (text == "") { return(defaultValue); } return(ParseHelper.FromString(text, to)); } if (text != null && typeof(Def).IsAssignableFrom(to)) { if (text == "") { return(defaultValue); } return(GenDefDatabase.GetDef(to, text)); } if (text != null && to == typeof(Faction)) { if (text == "") { return(defaultValue); } List <Faction> allFactionsListForReading = Find.FactionManager.AllFactionsListForReading; for (int i = 0; i < allFactionsListForReading.Count; i++) { if (allFactionsListForReading[i].GetUniqueLoadID() == text) { return(allFactionsListForReading[i]); } } for (int j = 0; j < allFactionsListForReading.Count; j++) { if (allFactionsListForReading[j].HasName && allFactionsListForReading[j].Name == text) { return(allFactionsListForReading[j]); } } for (int k = 0; k < allFactionsListForReading.Count; k++) { if (allFactionsListForReading[k].def.defName == text) { return(allFactionsListForReading[k]); } } return(defaultValue); } if (CanConvertBetweenDataTypes(obj.GetType(), to)) { return(ConvertBetweenDataTypes(obj, to)); } if (IsXml(obj) && !to.IsPrimitive) { try { Type type = to; if (type == typeof(IEnumerable)) { type = typeof(List <string>); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable <>) && type.GetGenericArguments().Length >= 1) { type = typeof(List <>).MakeGenericType(type.GetGenericArguments()[0]); } XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n" + text + "\n</root>"); object result = DirectXmlToObject.GetObjectFromXmlMethod(type)(xmlDocument.DocumentElement, arg2 : true); DirectXmlCrossRefLoader.ResolveAllWantedCrossReferences(FailMode.LogErrors); return(result); } finally { DirectXmlCrossRefLoader.Clear(); } } if (to.IsGenericType && (to.GetGenericTypeDefinition() == typeof(IEnumerable <>) || to.GetGenericTypeDefinition() == typeof(List <>)) && to.GetGenericArguments().Length >= 1 && (!(to.GetGenericArguments()[0] == typeof(string)) || !(obj is string))) { IEnumerable enumerable = obj as IEnumerable; if (enumerable != null) { Type type2 = to.GetGenericArguments()[0]; bool flag = true; foreach (object item in enumerable) { if (!CanConvert(item, type2)) { flag = false; break; } } if (flag) { IList list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(type2)); { foreach (object item2 in enumerable) { list.Add(Convert(item2, type2)); } return(list); } } } } if (obj is IEnumerable && !(obj is string)) { IEnumerable e = (IEnumerable)obj; if (GenCollection.Count_EnumerableBase(e) == 1) { object obj2 = GenCollection.FirstOrDefault_EnumerableBase(e); if (CanConvert(obj2, to)) { return(Convert(obj2, to)); } } } if (typeof(IList).IsAssignableFrom(to)) { IList list2 = (IList)Activator.CreateInstance(to); Type[] genericArguments = to.GetGenericArguments(); if (genericArguments.Length >= 1) { list2.Add(Convert(obj, genericArguments[0])); } else { list2.Add(obj); } return(list2); } if (to == typeof(IEnumerable)) { return(Gen.YieldSingleNonGeneric(obj)); } if (to.IsGenericType && to.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { Type[] genericArguments2 = to.GetGenericArguments(); if (genericArguments2.Length >= 1) { IList obj3 = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(genericArguments2[0])); obj3.Add(Convert(obj, genericArguments2[0])); return(obj3); } return(Gen.YieldSingleNonGeneric(obj)); } IConvertible convertible = obj as IConvertible; if (convertible == null) { return(defaultValue); } try { return(ConvertToPrimitive(convertible, to, defaultValue)); } catch (FormatException) { return(defaultValue); } }
public static T ObjectFromXml <T>(XmlNode xmlRoot, bool doPostLoad) where T : new() { MethodInfo methodInfo = DirectXmlToObject.CustomDataLoadMethodOf(typeof(T)); if (methodInfo != null) { xmlRoot = XmlInheritance.GetResolvedNodeFor(xmlRoot); Type type = DirectXmlToObject.ClassTypeOf <T>(xmlRoot); T t = (T)((object)Activator.CreateInstance(type)); try { methodInfo.Invoke(t, new object[] { xmlRoot }); } catch (Exception ex) { Log.Error(string.Concat(new object[] { "Exception in custom XML loader for ", typeof(T), ". Node is:\n ", xmlRoot.OuterXml, "\n\nException is:\n ", ex.ToString() })); t = default(T); } if (doPostLoad) { DirectXmlToObject.TryDoPostLoad(t); } return(t); } if (xmlRoot.ChildNodes.Count == 1 && xmlRoot.FirstChild.NodeType == XmlNodeType.CDATA) { if (typeof(T) != typeof(string)) { Log.Error("CDATA can only be used for strings. Bad xml: " + xmlRoot.OuterXml); return(default(T)); } return((T)((object)xmlRoot.FirstChild.Value)); } else { if (xmlRoot.ChildNodes.Count == 1 && xmlRoot.FirstChild.NodeType == XmlNodeType.Text) { try { return((T)((object)ParseHelper.FromString(xmlRoot.InnerText, typeof(T)))); } catch (Exception ex2) { Log.Error(string.Concat(new object[] { "Exception parsing ", xmlRoot.OuterXml, " to type ", typeof(T), ": ", ex2 })); } return(default(T)); } if (Attribute.IsDefined(typeof(T), typeof(FlagsAttribute))) { List <T> list = DirectXmlToObject.ListFromXml <T>(xmlRoot); int num = 0; foreach (T current in list) { int num2 = (int)((object)current); num |= num2; } return((T)((object)num)); } if (typeof(T).HasGenericDefinition(typeof(List <>))) { MethodInfo method = typeof(DirectXmlToObject).GetMethod("ListFromXml", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] genericArguments = typeof(T).GetGenericArguments(); MethodInfo methodInfo2 = method.MakeGenericMethod(genericArguments); object[] parameters = new object[] { xmlRoot }; object obj = methodInfo2.Invoke(null, parameters); return((T)((object)obj)); } if (typeof(T).HasGenericDefinition(typeof(Dictionary <, >))) { MethodInfo method2 = typeof(DirectXmlToObject).GetMethod("DictionaryFromXml", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] genericArguments2 = typeof(T).GetGenericArguments(); MethodInfo methodInfo3 = method2.MakeGenericMethod(genericArguments2); object[] parameters2 = new object[] { xmlRoot }; object obj2 = methodInfo3.Invoke(null, parameters2); return((T)((object)obj2)); } if (!xmlRoot.HasChildNodes) { if (typeof(T) == typeof(string)) { return((T)((object)string.Empty)); } XmlAttribute xmlAttribute = xmlRoot.Attributes["IsNull"]; if (xmlAttribute != null && xmlAttribute.Value.ToUpperInvariant() == "TRUE") { return(default(T)); } if (typeof(T).IsGenericType) { Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(List <>) || genericTypeDefinition == typeof(HashSet <>) || genericTypeDefinition == typeof(Dictionary <, >)) { return(Activator.CreateInstance <T>()); } } } xmlRoot = XmlInheritance.GetResolvedNodeFor(xmlRoot); Type type2 = DirectXmlToObject.ClassTypeOf <T>(xmlRoot); T t2 = (T)((object)Activator.CreateInstance(type2)); List <string> list2 = null; if (xmlRoot.ChildNodes.Count > 1) { list2 = new List <string>(); } for (int i = 0; i < xmlRoot.ChildNodes.Count; i++) { XmlNode xmlNode = xmlRoot.ChildNodes[i]; if (!(xmlNode is XmlComment)) { if (xmlRoot.ChildNodes.Count > 1) { if (list2.Contains(xmlNode.Name)) { Log.Error(string.Concat(new object[] { "XML ", typeof(T), " defines the same field twice: ", xmlNode.Name, ".\n\nField contents: ", xmlNode.InnerText, ".\n\nWhole XML:\n\n", xmlRoot.OuterXml })); } else { list2.Add(xmlNode.Name); } } FieldInfo fieldInfo = DirectXmlToObject.GetFieldInfoForType(t2.GetType(), xmlNode.Name, xmlRoot); if (fieldInfo == null) { FieldInfo[] fields = t2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int j = 0; j < fields.Length; j++) { FieldInfo fieldInfo2 = fields[j]; object[] customAttributes = fieldInfo2.GetCustomAttributes(typeof(LoadAliasAttribute), true); for (int k = 0; k < customAttributes.Length; k++) { object obj3 = customAttributes[k]; string alias = ((LoadAliasAttribute)obj3).alias; if (alias.EqualsIgnoreCase(xmlNode.Name)) { fieldInfo = fieldInfo2; break; } } if (fieldInfo != null) { break; } } } if (fieldInfo == null) { bool flag = false; object[] customAttributes2 = t2.GetType().GetCustomAttributes(typeof(IgnoreSavedElementAttribute), true); for (int l = 0; l < customAttributes2.Length; l++) { object obj4 = customAttributes2[l]; string elementToIgnore = ((IgnoreSavedElementAttribute)obj4).elementToIgnore; if (string.Equals(elementToIgnore, xmlNode.Name, StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } if (!flag) { Log.Error(string.Concat(new string[] { "XML error: ", xmlNode.OuterXml, " doesn't correspond to any field in type ", t2.GetType().Name, "." })); } } else if (typeof(Def).IsAssignableFrom(fieldInfo.FieldType)) { if (xmlNode.InnerText.NullOrEmpty()) { fieldInfo.SetValue(t2, null); } else { DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(t2, fieldInfo, xmlNode.InnerText); } } else { object value = null; try { MethodInfo method3 = typeof(DirectXmlToObject).GetMethod("ObjectFromXml", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo4 = method3.MakeGenericMethod(new Type[] { fieldInfo.FieldType }); value = methodInfo4.Invoke(null, new object[] { xmlNode, doPostLoad }); } catch (Exception ex3) { Log.Error("Exception loading from " + xmlNode.ToString() + ": " + ex3.ToString()); goto IL_78D; } if (!typeof(T).IsValueType) { fieldInfo.SetValue(t2, value); } else { object obj5 = t2; fieldInfo.SetValue(obj5, value); t2 = (T)((object)obj5); } } } IL_78D :; } if (doPostLoad) { DirectXmlToObject.TryDoPostLoad(t2); } return(t2); } }
public static object FromString(string str, Type itemType) { object result; try { itemType = (Nullable.GetUnderlyingType(itemType) ?? itemType); if (itemType == typeof(string)) { str = str.Replace("\\n", "\n"); result = str; } else if (itemType == typeof(int)) { result = ParseHelper.ParseIntPermissive(str); } else if (itemType == typeof(float)) { result = float.Parse(str, CultureInfo.InvariantCulture); } else if (itemType == typeof(bool)) { result = bool.Parse(str); } else if (itemType == typeof(long)) { result = long.Parse(str, CultureInfo.InvariantCulture); } else if (itemType == typeof(double)) { result = double.Parse(str, CultureInfo.InvariantCulture); } else if (itemType == typeof(sbyte)) { result = sbyte.Parse(str, CultureInfo.InvariantCulture); } else { if (itemType.IsEnum) { try { object obj = BackCompatibility.BackCompatibleEnum(itemType, str); if (obj != null) { return(obj); } return(Enum.Parse(itemType, str)); } catch (ArgumentException innerException) { string text = string.Concat(new object[] { "'", str, "' is not a valid value for ", itemType, ". Valid values are: \n" }); text += GenText.StringFromEnumerable(Enum.GetValues(itemType)); ArgumentException ex = new ArgumentException(text, innerException); throw ex; } } if (itemType == typeof(Type)) { if (str == "null" || str == "Null") { result = null; } else { Type typeInAnyAssembly = GenTypes.GetTypeInAnyAssembly(str); if (typeInAnyAssembly == null) { Log.Error("Could not find a type named " + str, false); } result = typeInAnyAssembly; } } else if (itemType == typeof(Action)) { string[] array = str.Split(new char[] { '.' }); string methodName = array[array.Length - 1]; string typeName = string.Empty; if (array.Length == 3) { typeName = array[0] + "." + array[1]; } else { typeName = array[0]; } Type typeInAnyAssembly2 = GenTypes.GetTypeInAnyAssembly(typeName); MethodInfo method = typeInAnyAssembly2.GetMethods().First((MethodInfo m) => m.Name == methodName); result = (Action)Delegate.CreateDelegate(typeof(Action), method); } else if (itemType == typeof(Vector3)) { result = ParseHelper.FromStringVector3(str); } else if (itemType == typeof(Vector2)) { result = ParseHelper.FromStringVector2(str); } else if (itemType == typeof(Rect)) { result = ParseHelper.FromStringRect(str); } else if (itemType == typeof(Color)) { str = str.TrimStart(new char[] { '(', 'R', 'G', 'B', 'A' }); str = str.TrimEnd(new char[] { ')' }); string[] array2 = str.Split(new char[] { ',' }); float num = (float)ParseHelper.FromString(array2[0], typeof(float)); float num2 = (float)ParseHelper.FromString(array2[1], typeof(float)); float num3 = (float)ParseHelper.FromString(array2[2], typeof(float)); bool flag = num > 1f || num3 > 1f || num2 > 1f; float num4 = (float)((!flag) ? 1 : 255); if (array2.Length == 4) { num4 = (float)ParseHelper.FromString(array2[3], typeof(float)); } Color color; if (!flag) { color.r = num; color.g = num2; color.b = num3; color.a = num4; } else { color = GenColor.FromBytes(Mathf.RoundToInt(num), Mathf.RoundToInt(num2), Mathf.RoundToInt(num3), Mathf.RoundToInt(num4)); } result = color; } else if (itemType == typeof(PublishedFileId_t)) { result = new PublishedFileId_t(ulong.Parse(str)); } else if (itemType == typeof(IntVec2)) { result = IntVec2.FromString(str); } else if (itemType == typeof(IntVec3)) { result = IntVec3.FromString(str); } else if (itemType == typeof(Rot4)) { result = Rot4.FromString(str); } else if (itemType == typeof(CellRect)) { result = CellRect.FromString(str); } else { if (itemType != typeof(CurvePoint)) { if (itemType == typeof(NameTriple)) { NameTriple nameTriple = NameTriple.FromString(str); nameTriple.ResolveMissingPieces(null); } else { if (itemType == typeof(FloatRange)) { return(FloatRange.FromString(str)); } if (itemType == typeof(IntRange)) { return(IntRange.FromString(str)); } if (itemType == typeof(QualityRange)) { return(QualityRange.FromString(str)); } if (itemType == typeof(ColorInt)) { str = str.TrimStart(new char[] { '(', 'R', 'G', 'B', 'A' }); str = str.TrimEnd(new char[] { ')' }); string[] array3 = str.Split(new char[] { ',' }); ColorInt colorInt = new ColorInt(255, 255, 255, 255); colorInt.r = (int)ParseHelper.FromString(array3[0], typeof(int)); colorInt.g = (int)ParseHelper.FromString(array3[1], typeof(int)); colorInt.b = (int)ParseHelper.FromString(array3[2], typeof(int)); if (array3.Length == 4) { colorInt.a = (int)ParseHelper.FromString(array3[3], typeof(int)); } else { colorInt.a = 255; } return(colorInt); } } throw new ArgumentException(string.Concat(new string[] { "Trying to parse to unknown data type ", itemType.Name, ". Content is '", str, "'." })); } result = CurvePoint.FromString(str); } } } catch (Exception innerException2) { ArgumentException ex2 = new ArgumentException(string.Concat(new object[] { "Exception parsing ", itemType, " from \"", str, "\"" }), innerException2); throw ex2; } return(result); }
public static T ObjectFromXml <T>(XmlNode xmlRoot, bool doPostLoad) { XmlAttribute xmlAttribute = xmlRoot.Attributes["IsNull"]; if (xmlAttribute != null && xmlAttribute.Value.ToUpperInvariant() == "TRUE") { return(default(T)); } MethodInfo methodInfo = CustomDataLoadMethodOf(typeof(T)); if (methodInfo != null) { xmlRoot = XmlInheritance.GetResolvedNodeFor(xmlRoot); Type type = ClassTypeOf <T>(xmlRoot); currentlyInstantiatingObjectOfType.Push(type); T val; try { val = (T)Activator.CreateInstance(type); } finally { currentlyInstantiatingObjectOfType.Pop(); } try { methodInfo.Invoke(val, new object[1] { xmlRoot }); } catch (Exception ex) { Log.Error(string.Concat("Exception in custom XML loader for ", typeof(T), ". Node is:\n ", xmlRoot.OuterXml, "\n\nException is:\n ", ex.ToString())); val = default(T); } if (doPostLoad) { TryDoPostLoad(val); } return(val); } if (typeof(ISlateRef).IsAssignableFrom(typeof(T))) { try { return(ParseHelper.FromString <T>(InnerTextWithReplacedNewlinesOrXML(xmlRoot))); } catch (Exception ex2) { Log.Error(string.Concat("Exception parsing ", xmlRoot.OuterXml, " to type ", typeof(T), ": ", ex2)); } return(default(T)); } if (xmlRoot.ChildNodes.Count == 1 && xmlRoot.FirstChild.NodeType == XmlNodeType.CDATA) { if (typeof(T) != typeof(string)) { Log.Error("CDATA can only be used for strings. Bad xml: " + xmlRoot.OuterXml); return(default(T)); } return((T)(object)xmlRoot.FirstChild.Value); } if (xmlRoot.ChildNodes.Count == 1 && xmlRoot.FirstChild.NodeType == XmlNodeType.Text) { try { return(ParseHelper.FromString <T>(xmlRoot.InnerText)); } catch (Exception ex3) { Log.Error(string.Concat("Exception parsing ", xmlRoot.OuterXml, " to type ", typeof(T), ": ", ex3)); } return(default(T)); } if (Attribute.IsDefined(typeof(T), typeof(FlagsAttribute))) { List <T> list = ListFromXml <T>(xmlRoot); int num = 0; foreach (T item in list) { int num2 = (int)(object)item; num |= num2; } return((T)(object)num); } if (typeof(T).HasGenericDefinition(typeof(List <>))) { Func <XmlNode, object> value = null; if (!listFromXmlMethods.TryGetValue(typeof(T), out value)) { MethodInfo method = typeof(DirectXmlToObject).GetMethod("ListFromXmlReflection", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] genericArguments = typeof(T).GetGenericArguments(); value = (Func <XmlNode, object>)Delegate.CreateDelegate(typeof(Func <XmlNode, object>), method.MakeGenericMethod(genericArguments)); listFromXmlMethods.Add(typeof(T), value); } return((T)value(xmlRoot)); } if (typeof(T).HasGenericDefinition(typeof(Dictionary <, >))) { Func <XmlNode, object> value2 = null; if (!dictionaryFromXmlMethods.TryGetValue(typeof(T), out value2)) { MethodInfo method2 = typeof(DirectXmlToObject).GetMethod("DictionaryFromXmlReflection", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] genericArguments2 = typeof(T).GetGenericArguments(); value2 = (Func <XmlNode, object>)Delegate.CreateDelegate(typeof(Func <XmlNode, object>), method2.MakeGenericMethod(genericArguments2)); dictionaryFromXmlMethods.Add(typeof(T), value2); } return((T)value2(xmlRoot)); } if (!xmlRoot.HasChildNodes) { if (typeof(T) == typeof(string)) { return((T)(object)""); } XmlAttribute xmlAttribute2 = xmlRoot.Attributes["IsNull"]; if (xmlAttribute2 != null && xmlAttribute2.Value.ToUpperInvariant() == "TRUE") { return(default(T)); } if (typeof(T).IsGenericType) { Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(List <>) || genericTypeDefinition == typeof(HashSet <>) || genericTypeDefinition == typeof(Dictionary <, >)) { return(Activator.CreateInstance <T>()); } } } xmlRoot = XmlInheritance.GetResolvedNodeFor(xmlRoot); Type type2 = ClassTypeOf <T>(xmlRoot); Type type3 = Nullable.GetUnderlyingType(type2) ?? type2; currentlyInstantiatingObjectOfType.Push(type3); T val2; try { val2 = (T)Activator.CreateInstance(type3); } finally { currentlyInstantiatingObjectOfType.Pop(); } HashSet <string> hashSet = null; if (xmlRoot.ChildNodes.Count > 1) { hashSet = new HashSet <string>(); } for (int i = 0; i < xmlRoot.ChildNodes.Count; i++) { XmlNode xmlNode = xmlRoot.ChildNodes[i]; if (xmlNode is XmlComment) { continue; } if (xmlRoot.ChildNodes.Count > 1) { if (hashSet.Contains(xmlNode.Name)) { Log.Error(string.Concat("XML ", typeof(T), " defines the same field twice: ", xmlNode.Name, ".\n\nField contents: ", xmlNode.InnerText, ".\n\nWhole XML:\n\n", xmlRoot.OuterXml)); } else { hashSet.Add(xmlNode.Name); } } FieldInfo value3 = null; DeepProfiler.Start("GetFieldInfoForType"); try { value3 = GetFieldInfoForType(val2.GetType(), xmlNode.Name, xmlRoot); } finally { DeepProfiler.End(); } if (value3 == null) { DeepProfiler.Start("Field search"); try { FieldAliasCache key = new FieldAliasCache(val2.GetType(), xmlNode.Name); if (!fieldAliases.TryGetValue(key, out value3)) { FieldInfo[] fields = val2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object[] customAttributes = fieldInfo.GetCustomAttributes(typeof(LoadAliasAttribute), inherit: true); for (int k = 0; k < customAttributes.Length; k++) { if (((LoadAliasAttribute)customAttributes[k]).alias.EqualsIgnoreCase(xmlNode.Name)) { value3 = fieldInfo; break; } } if (value3 != null) { break; } } fieldAliases.Add(key, value3); } } finally { DeepProfiler.End(); } } if (value3 != null && value3.TryGetAttribute <UnsavedAttribute>() != null && !value3.TryGetAttribute <UnsavedAttribute>().allowLoading) { Log.Error("XML error: " + xmlNode.OuterXml + " corresponds to a field in type " + val2.GetType().Name + " which has an Unsaved attribute. Context: " + xmlRoot.OuterXml); } else if (value3 == null) { DeepProfiler.Start("Field search 2"); try { bool flag = false; XmlAttribute xmlAttribute3 = xmlNode.Attributes?["IgnoreIfNoMatchingField"]; if (xmlAttribute3 != null && xmlAttribute3.Value.ToUpperInvariant() == "TRUE") { flag = true; } else { object[] customAttributes = val2.GetType().GetCustomAttributes(typeof(IgnoreSavedElementAttribute), inherit: true); for (int j = 0; j < customAttributes.Length; j++) { if (string.Equals(((IgnoreSavedElementAttribute)customAttributes[j]).elementToIgnore, xmlNode.Name, StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } } if (!flag) { Log.Error("XML error: " + xmlNode.OuterXml + " doesn't correspond to any field in type " + val2.GetType().Name + ". Context: " + xmlRoot.OuterXml); } } finally { DeepProfiler.End(); } } else if (typeof(Def).IsAssignableFrom(value3.FieldType)) { if (xmlNode.InnerText.NullOrEmpty()) { value3.SetValue(val2, null); continue; } XmlAttribute xmlAttribute4 = xmlNode.Attributes["MayRequire"]; DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(val2, value3, xmlNode.InnerText, xmlAttribute4?.Value.ToLower()); } else { object obj = null; try { obj = GetObjectFromXmlMethod(value3.FieldType)(xmlNode, doPostLoad); } catch (Exception ex4) { Log.Error("Exception loading from " + xmlNode.ToString() + ": " + ex4.ToString()); continue; } if (!typeof(T).IsValueType) { value3.SetValue(val2, obj); continue; } object obj2 = val2; value3.SetValue(obj2, obj); val2 = (T)obj2; } } if (doPostLoad) { TryDoPostLoad(val2); } return(val2); }
public static void Look <T>(ref List <T> list, bool saveDestroyedThings, string label, LookMode lookMode = LookMode.Undefined, params object[] ctorArgs) { if (lookMode == LookMode.Undefined) { if (ParseHelper.HandlesType(typeof(T))) { lookMode = LookMode.Value; } else if (typeof(T) == typeof(LocalTargetInfo)) { lookMode = LookMode.LocalTargetInfo; } else if (typeof(T) == typeof(TargetInfo)) { lookMode = LookMode.TargetInfo; } else if (typeof(T) == typeof(GlobalTargetInfo)) { lookMode = LookMode.GlobalTargetInfo; } else if (typeof(Def).IsAssignableFrom(typeof(T))) { lookMode = LookMode.Def; } else if (typeof(T) == typeof(BodyPartRecord)) { lookMode = LookMode.BodyPart; } else { if (!typeof(IExposable).IsAssignableFrom(typeof(T)) || typeof(ILoadReferenceable).IsAssignableFrom(typeof(T))) { Log.Error("LookList call with a list of " + typeof(T) + " must have lookMode set explicitly.", false); return; } lookMode = LookMode.Deep; } } if (Scribe.EnterNode(label)) { try { if (Scribe.mode == LoadSaveMode.Saving) { if (list == null) { Scribe.saver.WriteAttribute("IsNull", "True"); } else { foreach (T current in list) { if (lookMode == LookMode.Value) { T t = current; Scribe_Values.Look <T>(ref t, "li", default(T), true); } else if (lookMode == LookMode.LocalTargetInfo) { LocalTargetInfo localTargetInfo = (LocalTargetInfo)((object)current); Scribe_TargetInfo.Look(ref localTargetInfo, saveDestroyedThings, "li"); } else if (lookMode == LookMode.TargetInfo) { TargetInfo targetInfo = (TargetInfo)((object)current); Scribe_TargetInfo.Look(ref targetInfo, saveDestroyedThings, "li"); } else if (lookMode == LookMode.GlobalTargetInfo) { GlobalTargetInfo globalTargetInfo = (GlobalTargetInfo)((object)current); Scribe_TargetInfo.Look(ref globalTargetInfo, saveDestroyedThings, "li"); } else if (lookMode == LookMode.Def) { Def def = (Def)((object)current); Scribe_Defs.Look <Def>(ref def, "li"); } else if (lookMode == LookMode.BodyPart) { BodyPartRecord bodyPartRecord = (BodyPartRecord)((object)current); Scribe_BodyParts.Look(ref bodyPartRecord, "li", null); } else if (lookMode == LookMode.Deep) { T t2 = current; Scribe_Deep.Look <T>(ref t2, saveDestroyedThings, "li", ctorArgs); } else if (lookMode == LookMode.Reference) { ILoadReferenceable loadReferenceable = (ILoadReferenceable)((object)current); Scribe_References.Look <ILoadReferenceable>(ref loadReferenceable, "li", saveDestroyedThings); } } } } else if (Scribe.mode == LoadSaveMode.LoadingVars) { XmlNode curXmlParent = Scribe.loader.curXmlParent; XmlAttribute xmlAttribute = curXmlParent.Attributes["IsNull"]; if (xmlAttribute != null && xmlAttribute.Value.ToLower() == "true") { list = null; } else if (lookMode == LookMode.Value) { list = new List <T>(curXmlParent.ChildNodes.Count); foreach (XmlNode subNode in curXmlParent.ChildNodes) { T item = ScribeExtractor.ValueFromNode <T>(subNode, default(T)); list.Add(item); } } else if (lookMode == LookMode.Deep) { list = new List <T>(curXmlParent.ChildNodes.Count); foreach (XmlNode subNode2 in curXmlParent.ChildNodes) { T item2 = ScribeExtractor.SaveableFromNode <T>(subNode2, ctorArgs); list.Add(item2); } } else if (lookMode == LookMode.Def) { list = new List <T>(curXmlParent.ChildNodes.Count); foreach (XmlNode subNode3 in curXmlParent.ChildNodes) { T item3 = ScribeExtractor.DefFromNodeUnsafe <T>(subNode3); list.Add(item3); } } else if (lookMode == LookMode.BodyPart) { list = new List <T>(curXmlParent.ChildNodes.Count); int num = 0; foreach (XmlNode node in curXmlParent.ChildNodes) { T item4 = (T)((object)ScribeExtractor.BodyPartFromNode(node, num.ToString(), null)); list.Add(item4); num++; } } else if (lookMode == LookMode.LocalTargetInfo) { list = new List <T>(curXmlParent.ChildNodes.Count); int num2 = 0; foreach (XmlNode node2 in curXmlParent.ChildNodes) { LocalTargetInfo localTargetInfo2 = ScribeExtractor.LocalTargetInfoFromNode(node2, num2.ToString(), LocalTargetInfo.Invalid); T item5 = (T)((object)localTargetInfo2); list.Add(item5); num2++; } } else if (lookMode == LookMode.TargetInfo) { list = new List <T>(curXmlParent.ChildNodes.Count); int num3 = 0; foreach (XmlNode node3 in curXmlParent.ChildNodes) { TargetInfo targetInfo2 = ScribeExtractor.TargetInfoFromNode(node3, num3.ToString(), TargetInfo.Invalid); T item6 = (T)((object)targetInfo2); list.Add(item6); num3++; } } else if (lookMode == LookMode.GlobalTargetInfo) { list = new List <T>(curXmlParent.ChildNodes.Count); int num4 = 0; foreach (XmlNode node4 in curXmlParent.ChildNodes) { GlobalTargetInfo globalTargetInfo2 = ScribeExtractor.GlobalTargetInfoFromNode(node4, num4.ToString(), GlobalTargetInfo.Invalid); T item7 = (T)((object)globalTargetInfo2); list.Add(item7); num4++; } } else if (lookMode == LookMode.Reference) { List <string> list2 = new List <string>(curXmlParent.ChildNodes.Count); foreach (XmlNode xmlNode in curXmlParent.ChildNodes) { list2.Add(xmlNode.InnerText); } Scribe.loader.crossRefs.loadIDs.RegisterLoadIDListReadFromXml(list2, string.Empty); } } else if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs) { if (lookMode == LookMode.Reference) { list = Scribe.loader.crossRefs.TakeResolvedRefList <T>(string.Empty); } else if (lookMode == LookMode.LocalTargetInfo) { if (list != null) { for (int i = 0; i < list.Count; i++) { list[i] = (T)((object)ScribeExtractor.ResolveLocalTargetInfo((LocalTargetInfo)((object)list[i]), i.ToString())); } } } else if (lookMode == LookMode.TargetInfo) { if (list != null) { for (int j = 0; j < list.Count; j++) { list[j] = (T)((object)ScribeExtractor.ResolveTargetInfo((TargetInfo)((object)list[j]), j.ToString())); } } } else if (lookMode == LookMode.GlobalTargetInfo && list != null) { for (int k = 0; k < list.Count; k++) { list[k] = (T)((object)ScribeExtractor.ResolveGlobalTargetInfo((GlobalTargetInfo)((object)list[k]), k.ToString())); } } } } finally { Scribe.ExitNode(); } } else if (Scribe.mode == LoadSaveMode.LoadingVars) { if (lookMode == LookMode.Reference) { Scribe.loader.crossRefs.loadIDs.RegisterLoadIDListReadFromXml(null, label); } list = null; } }
private bool SetDefFieldAtPath(Type defType, string path, object value, Type ensureFieldType, bool errorOnDefNotFound, string fileSource, bool isPlaceholder, out string normalizedPath, out string suggestedPath, out string replacedString, out IEnumerable <string> replacedStringsList) { replacedString = null; replacedStringsList = null; string b = path; string text = path; bool flag = TKeySystem.TryGetNormalizedPath(path, out normalizedPath); if (flag) { text = text + " (" + normalizedPath + ")"; suggestedPath = path; path = normalizedPath; } else { normalizedPath = path; suggestedPath = path; } string defName = path.Split('.')[0]; defName = BackCompatibility.BackCompatibleDefName(defType, defName, forDefInjections: true); if (GenDefDatabase.GetDefSilentFail(defType, defName, specialCaseForSoundDefs: false) == null) { if (errorOnDefNotFound) { loadErrors.Add("Found no " + defType + " named " + defName + " to match " + text + " (" + fileSource + ")"); } return(false); } bool flag2 = false; int num = 0; List <object> list = new List <object>(); try { List <string> list2 = path.Split('.').ToList(); object obj = GenGeneric.InvokeStaticMethodOnGenericType(typeof(DefDatabase <>), defType, "GetNamedSilentFail", list2[0]); if (obj == null) { throw new InvalidOperationException("Def named " + list2[0] + " not found."); } num++; string text2; int result; DefInjectionPathPartKind defInjectionPathPartKind; while (true) { text2 = list2[num]; list.Add(obj); result = -1; if (int.TryParse(text2, out result)) { defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; } else if (GetFieldNamed(obj.GetType(), text2) != null) { defInjectionPathPartKind = DefInjectionPathPartKind.Field; } else if (obj.GetType().GetProperty("Count") != null) { if (text2.Contains('-')) { defInjectionPathPartKind = DefInjectionPathPartKind.ListHandleWithIndex; string[] array = text2.Split('-'); text2 = array[0]; result = ParseHelper.FromString <int>(array[1]); } else { defInjectionPathPartKind = DefInjectionPathPartKind.ListHandle; } } else { defInjectionPathPartKind = DefInjectionPathPartKind.Field; } if (num == list2.Count - 1) { break; } switch (defInjectionPathPartKind) { case DefInjectionPathPartKind.Field: { FieldInfo field = obj.GetType().GetField(text2, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { throw new InvalidOperationException("Field or TKey " + text2 + " does not exist."); } if (field.HasAttribute <NoTranslateAttribute>()) { throw new InvalidOperationException("Translated untranslatable field " + field.Name + " of type " + field.FieldType + " at path " + text + ". Translating this field will break the game."); } if (field.HasAttribute <UnsavedAttribute>()) { throw new InvalidOperationException("Translated untranslatable field ([Unsaved] attribute) " + field.Name + " of type " + field.FieldType + " at path " + text + ". Translating this field will break the game."); } if (field.HasAttribute <TranslationCanChangeCountAttribute>()) { flag2 = true; } if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { obj = field.GetValue(obj); } else { object value2 = field.GetValue(obj); PropertyInfo property2 = value2.GetType().GetProperty("Item"); if (property2 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } int num3 = (int)value2.GetType().GetProperty("Count").GetValue(value2, null); if (result < 0 || result >= num3) { throw new InvalidOperationException("Index out of bounds (max index is " + (num3 - 1) + ")"); } obj = property2.GetValue(value2, new object[1] { result }); } break; } case DefInjectionPathPartKind.ListIndex: case DefInjectionPathPartKind.ListHandle: case DefInjectionPathPartKind.ListHandleWithIndex: { object obj2 = obj; PropertyInfo property = obj2.GetType().GetProperty("Item"); if (property == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } bool flag3; if (defInjectionPathPartKind == DefInjectionPathPartKind.ListHandle || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandleWithIndex) { result = TranslationHandleUtility.GetElementIndexByHandle(obj2, text2, result); defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; flag3 = true; } else { flag3 = false; } int num2 = (int)obj2.GetType().GetProperty("Count").GetValue(obj2, null); if (result < 0 || result >= num2) { throw new InvalidOperationException("Index out of bounds (max index is " + (num2 - 1) + ")"); } obj = property.GetValue(obj2, new object[1] { result }); if (flag3) { string[] array2 = normalizedPath.Split('.'); array2[num] = result.ToString(); normalizedPath = string.Join(".", array2); } else if (!flag) { string bestHandleWithIndexForListElement = TranslationHandleUtility.GetBestHandleWithIndexForListElement(obj2, obj); if (!bestHandleWithIndexForListElement.NullOrEmpty()) { string[] array3 = suggestedPath.Split('.'); array3[num] = bestHandleWithIndexForListElement; suggestedPath = string.Join(".", array3); } } break; } default: loadErrors.Add("Can't enter node " + text2 + " at path " + text + ", element kind is " + defInjectionPathPartKind + ". (" + fileSource + ")"); break; } num++; } bool flag4 = false; foreach (KeyValuePair <string, DefInjection> injection in injections) { if (!(injection.Key == b) && injection.Value.injected && injection.Value.normalizedPath == normalizedPath) { string text3 = "Duplicate def-injected translation key. Both " + injection.Value.path + " and " + text + " refer to the same field (" + suggestedPath + ")"; if (injection.Value.path != injection.Value.nonBackCompatiblePath) { text3 = text3 + " (" + injection.Value.nonBackCompatiblePath + " was auto-renamed to " + injection.Value.path + ")"; } text3 = text3 + " (" + injection.Value.fileSource + ")"; loadErrors.Add(text3); flag4 = true; break; } } bool result2 = false; if (!flag4) { switch (defInjectionPathPartKind) { case DefInjectionPathPartKind.Field: { FieldInfo fieldNamed = GetFieldNamed(obj.GetType(), text2); if (fieldNamed == null) { throw new InvalidOperationException("Field " + text2 + " does not exist in type " + obj.GetType() + "."); } if (fieldNamed.HasAttribute <NoTranslateAttribute>()) { loadErrors.Add("Translated untranslatable field " + fieldNamed.Name + " of type " + fieldNamed.FieldType + " at path " + text + ". Translating this field will break the game. (" + fileSource + ")"); } else if (fieldNamed.HasAttribute <UnsavedAttribute>()) { loadErrors.Add("Translated untranslatable field (UnsavedAttribute) " + fieldNamed.Name + " of type " + fieldNamed.FieldType + " at path " + text + ". Translating this field will break the game. (" + fileSource + ")"); } else if (!isPlaceholder && fieldNamed.FieldType != ensureFieldType) { loadErrors.Add("Translated non-" + ensureFieldType + " field " + fieldNamed.Name + " of type " + fieldNamed.FieldType + " at path " + text + ". Expected " + ensureFieldType + ". (" + fileSource + ")"); } else if (!isPlaceholder && ensureFieldType != typeof(string) && !fieldNamed.HasAttribute <TranslationCanChangeCountAttribute>()) { loadErrors.Add("Tried to translate field " + fieldNamed.Name + " of type " + fieldNamed.FieldType + " at path " + text + ", but this field doesn't have [TranslationCanChangeCount] attribute so it doesn't allow this type of translation. (" + fileSource + ")"); } else if (!isPlaceholder) { if (ensureFieldType == typeof(string)) { replacedString = (string)fieldNamed.GetValue(obj); } else { replacedStringsList = (fieldNamed.GetValue(obj) as IEnumerable <string>); } fieldNamed.SetValue(obj, value); result2 = true; } break; } case DefInjectionPathPartKind.ListIndex: case DefInjectionPathPartKind.ListHandle: case DefInjectionPathPartKind.ListHandleWithIndex: { object obj3 = obj; if (obj3 == null) { throw new InvalidOperationException("Tried to use index on null list at " + text); } Type type = obj3.GetType(); PropertyInfo property3 = type.GetProperty("Count"); if (property3 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Count' property)."); } if (defInjectionPathPartKind == DefInjectionPathPartKind.ListHandle || defInjectionPathPartKind == DefInjectionPathPartKind.ListHandleWithIndex) { result = TranslationHandleUtility.GetElementIndexByHandle(obj3, text2, result); defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; } int num4 = (int)property3.GetValue(obj3, null); if (result >= num4) { throw new InvalidOperationException("Trying to translate " + defType + "." + text + " at index " + result + " but the list only has " + num4 + " entries (so max index is " + (num4 - 1).ToString() + ")."); } PropertyInfo property4 = type.GetProperty("Item"); if (property4 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } Type propertyType = property4.PropertyType; if (!isPlaceholder && propertyType != ensureFieldType) { loadErrors.Add("Translated non-" + ensureFieldType + " list item of type " + propertyType + " at path " + text + ". Expected " + ensureFieldType + ". (" + fileSource + ")"); } else if (!isPlaceholder && ensureFieldType != typeof(string) && !flag2) { loadErrors.Add("Tried to translate field of type " + propertyType + " at path " + text + ", but this field doesn't have [TranslationCanChangeCount] attribute so it doesn't allow this type of translation. (" + fileSource + ")"); } else if (result < 0 || result >= (int)type.GetProperty("Count").GetValue(obj3, null)) { loadErrors.Add("Index out of bounds (max index is " + ((int)type.GetProperty("Count").GetValue(obj3, null) - 1) + ")"); } else if (!isPlaceholder) { replacedString = (string)property4.GetValue(obj3, new object[1] { result }); property4.SetValue(obj3, value, new object[1] { result }); result2 = true; } break; } default: loadErrors.Add("Translated " + text2 + " at path " + text + " but it's not a field, it's " + defInjectionPathPartKind + ". (" + fileSource + ")"); break; } } for (int num5 = list.Count - 1; num5 > 0; num5--) { if (list[num5].GetType().IsValueType&& !list[num5].GetType().IsPrimitive) { FieldInfo fieldNamed2 = GetFieldNamed(list[num5 - 1].GetType(), list2[num5]); if (fieldNamed2 != null) { fieldNamed2.SetValue(list[num5 - 1], list[num5]); } } } string tKeyPath; if (flag) { path = suggestedPath; } else if (TKeySystem.TrySuggestTKeyPath(path, out tKeyPath)) { suggestedPath = tKeyPath; } if (path != suggestedPath) { IList <string> list3 = value as IList <string>; string text4 = (list3 == null) ? value.ToString() : list3.ToStringSafeEnumerable(); loadSyntaxSuggestions.Add("Consider using " + suggestedPath + " instead of " + text + " for translation '" + text4 + "' (" + fileSource + ")"); } return(result2); } catch (Exception ex) { string text5 = "Couldn't inject " + text + " into " + defType + " (" + fileSource + "): " + ex.Message; if (ex.InnerException != null) { text5 = text5 + " -> " + ex.InnerException.Message; } loadErrors.Add(text5); return(false); } }
public static object FromString(string str, Type itemType) { try { itemType = (Nullable.GetUnderlyingType(itemType) ?? itemType); if (itemType == typeof(string)) { str = str.Replace("\\n", "\n"); return(str); } if (itemType == typeof(int)) { return(int.Parse(str, CultureInfo.InvariantCulture)); } if (itemType == typeof(float)) { return(float.Parse(str, CultureInfo.InvariantCulture)); } if (itemType == typeof(bool)) { return(bool.Parse(str)); } if (itemType == typeof(long)) { return(long.Parse(str, CultureInfo.InvariantCulture)); } if (itemType == typeof(double)) { return(double.Parse(str, CultureInfo.InvariantCulture)); } if (itemType == typeof(sbyte)) { return(sbyte.Parse(str, CultureInfo.InvariantCulture)); } if (itemType.IsEnum) { try { return(Enum.Parse(itemType, str)); } catch (ArgumentException innerException) { string str2 = "'" + str + "' is not a valid value for " + itemType + ". Valid values are: \n"; str2 += GenText.StringFromEnumerable(Enum.GetValues(itemType)); ArgumentException ex = new ArgumentException(str2, innerException); throw ex; } } if (itemType == typeof(Type)) { if (!(str == "null") && !(str == "Null")) { Type typeInAnyAssembly = GenTypes.GetTypeInAnyAssembly(str); if (typeInAnyAssembly == null) { Log.Error("Could not find a type named " + str); } return(typeInAnyAssembly); } return(null); } if (itemType == typeof(Action)) { string[] array = str.Split('.'); string methodName = array[array.Length - 1]; string empty = string.Empty; empty = ((array.Length != 3) ? array[0] : (array[0] + "." + array[1])); Type typeInAnyAssembly2 = GenTypes.GetTypeInAnyAssembly(empty); MethodInfo method = typeInAnyAssembly2.GetMethods().First((MethodInfo m) => m.Name == methodName); return((Action)Delegate.CreateDelegate(typeof(Action), method)); } if (itemType == typeof(Vector3)) { return(ParseHelper.FromStringVector3(str)); } if (itemType == typeof(Vector2)) { return(ParseHelper.FromStringVector2(str)); } if (itemType == typeof(Rect)) { return(ParseHelper.FromStringRect(str)); } if (itemType == typeof(Color)) { str = str.TrimStart('(', 'R', 'G', 'B', 'A'); str = str.TrimEnd(')'); string[] array2 = str.Split(','); float num = (float)ParseHelper.FromString(array2[0], typeof(float)); float num2 = (float)ParseHelper.FromString(array2[1], typeof(float)); float num3 = (float)ParseHelper.FromString(array2[2], typeof(float)); bool flag = num > 1.0 || num3 > 1.0 || num2 > 1.0; float num4 = (float)((!flag) ? 1 : 255); if (array2.Length == 4) { num4 = (float)ParseHelper.FromString(array2[3], typeof(float)); } Color color = default(Color); if (!flag) { color.r = num; color.g = num2; color.b = num3; color.a = num4; } else { color = GenColor.FromBytes(Mathf.RoundToInt(num), Mathf.RoundToInt(num2), Mathf.RoundToInt(num3), Mathf.RoundToInt(num4)); } return(color); } if (itemType == typeof(PublishedFileId_t)) { return(new PublishedFileId_t(ulong.Parse(str))); } if (itemType == typeof(IntVec2)) { return(IntVec2.FromString(str)); } if (itemType == typeof(IntVec3)) { return(IntVec3.FromString(str)); } if (itemType == typeof(Rot4)) { return(Rot4.FromString(str)); } if (itemType == typeof(CellRect)) { return(CellRect.FromString(str)); } if (itemType == typeof(CurvePoint)) { return(CurvePoint.FromString(str)); } if (itemType == typeof(NameTriple)) { NameTriple nameTriple = NameTriple.FromString(str); nameTriple.ResolveMissingPieces(null); } else { if (itemType == typeof(FloatRange)) { return(FloatRange.FromString(str)); } if (itemType == typeof(IntRange)) { return(IntRange.FromString(str)); } if (itemType == typeof(QualityRange)) { return(QualityRange.FromString(str)); } if (itemType == typeof(ColorInt)) { str = str.TrimStart('(', 'R', 'G', 'B', 'A'); str = str.TrimEnd(')'); string[] array3 = str.Split(','); ColorInt colorInt = new ColorInt(255, 255, 255, 255); colorInt.r = (int)ParseHelper.FromString(array3[0], typeof(int)); colorInt.g = (int)ParseHelper.FromString(array3[1], typeof(int)); colorInt.b = (int)ParseHelper.FromString(array3[2], typeof(int)); if (array3.Length == 4) { colorInt.a = (int)ParseHelper.FromString(array3[3], typeof(int)); } else { colorInt.a = 255; } return(colorInt); } } throw new ArgumentException("Trying to parse to unknown data type " + itemType.Name + ". Content is '" + str + "'."); } catch (Exception innerException2) { ArgumentException ex2 = new ArgumentException("Exception parsing " + itemType + " from \"" + str + "\"", innerException2); throw ex2; } }
private void SetDefFieldAtPath(Type defType, string path, string value) { path = BackCompatibility.BackCompatibleModifiedTranslationPath(defType, path); try { List <string> list = path.Split('.').ToList(); object obj = GenGeneric.InvokeStaticMethodOnGenericType(typeof(DefDatabase <>), defType, "GetNamedSilentFail", list[0]); if (obj == null) { throw new InvalidOperationException("Def named " + list[0] + " not found."); } list.RemoveAt(0); while (true) { DefInjectionPathPartKind defInjectionPathPartKind = DefInjectionPathPartKind.Field; string text = list[0]; int num = -1; if (text.Contains('[')) { defInjectionPathPartKind = DefInjectionPathPartKind.FieldWithListIndex; string[] array = text.Split('['); string text2 = array[1]; text2 = text2.Substring(0, text2.Length - 1); num = (int)ParseHelper.FromString(text2, typeof(int)); text = array[0]; } else if (int.TryParse(text, out num)) { defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; } if (list.Count == 1) { object obj2; switch (defInjectionPathPartKind) { case DefInjectionPathPartKind.Field: { FieldInfo fieldNamed = this.GetFieldNamed(obj.GetType(), text); if (fieldNamed == null) { throw new InvalidOperationException("Field " + text + " does not exist in type " + obj.GetType() + "."); } if (fieldNamed.HasAttribute <NoTranslateAttribute>()) { Log.Error("Translated untranslateable field " + fieldNamed.Name + " of type " + fieldNamed.FieldType + " at path " + path + ". Translating this field will break the game."); } else if (fieldNamed.FieldType != typeof(string)) { Log.Error("Translated non-string field " + fieldNamed.Name + " of type " + fieldNamed.FieldType + " at path " + path + ". Only string fields should be translated."); } else { fieldNamed.SetValue(obj, value); } return; } case DefInjectionPathPartKind.FieldWithListIndex: { FieldInfo field = obj.GetType().GetField(text, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { throw new InvalidOperationException("Field " + text + " does not exist."); } obj2 = field.GetValue(obj); break; } default: obj2 = obj; break; } Type type = obj2.GetType(); PropertyInfo property = type.GetProperty("Count"); if (property == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Count' property)."); } int num2 = (int)property.GetValue(obj2, null); if (num >= num2) { throw new InvalidOperationException("Trying to translate " + defType + "." + path + " at index " + num + " but the original list only has " + num2 + " entries (so the max index is " + (num2 - 1).ToString() + ")."); } PropertyInfo property2 = type.GetProperty("Item"); if (property2 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } property2.SetValue(obj2, value, new object[1] { num }); return; } if (defInjectionPathPartKind == DefInjectionPathPartKind.ListIndex) { PropertyInfo property3 = obj.GetType().GetProperty("Item"); if (property3 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } obj = property3.GetValue(obj, new object[1] { num }); goto IL_0421; } FieldInfo field2 = obj.GetType().GetField(text, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null) { throw new InvalidOperationException("Field " + text + " does not exist."); } if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { obj = field2.GetValue(obj); goto IL_0421; } object value2 = field2.GetValue(obj); PropertyInfo property4 = value2.GetType().GetProperty("Item"); if (property4 != null) { obj = property4.GetValue(value2, new object[1] { num }); goto IL_0421; } break; IL_0421: list.RemoveAt(0); } throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } catch (Exception ex) { Log.Warning("Def-linked translation error: Exception getting field at path " + path + " in " + defType + ": " + ex.ToString()); } }
public static void Look <T>(ref List <T> list, bool saveDestroyedThings, string label, LookMode lookMode = LookMode.Undefined, params object[] ctorArgs) { if (lookMode == LookMode.Undefined) { if (ParseHelper.HandlesType(typeof(T))) { lookMode = LookMode.Value; } else if (typeof(T) == typeof(LocalTargetInfo)) { lookMode = LookMode.LocalTargetInfo; } else if (typeof(T) == typeof(TargetInfo)) { lookMode = LookMode.TargetInfo; } else if (typeof(T) == typeof(GlobalTargetInfo)) { lookMode = LookMode.GlobalTargetInfo; } else if (typeof(Def).IsAssignableFrom(typeof(T))) { lookMode = LookMode.Def; } else if (typeof(T) == typeof(BodyPartRecord)) { lookMode = LookMode.BodyPart; } else { if (!typeof(IExposable).IsAssignableFrom(typeof(T)) || typeof(ILoadReferenceable).IsAssignableFrom(typeof(T))) { Log.Error("LookList call with a list of " + typeof(T) + " must have lookMode set explicitly."); return; } lookMode = LookMode.Deep; } } if (Scribe.EnterNode(label)) { try { if (Scribe.mode == LoadSaveMode.Saving) { if (list == null) { Scribe.saver.WriteAttribute("IsNull", "True"); } else { foreach (T item8 in list) { switch (lookMode) { case LookMode.Value: { T value5 = item8; Scribe_Values.Look(ref value5, "li", default(T), forceSave: true); break; } case LookMode.LocalTargetInfo: { LocalTargetInfo value4 = (LocalTargetInfo)(object)item8; Scribe_TargetInfo.Look(ref value4, saveDestroyedThings, "li"); break; } case LookMode.TargetInfo: { TargetInfo value3 = (TargetInfo)(object)item8; Scribe_TargetInfo.Look(ref value3, saveDestroyedThings, "li"); break; } case LookMode.GlobalTargetInfo: { GlobalTargetInfo value2 = (GlobalTargetInfo)(object)item8; Scribe_TargetInfo.Look(ref value2, saveDestroyedThings, "li"); break; } case LookMode.Def: { Def value = (Def)(object)item8; Scribe_Defs.Look(ref value, "li"); break; } case LookMode.BodyPart: { BodyPartRecord part = (BodyPartRecord)(object)item8; Scribe_BodyParts.Look(ref part, "li"); break; } case LookMode.Deep: { T target = item8; Scribe_Deep.Look(ref target, saveDestroyedThings, "li", ctorArgs); break; } case LookMode.Reference: { ILoadReferenceable refee = (ILoadReferenceable)(object)item8; Scribe_References.Look(ref refee, "li", saveDestroyedThings); break; } } } } } else if (Scribe.mode == LoadSaveMode.LoadingVars) { XmlNode curXmlParent = Scribe.loader.curXmlParent; XmlAttribute xmlAttribute = curXmlParent.Attributes["IsNull"]; if (xmlAttribute == null || !(xmlAttribute.Value.ToLower() == "true")) { switch (lookMode) { case LookMode.Value: { list = new List <T>(curXmlParent.ChildNodes.Count); IEnumerator enumerator3 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator3.MoveNext()) { XmlNode subNode = (XmlNode)enumerator3.Current; T item = ScribeExtractor.ValueFromNode(subNode, default(T)); list.Add(item); } } finally { IDisposable disposable2; if ((disposable2 = (enumerator3 as IDisposable)) != null) { disposable2.Dispose(); } } break; } case LookMode.Deep: { list = new List <T>(curXmlParent.ChildNodes.Count); IEnumerator enumerator9 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator9.MoveNext()) { XmlNode subNode3 = (XmlNode)enumerator9.Current; T item7 = ScribeExtractor.SaveableFromNode <T>(subNode3, ctorArgs); list.Add(item7); } } finally { IDisposable disposable8; if ((disposable8 = (enumerator9 as IDisposable)) != null) { disposable8.Dispose(); } } break; } case LookMode.Def: { list = new List <T>(curXmlParent.ChildNodes.Count); IEnumerator enumerator8 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator8.MoveNext()) { XmlNode subNode2 = (XmlNode)enumerator8.Current; T item6 = ScribeExtractor.DefFromNodeUnsafe <T>(subNode2); list.Add(item6); } } finally { IDisposable disposable7; if ((disposable7 = (enumerator8 as IDisposable)) != null) { disposable7.Dispose(); } } break; } case LookMode.BodyPart: { list = new List <T>(curXmlParent.ChildNodes.Count); int num4 = 0; IEnumerator enumerator7 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator7.MoveNext()) { XmlNode node4 = (XmlNode)enumerator7.Current; T item5 = (T)(object)ScribeExtractor.BodyPartFromNode(node4, num4.ToString(), null); list.Add(item5); num4++; } } finally { IDisposable disposable6; if ((disposable6 = (enumerator7 as IDisposable)) != null) { disposable6.Dispose(); } } break; } case LookMode.LocalTargetInfo: { list = new List <T>(curXmlParent.ChildNodes.Count); int num3 = 0; IEnumerator enumerator6 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator6.MoveNext()) { XmlNode node3 = (XmlNode)enumerator6.Current; LocalTargetInfo localTargetInfo = ScribeExtractor.LocalTargetInfoFromNode(node3, num3.ToString(), LocalTargetInfo.Invalid); T item4 = (T)(object)localTargetInfo; list.Add(item4); num3++; } } finally { IDisposable disposable5; if ((disposable5 = (enumerator6 as IDisposable)) != null) { disposable5.Dispose(); } } break; } case LookMode.TargetInfo: { list = new List <T>(curXmlParent.ChildNodes.Count); int num2 = 0; IEnumerator enumerator5 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator5.MoveNext()) { XmlNode node2 = (XmlNode)enumerator5.Current; TargetInfo targetInfo = ScribeExtractor.TargetInfoFromNode(node2, num2.ToString(), TargetInfo.Invalid); T item3 = (T)(object)targetInfo; list.Add(item3); num2++; } } finally { IDisposable disposable4; if ((disposable4 = (enumerator5 as IDisposable)) != null) { disposable4.Dispose(); } } break; } case LookMode.GlobalTargetInfo: { list = new List <T>(curXmlParent.ChildNodes.Count); int num = 0; IEnumerator enumerator4 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator4.MoveNext()) { XmlNode node = (XmlNode)enumerator4.Current; GlobalTargetInfo globalTargetInfo = ScribeExtractor.GlobalTargetInfoFromNode(node, num.ToString(), GlobalTargetInfo.Invalid); T item2 = (T)(object)globalTargetInfo; list.Add(item2); num++; } } finally { IDisposable disposable3; if ((disposable3 = (enumerator4 as IDisposable)) != null) { disposable3.Dispose(); } } break; } case LookMode.Reference: { List <string> list2 = new List <string>(curXmlParent.ChildNodes.Count); IEnumerator enumerator2 = curXmlParent.ChildNodes.GetEnumerator(); try { while (enumerator2.MoveNext()) { XmlNode xmlNode = (XmlNode)enumerator2.Current; list2.Add(xmlNode.InnerText); } } finally { IDisposable disposable; if ((disposable = (enumerator2 as IDisposable)) != null) { disposable.Dispose(); } } Scribe.loader.crossRefs.loadIDs.RegisterLoadIDListReadFromXml(list2, string.Empty); break; } } } else { list = null; } } else if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs) { switch (lookMode) { case LookMode.Reference: list = Scribe.loader.crossRefs.TakeResolvedRefList <T>(string.Empty); break; case LookMode.LocalTargetInfo: if (list != null) { for (int j = 0; j < list.Count; j++) { list[j] = (T)(object)ScribeExtractor.ResolveLocalTargetInfo((LocalTargetInfo)(object)list[j], j.ToString()); } } break; case LookMode.TargetInfo: if (list != null) { for (int k = 0; k < list.Count; k++) { list[k] = (T)(object)ScribeExtractor.ResolveTargetInfo((TargetInfo)(object)list[k], k.ToString()); } } break; case LookMode.GlobalTargetInfo: if (list != null) { for (int i = 0; i < list.Count; i++) { list[i] = (T)(object)ScribeExtractor.ResolveGlobalTargetInfo((GlobalTargetInfo)(object)list[i], i.ToString()); } } break; } } } finally { Scribe.ExitNode(); } } else if (Scribe.mode == LoadSaveMode.LoadingVars) { if (lookMode == LookMode.Reference) { Scribe.loader.crossRefs.loadIDs.RegisterLoadIDListReadFromXml(null, label); } list = null; } }
public static T ObjectFromXml <T>(XmlNode xmlRoot, bool doPostLoad) where T : new() { MethodInfo methodInfo = CustomDataLoadMethodOf(typeof(T)); if (methodInfo != null) { xmlRoot = XmlInheritance.GetResolvedNodeFor(xmlRoot); Type type = ClassTypeOf <T>(xmlRoot); currentlyInstantiatingObjectOfType.Push(type); T val; try { val = (T)Activator.CreateInstance(type); } finally { currentlyInstantiatingObjectOfType.Pop(); } try { methodInfo.Invoke(val, new object[1] { xmlRoot }); } catch (Exception ex) { Log.Error("Exception in custom XML loader for " + typeof(T) + ". Node is:\n " + xmlRoot.OuterXml + "\n\nException is:\n " + ex.ToString()); val = default(T); } if (doPostLoad) { TryDoPostLoad(val); } return(val); } if (xmlRoot.ChildNodes.Count == 1 && xmlRoot.FirstChild.NodeType == XmlNodeType.CDATA) { if (typeof(T) != typeof(string)) { Log.Error("CDATA can only be used for strings. Bad xml: " + xmlRoot.OuterXml); return(default(T)); } return((T)(object)xmlRoot.FirstChild.Value); } if (xmlRoot.ChildNodes.Count == 1 && xmlRoot.FirstChild.NodeType == XmlNodeType.Text) { try { return((T)ParseHelper.FromString(xmlRoot.InnerText, typeof(T))); } catch (Exception ex2) { Log.Error("Exception parsing " + xmlRoot.OuterXml + " to type " + typeof(T) + ": " + ex2); } return(default(T)); } if (Attribute.IsDefined(typeof(T), typeof(FlagsAttribute))) { List <T> list = ListFromXml <T>(xmlRoot); int num = 0; foreach (T item in list) { int num2 = (int)(object)item; num |= num2; } return((T)(object)num); } if (typeof(T).HasGenericDefinition(typeof(List <>))) { MethodInfo method = typeof(DirectXmlToObject).GetMethod("ListFromXml", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] genericArguments = typeof(T).GetGenericArguments(); MethodInfo methodInfo2 = method.MakeGenericMethod(genericArguments); object[] parameters = new object[1] { xmlRoot }; object obj = methodInfo2.Invoke(null, parameters); return((T)obj); } if (typeof(T).HasGenericDefinition(typeof(Dictionary <, >))) { MethodInfo method2 = typeof(DirectXmlToObject).GetMethod("DictionaryFromXml", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] genericArguments2 = typeof(T).GetGenericArguments(); MethodInfo methodInfo3 = method2.MakeGenericMethod(genericArguments2); object[] parameters2 = new object[1] { xmlRoot }; object obj2 = methodInfo3.Invoke(null, parameters2); return((T)obj2); } if (!xmlRoot.HasChildNodes) { if (typeof(T) == typeof(string)) { return((T)(object)string.Empty); } XmlAttribute xmlAttribute = xmlRoot.Attributes["IsNull"]; if (xmlAttribute != null && xmlAttribute.Value.ToUpperInvariant() == "TRUE") { return(default(T)); } if (typeof(T).IsGenericType) { Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(List <>) || genericTypeDefinition == typeof(HashSet <>) || genericTypeDefinition == typeof(Dictionary <, >)) { return(new T()); } } } xmlRoot = XmlInheritance.GetResolvedNodeFor(xmlRoot); Type type2 = ClassTypeOf <T>(xmlRoot); Type type3 = Nullable.GetUnderlyingType(type2) ?? type2; currentlyInstantiatingObjectOfType.Push(type3); T val2; try { val2 = (T)Activator.CreateInstance(type3); } finally { currentlyInstantiatingObjectOfType.Pop(); } List <string> list2 = null; if (xmlRoot.ChildNodes.Count > 1) { list2 = new List <string>(); } for (int i = 0; i < xmlRoot.ChildNodes.Count; i++) { XmlNode xmlNode = xmlRoot.ChildNodes[i]; if (!(xmlNode is XmlComment)) { if (xmlRoot.ChildNodes.Count > 1) { if (list2.Contains(xmlNode.Name)) { Log.Error("XML " + typeof(T) + " defines the same field twice: " + xmlNode.Name + ".\n\nField contents: " + xmlNode.InnerText + ".\n\nWhole XML:\n\n" + xmlRoot.OuterXml); } else { list2.Add(xmlNode.Name); } } FieldInfo fieldInfo = GetFieldInfoForType(val2.GetType(), xmlNode.Name, xmlRoot); if (fieldInfo == null) { FieldInfo[] fields = val2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo2 in fields) { object[] customAttributes = fieldInfo2.GetCustomAttributes(typeof(LoadAliasAttribute), inherit: true); foreach (object obj3 in customAttributes) { string alias = ((LoadAliasAttribute)obj3).alias; if (alias.EqualsIgnoreCase(xmlNode.Name)) { fieldInfo = fieldInfo2; break; } } if (fieldInfo != null) { break; } } } if (fieldInfo != null && fieldInfo.TryGetAttribute <UnsavedAttribute>() != null) { Log.Error("XML error: " + xmlNode.OuterXml + " corresponds to a field in type " + val2.GetType().Name + " which has an Unsaved attribute. Context: " + xmlRoot.OuterXml); } else if (fieldInfo == null) { bool flag = false; object[] customAttributes2 = val2.GetType().GetCustomAttributes(typeof(IgnoreSavedElementAttribute), inherit: true); foreach (object obj4 in customAttributes2) { string elementToIgnore = ((IgnoreSavedElementAttribute)obj4).elementToIgnore; if (string.Equals(elementToIgnore, xmlNode.Name, StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } if (!flag) { Log.Error("XML error: " + xmlNode.OuterXml + " doesn't correspond to any field in type " + val2.GetType().Name + ". Context: " + xmlRoot.OuterXml); } } else if (typeof(Def).IsAssignableFrom(fieldInfo.FieldType)) { if (xmlNode.InnerText.NullOrEmpty()) { fieldInfo.SetValue(val2, null); } else { DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(val2, fieldInfo, xmlNode.InnerText); } } else { object obj5 = null; try { MethodInfo method3 = typeof(DirectXmlToObject).GetMethod("ObjectFromXml", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo4 = method3.MakeGenericMethod(fieldInfo.FieldType); obj5 = methodInfo4.Invoke(null, new object[2] { xmlNode, doPostLoad }); } catch (Exception ex3) { Log.Error("Exception loading from " + xmlNode.ToString() + ": " + ex3.ToString()); continue; } if (!typeof(T).IsValueType) { fieldInfo.SetValue(val2, obj5); } else { object obj6 = val2; fieldInfo.SetValue(obj6, obj5); val2 = (T)obj6; } } } } if (doPostLoad) { TryDoPostLoad(val2); } return(val2); }
public static bool TryResolveLookMode(Type type, out LookMode lookMode, bool desperate = false, bool preferDeepIfDesperateAndAmbiguous = false) { if (type == null) { if (desperate) { lookMode = LookMode.Value; return(true); } lookMode = LookMode.Undefined; return(false); } if (type == typeof(object) && desperate) { lookMode = LookMode.Value; return(true); } if (ParseHelper.HandlesType(type)) { lookMode = LookMode.Value; return(true); } if (type == typeof(LocalTargetInfo)) { lookMode = LookMode.LocalTargetInfo; return(true); } if (type == typeof(TargetInfo)) { lookMode = LookMode.TargetInfo; return(true); } if (type == typeof(GlobalTargetInfo)) { lookMode = LookMode.GlobalTargetInfo; return(true); } if (typeof(Def).IsAssignableFrom(type)) { lookMode = LookMode.Def; return(true); } if (type == typeof(BodyPartRecord)) { lookMode = LookMode.BodyPart; return(true); } if (typeof(IExposable).IsAssignableFrom(type) && !typeof(ILoadReferenceable).IsAssignableFrom(type)) { lookMode = LookMode.Deep; return(true); } if (desperate && typeof(ILoadReferenceable).IsAssignableFrom(type)) { if (preferDeepIfDesperateAndAmbiguous) { lookMode = LookMode.Deep; } else { lookMode = LookMode.Reference; } return(true); } lookMode = LookMode.Undefined; return(false); }
private void SetDefFieldAtPath(Type defType, string path, string value) { path = BackCompatibility.BackCompatibleModifiedTranslationPath(defType, path); try { List <string> list = path.Split(new char[] { '.' }).ToList <string>(); object obj = GenGeneric.InvokeStaticMethodOnGenericType(typeof(DefDatabase <>), defType, "GetNamedSilentFail", new object[] { list[0] }); if (obj == null) { throw new InvalidOperationException("Def named " + list[0] + " not found."); } list.RemoveAt(0); DefInjectionPathPartKind defInjectionPathPartKind; string text; int num; while (true) { defInjectionPathPartKind = DefInjectionPathPartKind.Field; text = list[0]; num = -1; if (text.Contains('[')) { defInjectionPathPartKind = DefInjectionPathPartKind.FieldWithListIndex; string[] array = text.Split(new char[] { '[' }); string text2 = array[1]; text2 = text2.Substring(0, text2.Length - 1); num = (int)ParseHelper.FromString(text2, typeof(int)); text = array[0]; } else if (int.TryParse(text, out num)) { defInjectionPathPartKind = DefInjectionPathPartKind.ListIndex; } if (list.Count == 1) { break; } if (defInjectionPathPartKind == DefInjectionPathPartKind.ListIndex) { PropertyInfo property = obj.GetType().GetProperty("Item"); if (property == null) { goto Block_17; } obj = property.GetValue(obj, new object[] { num }); } else { FieldInfo field = obj.GetType().GetField(text, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { goto Block_18; } if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { obj = field.GetValue(obj); } else { object value2 = field.GetValue(obj); PropertyInfo property2 = value2.GetType().GetProperty("Item"); if (property2 == null) { goto Block_20; } obj = property2.GetValue(value2, new object[] { num }); } } list.RemoveAt(0); } if (defInjectionPathPartKind == DefInjectionPathPartKind.Field) { FieldInfo fieldNamed = this.GetFieldNamed(obj.GetType(), text); if (fieldNamed == null) { throw new InvalidOperationException(string.Concat(new object[] { "Field ", text, " does not exist in type ", obj.GetType(), "." })); } if (fieldNamed.HasAttribute <NoTranslateAttribute>()) { Log.Error(string.Concat(new object[] { "Translated untranslateable field ", fieldNamed.Name, " of type ", fieldNamed.FieldType, " at path ", path, ". Translating this field will break the game." })); } else if (fieldNamed.FieldType != typeof(string)) { Log.Error(string.Concat(new object[] { "Translated non-string field ", fieldNamed.Name, " of type ", fieldNamed.FieldType, " at path ", path, ". Only string fields should be translated." })); } else { fieldNamed.SetValue(obj, value); } } else { object obj2; if (defInjectionPathPartKind == DefInjectionPathPartKind.FieldWithListIndex) { FieldInfo field2 = obj.GetType().GetField(text, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null) { throw new InvalidOperationException("Field " + text + " does not exist."); } obj2 = field2.GetValue(obj); } else { obj2 = obj; } Type type = obj2.GetType(); PropertyInfo property3 = type.GetProperty("Count"); if (property3 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Count' property)."); } int num2 = (int)property3.GetValue(obj2, null); if (num >= num2) { throw new InvalidOperationException(string.Concat(new object[] { "Trying to translate ", defType, ".", path, " at index ", num, " but the original list only has ", num2, " entries (so the max index is ", (num2 - 1).ToString(), ")." })); } PropertyInfo property4 = type.GetProperty("Item"); if (property4 == null) { throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } property4.SetValue(obj2, value, new object[] { num }); } return; Block_17: throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); Block_18: throw new InvalidOperationException("Field " + text + " does not exist."); Block_20: throw new InvalidOperationException("Tried to use index on non-list (missing 'Item' property)."); } catch (Exception ex) { Log.Warning(string.Concat(new object[] { "Def-linked translation error: Exception getting field at path ", path, " in ", defType, ": ", ex.ToString() })); } }
public static bool CanConvert(object obj, Type to) { if (obj == null) { return(true); } if (to.IsAssignableFrom(obj.GetType())) { return(true); } if (to == typeof(string)) { return(true); } if (obj is string && !to.IsPrimitive && ParseHelper.CanParse(to, (string)obj)) { return(true); } if (obj is string && typeof(Def).IsAssignableFrom(to)) { return(true); } if (obj is string && to == typeof(Faction)) { return(true); } if (CanConvertBetweenDataTypes(obj.GetType(), to)) { return(true); } if (IsXml(obj) && !to.IsPrimitive) { return(true); } if (to.IsGenericType && (to.GetGenericTypeDefinition() == typeof(IEnumerable <>) || to.GetGenericTypeDefinition() == typeof(List <>)) && to.GetGenericArguments().Length >= 1 && (!(to.GetGenericArguments()[0] == typeof(string)) || !(obj is string))) { IEnumerable enumerable = obj as IEnumerable; if (enumerable != null) { Type to2 = to.GetGenericArguments()[0]; bool flag = true; foreach (object item in enumerable) { if (!CanConvert(item, to2)) { flag = false; break; } } if (flag) { return(true); } } } if (obj is IEnumerable && !(obj is string)) { IEnumerable e = (IEnumerable)obj; if (GenCollection.Count_EnumerableBase(e) == 1 && CanConvert(GenCollection.FirstOrDefault_EnumerableBase(e), to)) { return(true); } } if (typeof(IList).IsAssignableFrom(to)) { Type[] genericArguments = to.GetGenericArguments(); if (genericArguments.Length >= 1) { return(CanConvert(obj, genericArguments[0])); } return(true); } if (to == typeof(IEnumerable)) { return(true); } if (to.IsGenericType && to.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { Type[] genericArguments2 = to.GetGenericArguments(); if (genericArguments2.Length >= 1) { return(CanConvert(obj, genericArguments2[0])); } return(true); } IConvertible convertible = obj as IConvertible; if (convertible == null) { return(false); } Type left = Nullable.GetUnderlyingType(to) ?? to; if (left != typeof(bool) && left != typeof(byte) && left != typeof(char) && left != typeof(DateTime) && left != typeof(decimal) && left != typeof(double) && left != typeof(short) && left != typeof(int) && left != typeof(long) && left != typeof(sbyte) && left != typeof(float) && left != typeof(string) && left != typeof(ushort) && left != typeof(uint) && left != typeof(ulong)) { return(false); } try { ConvertToPrimitive(convertible, to, null); } catch (FormatException) { return(false); } return(true); }
public static CurvePoint FromString(string str) { return(new CurvePoint((Vector2)ParseHelper.FromString(str, typeof(Vector2)))); }
public void LoadDataFromXmlCustom(XmlNode xmlRoot) { DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(this, "skill", xmlRoot.Name); this.minLevel = (int)ParseHelper.FromString(xmlRoot.FirstChild.Value, typeof(int)); }
public static CurvePoint FromString(string str) { return(new CurvePoint(ParseHelper.FromString <Vector2>(str))); }