public static bool HandlesMatch(object item, string handle)
        {
            if (item == null)
            {
                return(false);
            }
            if (handle.NullOrEmpty())
            {
                return(false);
            }
            handle = TranslationHandleUtility.NormalizedHandle(handle);
            if (handle.NullOrEmpty())
            {
                return(false);
            }
            Type type = item as Type;

            if (type != null)
            {
                return(TranslationHandleUtility.NormalizedHandle(type.Name) == handle || TranslationHandleUtility.NormalizedHandle(type.FullName) == handle || TranslationHandleUtility.NormalizedHandle(type.ToString()) == handle);
            }
            string text;

            try
            {
                text = item.ToString();
            }
            catch (Exception arg)
            {
                throw new InvalidOperationException("Could not get element by handle because one of the elements threw an exception in its ToString(): " + arg);
            }
            return(!text.NullOrEmpty() && TranslationHandleUtility.NormalizedHandle(text) == handle);
        }
 private static void ForEachPossibleDefInjectionInDefRecursive(object obj, string curNormalizedPath, string curSuggestedPath, HashSet <object> visited, bool translationAllowed, Def def, PossibleDefInjectionTraverser action)
 {
     if (obj == null || (!obj.GetType().IsValueType&& visited.Contains(obj)))
     {
         return;
     }
     visited.Add(obj);
     foreach (FieldInfo item in FieldsInDeterministicOrder(obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)))
     {
         object value = item.GetValue(obj);
         bool   flag  = translationAllowed && !item.HasAttribute <NoTranslateAttribute>() && !item.HasAttribute <UnsavedAttribute>();
         if (value is Def)
         {
             continue;
         }
         if (typeof(string).IsAssignableFrom(item.FieldType))
         {
             string currentValue  = (string)value;
             string text          = curNormalizedPath + "." + item.Name;
             string suggestedPath = curSuggestedPath + "." + item.Name;
             if (TKeySystem.TrySuggestTKeyPath(text, out var tKeyPath))
             {
                 suggestedPath = tKeyPath;
             }
             action(suggestedPath, text, isCollection: false, currentValue, null, flag, fullListTranslationAllowed: false, item, def);
         }
         else if (value is IEnumerable <string> )
         {
             IEnumerable <string> currentValueCollection = (IEnumerable <string>)value;
             bool   flag2          = item.HasAttribute <TranslationCanChangeCountAttribute>();
             string text2          = curNormalizedPath + "." + item.Name;
             string suggestedPath2 = curSuggestedPath + "." + item.Name;
             if (TKeySystem.TrySuggestTKeyPath(text2, out var tKeyPath2))
             {
                 suggestedPath2 = tKeyPath2;
             }
             action(suggestedPath2, text2, isCollection: true, null, currentValueCollection, flag, flag && flag2, item, def);
         }
         else if (value is IEnumerable)
         {
             IEnumerable enumerable = (IEnumerable)value;
             int         num        = 0;
             foreach (object item2 in enumerable)
             {
                 if (item2 != null && !(item2 is Def) && GenTypes.IsCustomType(item2.GetType()))
                 {
                     string text3 = TranslationHandleUtility.GetBestHandleWithIndexForListElement(enumerable, item2);
                     if (text3.NullOrEmpty())
                     {
                         text3 = num.ToString();
                     }
                     string curNormalizedPath2 = curNormalizedPath + "." + item.Name + "." + num;
                     string curSuggestedPath2  = curSuggestedPath + "." + item.Name + "." + text3;
                     ForEachPossibleDefInjectionInDefRecursive(item2, curNormalizedPath2, curSuggestedPath2, visited, flag, def, action);
                 }
                 num++;
             }
         }
         else if (value != null && GenTypes.IsCustomType(value.GetType()))
         {
             string curNormalizedPath3 = curNormalizedPath + "." + item.Name;
             string curSuggestedPath3  = curSuggestedPath + "." + item.Name;
             ForEachPossibleDefInjectionInDefRecursive(value, curNormalizedPath3, curSuggestedPath3, visited, flag, def, action);
         }
     }
 }
        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 int GetElementIndexByHandle(object list, string handle, int handleIndex)
        {
            if (list == null)
            {
                throw new InvalidOperationException("Tried to get element by handle on null object.");
            }
            if (handleIndex < 0)
            {
                handleIndex = 0;
            }
            PropertyInfo property = list.GetType().GetProperty("Count");

            if (property == null)
            {
                throw new InvalidOperationException("Tried to get element by handle on non-list (missing 'Count' property).");
            }
            PropertyInfo property2 = list.GetType().GetProperty("Item");

            if (property2 == null)
            {
                throw new InvalidOperationException("Tried to get element by handle on non-list (missing 'Item' property).");
            }
            int       num       = (int)property.GetValue(list, null);
            FieldInfo fieldInfo = null;
            int       num2      = 0;

            for (int i = 0; i < num; i++)
            {
                object value = property2.GetValue(list, new object[]
                {
                    i
                });
                if (value != null)
                {
                    FieldInfo[] fields = value.GetType().GetFields(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                    FieldInfo[] array  = fields;
                    for (int j = 0; j < array.Length; j++)
                    {
                        FieldInfo fieldInfo2 = array[j];
                        TranslationHandleAttribute translationHandleAttribute = fieldInfo2.TryGetAttribute <TranslationHandleAttribute>();
                        if (translationHandleAttribute != null)
                        {
                            object value2 = fieldInfo2.GetValue(value);
                            if (value2 != null)
                            {
                                if (TranslationHandleUtility.HandlesMatch(value2, handle))
                                {
                                    int priority = translationHandleAttribute.Priority;
                                    if (fieldInfo == null || priority > num2)
                                    {
                                        fieldInfo = fieldInfo2;
                                        num2      = priority;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (fieldInfo == null)
            {
                throw new InvalidOperationException("None of the list elements have a handle named " + handle + ".");
            }
            int num3 = 0;

            for (int k = 0; k < num; k++)
            {
                object value3 = property2.GetValue(list, new object[]
                {
                    k
                });
                if (value3 != null)
                {
                    FieldInfo[] fields2 = value3.GetType().GetFields(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                    FieldInfo[] array2  = fields2;
                    for (int l = 0; l < array2.Length; l++)
                    {
                        FieldInfo fieldInfo3 = array2[l];
                        if (TranslationHandleUtility.FieldInfosEqual(fieldInfo3, fieldInfo))
                        {
                            object value4 = fieldInfo3.GetValue(value3);
                            if (value4 != null)
                            {
                                if (TranslationHandleUtility.HandlesMatch(value4, handle))
                                {
                                    if (num3 == handleIndex)
                                    {
                                        return(k);
                                    }
                                    num3++;
                                }
                            }
                        }
                    }
                }
            }
            throw new InvalidOperationException(string.Concat(new object[]
            {
                "Tried to access handle ",
                handle,
                "[",
                handleIndex,
                "], but there are only ",
                num3,
                " handles matching this name."
            }));
        }
        public static string GetBestHandleWithIndexForListElement(object list, object element)
        {
            if (list == null || element == null)
            {
                return(null);
            }
            PropertyInfo property = list.GetType().GetProperty("Count");

            if (property == null)
            {
                return(null);
            }
            PropertyInfo property2 = list.GetType().GetProperty("Item");

            if (property2 == null)
            {
                return(null);
            }
            FieldInfo fieldInfo = null;
            string    handle    = null;
            int       num       = 0;

            FieldInfo[] fields = element.GetType().GetFields(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            FieldInfo[] array  = fields;
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo fieldInfo2 = array[i];
                TranslationHandleAttribute translationHandleAttribute = fieldInfo2.TryGetAttribute <TranslationHandleAttribute>();
                if (translationHandleAttribute != null)
                {
                    object value = fieldInfo2.GetValue(element);
                    if (value != null)
                    {
                        Type   type = value as Type;
                        string text;
                        if (type != null)
                        {
                            text = type.Name;
                        }
                        else
                        {
                            try
                            {
                                text = value.ToString();
                            }
                            catch
                            {
                                return(null);
                            }
                        }
                        if (!text.NullOrEmpty())
                        {
                            int priority = translationHandleAttribute.Priority;
                            if (fieldInfo == null || priority > num)
                            {
                                fieldInfo = fieldInfo2;
                                handle    = text;
                                num       = priority;
                            }
                        }
                    }
                }
            }
            if (fieldInfo == null)
            {
                return(null);
            }
            int num2 = 0;
            int num3 = -1;
            int num4 = (int)property.GetValue(list, null);

            for (int j = 0; j < num4; j++)
            {
                object value2 = property2.GetValue(list, new object[]
                {
                    j
                });
                if (value2 != null)
                {
                    if (value2 == element)
                    {
                        num3 = num2;
                        num2++;
                    }
                    else
                    {
                        FieldInfo[] fields2 = value2.GetType().GetFields(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        FieldInfo[] array2  = fields2;
                        for (int k = 0; k < array2.Length; k++)
                        {
                            FieldInfo fieldInfo3 = array2[k];
                            if (TranslationHandleUtility.FieldInfosEqual(fieldInfo3, fieldInfo))
                            {
                                object value3 = fieldInfo3.GetValue(value2);
                                if (value3 != null)
                                {
                                    if (TranslationHandleUtility.HandlesMatch(value3, handle))
                                    {
                                        num2++;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (num3 < 0)
            {
                return(null);
            }
            string text2 = TranslationHandleUtility.NormalizedHandle(handle);

            if (num2 <= 1)
            {
                return(text2);
            }
            return(text2 + '-' + num3);
        }
Exemple #6
0
 private static void ForEachPossibleDefInjectionInDefRecursive(object obj, string curNormalizedPath, string curSuggestedPath, HashSet <object> visited, bool translationAllowed, Def def, DefInjectionUtility.PossibleDefInjectionTraverser action)
 {
     if (obj == null)
     {
         return;
     }
     if (visited.Contains(obj))
     {
         return;
     }
     visited.Add(obj);
     foreach (FieldInfo fieldInfo in DefInjectionUtility.FieldsInDeterministicOrder(obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)))
     {
         object value = fieldInfo.GetValue(obj);
         bool   flag  = translationAllowed && !fieldInfo.HasAttribute <NoTranslateAttribute>() && !fieldInfo.HasAttribute <UnsavedAttribute>();
         if (!(value is Def))
         {
             if (typeof(string).IsAssignableFrom(fieldInfo.FieldType))
             {
                 string currentValue   = (string)value;
                 string normalizedPath = curNormalizedPath + "." + fieldInfo.Name;
                 string suggestedPath  = curSuggestedPath + "." + fieldInfo.Name;
                 action(suggestedPath, normalizedPath, false, currentValue, null, flag, false, fieldInfo, def);
             }
             else if (value is IEnumerable <string> )
             {
                 IEnumerable <string> currentValueCollection = (IEnumerable <string>)value;
                 bool   flag2           = fieldInfo.HasAttribute <TranslationCanChangeCountAttribute>();
                 string normalizedPath2 = curNormalizedPath + "." + fieldInfo.Name;
                 string suggestedPath2  = curSuggestedPath + "." + fieldInfo.Name;
                 action(suggestedPath2, normalizedPath2, true, null, currentValueCollection, flag, flag && flag2, fieldInfo, def);
             }
             else if (value is IEnumerable)
             {
                 IEnumerable enumerable  = (IEnumerable)value;
                 int         num         = 0;
                 IEnumerator enumerator2 = enumerable.GetEnumerator();
                 try
                 {
                     while (enumerator2.MoveNext())
                     {
                         object obj2 = enumerator2.Current;
                         if (obj2 != null && !(obj2 is Def) && GenTypes.IsCustomType(obj2.GetType()))
                         {
                             string text = TranslationHandleUtility.GetBestHandleWithIndexForListElement(enumerable, obj2);
                             if (text.NullOrEmpty())
                             {
                                 text = num.ToString();
                             }
                             string curNormalizedPath2 = string.Concat(new object[]
                             {
                                 curNormalizedPath,
                                 ".",
                                 fieldInfo.Name,
                                 ".",
                                 num
                             });
                             string curSuggestedPath2 = string.Concat(new string[]
                             {
                                 curSuggestedPath,
                                 ".",
                                 fieldInfo.Name,
                                 ".",
                                 text
                             });
                             DefInjectionUtility.ForEachPossibleDefInjectionInDefRecursive(obj2, curNormalizedPath2, curSuggestedPath2, visited, flag, def, action);
                         }
                         num++;
                     }
                 }
                 finally
                 {
                     IDisposable disposable;
                     if ((disposable = (enumerator2 as IDisposable)) != null)
                     {
                         disposable.Dispose();
                     }
                 }
             }
             else if (value != null && GenTypes.IsCustomType(value.GetType()))
             {
                 string curNormalizedPath3 = curNormalizedPath + "." + fieldInfo.Name;
                 string curSuggestedPath3  = curSuggestedPath + "." + fieldInfo.Name;
                 DefInjectionUtility.ForEachPossibleDefInjectionInDefRecursive(value, curNormalizedPath3, curSuggestedPath3, visited, flag, def, action);
             }
         }
     }
 }
Exemple #7
0
        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);
            }
        }