Decompiled source of Russian textures v1.0.8
BepInEx/core/XUnity.Common.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Utils; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using XUnity.Common.Constants; using XUnity.Common.Extensions; using XUnity.Common.Logging; using XUnity.Common.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("XUnity.AutoTranslator.Plugin.Core")] [assembly: AssemblyCompany("gravydevsupreme")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Common dependencies shared between XUnity Auto Translator and Resource Redirector.")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3")] [assembly: AssemblyProduct("XUnity.Common")] [assembly: AssemblyTitle("XUnity.Common")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: UnverifiableCode] namespace XUnity.Common.Utilities { public static class ArrayHelper { public static T[] Null<T>() { return null; } } public static class CabHelper { private static string CreateRandomCab() { return "CAB-" + Guid.NewGuid().ToString("N"); } public static void RandomizeCab(byte[] assetBundleData) { string @string = Encoding.ASCII.GetString(assetBundleData, 0, Math.Min(1024, assetBundleData.Length - 4)); int num = @string.IndexOf("CAB-", StringComparison.Ordinal); if (num >= 0) { int num2 = @string.Substring(num).IndexOf('\0'); if (num2 >= 0 && num2 <= 36) { string s = CreateRandomCab(); Buffer.BlockCopy(Encoding.ASCII.GetBytes(s), 36 - num2, assetBundleData, num, num2); } } } public static void RandomizeCabWithAnyLength(byte[] assetBundleData) { FindAndReplaceCab("CAB-", 0, assetBundleData, 2048); } private static void FindAndReplaceCab(string ansiStringToStartWith, byte byteToEndWith, byte[] data, int maxIterations = -1) { int num = Math.Min(data.Length, maxIterations); if (num == -1) { num = data.Length; } int num2 = 0; int length = ansiStringToStartWith.Length; string text = Guid.NewGuid().ToString("N"); int num3 = 0; for (int i = 0; i < num; i++) { char c = (char)data[i]; if (num2 == length) { while (data[i] != byteToEndWith && i < num) { if (num3 >= text.Length) { num3 = 0; text = Guid.NewGuid().ToString("N"); } data[i++] = (byte)text[num3++]; } break; } num2 = ((c == ansiStringToStartWith[num2]) ? (num2 + 1) : 0); } } } internal static class CecilFastReflectionHelper { private static readonly Type[] DynamicMethodDelegateArgs = new Type[2] { typeof(object), typeof(object[]) }; public static FastReflectionDelegate CreateFastDelegate(MethodBase method, bool directBoxValueAccess, bool forceNonVirtcall) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown DynamicMethodDefinition val = new DynamicMethodDefinition("FastReflection<" + method.DeclaringType.FullName + "." + method.Name + ">", typeof(object), DynamicMethodDelegateArgs); ILProcessor iLProcessor = val.GetILProcessor(); ParameterInfo[] parameters = method.GetParameters(); bool flag = true; if (!method.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); if (method.DeclaringType.IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, method.DeclaringType); } } for (int i = 0; i < parameters.Length; i++) { Type type = parameters[i].ParameterType; bool isByRef = type.IsByRef; if (isByRef) { type = type.GetElementType(); } bool isValueType = type.IsValueType; if (isByRef && isValueType && !directBoxValueAccess) { iLProcessor.Emit(OpCodes.Ldarg_1); iLProcessor.Emit(OpCodes.Ldc_I4, i); } iLProcessor.Emit(OpCodes.Ldarg_1); iLProcessor.Emit(OpCodes.Ldc_I4, i); if (isByRef && !isValueType) { Extensions.Emit(iLProcessor, OpCodes.Ldelema, typeof(object)); continue; } iLProcessor.Emit(OpCodes.Ldelem_Ref); if (!isValueType) { continue; } if (!isByRef || !directBoxValueAccess) { Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, type); if (isByRef) { Extensions.Emit(iLProcessor, OpCodes.Box, type); iLProcessor.Emit(OpCodes.Dup); Extensions.Emit(iLProcessor, OpCodes.Unbox, type); if (flag) { flag = false; val.Definition.Body.Variables.Add(new VariableDefinition((TypeReference)new PinnedType((TypeReference)new PointerType(((MemberReference)val.Definition).Module.TypeSystem.Void)))); } iLProcessor.Emit(OpCodes.Stloc_0); iLProcessor.Emit(OpCodes.Stelem_Ref); iLProcessor.Emit(OpCodes.Ldloc_0); } } else { Extensions.Emit(iLProcessor, OpCodes.Unbox, type); } } if (method.IsConstructor) { Extensions.Emit(iLProcessor, OpCodes.Newobj, (MethodBase)(method as ConstructorInfo)); } else if (method.IsFinal || !method.IsVirtual || forceNonVirtcall) { Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)(method as MethodInfo)); } else { Extensions.Emit(iLProcessor, OpCodes.Callvirt, (MethodBase)(method as MethodInfo)); } Type type2 = (method.IsConstructor ? method.DeclaringType : (method as MethodInfo).ReturnType); if ((object)type2 != typeof(void)) { if (type2.IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, type2); } } else { iLProcessor.Emit(OpCodes.Ldnull); } iLProcessor.Emit(OpCodes.Ret); return (FastReflectionDelegate)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(FastReflectionDelegate)); } public static Func<T, F> CreateFastFieldGetter<T, F>(FieldInfo fieldInfo) { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if ((object)fieldInfo == null) { throw new ArgumentNullException("fieldInfo"); } if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType)) { throw new ArgumentException("FieldInfo type does not match return type."); } if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T)))) { throw new MissingFieldException(typeof(T).Name, fieldInfo.Name); } DynamicMethodDefinition val = new DynamicMethodDefinition("FastReflection<" + typeof(T).FullName + ".Get_" + fieldInfo.Name + ">", typeof(F), new Type[1] { typeof(T) }); ILProcessor iLProcessor = val.GetILProcessor(); if (!fieldInfo.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); Extensions.Emit(iLProcessor, OpCodes.Castclass, fieldInfo.DeclaringType); } Extensions.Emit(iLProcessor, fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, fieldInfo); if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Box, fieldInfo.FieldType); } iLProcessor.Emit(OpCodes.Ret); return (Func<T, F>)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(Func<T, F>)); } public static Action<T, F> CreateFastFieldSetter<T, F>(FieldInfo fieldInfo) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) if ((object)fieldInfo == null) { throw new ArgumentNullException("fieldInfo"); } if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType)) { throw new ArgumentException("FieldInfo type does not match argument type."); } if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T)))) { throw new MissingFieldException(typeof(T).Name, fieldInfo.Name); } DynamicMethodDefinition val = new DynamicMethodDefinition("FastReflection<" + typeof(T).FullName + ".Set_" + fieldInfo.Name + ">", (Type)null, new Type[2] { typeof(T), typeof(F) }); ILProcessor iLProcessor = val.GetILProcessor(); if (!fieldInfo.IsStatic) { iLProcessor.Emit(OpCodes.Ldarg_0); Extensions.Emit(iLProcessor, OpCodes.Castclass, fieldInfo.DeclaringType); } iLProcessor.Emit(OpCodes.Ldarg_1); if ((object)fieldInfo.FieldType != typeof(F)) { if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType) { if (fieldInfo.FieldType.IsValueType) { Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, fieldInfo.FieldType); } else { Extensions.Emit(iLProcessor, OpCodes.Box, fieldInfo.FieldType); } } else { Extensions.Emit(iLProcessor, OpCodes.Castclass, fieldInfo.FieldType); } } Extensions.Emit(iLProcessor, fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo); iLProcessor.Emit(OpCodes.Ret); return (Action<T, F>)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(Action<T, F>)); } } public static class CustomFastReflectionHelper { private struct FastReflectionDelegateKey { public MethodBase Method { get; } public bool DirectBoxValueAccess { get; } public bool ForceNonVirtCall { get; } public FastReflectionDelegateKey(MethodBase method, bool directBoxValueAccess, bool forceNonVirtCall) { Method = method; DirectBoxValueAccess = directBoxValueAccess; ForceNonVirtCall = forceNonVirtCall; } public override bool Equals(object obj) { if (obj is FastReflectionDelegateKey fastReflectionDelegateKey && EqualityComparer<MethodBase>.Default.Equals(Method, fastReflectionDelegateKey.Method) && DirectBoxValueAccess == fastReflectionDelegateKey.DirectBoxValueAccess) { return ForceNonVirtCall == fastReflectionDelegateKey.ForceNonVirtCall; } return false; } public override int GetHashCode() { return ((1017116076 * -1521134295 + EqualityComparer<MethodBase>.Default.GetHashCode(Method)) * -1521134295 + DirectBoxValueAccess.GetHashCode()) * -1521134295 + ForceNonVirtCall.GetHashCode(); } } private static readonly Dictionary<FastReflectionDelegateKey, FastReflectionDelegate> MethodCache = new Dictionary<FastReflectionDelegateKey, FastReflectionDelegate>(); public static FastReflectionDelegate CreateFastDelegate(this MethodBase method, bool directBoxValueAccess = true, bool forceNonVirtCall = false) { FastReflectionDelegateKey key = new FastReflectionDelegateKey(method, directBoxValueAccess, forceNonVirtCall); if (MethodCache.TryGetValue(key, out var value)) { return value; } value = (((object)ClrTypes.DynamicMethodDefinition == null) ? GetFastDelegateForSRE(method, directBoxValueAccess, forceNonVirtCall) : GetFastDelegateForCecil(method, directBoxValueAccess, forceNonVirtCall)); MethodCache.Add(key, value); return value; } public static Func<T, F> CreateFastFieldGetter<T, F>(FieldInfo fieldInfo) { if ((object)ClrTypes.DynamicMethodDefinition != null) { return CreateFastFieldGetterForCecil<T, F>(fieldInfo); } return CreateFastFieldGetterForSRE<T, F>(fieldInfo); } public static Action<T, F> CreateFastFieldSetter<T, F>(FieldInfo fieldInfo) { if ((object)ClrTypes.DynamicMethodDefinition != null) { return CreateFastFieldSetterForCecil<T, F>(fieldInfo); } return CreateFastFieldSetterForSRE<T, F>(fieldInfo); } private static FastReflectionDelegate GetFastDelegateForCecil(MethodBase method, bool directBoxValueAccess, bool forceNonVirtCall) { try { return CecilFastReflectionHelper.CreateFastDelegate(method, directBoxValueAccess, forceNonVirtCall); } catch (Exception e) { try { XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with cecil. Retrying with reflection emit..."); return ReflectionEmitFastReflectionHelper.CreateFastDelegate(method, directBoxValueAccess, forceNonVirtCall); } catch (Exception e2) { XuaLogger.Common.Warn(e2, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection..."); return (object target, object[] args) => method.Invoke(target, args); } } } private static Func<T, F> CreateFastFieldGetterForCecil<T, F>(FieldInfo fieldInfo) { try { return CecilFastReflectionHelper.CreateFastFieldGetter<T, F>(fieldInfo); } catch (Exception e) { try { XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with cecil. Retrying with reflection emit..."); return ReflectionEmitFastReflectionHelper.CreateFastFieldGetter<T, F>(fieldInfo); } catch (Exception e2) { XuaLogger.Common.Warn(e2, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection..."); return (T target) => (F)fieldInfo.GetValue(target); } } } private static Action<T, F> CreateFastFieldSetterForCecil<T, F>(FieldInfo fieldInfo) { try { return CecilFastReflectionHelper.CreateFastFieldSetter<T, F>(fieldInfo); } catch (Exception e) { try { XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with cecil. Retrying with reflection emit..."); return ReflectionEmitFastReflectionHelper.CreateFastFieldSetter<T, F>(fieldInfo); } catch (Exception e2) { XuaLogger.Common.Warn(e2, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection..."); return delegate(T target, F value) { fieldInfo.SetValue(target, value); }; } } } private static FastReflectionDelegate GetFastDelegateForSRE(MethodBase method, bool directBoxValueAccess, bool forceNonVirtCall) { try { return ReflectionEmitFastReflectionHelper.CreateFastDelegate(method, directBoxValueAccess, forceNonVirtCall); } catch (Exception e) { XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection..."); return (object target, object[] args) => method.Invoke(target, args); } } private static Func<T, F> CreateFastFieldGetterForSRE<T, F>(FieldInfo fieldInfo) { try { return ReflectionEmitFastReflectionHelper.CreateFastFieldGetter<T, F>(fieldInfo); } catch (Exception e) { XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection..."); return (T target) => (F)fieldInfo.GetValue(target); } } private static Action<T, F> CreateFastFieldSetterForSRE<T, F>(FieldInfo fieldInfo) { try { return ReflectionEmitFastReflectionHelper.CreateFastFieldSetter<T, F>(fieldInfo); } catch (Exception e) { XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection..."); return delegate(T target, F value) { fieldInfo.SetValue(target, value); }; } } } public static class DiacriticHelper { public static string RemoveAllDiacritics(this string input) { return new string((from c in input.SafeNormalize(NormalizationForm.FormD) where CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark select c).ToArray()).SafeNormalize(); } private static string SafeNormalize(this string input, NormalizationForm normalizationForm = NormalizationForm.FormC) { return ReplaceNonCharacters(input, '?').Normalize(normalizationForm); } private static string ReplaceNonCharacters(string input, char replacement) { StringBuilder stringBuilder = new StringBuilder(input.Length); for (int i = 0; i < input.Length; i++) { if (char.IsSurrogatePair(input, i)) { int num = char.ConvertToUtf32(input, i); i++; if (IsValidCodePoint(num)) { stringBuilder.Append(char.ConvertFromUtf32(num)); } else { stringBuilder.Append(replacement); } } else { char c = input[i]; if (IsValidCodePoint(c)) { stringBuilder.Append(c); } else { stringBuilder.Append(replacement); } } } return stringBuilder.ToString(); } private static bool IsValidCodePoint(int point) { if (point >= 64976) { if (point >= 65008 && (point & 0xFFFF) != 65535 && (point & 0xFFFE) != 65534) { return point <= 1114111; } return false; } return true; } } public static class ExpressionHelper { public static Delegate CreateTypedFastInvoke(MethodBase method) { if ((object)method == null) { throw new ArgumentNullException("method"); } return CreateTypedFastInvokeUnchecked(method); } public static Delegate CreateTypedFastInvokeUnchecked(MethodBase method) { if ((object)method == null) { return null; } if (method.IsGenericMethod) { throw new ArgumentException("The provided method must not be generic.", "method"); } if (method is MethodInfo methodInfo) { Expression[] arguments; if (method.IsStatic) { ParameterExpression[] array = (from p in methodInfo.GetParameters() select Expression.Parameter(p.ParameterType, p.Name)).ToArray(); arguments = array; return Expression.Lambda(Expression.Call(null, methodInfo, arguments), array).Compile(); } List<ParameterExpression> list = (from p in methodInfo.GetParameters() select Expression.Parameter(p.ParameterType, p.Name)).ToList(); list.Insert(0, Expression.Parameter(methodInfo.DeclaringType, "instance")); ParameterExpression instance = list[0]; arguments = list.Skip(1).ToArray(); return Expression.Lambda(Expression.Call(instance, methodInfo, arguments), list.ToArray()).Compile(); } if (method is ConstructorInfo constructorInfo) { ParameterExpression[] array2 = (from p in constructorInfo.GetParameters() select Expression.Parameter(p.ParameterType, p.Name)).ToArray(); Expression[] arguments = array2; return Expression.Lambda(Expression.New(constructorInfo, arguments), array2).Compile(); } throw new ArgumentException("method", "This method only supports MethodInfo and ConstructorInfo."); } } public static class ExtensionDataHelper { private static readonly object Sync; private static readonly WeakDictionary<object, object> WeakDynamicFields; public static int WeakReferenceCount { get { lock (Sync) { return WeakDynamicFields.Count; } } } static ExtensionDataHelper() { Sync = new object(); WeakDynamicFields = new WeakDictionary<object, object>(); MaintenanceHelper.AddMaintenanceFunction(Cull, 12); } public static void SetExtensionData<T>(this object obj, T t) { lock (Sync) { if (WeakDynamicFields.TryGetValue(obj, out var value)) { if (value is Dictionary<Type, object> dictionary) { dictionary[typeof(T)] = t; return; } Dictionary<Type, object> dictionary2 = new Dictionary<Type, object>(); dictionary2.Add(value.GetType(), value); dictionary2[typeof(T)] = t; WeakDynamicFields[obj] = dictionary2; } else { WeakDynamicFields[obj] = t; } } } public static T GetOrCreateExtensionData<T>(this object obj) where T : new() { if (obj == null) { return default(T); } lock (Sync) { if (WeakDynamicFields.TryGetValue(obj, out var value)) { if (value is Dictionary<Type, object> dictionary) { if (dictionary.TryGetValue(typeof(T), out value)) { return (T)value; } T val = new T(); dictionary[typeof(T)] = val; return val; } if (!(value is T result)) { Dictionary<Type, object> dictionary2 = new Dictionary<Type, object>(); dictionary2.Add(value.GetType(), value); T val2 = new T(); dictionary2[typeof(T)] = val2; WeakDynamicFields[obj] = dictionary2; return val2; } return result; } T val3 = new T(); WeakDynamicFields[obj] = val3; return val3; } } public static T GetExtensionData<T>(this object obj) { if (obj == null) { return default(T); } lock (Sync) { if (WeakDynamicFields.TryGetValue(obj, out var value)) { if (value is Dictionary<Type, object> dictionary && dictionary.TryGetValue(typeof(T), out value)) { if (!(value is T result)) { return default(T); } return result; } if (!(value is T result2)) { return default(T); } return result2; } } return default(T); } public static void Cull() { lock (Sync) { WeakDynamicFields.RemoveCollectedEntries(); } } public static List<KeyValuePair<object, object>> GetAllRegisteredObjects() { lock (Sync) { return IterateAllPairs().ToList(); } } public static void Remove(object obj) { lock (Sync) { WeakDynamicFields.Remove(obj); } } private static IEnumerable<KeyValuePair<object, object>> IterateAllPairs() { foreach (KeyValuePair<object, object> kvp in WeakDynamicFields) { if (kvp.Value is Dictionary<Type, object> dictionary) { foreach (KeyValuePair<Type, object> item in dictionary) { yield return new KeyValuePair<object, object>(kvp.Key, item.Value); } } else { yield return kvp; } } } } public delegate object FastReflectionDelegate(object target, params object[] args); public static class HookingHelper { private static readonly MethodInfo PatchMethod12; private static readonly MethodInfo PatchMethod20; private static readonly object Harmony; private static bool _loggedHarmonyError; static HookingHelper() { PatchMethod12 = ClrTypes.HarmonyInstance?.GetMethod("Patch", new Type[4] { ClrTypes.MethodBase, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod }); PatchMethod20 = ClrTypes.Harmony?.GetMethod("Patch", new Type[5] { ClrTypes.MethodBase, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod }); _loggedHarmonyError = false; try { if ((object)ClrTypes.HarmonyInstance != null) { Harmony = ClrTypes.HarmonyInstance.GetMethod("Create", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[1] { "xunity.common.hookinghelper" }); } else if ((object)ClrTypes.Harmony != null) { Harmony = ClrTypes.Harmony.GetConstructor(new Type[1] { typeof(string) }).Invoke(new object[1] { "xunity.common.hookinghelper" }); } else { XuaLogger.Common.Error("An unexpected exception occurred during harmony initialization, likely caused by unknown Harmony version. Harmony hooks will be unavailable!"); } } catch (Exception e) { XuaLogger.Common.Error(e, "An unexpected exception occurred during harmony initialization. Harmony hooks will be unavailable!"); } } public static void PatchAll(IEnumerable<Type> types, bool forceExternHooks) { foreach (Type type in types) { PatchType(type, forceExternHooks); } } public static void PatchAll(IEnumerable<Type[]> types, bool forceMonoModHooks) { foreach (Type[] type in types) { for (int i = 0; i < type.Length && !PatchType(type[i], forceMonoModHooks); i++) { } } } public static bool PatchType(Type type, bool forceExternHooks) { MethodBase methodBase = null; IntPtr intPtr = IntPtr.Zero; try { if (Harmony == null && !_loggedHarmonyError) { _loggedHarmonyError = true; XuaLogger.Common.Warn("Harmony is not loaded or could not be initialized. Using fallback hooks instead."); } BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = type.GetMethod("Prepare", bindingAttr); if ((object)method == null || (bool)method.Invoke(null, new object[1] { Harmony })) { try { methodBase = (MethodBase)(type.GetMethod("TargetMethod", bindingAttr)?.Invoke(null, new object[1] { Harmony })); } catch { } try { intPtr = ((IntPtr?)type.GetMethod("TargetMethodPointer", bindingAttr)?.Invoke(null, null)) ?? IntPtr.Zero; } catch { } if ((object)methodBase == null && intPtr == IntPtr.Zero) { if ((object)methodBase != null) { XuaLogger.Common.Warn("Could not hook '" + methodBase.DeclaringType.FullName + "." + methodBase.Name + "'. Likely due differences between different versions of the engine or text framework."); } else { XuaLogger.Common.Warn("Could not hook '" + type.Name + "'. Likely due differences between different versions of the engine or text framework."); } return false; } MethodInfo method2 = type.GetMethod("Prefix", bindingAttr); MethodInfo method3 = type.GetMethod("Postfix", bindingAttr); MethodInfo method4 = type.GetMethod("Finalizer", bindingAttr); if ((object)methodBase == null || forceExternHooks || Harmony == null || ((object)method2 == null && (object)method3 == null && (object)method4 == null)) { return PatchWithExternHooks(type, methodBase, intPtr, forced: true); } if ((object)methodBase != null) { try { int? priority = type.GetCustomAttributes(typeof(HookingHelperPriorityAttribute), inherit: false).OfType<HookingHelperPriorityAttribute>().FirstOrDefault()?.priority; object obj3 = (((object)method2 != null) ? CreateHarmonyMethod(method2, priority) : null); object obj4 = (((object)method3 != null) ? CreateHarmonyMethod(method3, priority) : null); object obj5 = (((object)method4 != null) ? CreateHarmonyMethod(method4, priority) : null); if ((object)PatchMethod12 != null) { PatchMethod12.Invoke(Harmony, new object[4] { methodBase, obj3, obj4, null }); } else { PatchMethod20.Invoke(Harmony, new object[5] { methodBase, obj3, obj4, null, obj5 }); } XuaLogger.Common.Debug("Hooked " + methodBase.DeclaringType.FullName + "." + methodBase.Name + " through Harmony hooks."); return true; } catch (Exception e) when (((Func<bool>)delegate { // Could not convert BlockContainer to single expression System.Runtime.CompilerServices.Unsafe.SkipInit(out int num); if (e.FirstInnerExceptionOfType<PlatformNotSupportedException>() == null) { ArgumentException ex = e.FirstInnerExceptionOfType<ArgumentException>(); num = ((ex != null && ex.Message?.Contains("no body") == true) ? 1 : 0); } else { num = 1; } return num != 0; }).Invoke()) { return PatchWithExternHooks(type, methodBase, intPtr, forced: false); } } XuaLogger.Common.Warn("Could not hook '" + type.Name + "'. Likely due differences between different versions of the engine or text framework."); } } catch (Exception e2) { if ((object)methodBase != null) { XuaLogger.Common.Warn(e2, "An error occurred while patching property/method '" + methodBase.DeclaringType.FullName + "." + methodBase.Name + "'. Failing hook: '" + type.Name + "'."); } else { XuaLogger.Common.Warn(e2, "An error occurred while patching property/method. Failing hook: '" + type.Name + "'."); } } return false; } private static bool PatchWithExternHooks(Type type, MethodBase original, IntPtr originalPtr, bool forced) { BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; if ((object)ClrTypes.Imports != null) { if (originalPtr == IntPtr.Zero) { XuaLogger.Common.Warn("Could not hook '" + type.Name + "'. Likely due differences between different versions of the engine or text framework."); return false; } IntPtr? intPtr = type.GetMethod("ML_Detour", bindingAttr)?.MethodHandle.GetFunctionPointer(); if (intPtr.HasValue && intPtr.Value != IntPtr.Zero) { ClrTypes.Imports.GetMethod("Hook", bindingAttr).Invoke(null, new object[2] { originalPtr, intPtr.Value }); XuaLogger.Common.Debug("Hooked " + type.Name + " through MelonMod Imports.Hook method."); return true; } XuaLogger.Common.Warn("Could not hook '" + type.Name + "' because no detour method was found."); } else { if ((object)original == null) { XuaLogger.Common.Warn("Cannot hook '" + type.Name + "'. Could not locate the original method. Failing hook: '" + type.Name + "'."); return false; } if ((object)ClrTypes.Hook == null || (object)ClrTypes.NativeDetour == null) { XuaLogger.Common.Warn("Cannot hook '" + original.DeclaringType.FullName + "." + original.Name + "'. MonoMod hooks is not supported in this runtime as MonoMod is not loaded. Failing hook: '" + type.Name + "'."); return false; } object obj = type.GetMethod("Get_MM_Detour", bindingAttr)?.Invoke(null, null) ?? type.GetMethod("MM_Detour", bindingAttr); if (obj != null) { string text = "(managed)"; object obj2; try { obj2 = ClrTypes.Hook.GetConstructor(new Type[2] { typeof(MethodBase), typeof(MethodInfo) }).Invoke(new object[2] { original, obj }); obj2.GetType().GetMethod("Apply").Invoke(obj2, null); } catch (Exception e) when (((Func<bool>)delegate { // Could not convert BlockContainer to single expression System.Runtime.CompilerServices.Unsafe.SkipInit(out int num); if (e.FirstInnerExceptionOfType<NullReferenceException>() == null) { NotSupportedException ex = e.FirstInnerExceptionOfType<NotSupportedException>(); num = ((ex != null && ex.Message?.Contains("Body-less") == true) ? 1 : 0); } else { num = 1; } return num != 0; }).Invoke()) { text = "(native)"; obj2 = ClrTypes.NativeDetour.GetConstructor(new Type[2] { typeof(MethodBase), typeof(MethodBase) }).Invoke(new object[2] { original, obj }); obj2.GetType().GetMethod("Apply").Invoke(obj2, null); } type.GetMethod("MM_Init", bindingAttr)?.Invoke(null, new object[1] { obj2 }); if (forced) { XuaLogger.Common.Debug("Hooked " + original.DeclaringType.FullName + "." + original.Name + " through forced MonoMod hooks. " + text); } else { XuaLogger.Common.Debug("Hooked " + original.DeclaringType.FullName + "." + original.Name + " through MonoMod hooks. " + text); } return true; } if (forced) { XuaLogger.Common.Warn("Cannot hook '" + original.DeclaringType.FullName + "." + original.Name + "'. Harmony is not supported in this runtime and no alternate MonoMod hook has been implemented. Failing hook: '" + type.Name + "'."); } else { XuaLogger.Common.Warn("Cannot hook '" + original.DeclaringType.FullName + "." + original.Name + "'. Harmony is not supported in this runtime and no alternate MonoMod hook has been implemented. Failing hook: '" + type.Name + "'."); } } return false; } private static object CreateHarmonyMethod(MethodInfo method, int? priority) { object obj = ClrTypes.HarmonyMethod.GetConstructor(new Type[1] { typeof(MethodInfo) }).Invoke(new object[1] { method }); if (priority.HasValue) { (ClrTypes.HarmonyMethod.GetField("priority", BindingFlags.Instance | BindingFlags.Public) ?? ClrTypes.HarmonyMethod.GetField("prioritiy", BindingFlags.Instance | BindingFlags.Public)).SetValue(obj, priority.Value); } return obj; } } public class HookingHelperPriorityAttribute : Attribute { public int priority; public HookingHelperPriorityAttribute(int priority) { this.priority = priority; } } public static class HookPriority { public const int Last = 0; public const int VeryLow = 100; public const int Low = 200; public const int LowerThanNormal = 300; public const int Normal = 400; public const int HigherThanNormal = 500; public const int High = 600; public const int VeryHigh = 700; public const int First = 800; } public static class ListExtensions { public static void BinarySearchInsert<T>(this List<T> items, T item) where T : IComparable<T> { int num = items.BinarySearch(item); if (num < 0) { items.Insert(~num, item); } else { items.Insert(num, item); } } } public static class MaintenanceHelper { private class ActionRegistration { public Action Action { get; } public int Filter { get; } public ActionRegistration(Action action, int filter) { Action = action; Filter = filter; } } private static readonly object Sync = new object(); private static readonly List<ActionRegistration> RegisteredActions = new List<ActionRegistration>(); private static bool _initialized; public static void AddMaintenanceFunction(Action action, int filter) { lock (Sync) { if (!_initialized) { _initialized = true; StartMaintenance(); } ActionRegistration item = new ActionRegistration(action, filter); RegisteredActions.Add(item); } } private static void StartMaintenance() { Thread thread = new Thread(MaintenanceLoop); thread.IsBackground = true; thread.Start(); } private static void MaintenanceLoop(object state) { int num = 0; while (true) { lock (Sync) { foreach (ActionRegistration registeredAction in RegisteredActions) { if (num % registeredAction.Filter == 0) { try { registeredAction.Action(); } catch (Exception e) { XuaLogger.Common.Error(e, "An unexpected error occurred during maintenance."); } } } } num++; Thread.Sleep(5000); } } } public static class Paths { private static string _gameRoot; public static string GameRoot { get { return _gameRoot ?? GetAndSetGameRoot(); } set { _gameRoot = value; } } public static void Initialize() { GetAndSetGameRoot(); } private static string GetAndSetGameRoot() { return _gameRoot = new DirectoryInfo(Application.dataPath).Parent.FullName; } } public static class ReflectionCache { private struct MemberLookupKey { public Type Type { get; set; } public string MemberName { get; set; } public MemberLookupKey(Type type, string memberName) { Type = type; MemberName = memberName; } public override bool Equals(object obj) { if (obj is MemberLookupKey memberLookupKey) { if ((object)Type == memberLookupKey.Type) { return MemberName == memberLookupKey.MemberName; } return false; } return false; } public override int GetHashCode() { return Type.GetHashCode() + MemberName.GetHashCode(); } } private static Dictionary<MemberLookupKey, CachedMethod> Methods = new Dictionary<MemberLookupKey, CachedMethod>(); private static Dictionary<MemberLookupKey, CachedProperty> Properties = new Dictionary<MemberLookupKey, CachedProperty>(); private static Dictionary<MemberLookupKey, CachedField> Fields = new Dictionary<MemberLookupKey, CachedField>(); public static CachedMethod CachedMethod(this Type type, string name) { return type.CachedMethod(name, (Type[])null); } public static CachedMethod CachedMethod(this Type type, string name, params Type[] types) { MemberLookupKey key = new MemberLookupKey(type, name); if (!Methods.TryGetValue(key, out var value)) { Type type2 = type; MethodInfo methodInfo = null; while ((object)methodInfo == null && (object)type2 != null) { methodInfo = ((types != null && types.Length != 0) ? type2.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null) : type2.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); type2 = type2.BaseType; } if ((object)methodInfo != null) { value = new CachedMethod(methodInfo); } Methods[key] = value; } return value; } public static CachedProperty CachedProperty(this Type type, string name) { MemberLookupKey key = new MemberLookupKey(type, name); if (!Properties.TryGetValue(key, out var value)) { Type type2 = type; PropertyInfo propertyInfo = null; while ((object)propertyInfo == null && (object)type2 != null) { propertyInfo = type2.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); type2 = type2.BaseType; } if ((object)propertyInfo != null) { value = new CachedProperty(propertyInfo); } Properties[key] = value; } return value; } public static CachedField CachedField(this Type type, string name) { MemberLookupKey key = new MemberLookupKey(type, name); if (!Fields.TryGetValue(key, out var value)) { Type type2 = type; FieldInfo fieldInfo = null; while ((object)fieldInfo == null && (object)type2 != null) { fieldInfo = type2.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); type2 = type2.BaseType; } if ((object)fieldInfo != null) { value = new CachedField(fieldInfo); } Fields[key] = value; } return value; } public static CachedField CachedFieldByIndex(this Type type, int index, Type fieldType, BindingFlags flags) { FieldInfo[] array = (from x in type.GetFields(flags) where (object)x.FieldType == fieldType select x).ToArray(); if (index < array.Length) { return new CachedField(array[index]); } return null; } } public class CachedMethod { private static readonly object[] Args0 = new object[0]; private static readonly object[] Args1 = new object[1]; private static readonly object[] Args2 = new object[2]; private FastReflectionDelegate _invoke; internal CachedMethod(MethodInfo method) { _invoke = method.CreateFastDelegate(); } public object Invoke(object instance, object[] arguments) { return _invoke(instance, arguments); } public object Invoke(object instance) { return _invoke(instance, Args0); } public object Invoke(object instance, object arg1) { try { Args1[0] = arg1; return _invoke(instance, Args1); } finally { Args1[0] = null; } } public object Invoke(object instance, object arg1, object arg2) { try { Args2[0] = arg1; Args2[1] = arg2; return _invoke(instance, Args2); } finally { Args2[0] = null; Args2[1] = null; } } } public class CachedProperty { private static readonly object[] Args0 = new object[0]; private static readonly object[] Args1 = new object[1]; private FastReflectionDelegate _set; private FastReflectionDelegate _get; public Type PropertyType { get; } internal CachedProperty(PropertyInfo propertyInfo) { if (propertyInfo.CanRead) { _get = propertyInfo.GetGetMethod(nonPublic: true).CreateFastDelegate(); } if (propertyInfo.CanWrite) { _set = propertyInfo.GetSetMethod(nonPublic: true).CreateFastDelegate(); } PropertyType = propertyInfo.PropertyType; } public void Set(object instance, object[] arguments) { if (_set != null) { _set(instance, arguments); } } public void Set(object instance, object arg1) { if (_set == null) { return; } try { Args1[0] = arg1; _set(instance, Args1); } finally { Args1[0] = null; } } public object Get(object instance, object[] arguments) { if (_get == null) { return null; } return _get(instance, arguments); } public object Get(object instance) { if (_get == null) { return null; } return _get(instance, Args0); } } public class CachedField { private Func<object, object> _get; private Action<object, object> _set; public Type FieldType { get; } internal CachedField(FieldInfo fieldInfo) { _get = CustomFastReflectionHelper.CreateFastFieldGetter<object, object>(fieldInfo); _set = CustomFastReflectionHelper.CreateFastFieldSetter<object, object>(fieldInfo); FieldType = fieldInfo.FieldType; } public void Set(object instance, object value) { if (_set != null) { _set(instance, value); } } public object Get(object instance) { if (_get == null) { return null; } return _get(instance); } } internal static class ReflectionEmitFastReflectionHelper { private static readonly Type[] DynamicMethodDelegateArgs = new Type[2] { typeof(object), typeof(object[]) }; public static FastReflectionDelegate CreateFastDelegate(MethodBase method, bool directBoxValueAccess, bool forceNonVirtcall) { DynamicMethod dynamicMethod = new DynamicMethod("FastReflection<" + method.DeclaringType.FullName + "." + method.Name + ">", typeof(object), DynamicMethodDelegateArgs, method.DeclaringType.Module, skipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); ParameterInfo[] parameters = method.GetParameters(); bool flag = true; if (!method.IsStatic) { iLGenerator.Emit(OpCodes.Ldarg_0); if (method.DeclaringType.IsValueType) { iLGenerator.Emit(OpCodes.Unbox_Any, method.DeclaringType); } } for (int i = 0; i < parameters.Length; i++) { Type type = parameters[i].ParameterType; bool isByRef = type.IsByRef; if (isByRef) { type = type.GetElementType(); } bool isValueType = type.IsValueType; if (isByRef && isValueType && !directBoxValueAccess) { iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldc_I4, i); } iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldc_I4, i); if (isByRef && !isValueType) { iLGenerator.Emit(OpCodes.Ldelema, typeof(object)); continue; } iLGenerator.Emit(OpCodes.Ldelem_Ref); if (!isValueType) { continue; } if (!isByRef || !directBoxValueAccess) { iLGenerator.Emit(OpCodes.Unbox_Any, type); if (isByRef) { iLGenerator.Emit(OpCodes.Box, type); iLGenerator.Emit(OpCodes.Dup); iLGenerator.Emit(OpCodes.Unbox, type); if (flag) { flag = false; throw new NotImplementedException("No idea how to implement this..."); } iLGenerator.Emit(OpCodes.Stloc_0); iLGenerator.Emit(OpCodes.Stelem_Ref); iLGenerator.Emit(OpCodes.Ldloc_0); } } else { iLGenerator.Emit(OpCodes.Unbox, type); } } if (method.IsConstructor) { iLGenerator.Emit(OpCodes.Newobj, method as ConstructorInfo); } else if (method.IsFinal || !method.IsVirtual || forceNonVirtcall) { iLGenerator.Emit(OpCodes.Call, method as MethodInfo); } else { iLGenerator.Emit(OpCodes.Callvirt, method as MethodInfo); } Type type2 = (method.IsConstructor ? method.DeclaringType : (method as MethodInfo).ReturnType); if ((object)type2 != typeof(void)) { if (type2.IsValueType) { iLGenerator.Emit(OpCodes.Box, type2); } } else { iLGenerator.Emit(OpCodes.Ldnull); } iLGenerator.Emit(OpCodes.Ret); return (FastReflectionDelegate)dynamicMethod.CreateDelegate(typeof(FastReflectionDelegate)); } public static Func<T, F> CreateFastFieldGetter<T, F>(FieldInfo fieldInfo) { if ((object)fieldInfo == null) { throw new ArgumentNullException("fieldInfo"); } if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType)) { throw new ArgumentException("FieldInfo type does not match return type."); } if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T)))) { throw new MissingFieldException(typeof(T).Name, fieldInfo.Name); } DynamicMethod dynamicMethod = new DynamicMethod("FastReflection<" + typeof(T).FullName + ".Get_" + fieldInfo.Name + ">", typeof(F), new Type[1] { typeof(T) }, fieldInfo.DeclaringType.Module, skipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); if (!fieldInfo.IsStatic) { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType); } iLGenerator.Emit(fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, fieldInfo); if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType) { iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType); } iLGenerator.Emit(OpCodes.Ret); return (Func<T, F>)dynamicMethod.CreateDelegate(typeof(Func<T, F>)); } public static Action<T, F> CreateFastFieldSetter<T, F>(FieldInfo fieldInfo) { if ((object)fieldInfo == null) { throw new ArgumentNullException("fieldInfo"); } if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType)) { throw new ArgumentException("FieldInfo type does not match argument type."); } if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T)))) { throw new MissingFieldException(typeof(T).Name, fieldInfo.Name); } DynamicMethod dynamicMethod = new DynamicMethod("FastReflection<" + typeof(T).FullName + ".Set_" + fieldInfo.Name + ">", null, new Type[2] { typeof(T), typeof(F) }, fieldInfo.DeclaringType.Module, skipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); if (!fieldInfo.IsStatic) { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType); } iLGenerator.Emit(OpCodes.Ldarg_1); if ((object)fieldInfo.FieldType != typeof(F)) { if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType) { if (fieldInfo.FieldType.IsValueType) { iLGenerator.Emit(OpCodes.Unbox, fieldInfo.FieldType); } else { iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType); } } else { iLGenerator.Emit(OpCodes.Castclass, fieldInfo.FieldType); } } iLGenerator.Emit(fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo); iLGenerator.Emit(OpCodes.Ret); return (Action<T, F>)dynamicMethod.CreateDelegate(typeof(Action<T, F>)); } } public static class TimeHelper { public static float realtimeSinceStartup => Time.realtimeSinceStartup; } public class UnityObjectReferenceComparer : IEqualityComparer<object> { public static readonly UnityObjectReferenceComparer Default = new UnityObjectReferenceComparer(); public new bool Equals(object x, object y) { return x == y; } public int GetHashCode(object obj) { return obj.GetHashCode(); } } public class WeakReference<T> : WeakReference where T : class { public new T Target => (T)base.Target; public static WeakReference<T> Create(T target) { if (target == null) { return WeakNullReference<T>.Singleton; } return new WeakReference<T>(target); } protected WeakReference(T target) : base(target, trackResurrection: false) { } } internal class WeakNullReference<T> : WeakReference<T> where T : class { public static readonly WeakNullReference<T> Singleton = new WeakNullReference<T>(); public override bool IsAlive => true; private WeakNullReference() : base((T)null) { } } internal sealed class WeakKeyReference<T> : WeakReference<T> where T : class { public readonly int HashCode; public WeakKeyReference(T key, WeakKeyComparer<T> comparer) : base(key) { HashCode = comparer.GetHashCode(key); } } internal sealed class WeakKeyComparer<T> : IEqualityComparer<object> where T : class { private IEqualityComparer<T> comparer; internal WeakKeyComparer(IEqualityComparer<T> comparer) { if (comparer == null) { comparer = EqualityComparer<T>.Default; } this.comparer = comparer; } public int GetHashCode(object obj) { if (obj is WeakKeyReference<T> weakKeyReference) { return weakKeyReference.HashCode; } return comparer.GetHashCode((T)obj); } public new bool Equals(object x, object y) { bool isDead; T target = GetTarget(x, out isDead); bool isDead2; T target2 = GetTarget(y, out isDead2); if (isDead) { if (!isDead2) { return false; } return x == y; } if (isDead2) { return false; } return comparer.Equals(target, target2); } private static T GetTarget(object obj, out bool isDead) { T result; if (obj is WeakKeyReference<T> weakKeyReference) { result = weakKeyReference.Target; isDead = !weakKeyReference.IsAlive; } else { result = (T)obj; isDead = false; } return result; } } public sealed class WeakDictionary<TKey, TValue> : BaseDictionary<TKey, TValue> where TKey : class { private Dictionary<object, TValue> dictionary; private WeakKeyComparer<TKey> comparer; public override int Count => dictionary.Count; public WeakDictionary() : this(0, (IEqualityComparer<TKey>)null) { } public WeakDictionary(int capacity) : this(capacity, (IEqualityComparer<TKey>)null) { } public WeakDictionary(IEqualityComparer<TKey> comparer) : this(0, comparer) { } public WeakDictionary(int capacity, IEqualityComparer<TKey> comparer) { this.comparer = new WeakKeyComparer<TKey>(comparer); dictionary = new Dictionary<object, TValue>(capacity, this.comparer); } public override void Add(TKey key, TValue value) { if (key == null) { throw new ArgumentNullException("key"); } WeakReference<TKey> key2 = new WeakKeyReference<TKey>(key, comparer); dictionary.Add(key2, value); } public override bool ContainsKey(TKey key) { return dictionary.ContainsKey(key); } public override bool Remove(TKey key) { return dictionary.Remove(key); } public override bool TryGetValue(TKey key, out TValue value) { if (dictionary.TryGetValue(key, out value)) { return true; } value = default(TValue); return false; } protected override void SetValue(TKey key, TValue value) { WeakReference<TKey> key2 = new WeakKeyReference<TKey>(key, comparer); dictionary[key2] = value; } public override void Clear() { dictionary.Clear(); } public override IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { foreach (KeyValuePair<object, TValue> item in dictionary) { WeakReference<TKey> obj = (WeakReference<TKey>)item.Key; TValue value = item.Value; TKey target = obj.Target; if (obj.IsAlive) { yield return new KeyValuePair<TKey, TValue>(target, value); } } } public void RemoveCollectedEntries() { List<object> list = null; foreach (KeyValuePair<object, TValue> item in dictionary) { WeakReference<TKey> weakReference = (WeakReference<TKey>)item.Key; if (!weakReference.IsAlive) { if (list == null) { list = new List<object>(); } list.Add(weakReference); } } if (list == null) { return; } foreach (object item2 in list) { dictionary.Remove(item2); } } } [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy("System.Collections.Generic.Mscorlib_DictionaryDebugView`2,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089")] public abstract class BaseDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable { private abstract class Collection<T> : ICollection<T>, IEnumerable<T>, IEnumerable { protected readonly IDictionary<TKey, TValue> dictionary; public int Count => dictionary.Count; public bool IsReadOnly => true; protected Collection(IDictionary<TKey, TValue> dictionary) { this.dictionary = dictionary; } public void CopyTo(T[] array, int arrayIndex) { BaseDictionary<TKey, TValue>.Copy((ICollection<T>)this, array, arrayIndex); } public virtual bool Contains(T item) { using (IEnumerator<T> enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { T current = enumerator.Current; if (EqualityComparer<T>.Default.Equals(current, item)) { return true; } } } return false; } public IEnumerator<T> GetEnumerator() { foreach (KeyValuePair<TKey, TValue> item in dictionary) { yield return GetItem(item); } } protected abstract T GetItem(KeyValuePair<TKey, TValue> pair); public bool Remove(T item) { throw new NotSupportedException("Collection is read-only."); } public void Add(T item) { throw new NotSupportedException("Collection is read-only."); } public void Clear() { throw new NotSupportedException("Collection is read-only."); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy("System.Collections.Generic.Mscorlib_DictionaryKeyCollectionDebugView`2,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089")] private class KeyCollection : Collection<TKey> { public KeyCollection(IDictionary<TKey, TValue> dictionary) : base(dictionary) { } protected override TKey GetItem(KeyValuePair<TKey, TValue> pair) { return pair.Key; } public override bool Contains(TKey item) { return dictionary.ContainsKey(item); } } [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy("System.Collections.Generic.Mscorlib_DictionaryValueCollectionDebugView`2,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089")] private class ValueCollection : Collection<TValue> { public ValueCollection(IDictionary<TKey, TValue> dictionary) : base(dictionary) { } protected override TValue GetItem(KeyValuePair<TKey, TValue> pair) { return pair.Value; } } private const string PREFIX = "System.Collections.Generic.Mscorlib_"; private const string SUFFIX = ",mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"; private KeyCollection keys; private ValueCollection values; public abstract int Count { get; } public bool IsReadOnly => false; public ICollection<TKey> Keys { get { if (keys == null) { keys = new KeyCollection(this); } return keys; } } public ICollection<TValue> Values { get { if (values == null) { values = new ValueCollection(this); } return values; } } public TValue this[TKey key] { get { if (!TryGetValue(key, out var value)) { throw new KeyNotFoundException(); } return value; } set { SetValue(key, value); } } public abstract void Clear(); public abstract void Add(TKey key, TValue value); public abstract bool ContainsKey(TKey key); public abstract bool Remove(TKey key); public abstract bool TryGetValue(TKey key, out TValue value); public abstract IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator(); protected abstract void SetValue(TKey key, TValue value); public void Add(KeyValuePair<TKey, TValue> item) { Add(item.Key, item.Value); } public bool Contains(KeyValuePair<TKey, TValue> item) { if (!TryGetValue(item.Key, out var value)) { return false; } return EqualityComparer<TValue>.Default.Equals(value, item.Value); } public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { Copy(this, array, arrayIndex); } public bool Remove(KeyValuePair<TKey, TValue> item) { if (!Contains(item)) { return false; } return Remove(item.Key); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static void Copy<T>(ICollection<T> source, T[] array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } if (arrayIndex < 0 || arrayIndex > array.Length) { throw new ArgumentOutOfRangeException("arrayIndex"); } if (array.Length - arrayIndex < source.Count) { throw new ArgumentException("Destination array is not large enough. Check array.Length and arrayIndex."); } foreach (T item in source) { array[arrayIndex++] = item; } } } } namespace XUnity.Common.MonoMod { public static class DetourExtensions { public static T GenerateTrampolineEx<T>(this object detour) { return (T)(from x in detour.GetType().GetMethods() where x.Name == "GenerateTrampoline" && x.IsGenericMethod select x).FirstOrDefault().MakeGenericMethod(typeof(T)).Invoke(detour, null); } } } namespace XUnity.Common.Logging { internal class ConsoleLogger : XuaLogger { public ConsoleLogger(string source) : base(source) { } protected override void Log(LogLevel level, string message) { Console.WriteLine(GetDefaultPrefix(level) + " " + message); } } public enum LogLevel { Debug, Info, Warn, Error } internal class ModLoaderSpecificLogger : XuaLogger { public static class BepInExLogLevel { public const int None = 0; public const int Fatal = 1; public const int Error = 2; public const int Warning = 4; public const int Message = 8; public const int Info = 16; public const int Debug = 32; public const int All = 63; } private static Action<LogLevel, string> _logMethod; public ModLoaderSpecificLogger(string source) : base(source) { if (_logMethod != null) { return; } BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public; BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public; Type type = Type.GetType("BepInEx.Logging.LogLevel, BepInEx", throwOnError: false) ?? Type.GetType("BepInEx.Logging.LogLevel, BepInEx.Core", throwOnError: false); if ((object)type != null) { if ((object)(Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx", throwOnError: false) ?? Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx.Core", throwOnError: false)) != null) { MethodInfo method = (Type.GetType("BepInEx.Logging.Logger, BepInEx", throwOnError: false) ?? Type.GetType("BepInEx.Logging.Logger, BepInEx.Core", throwOnError: false)).GetMethod("CreateLogSource", bindingAttr, null, new Type[1] { typeof(string) }, null); object logInstance2 = method.Invoke(null, new object[1] { base.Source }); MethodInfo method2 = logInstance2.GetType().GetMethod("Log", bindingAttr2, null, new Type[2] { type, typeof(object) }, null); FastReflectionDelegate log2 = method2.CreateFastDelegate(); _logMethod = delegate(LogLevel level, string msg) { int num2 = Convert(level); log2(logInstance2, num2, msg); }; } else { Type type2 = Type.GetType("BepInEx.Logger, BepInEx", throwOnError: false); object logInstance = type2.GetProperty("CurrentLogger", bindingAttr).GetValue(null, null); MethodInfo method3 = logInstance.GetType().GetMethod("Log", bindingAttr2, null, new Type[2] { type, typeof(object) }, null); FastReflectionDelegate log = method3.CreateFastDelegate(); _logMethod = delegate(LogLevel level, string msg) { int num = Convert(level); log(logInstance, num, msg); }; } } else { Type type3 = Type.GetType("MelonLoader.MelonLogger, MelonLoader.ModHandler", throwOnError: false); if ((object)type3 != null) { MethodInfo method4 = type3.GetMethod("Log", bindingAttr, null, new Type[2] { typeof(ConsoleColor), typeof(string) }, null); MethodInfo method5 = type3.GetMethod("Log", bindingAttr, null, new Type[1] { typeof(string) }, null); MethodInfo method6 = type3.GetMethod("LogWarning", bindingAttr, null, new Type[1] { typeof(string) }, null); MethodInfo method7 = type3.GetMethod("LogError", bindingAttr, null, new Type[1] { typeof(string) }, null); FastReflectionDelegate logDebug = method4.CreateFastDelegate(); FastReflectionDelegate logInfo = method5.CreateFastDelegate(); FastReflectionDelegate logWarning = method6.CreateFastDelegate(); FastReflectionDelegate logError = method7.CreateFastDelegate(); _logMethod = delegate(LogLevel level, string msg) { switch (level) { case LogLevel.Debug: logDebug(null, ConsoleColor.Gray, msg); break; case LogLevel.Info: logInfo(null, msg); break; case LogLevel.Warn: logWarning(null, msg); break; case LogLevel.Error: logError(null, msg); break; default: throw new ArgumentException("level"); } }; } } if (_logMethod != null) { return; } throw new Exception("Did not recognize any mod loader!"); } protected override void Log(LogLevel level, string message) { _logMethod(level, message); } public static int Convert(LogLevel level) { return level switch { LogLevel.Debug => 32, LogLevel.Info => 16, LogLevel.Warn => 4, LogLevel.Error => 2, _ => 0, }; } } public abstract class XuaLogger { private static XuaLogger _default; private static XuaLogger _common; private static XuaLogger _resourceRedirector; public static XuaLogger AutoTranslator { get { if (_default == null) { _default = CreateLogger("XUnity.AutoTranslator"); } return _default; } set { _default = value ?? throw new ArgumentNullException("value"); } } public static XuaLogger Common { get { if (_common == null) { _common = CreateLogger("XUnity.Common"); } return _common; } set { _common = value ?? throw new ArgumentNullException("value"); } } public static XuaLogger ResourceRedirector { get { if (_resourceRedirector == null) { _resourceRedirector = CreateLogger("XUnity.ResourceRedirector"); } return _resourceRedirector; } set { _resourceRedirector = value ?? throw new ArgumentNullException("value"); } } public string Source { get; set; } internal static XuaLogger CreateLogger(string source) { try { return new ModLoaderSpecificLogger(source); } catch (Exception) { return new ConsoleLogger(source); } } public XuaLogger(string source) { Source = source; } public void Error(Exception e, string message) { Log(LogLevel.Error, message + Environment.NewLine + e); } public void Error(string message) { Log(LogLevel.Error, message); } public void Warn(Exception e, string message) { Log(LogLevel.Warn, message + Environment.NewLine + e); } public void Warn(string message) { Log(LogLevel.Warn, message); } public void Info(Exception e, string message) { Log(LogLevel.Info, message + Environment.NewLine + e); } public void Info(string message) { Log(LogLevel.Info, message); } public void Debug(Exception e, string message) { Log(LogLevel.Debug, message + Environment.NewLine + e); } public void Debug(string message) { Log(LogLevel.Debug, message); } protected abstract void Log(LogLevel level, string message); protected string GetDefaultPrefix(LogLevel level) { return level switch { LogLevel.Debug => "[DEBUG][" + Source + "]: ", LogLevel.Info => "[INFO][" + Source + "]: ", LogLevel.Warn => "[WARN][" + Source + "]: ", LogLevel.Error => "[ERROR][" + Source + "]: ", _ => "[UNKNOW][" + Source + "]: ", }; } } } namespace XUnity.Common.Harmony { public static class AccessToolsShim { private static readonly BindingFlags All; private static readonly Func<Type, string, Type[], Type[], MethodInfo> AccessTools_Method; private static readonly Func<Type, string, PropertyInfo> AccessTools_Property; static AccessToolsShim() { All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = ClrTypes.AccessTools.GetMethod("Method", All, null, new Type[4] { typeof(Type), typeof(string), typeof(Type[]), typeof(Type[]) }, null); MethodInfo? method2 = ClrTypes.AccessTools.GetMethod("Property", All, null, new Type[2] { typeof(Type), typeof(string) }, null); AccessTools_Method = (Func<Type, string, Type[], Type[], MethodInfo>)ExpressionHelper.CreateTypedFastInvoke(method); AccessTools_Property = (Func<Type, string, PropertyInfo>)ExpressionHelper.CreateTypedFastInvoke(method2); } public static MethodInfo Method(Type type, string name, params Type[] parameters) { return AccessTools_Method(type, name, parameters, null); } public static PropertyInfo Property(Type type, string name) { return AccessTools_Property(type, name); } } } namespace XUnity.Common.Extensions { public static class ExceptionExtensions { public static TException FirstInnerExceptionOfType<TException>(this Exception e) where TException : Exception { for (Exception ex = e; ex != null; ex = ex.InnerException) { if (ex is TException) { return (TException)ex; } } return null; } } public static class ObjectExtensions { public static Type GetUnityType(this object obj) { return obj.GetType(); } public static bool TryCastTo<TObject>(this object obj, out TObject castedObject) { if (obj is TObject val) { castedObject = val; return true; } castedObject = default(TObject); return false; } } public static class StreamExtensions { public static byte[] ReadFully(this Stream stream, int initialLength) { if (initialLength < 1) { initialLength = 32768; } byte[] array = new byte[initialLength]; int num = 0; int num2; while ((num2 = stream.Read(array, num, array.Length - num)) > 0) { num += num2; if (num == array.Length) { int num3 = stream.ReadByte(); if (num3 == -1) { return array; } byte[] array2 = new byte[array.Length * 2]; Array.Copy(array, array2, array.Length); array2[num] = (byte)num3; array = array2; num++; } } byte[] array3 = new byte[num]; Array.Copy(array, array3, num); return array3; } } public static class StringExtensions { private static readonly HashSet<char> InvalidFileNameChars = new HashSet<char>(Path.GetInvalidFileNameChars()); public static string UseCorrectDirectorySeparators(this string path) { if (Path.DirectorySeparatorChar == '\\') { return path.Replace('/', Path.DirectorySeparatorChar); } if (Path.DirectorySeparatorChar == '/') { return path.Replace('\\', Path.DirectorySeparatorChar); } return path; } public static bool IsNullOrWhiteSpace(this string value) { if (value == null) { return true; } for (int i = 0; i < value.Length; i++) { if (!char.IsWhiteSpace(value[i])) { return false; } } return true; } public static string MakeRelativePath(this string fullOrRelativePath, string basePath) { StringBuilder stringBuilder = new StringBuilder(); int i = 0; bool flag = false; string[] array = basePath.Split(':', '\\', '/'); List<string> list = fullOrRelativePath.Split(':', '\\', '/').ToList(); if (array.Length == 0 || list.Count <= 0 || array[0] != list[0]) { flag = true; } bool flag2 = false; for (int j = 0; j < list.Count; j++) { if (list[j] == "..") { if (flag2) { int num = j - 1; if (num >= 0) { list.RemoveAt(j); list.RemoveAt(num); j -= 2; } } } else { flag2 = true; } } if (!flag) { for (i = 1; i < array.Length && !(array[i] != list[i]); i++) { } for (int k = 0; k < array.Length - i; k++) { char directorySeparatorChar = Path.DirectorySeparatorChar; stringBuilder.Append(".." + directorySeparatorChar); } } for (int l = i; l < list.Count - 1; l++) { string value = list[l]; stringBuilder.Append(value).Append(Path.DirectorySeparatorChar); } string value2 = list[^1]; stringBuilder.Append(value2); return stringBuilder.ToString(); } public static string SanitizeForFileSystem(this string path) { StringBuilder stringBuilder = new StringBuilder(path.Length); foreach (char c in path) { if (!InvalidFileNameChars.Contains(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } public static string SplitToLines(this string text, int maxStringLength, params char[] splitOnCharacters) { StringBuilder stringBuilder = new StringBuilder(); int num; for (int i = 0; text.Length > i; i += num) { if (i != 0) { stringBuilder.Append('\n'); } num = ((i + maxStringLength <= text.Length) ? text.Substring(i, maxStringLength).LastIndexOfAny(splitOnCharacters) : (text.Length - i)); num = ((num == -1) ? maxStringLength : num); stringBuilder.Append(text.Substring(i, num).Trim()); } return stringBuilder.ToString(); } public static bool StartsWithStrict(this string str, string prefix) { int num = Math.Min(str.Length, prefix.Length); if (num < prefix.Length) { return false; } for (int i = 0; i < num; i++) { if (str[i] != prefix[i]) { return false; } } return true; } public static string GetBetween(this string strSource, string strStart, string strEnd) { int num = strSource.IndexOf(strStart); if (num != -1) { num += strStart.Length; int num2 = strSource.IndexOf(strEnd, num); if (num2 > num) { return strSource.Substring(num, num2 - num); } } return string.Empty; } public static bool RemindsOf(this string that, string other) { if (!that.StartsWith(other) && !other.StartsWith(that) && !that.EndsWith(other)) { return other.EndsWith(that); } return true; } } } namespace XUnity.Common.Constants { public static class ClrTypes { public static readonly Type AccessTools = FindTypeStrict("Harmony.AccessTools, 0Harmony") ?? FindTypeStrict("HarmonyLib.AccessTools, 0Harmony") ?? FindTypeStrict("Harmony.AccessTools, MelonLoader.ModHandler") ?? FindTypeStrict("HarmonyLib.AccessTools, MelonLoader.ModHandler"); public static readonly Type HarmonyMethod = FindTypeStrict("Harmony.HarmonyMethod, 0Harmony") ?? FindTypeStrict("HarmonyLib.HarmonyMethod, 0Harmony") ?? FindTypeStrict("Harmony.HarmonyMethod, MelonLoader.ModHandler") ?? FindTypeStrict("HarmonyLib.HarmonyMethod, MelonLoader.ModHandler"); public static readonly Type HarmonyInstance = FindTypeStrict("Harmony.HarmonyInstance, 0Harmony") ?? FindTypeStrict("Harmony.HarmonyInstance, MelonLoader.ModHandler"); public static readonly Type Harmony = FindTypeStrict("HarmonyLib.Harmony, 0Harmony") ?? FindTypeStrict("HarmonyLib.Harmony, MelonLoader.ModHandler"); public static readonly Type Hook = FindTypeStrict("MonoMod.RuntimeDetour.Hook, MonoMod.RuntimeDetour"); public static readonly Type Detour = FindTypeStrict("MonoMod.RuntimeDetour.Detour, MonoMod.RuntimeDetour"); public static readonly Type NativeDetour = FindTypeStrict("MonoMod.RuntimeDetour.NativeDetour, MonoMod.RuntimeDetour"); public static readonly Type DynamicMethodDefinition = FindTypeStrict("MonoMod.Utils.DynamicMethodDefinition, MonoMod.Utils"); public static readonly Type Imports = FindTypeStrict("MelonLoader.Imports, MelonLoader.ModHandler"); public static readonly Type MethodBase = FindType("System.Reflection.MethodBase"); public static readonly Type Task = FindType("System.Threading.Tasks.Task"); private static Type FindType(string name) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(name, throwOnError: false); if ((object)type != null) { return type; } } catch { } } return null; } private static Type FindTypeStrict(string name) { return Type.GetType(name, throwOnError: false); } } public class TypeContainer { public Type ClrType { get; } public Type UnityType { get; } public TypeContainer(Type type) { UnityType = type; ClrType = type; } public bool IsAssignableFrom(Type unityType) { if ((object)UnityType != null) { return UnityType.IsAssignableFrom(unityType); } return false; } } public static class UnityFeatures { private static readonly BindingFlags All; public static bool SupportsMouseScrollDelta { get; } public static bool SupportsClipboard { get; } public static bool SupportsCustomYieldInstruction { get; } public static bool SupportsSceneManager { get; } public static bool SupportsWaitForSecondsRealtime { get; set; } static UnityFeatures() { All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; SupportsMouseScrollDelta = false; SupportsClipboard = false; SupportsCustomYieldInstruction = false; SupportsSceneManager = false; SupportsWaitForSecondsRealtime = false; try { SupportsClipboard = (object)UnityTypes.TextEditor?.ClrType.GetProperty("text")?.GetSetMethod() != null; } catch (Exception) { } try { SupportsCustomYieldInstruction = UnityTypes.CustomYieldInstruction != null; } catch (Exception) { } try { SupportsSceneManager = UnityTypes.Scene != null && UnityTypes.SceneManager != null && (object)UnityTypes.SceneManager.ClrType.GetMethod("add_sceneLoaded", All) != null; } catch (Exception) { } try { SupportsMouseScrollDelta = (object)UnityTypes.Input?.ClrType.GetProperty("mouseScrollDelta") != null; } catch (Exception) { } try { SupportsWaitForSecondsRealtime = UnityTypes.WaitForSecondsRealtime != null; } catch (Exception) { } } } public static class UnityTypes { public static class TMP_Settings_Properties { public static CachedProperty Version = TMP_Settings?.ClrType.CachedProperty("version"); public static CachedProperty FallbackFontAssets = TMP_Settings?.ClrType.CachedProperty("fallbackFontAssets"); } public static class TMP_FontAsset_Properties { public static CachedProperty Version = TMP_FontAsset?.ClrType.CachedProperty("version"); } public static class AdvScenarioData_Properties { public static CachedProperty ScenarioLabels = AdvScenarioData?.ClrType.CachedProperty("ScenarioLabels"); } public static class UguiNovelText_Properties { public static CachedProperty TextGenerator = UguiNovelText?.ClrType.CachedProperty("TextGenerator"); } public static class UguiNovelText_Methods { public static CachedMethod SetAllDirty = UguiNovelText?.ClrType.CachedMethod("SetAllDirty"); } public static class UguiNovelTextGenerator_Methods { public static CachedMethod Refresh = UguiNovelTextGenerator?.ClrType.CachedMethod("Refresh"); } public static class AdvUguiMessageWindow_Properties { public static CachedProperty Text = AdvUguiMessageWindow?.ClrType.CachedProperty("Text"); public static CachedProperty Engine = AdvUguiMessageWindow?.ClrType.CachedProperty("Engine"); } public static class AdvUiMessageWindow_Fields { public static CachedField text = AdvUiMessageWindow?.ClrType.CachedField("text"); public static CachedField nameText = AdvUiMessageWindow?.ClrType.CachedField("nameText"); } public static class AdvUguiMessageWindow_Fields { public static FieldInfo text = AdvUguiMessageWindow?.ClrType.GetField("text", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); public static FieldInfo nameText = AdvUguiMessageWindow?.ClrType.GetField("nameText", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); public static FieldInfo engine = AdvUguiMessageWindow?.ClrType.GetField("engine", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static class AdvEngine_Properties { public static CachedProperty Page = AdvEngine?.ClrType.CachedProperty("Page"); } public static class AdvPage_Methods { public static CachedMethod RemakeTextData = AdvPage?.ClrType.CachedMethod("RemakeTextData"); public static CachedMethod RemakeText = AdvPage?.ClrType.CachedMethod("RemakeText"); public static CachedMethod ChangeMessageWindowText = AdvPage?.ClrType.CachedMethod("ChangeMessageWindowText", typeof(string), typeof(string), typeof(string), typeof(string)); } public static class UILabel_Properties { public static CachedProperty MultiLine = UILabel?.ClrType.CachedProperty("multiLine"); public static CachedProperty OverflowMethod = UILabel?.ClrType.CachedProperty("overflowMethod"); public static CachedProperty SpacingX = UILabel?.ClrType.CachedProperty("spacingX"); public static CachedProperty UseFloatSpacing = UILabel?.ClrType.CachedProperty("useFloatSpacing"); } public static class Text_Properties { public static CachedProperty Font = Text?.ClrType.CachedProperty("font"); public static CachedProperty FontSize = Text?.ClrType.CachedProperty("fontSize"); public static CachedProperty HorizontalOverflow = Text?.ClrType.CachedProperty("horizontalOverflow"); public static CachedProperty VerticalOverflow = Text?.ClrType.CachedProperty("verticalOverflow"); public static CachedProperty LineSpacing = Text?.ClrType.CachedProperty("lineSpacing"); public static CachedProperty ResizeTextForBestFit = Text?.ClrType.CachedProperty("resizeTextForBestFit"); public static CachedProperty ResizeTextMinSize = Text?.ClrType.CachedProperty("resizeTextMinSize"); public static CachedProperty ResizeTextMaxSize = Text?.ClrType.CachedProperty("resizeTextMaxSize"); } public static class InputField_Properties { public static CachedProperty Placeholder = InputField?.ClrType.CachedProperty("placeholder"); } public static class TMP_InputField_Properties { public static CachedProperty Placeholder = TMP_InputField?.ClrType.CachedProperty("placeholder"); } public static class Font_Properties { public static CachedProperty FontSize = Font?.ClrType.CachedProperty("fontSize"); } public static class AssetBundle_Methods { public static CachedMethod LoadAll = AssetBundle?.ClrType.CachedMethod("LoadAll", typeof(Type)); public static CachedMethod LoadAllAssets = AssetBundle?.ClrType.CachedMethod("LoadAllAssets", typeof(Type)); public static CachedMethod LoadFromFile = AssetBundle?.ClrType.CachedMethod("LoadFromFile", typeof(string)); public static CachedMethod CreateFromFile = AssetBundle?.ClrType.CachedMethod("CreateFromFile", typeof(string)); } public static class TextExpansion_Methods { public static CachedMethod SetMessageType = TextExpansion?.ClrType.CachedMethod("SetMessageType"); public static CachedMethod SkipTypeWriter = TextExpansion?.ClrType.CachedMethod("SkipTypeWriter"); } public static class GameObject_Methods { } public static class TextMesh_Methods { } public static class Text_Methods { } public static class InputField_Methods { } public static class TMP_Text_Methods { } public static class TMP_InputField_Methods { } public static class TextMeshPro_Methods { } public static class TextMeshProUGUI_Methods { } public static class UILabel_Methods { } public static class UIRect_Methods { } public static class SceneManager_Methods { public static readonly Action<UnityAction<Scene, LoadSceneMode>> add_sceneLoaded = (Action<UnityAction<Scene, LoadSceneMode>>)ExpressionHelper.CreateTypedFastInvokeUnchecked(typeof(SceneManager).GetMethod("add_sceneLoaded", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(UnityAction<Scene, LoadSceneMode>) }, null)); } public static class Texture2D_Methods { public static readonly Func<Texture2D, byte[], bool> LoadImage = (Func<Texture2D, byte[], bool>)ExpressionHelper.CreateTypedFastInvokeUnchecked(typeof(Texture2D).GetMethod("LoadImage", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(byte[]) }, null)); public static readonly Func<Texture2D, byte[]> EncodeToPNG = (Func<Texture2D, byte[]>)ExpressionHelper.CreateTypedFastInvokeUnchecked(typeof(Texture2D).GetMethod("EncodeToPNG", BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null)); } public static class ImageConversion_Methods { public static readonly Func<Texture2D, byte[], bool, bool> LoadImage = (Func<Texture2D, byte[], bool, bool>)ExpressionHelper.CreateTypedFastInvokeUnchecked(ImageConversion?.ClrType.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null)); public static readonly Func<Texture2D, byte[]> EncodeToPNG = (Func<Texture2D, byte[]>)ExpressionHelper.CreateTypedFastInvokeUnchecked(ImageConversion?.ClrType.GetMethod("EncodeToPNG", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Texture2D) }, null)); } public static readonly TypeContainer UILabel = FindType("UILabel"); public static readonly TypeContainer UIWidget = FindType("UIWidget"); public static readonly TypeContainer UIAtlas = FindType("UIAtlas"); public static readonly TypeContainer UISprite = FindType("UISprite"); public static readonly TypeContainer UITexture = FindType("UITexture"); public static readonly TypeContainer UI2DSprite = FindType("UI2DSprite"); public static readonly TypeContainer UIFont = FindType("UIFont"); public static readonly TypeContainer UIPanel = FindType("UIPanel"); public static readonly TypeContainer UIRect = FindType("UIRect"); public static readonly TypeContainer UIInput = FindType("UIInput"); public static readonly TypeContainer TextField = FindType("FairyGUI.TextField"); public static readonly TypeContainer TMP_InputField = FindType("TMPro.TMP_InputField"); public static readonly TypeContainer TMP_Text = FindType("TMPro.TMP_Text"); public static readonly TypeContainer TextMeshProUGUI = FindType("TMPro.TextMeshProUGUI"); public static readonly TypeContainer TextMeshPro = FindType("TMPro.TextMeshPro"); public static readonly TypeContainer TMP_FontAsset = FindType("TMPro.TMP_FontAsset"); public static readonly TypeContainer TMP_Settings = FindType("TMPro.TMP_Settings"); public static readonly TypeContainer GameObject = FindType("UnityEngine.GameObject"); public static readonly TypeContainer Transform = FindType("UnityEngine.Transform"); public static readonly TypeContainer TextMesh = FindType("UnityEngine.TextMesh"); public static readonly TypeContainer Text = FindType("UnityEngine.UI.Text"); public static readonly TypeContainer Image = FindType("UnityEngine.UI.Image"); public static readonly TypeContainer RawImage = FindType("UnityEngine.UI.RawImage"); public static readonly TypeContainer MaskableGraphic = FindType("UnityEngine.UI.MaskableGraphic"); public static readonly TypeContainer Graphic = FindType("UnityEngine.UI.Graphic"); public static readonly TypeContainer GUIContent = FindType("UnityEngine.GUIContent"); public static readonly TypeContainer WWW = FindType("UnityEngine.WWW"); public static readonly TypeContainer InputField = FindType("UnityEngine.UI.InputField"); public static readonly TypeContainer GUI = FindType("UnityEngine.GUI"); public static readonly TypeContainer GUI_ToolbarButtonSize = FindType("UnityEngine.GUI+ToolbarButtonSize"); public static readonly TypeContainer GUIStyle = FindType("UnityEngine.GUIStyle"); public static readonly TypeContainer ImageConversion = FindType("UnityEngine.ImageConversion"); public static readonly TypeContainer Texture2D = FindType("UnityEngine.Texture2D"); public static readonly TypeContainer Texture = FindType("UnityEngine.Texture"); public static readonly TypeContainer SpriteRenderer = FindType("UnityEngine.SpriteRenderer"); public static readonly TypeContainer Sprite = FindType("UnityEngine.Sprite"); public static readonly TypeContainer Object = FindType("UnityEngine.Object"); public static readonly TypeContainer TextEditor = FindType("UnityEngine.TextEditor"); public static readonly TypeContainer CustomYieldInstruction = FindType("UnityEngine.CustomYieldInstruction"); public static readonly TypeContainer SceneManager = FindType("UnityEngine.SceneManagement.SceneManager"); public static readonly TypeContainer Scene = FindType("UnityEngine.SceneManagement.Scene"); public static readonly TypeContainer UnityEventBase = FindType("UnityEngine.Events.UnityEventBase"); public static readonly TypeContainer BaseInvokableCall = FindType("UnityEngine.Events.BaseInvokableCall"); public static readonly TypeContainer Font = FindType("UnityEngine.Font"); public static readonly TypeContainer WaitForSecondsRealtime = FindType("UnityEngine.WaitForSecondsRealtime"); public static readonly TypeContainer Input = FindType("UnityEngine.Input"); public static readonly TypeContainer AssetBundleCreateRequest = FindType("UnityEngine.AssetBundleCreateRequest"); public static readonly TypeContainer AssetBundle = FindType("UnityEngine.AssetBundle"); public static readonly TypeContainer AssetBundleRequest = FindType("UnityEngine.AssetBundleRequest"); public static readonly TypeContainer Resources = FindType("UnityEngine.Resources"); public static readonly TypeContainer AsyncOperation = FindType("UnityEngine.AsyncOperation"); public static readonly TypeContainer TextAsset = FindType("UnityEngine.TextAsset"); public static readonly Type HorizontalWrapMode = FindClrType("UnityEngine.HorizontalWrapMode"); public static readonly Type TextOverflowModes = FindClrType("TMPro.TextOverflowModes"); public static readonly Type TextAlignmentOptions = FindClrType("TMPro.TextAlignmentOptions"); public static readonly Type VerticalWrapMode = FindClrType("UnityEngine.VerticalWrapMode"); public static readonly TypeContainer TextExpansion = FindType("UnityEngine.UI.TextExpansion"); public static readonly TypeContainer Typewriter = FindType("Typewriter"); public static readonly TypeContainer UguiNovelText = FindType("Utage.UguiNovelText"); public static readonly TypeContainer UguiNovelTextGenerator = FindType("Utage.UguiNovelTextGenerator"); public static readonly TypeContainer AdvEngine = FindType("Utage.AdvEngine"); public static readonly TypeContainer AdvPage = FindType("Utage.AdvPage"); public static readonly TypeContainer TextData = FindType("Utage.TextData"); public static readonly TypeContainer AdvUguiMessageWindow = FindType("Utage.AdvUguiMessageWindow") ?? FindType("AdvUguiMessageWindow"); public static readonly TypeContainer AdvUiMessageWindow = FindType("AdvUiMessageWindow"); public static readonly TypeContainer AdvDataManager = FindType("Utage.AdvDataManager"); public static readonly TypeContainer AdvScenarioData = FindType("Utage.AdvScenarioData"); public static readonly TypeContainer AdvScenarioLabelData = FindType("Utage.AdvScenarioLabelData"); public static readonly TypeContainer DicingTextures = FindType("Utage.DicingTextures"); public static readonly TypeContainer DicingImage = FindType("Utage.DicingImage"); public static readonly TypeContainer TextArea2D = FindType("Utage.TextArea2D"); public static readonly TypeContainer CubismRenderer = FindType("Live2D.Cubism.Rendering.CubismRenderer"); public static readonly TypeContainer TextWindow = FindType("Assets.System.Text.TextWindow"); private static Type FindClrType(string name) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(name, throwOnError: false); if ((object)type != null) { return type; } } catch { } } return null; } private static TypeContainer FindType(string name) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(name, throwOnError: false); if ((object)type != null) { return new TypeContainer(type); } } catch { } } return null; } } }
BepInEx/plugins/Fixlagscan.dll
Decompiled a year agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Fixlagscan")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Fixlagscan")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c95544d9-12c3-409a-a8c2-c459a89e21ef")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] internal class BundleLoader { public static AssetBundle Localization; public static bool TryLoadBundle() { try { string text = "Localization.bundle"; string text2 = Path.Combine(Paths.BepInExRootPath, "Bundles", text); if (!File.Exists(text2)) { Console.WriteLine("Bundle not found: " + text); return false; } Localization = AssetBundle.LoadFromFile(text2); return true; } catch (Exception arg) { Console.WriteLine($"Error loading bundle: {arg}"); return false; } } } namespace Patchers { [HarmonyPatch(typeof(TextMeshProUGUI), "Awake")] internal class PatchFontAtlas { [HarmonyPostfix] public static void Postfix(TextMeshProUGUI __instance) { if (((Object)((TMP_Text)__instance).font).name == "b") { ((TMP_Text)__instance).font = BundleLoader.Localization.LoadAsset<TMP_FontAsset>("3270-Regular"); } } } } namespace FixLagScan { [BepInPlugin("FixLagScan", "fixlag", "1.0.0")] [BepInProcess("Lethal Company.exe")] public class Plugin : BaseUnityPlugin { private void Awake() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)" ______ _ _ "); ((BaseUnityPlugin)this).Logger.LogInfo((object)"| ____(_) | | "); ((BaseUnityPlugin)this).Logger.LogInfo((object)"| |__ ___ _| | __ _ __ _ "); ((BaseUnityPlugin)this).Logger.LogInfo((object)"| __| | \\ \\/ / | / _` |/ _` |"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"| | | |> <| |___| (_| | (_| |"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"|_| |_/_/\\_\\______\\__,_|\\__, |"); ((BaseUnityPlugin)this).Logger.LogInfo((object)" __/ |"); ((BaseUnityPlugin)this).Logger.LogInfo((object)" |___/ "); if (!BundleLoader.TryLoadBundle()) { ((BaseUnityPlugin)this).Logger.LogError((object)"Произошла ошибка при загрузке ресурсов."); return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"fixlag версии 1.0.0 был успешно загружен!"); new Harmony("com.fixlagscan.patcher").PatchAll(); } } }
BepInEx/plugins/RussianTranslateTerminal.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("TerminalTranslator")] [assembly: AssemblyDescription("该文件由B站用户吹到江心的孤雪制作并编译, 个人链接为https://space.bilibili.com/21754758, 未经本人允许, 请勿擅自改造分发, 造成任何后果及危害, 本人概不负责. 本人及本制作方享有最终解释权。")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TerminalTranslator")] [assembly: AssemblyCopyright("Copyright © B站吹到江心的孤雪 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7286f300-1e32-456a-8efc-5d28af5344d6")] [assembly: AssemblyFileVersion("0.9.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.9.0.0")] namespace RussianTranslateTerminal { [BepInPlugin("snowflake.plugin.russiantranslateterminal", "RussianTranslateTerminal", "1.0.0")] public class RussianTranslateTerminal : BaseUnityPlugin { private const string PLUGIN_GUID = "snowflake.plugin.russiantranslateterminal"; private const string PLUGIN_NAME = "RussianTranslateTerminal"; private const string PLUGIN_VERSION = "1.0.0"; private readonly Harmony harmony = new Harmony("snowflake.plugin.russiantranslateterminal"); private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin snowflake.plugin.russiantranslateterminal (RussianTranslateTerminal) is loaded!"); PatchHarmony(); } private void PatchHarmony() { try { harmony.PatchAll(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error applying Harmony patches: " + ex.Message)); } } } } namespace TerminalTranslator { internal class RussianTranslateTerminal { private bool firstUse = true; public string translate(ref string modifiedDisplayText, ref TerminalNode node) { string text = node.displayText.ToString(); if (firstUse & (((Object)node).name == "OtherCommands")) { modifiedDisplayText = modifiedDisplayText.Replace(".\n\n\n", ".\n\n>TRANSLATE\nИнформация о переводе.\n\n"); } string result; if (text.Contains("[translate]")) { credits(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[currentDay]")) { translateWelcome(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[numberOfItemsOnRoute]")) { translateMenu(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[planetTime]")) { translateCommandMoons(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[unlockablesSelectionList]")) { translateCommandStore(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[currentScannedEnemiesList]")) { translateCommandBestiary(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[storedUnlockablesList]")) { translateCommandStorage(ref modifiedDisplayText); result = modifiedDisplayText; } else if (text.Contains("[currentUnlockedLogsList]")) { translateCommandSigurd(ref modifiedDisplayText); result = modifiedDisplayText; } else { translateCommandOther(ref modifiedDisplayText); translateMisc(ref modifiedDisplayText); translateDetailStore(ref modifiedDisplayText); if (modifiedDisplayText.Length > 180) { if (!translateDetailMoons(ref modifiedDisplayText)) { return modifiedDisplayText; } if (!translateDetailBestiary(ref modifiedDisplayText)) { return modifiedDisplayText; } if (!translateDetailSigurd(ref modifiedDisplayText)) { return modifiedDisplayText; } } result = modifiedDisplayText; } return result; } public void credits(ref string raw) { raw = "\n\n\nДобро пожаловать в раздел информации о переводе.\nТут можно узнать об авторах и помощниках проекта.\nВ будущем данный раздел будет пополнятся.\n____________________________\n\n* Автор перевода: Hayrizan\n\n* Помощь с консолью: incredibleIdea\n\n\n"; } public void translateWelcome(ref string raw) { raw = raw.Replace("Welcome to the FORTUNE-9 OS", "Добро пожаловать в FORTUNE-9 ОС").Replace("Courtesy of the Company", "Предоставлено компанией").Replace("Happy Monday", "Счастливого понедельника") .Replace("Happy TuesDay", "Счастливого вторника") .Replace("Happy Wednesday", "Счастливой среды") .Replace("Happy Thursday", "Счастливого четверга") .Replace("Happy Friday", "Счастливой пятницы") .Replace("Happy Saturday", "Счастливой субботы") .Replace("Happy Sunday", "Счастливого воскресенья") .Replace("Type \"Help\" for a list of commands", "Введите \"Help\" для получения списка команд"); } public void translateMenu(ref string raw) { raw = raw.Replace("To see the list of moons the autopilot can route to", "Увидеть список лун, к которым можно проложить маршрут").Replace("To see the company store's selection of useful items", "Фирменный магазин компании").Replace("To see the list of wildlife on record", "Записи о существах добавленные в базу") .Replace("To access objects placed into storage", "Доступа к объектам, помещенным на склад") .Replace("To see the list of other commands", "Посмотреть список других команд".Replace("purchased items on route", "предметов в пути")); } public void translateCommandMoons(ref string raw) { raw = raw.Replace("Welcome to the exomoons catalogue", "Добро пожаловать в каталог экзолун").Replace("To route the autopilot to a moon, use the word ROUTE", "Для направления корабля к луне используйте \"ROUTE\"").Replace("To learn about any moon, use the word INFO", "Чтобы узнать о любой луне, используйте \"INFO\"") .Replace("Buying at", "Скупка за") .Replace("Eclipsed", "Затмение") .Replace("Flooded", "Наводнение") .Replace("Stormy", "Шторм") .Replace("Foggy", "Туман") .Replace("Rainy", "Дождь"); } public void translateCommandStore(ref string raw) { raw = raw.Replace("Welcome to the Company store", "Добро пожаловать в магазин Компании").Replace("Use words BUY and INFO on any item", "Используйте \"BUY\" или \"INFO\" для любого товара").Replace("Order tools in bulk by typing a number", "Закажите инструменты оптом, введя количество") .Replace("Price", "Цена") .Replace("* Walkie-talkie", "* Walkie-talkie(Рация)") .Replace("* Spray paint", "* Spray paint(Спрей краска)") .Replace("* Flashlight", "* Flashlight(Фонарик)") .Replace("* Shovel", "* Shovel(Лопата)") .Replace("* Lockpicker", "* Lockpicker(Взломщик)") .Replace("* Pro-flashlight", "* Pro-flashlight(Про-фонарик)") .Replace("* Stun grenade", "* Stun grenade(Светошумовая граната)") .Replace("* Boombox", "* Boombox(Бумбокс)") .Replace("* TZP-Inhalant", "* TZP-Inhalant(ТЗП-Ингалятор)") .Replace("* Zap gun", "* Zap gun(Шоковый пистолет)") .Replace("* Jetpack", "* Jetpack(Реактивный ранец)") .Replace("* Extension ladder", "* Extension ladder(Выдвижная лестница)") .Replace("* Radar-booster", "* Radar-booster(Радар-усилитель)") .Replace("SHIP UPGRADES", "УЛУЧШЕНИЯ КОРАБЛЯ") .Replace("* Loud horn", "* Loud horn(Громкий гудок)") .Replace("Goldfish", "Goldfish(Золотая рыбка)") .Replace("Plushie pajama man", "Plushie pajama man(Плюшевая игрушка)") .Replace("* Teleporter", "* Teleporter(Телепортатор)") .Replace("* Signal Translator", "* Signal Translator(Транслятор сигнала)") .Replace("* Inverse Teleporter", "* Inverse Teleporter(Обратный телепортатор)") .Replace("The selection of ship decor rotates per-quota. Be sure to check back next week", "Выбор декора меняется в зависимости от квоты. Обязательно загляните на следующей неделе") .Replace("Romantic table", "Romantic table(Романтический стол)") .Replace("Toilet", "Toilet(Туалет)") .Replace("Shower", "Shower(Душевая кабина)") .Replace("Table", "Table(Стол)") .Replace("Record player", "Record player(Граммофон)") .Replace("Cozy lights", "Cozy lights(Гирлянда)") .Replace("Pajama suit", "Pajama suit(Пижамный костюм)") .Replace("Green suit", "Green suit(Зеленый костюм)") .Replace("Hazard suit", "Hazard suit(Защитный костюм)") .Replace("Television", "Television(Телевизор)") .Replace("Jack-o-Lantern", "Jack-o-Lantern(Фонарь из тыквы)"); } public void translateCommandBestiary(ref string raw) { raw = raw.Replace("To access a creature file, type \"INFO\" after its name", "Для доступа к файлу существа введите \"INFO\" после его имени").Replace("No data collected on wildlife. Scans are required", "Данные о существах не собраны. Требуются сканирование").Replace("NEW", "Новый") .Replace("Hygroderes", "Hygroderes - Гидродер") .Replace("Snare fleas", "Snare fleas - Удушающая многоножка") .Replace("Bunker spiders", "Bunker spiders - Бункерный паук") .Replace("Hoarding bugs", "Hoarding bugs - Жук собиратель") .Replace("Thumpers", "Thumpers - Топтун") .Replace("Coil-heads", "Coil-heads - Пружиноголовый") .Replace("Spore lizards", "Spore lizards - Споровик") .Replace("Brackens", "Brackens - Брэкен") .Replace("Jesters", "Jesters - Шутник") .Replace("Manticoils", "Manticoils - Мантикоил") .Replace("Roaming locusts", "Roaming locusts - Бродячая саранча") .Replace("Circuit bees", "Circuit bees - Электропчелы") .Replace("Baboon hawks", "Baboon hawks - Бабуин-ястреб") .Replace("Eyeless dogs", "Eyeless dogs - Слепая собака") .Replace("Forest keepers", "Forest keepers - Хранитель леса") .Replace("Earth leviathans", "Earth leviathans - Земляной левиафан"); } public void translateCommandStorage(ref string raw) { raw = raw.Replace("While moving furniture with [B], you can press [X] to send it to storage. You can call it back from storage here", "При перемещении объектов с помощью [B] вы можете нажать [X], чтобы отправить их на склад. Здесь вы можете вызвать их обратно").Replace("These are the items in storage", "Список предметов на складе").Replace("Order tools in bulk by typing a number", "Закажите инструменты оптом, введя количество") .Replace("No items stored. While moving an object with B, press X to store it", "Нет объектов на складе. При перемещении объекта с помощью B нажмите X, чтобы складировать его") .Replace("Loud horn\n", "Loud horn(Громкий гудок)\n") .Replace("Inverse Teleporter\n", "Inverse Teleporter(Обратный телепортатор)\n") .Replace("Teleporter\n", "Teleporter(Телепортатор)\n"); translateCommandStore(ref raw); } public void translateCommandOther(ref string raw) { raw = raw.Replace("Other commands", "Другие команды").Replace("To toggle on AND off the main monitor's map cam", "Вкл/выкл камеру карты основного монитора").Replace("[Player name]", "[Имя игрока]") .Replace("To switch view to a player on the main monitor", "Переключить камеру на другого игрока") .Replace("[Radar booster name]", "[Имя радар-усилителя]") .Replace("[message]", "[сообщение]") .Replace("To transmit a message with the signal translator", "Передача сообщения с помощью транслятора сигналов.") .Replace("To make a radar booster play a noise", "Заставить радар-усилитель воспроизвести шум") .Replace("To scan for the number of items left on the current planet", "Просканировать количество лома, оставшегося на текущей планете"); } public void translateCommandSigurd(ref string raw) { raw = raw.Replace("SIGURD'S LOG ENTRIES", "ЗАПИСИ СИГУРДА").Replace("NEW", "НОВОЕ").Replace("To read a log, use keyword \"VIEW\" before its name", "Для прочтения записи используйте \"VIEW\" перед ее названием") .Replace("First Log - Aug 22", "First Log - 22 Августа (Первая запись)") .Replace("Smells here! - Aug 24", "Smells here! - 24 Августа (Тут воняет!)") .Replace("Swing of things - Aug 27", "Swing of things - 27 Августа (Размах событий)") .Replace("Golden planet - Aug ??", "Golden planet - ?? Августа (Золотая планета)") .Replace("Shady - Aug 31", "Shady - 31 Августа (Подозрительно)") .Replace("Sound behind the wall - Sep 4", "Sound behind the wall - 4 Сентября (Звук за стеной)") .Replace("Goodbye - Sep 7", "Goodbye - 7 Сентября (Прощай)") .Replace("Screams - Sep 13", "Screams - 13 Сентября (Крики)") .Replace("Idea - Sep 19", "Idea - 19 Сентября (Идея)") .Replace("Nonsense - Sep 27", "Nonsense - 27 Сентября (Бессмыслица)") .Replace("Hiding - Sep 30", "Hiding - 30 Сентября (Сокрытие)") .Replace("Desmond - Oct 15", "Desmond - 15 Октбяря (Десмонд)"); } public bool translateDetailMoons(ref string raw) { string text = raw; raw = raw.Replace("Go here to drop off any valuable scrap you've collected while on the job. The rate of return updates hourly and fluctuates over the course of several days.", "Сюда можно сдать весь ценный лом, который вы собрали во время работы. Цена скупки обновляется каждый день. ").Replace("CONDITIONS: Arid. Low habitability, worsened by industrial artifacts.", "УСЛОВИЯ: Сухая. Низкая пригодность для жизни, ухудшенная промышленными артефактами. ").Replace("HISTORY: Not discovered for quite some time due to its close orbit around gas giant Big Grin. However it appears to have been used in secret.", "ИСТОРИЯ: Долгое время оставалась незамеченной из-за ее близкой орбиты вокруг газового гиганта Big Grin. Однако похоже, что она использовалась в секрете. ") .Replace("FAUNA: Unknown", "ФАУНА: Неизвестно") .Replace("CONDITIONS: Arid. Low habitability, worsened by industrial artifacts.", "УСЛОВИЯ: Сухая. Низкая пригодность для жизни, ухудшенная промышленными артефактами. ") .Replace("HISTORY: Not discovered for quite some time due to its close orbit around gas giant Big Grin. However it appears to have been used in secret.", "ИСТОРИЯ: Долгое время оставалась незамеченной из-за ее близкой орбиты вокруг газового гиганта Big Grin. Однако похоже, что она использовалась в секрете. ") .Replace("CONDITIONS: Similar to its twin moon, 41-Experimentation, featuring far more jagged and weathered terrain.", "УСЛОВИЯ: Как и луна-близнец 41-Experimentation, отличается более изрезанным и выветренным рельефом. ") .Replace("HISTORY: 220-Assurance is far younger than its counterpart. Discovered not long before 41-Experimentation.", "ИСТОРИЯ: 220-Assurance гораздо моложе своей коллеги. Обнаружен незадолго до 41-Experimentation. ") .Replace("CONDITIONS: Humid.", "Условия: Влажная. ") .Replace("HISTORY: Vow appears to have been inhabited by several colonies across its continents, but there is now no sign of life, and they have become a mystery.", "ИСТОРИЯ: По всей видимости, Vow была населена несколькими колониями, но теперь не осталось никаких признаков жизни, и она стала загадкой. ") .Replace("FAUNA: Diverse, teeming with plant-life", "ФАУНА: Разнообразна, кишащая растительностью. ") .Replace("CONDITIONS: Believed to have splintered off from its cousin Assurance, Offense features similar jagged and dry conditions but differs in its ecosystem.", "УСЛОВИЯ: Предполагается, что Offense откололась от своей кузины Assurance и обладает схожими неровными и засушливыми условиями, но отличается своей экосистемой. ") .Replace("HISTORY: 21-Offense is categorized as an asteroid moon and seems to have not existed on its own for more than several hundred years. The industrial artifacts here have suffered damage; it's believed they were built long before 21-Offense was splintered off.", "ИСТОРИЯ: 21-Offense относится к категории астероидных лун и, похоже, существует самостоятельно не более нескольких сотен лет. Промышленные артефакты здесь повреждены, считается, что они были построены задолго до того, как 21-Offense откололась. ") .Replace("FAUNA: A competitive and toughened ecosystem supports aggressive lifeforms. Travellers to 21-Offense should know it's not for the faint of heart.", "ФАУНА: конкурентная и жесткая экосистема поддерживает агрессивные формы жизни. Путешественники на 21-Offense должны знать, что это место не для слабонервных. ") .Replace("CONDITIONS: March undergoes constant drizzling weather. Its terrain is more expansive.", "УСЛОВИЯ: На March постоянно идет дождь. Ее местность более просторная. ") .Replace("HISTORY: This moon is overlooked due to its twin moon, Vow.", "ИСТОРИЯ: Эта луна часто упускается из виду из-за ее близнеца, Vow.") .Replace("CONDITIONS: Its planet orbits white dwarf star, making for inhospitable, cold conditions. Constant blizzards decrease visibility.", "УСЛОВИЯ: Вращается вокруг белой карликовой звезды, что создает негостеприимные, холодные условия. Постоянные метели снижают видимость. ") .Replace("HISTORY: Several famous travelers went missing here, giving it some reputation. Their bodies are unlikely to be found due to the planet's conditions.", "ИСТОРИЯ: Здесь пропали без вести несколько знаменитых путешественников, что создало планете определенную репутацию. Их тела вряд ли будут найдены из-за условий планеты. ") .Replace("FAUNA: It's highly unlikely for complex life to exist here.", "ФАУНА: Очень маловероятно, что здесь могут существовать сложные формы жизни. ") .Replace("CONDITIONS: A frozen, flat landscape.", "УСЛОВИЯ: Замороженная, плоская местность. ") .Replace("HISTORY: It looks like this moon was mined for resources. It's easy to get lost within the giant industrial complex. There are many entrances to it littered about the landscape.", "ИСТОРИЯ: По всей видимости, на этой луне велась добыча ресурсов. Легко заблудиться внутри огромного промышленного комплекса. По всей местности раскиданы многочисленные входы в него. ") .Replace("FAUNA: Dangerous entities have been rumored to take residence in the vast network of tunnels.", "ФАУНА: Существуют слухи о том, что опасные сущности обосновались в обширной сети туннелей. "); return raw == text; } public void translateDetailStore(ref string raw) { raw = raw.Replace("Useful for keeping in touch! Hear other players when the wakie talkie is in your inventory. Must be in your hand and pressed down to transmit voice", "Полезно для поддержания связи! Вы можете слышать других игроков, если в рюкзаке есть рация. Чтобы передать голос, она должна быть в руке и удерживаться кнопка передачи").Replace("The most affordable light source. It's even waterproof", "Самый доступный источник света. Он ещё и водонепроницаемый").Replace("For self-defense", "Для самообороны") .Replace("Lock-pickers will unlock your limitless potential for efficiency on the job. Powered by proprietary AI software, they will get you access through any locked door", "Взломщик раскроет ваш безграничный потенциал эффективности в работе. Благодаря запатентованному программному обеспечению с искусственным интеллектом он откроют вам доступ к любой запертой двери") .Replace("With an extra battery life and even brighter bulb, your colleagues can never leave you in the dark again", "Благодаря увеличенному времени автономной работы и еще более яркой лампе ваши коллеги никогда больше не оставят вас в темноте") .Replace("This action was not compatible with this object", "Это действие несовместимо с данным объектом") .Replace("These jamming tunes are great for a morale boost on your crew", "Музыка отлично поднимет боевой дух вашего экипажа") .Replace("This safe and legal medicine can be administered to see great benefits to your performance on the job! Your ability to move LONG distances while carrying HEFTY objects will be second to none! Warning: TZP gas may impact the brain with extended exposure. Follow instructions manual provided with the canister", "Этот безопасный и законный препарат может быть принят для получения значительных преимуществ в вашей работоспособности! Ваша способность перемещаться на БОЛЬШИЕ расстояния, несмотря на ТЯЖЕЛЫЕ объекты, будет непревзойденной! Предупреждение: ТЗП-Ингалятор может воздействовать на мозг при длительном воздействии. Следуйте инструкциям, предоставленным в руководстве по использованию баллона") .Replace("Don't forget to share", "Не забудьте поделиться") .Replace("The most specialized self-protective equipment, capable of sending upwards of 80,000 volts", "Самые специализированные средства самозащиты, способные посылать до 80,000 вольт") .Replace("To keep it targeted as long as possible, pull the gun side-to-side to counter the bend and fight against the pull of the electric beam. It can only stun for as long as you keep the current flowing", "Чтобы как можно дольше держать его на прицеле, тяните пистолет из стороны в сторону, чтобы противостоять изгибу и бороться с притяжением электрического луча. Он может оглушать только до тех пор, пока есть заряд") .Replace("This device will get you around anywhere! Just use it responsibly", "Это устройство доставит вас куда угодно! Только используйте его ответственно") .Replace("The extension ladder can reach as high as nine meters! Use it to scale any cliff and reach for the stars! To save batteries the extension ladder automatically stores itself after 18 seconds", "Выдвижная лестница может подниматься на высоту до девяти метров! С ее помощью можно преодолеть любой обрыв и дотянуться до звезд! Для экономии батареек автоматически убирается через 18 секунд") .Replace("Radar boosters come with many uses", "Радар-усилители имеют много применений") .Replace("Use the \"SWITCH\" command before the radar booster's name to view it on the main monitor. It must be activated", "Используйте \"SWITCH \" перед именем радар-усилителя, чтобы просмотреть его на основном мониторе. Он должен быть активирован") .Replace("Use the \"PING\" command before the radar booster's name to play a special sound from the device", "Используйте \"PING \" перед именем радар-усилителя, чтобы воспроизвести звук, издаваемый устройством") .Replace("Used to communicate with any crew member from any distance, no walkie talkie required! The horn can be heard from anywhere. But what does it mean? That's up to you", "Используется для связи с членами экипажа на любом расстоянии, не требуя рации! Гудок можно услышать отовсюду. Но что он означает? Это зависит от вас") .Replace("Press the button to activate the teleporter. It will teleport whoever is currently being monitored on the ship's radar. They will not be able to keep any of their held items through the teleport. It takes about ten seconds to recharge", "Нажмите кнопку, чтобы активировать телепортатор. Он телепортирует того, кто в данный момент находится под наблюдением радара корабля. Во время телепортации они не смогут сохранить ни одного из своих предметов. Перезарядка занимает около десяти секунд") .Replace("The inverse teleporter is a modified teleporter which will teleport you to a random position outside the ship. All your items will be dropped at the teleporter before transport. The inverse teleporter can be used by everyone at once and has a 3.5 minute cooldown", "Обратный телепортатор - это модифицированный телепортатор, который перемещает вас на случайную позицию вне корабля. Все ваши предметы будут оставлены у телепорта перед перемещением. Обратный телепортатор может использоваться всеми одновременно и имеет перезарядку в 3,5 минуты. ") .Replace("DISCLAIMER: The inverse teleporter can only transport you out, not in, and you may become trapped. The Company is not responsible for injury or replacement of heads and limbs induced by quantum entanglement and bad luck", "ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Обратный телепортатор может только телепортировать вас наружу, не внутрь, и вы можете оказаться запертыми. Компания не несет ответственности за травмы или замену голов и конечностей, вызванные квантовым запутыванием и неудачей. "); } public bool translateDetailBestiary(ref string raw) { string text = raw; raw = raw.Replace("Thumpers\n\n", "Thumpers - Тамперы\n\n").Replace("Sigurd's danger level: 90%\n\n", "Уровень опасности по шкале Сигурда: 90%\n\n").Replace("Scientific name: Pistris-saevus", "Научное название: Pistris-saevus") .Replace("Halves, or Thumpers, are a highly aggressive, carnivorous species of the order Chondrichthyes. Their skeletons are cartilaginous, giving their bodies a stretchy and rubbery quality. Their name comes from the fact they must eat their bottom legs in order to escape the shell of their hatched egg; their bottom legs are hardly functional to begin with. Their arms, or front legs, are very strong, and they occasionally use them to stomp prey. They can reach great speeds in a straight line", "Половинчатые, или Тамперы, представляют собой высокоагрессивный, плотоядный вид из отряда Chondrichthyes. Их скелет состоит из хрящевой ткани, придающей их телам упругость и резиновость. Их название происходит от того факта, что им приходится съедать свои задние ноги, чтобы выбраться из скорлупы своего яйца; их задние ноги изначально слабо функциональны. Их руки, или передние ноги, очень крепкие, и время от времени они используют их, чтобы топтать добычу. Они способны развивать высокие скорости на прямой линии") .Replace("They are relentless hunters, typically at the top of their food chain. Their main weaknesses are their intelligence and complete lack of hearing. If you come across a thumper, your best means of survival are leaving its line of sight, as it is slower around corners and can't easily track prey.", "Они беспощадные охотники, обычно на вершине своей пищевой цепи. Их основные слабости — это их интеллект и полное отсутствие слуха. Если вы столкнулись с тампером, лучший способ выживания — оставить его поле зрения, так как он медленннно поворачивается и не может легко преследовать добычу. ") .Replace("Due to the fast and volatile evolution of this species, some theorize that thumpers are one of the examples of an increased number of mutations causing higher levels of speciation in planets around the Thistle Nebula.", "Из-за быстрой и нестабильной эволюции этого вида некоторые предполагают, что тамперы являются одним из примеров увеличенного числа мутаций, вызывающих более высокие уровни видообразования на планетах в области туманности Thistle ") .Replace("HOARDING BUG", "HOARDING BUG - Жук собиратель") .Replace("Sigurd's danger level: 0%\n\n", "Уровень опасности по шкале Сигурда: 0%\n\n") .Replace("Scientific name: Linepithema-crassus", "Научное название: Linepithema-crassus") .Replace("Hoarding bugs (of the order Hymenoptera) are large, social insects. While often found living alone, they have been found to share their nests with members of their own species. They measure a height of 3 feet on average, with bulbous bodies. The thinness of their fluid and blood and the material of their carapaces contributes to their low weight, making them capable of flight with their membranous wings. It also makes their bodies somewhat transparent.", "Жуки собиратели (отряд Hymenoptera) - это крупные социальные насекомые. Хотя их часто можно встретить, живущими в одиночестве, было установлено, что они делят свои гнезда с представителями своего вида. Средняя высота их тел составляет примерно 1 метр, их тела округлые. Тонкость их жидкости и крови, а также материал панцирей, способствуют их низкому весу, что делает их способными к полету на мембранных крыльях. Это также делает их тела отчасти прозрачными. ") .Replace("Hoarding bugs were given their name due to their territorial nature. Once they have chosen a place as their nest, they will seek to adorn it with any object they can find and will protect these objects as a part of the nest. Hoarding bugs are not so dangerous alone as they are in large hives. However, if left alone, hoarding bugs are surprisingly neutral and pose little danger. wWe love the stupid cuddle bugs.!! - tjhis has been a note from the indomitable Sigurd", "Жуки собиратели получили свое название из-за своей территориальной природы. Как только они выбирают место для своего гнезда, они стремятся украсить его любыми предметами, которые они могут найти, и будут защищать эти предметы как часть гнезда. Жуки собиратели не так опасны в одиночку, как в больших ульях. Тем не менее, если их оставить в покое, жуки собиратели удивительно нейтральны и представляют мало опасности. Мы любим этих глупых и ласковых жуков!! - это была заметка от неудержимого Сигурда") .Replace("HYGRODERE", "HYGRODERE - Гидродер") .Replace("Sigurd's danger level: 0%, if you're faster than a snail!", "Уровень опасности по шкале Сигурда: 0%, если вы быстрее улитки!") .Replace("Scientific name: Hygrodere", "Научное название: Hygrodere") .Replace("A eukaryotic organism classified within the paraphyletic group Prostita. With the incredible speed of reproduction, these small organisms can multiply to millions. Hygrodere rarely split apart, instead choosing to form large, viscous masses which can take up large amounts of space and become a danger to deal with, requiring large tools or lures to relocate.", "Эукариотический организм, классифицированный в пафилетической группе Prostita. С невероятной скоростью размножения эти мелкие организмы могут умножаться до миллионов. Гидродеры редко расщепляются, вместо этого предпочитая формировать большие вязкие массы, которые могут занимать большие пространства и становиться опасностью, требующей применения крупных инструментов или приманок для перемещения. ") .Replace("Hygrodere are drawn to heat and oxygen and can detect it from seemingly anywhere. There's almost nothing organic they can't convert to their own body mass. Nothing has been found to poison them. Constantly replacing themselves, they can persist for hundreds of thousands of years. If you ever find yourself cornered, find a tall object to stand on top of; hygroderes have trouble climbing. they have great taste! cause I made a friend with one somehow,, and we think it was my music.", "Гидродеры тянутся к теплу и кислороду и могут обнаруживать его практически откуда угодно. Почти нет ничего органического, что они не могли бы преобразовать в собственную массу тела. Ничего не обнаружено, что могло бы отравить их. Постоянно заменяя себя, они могут существовать сотни тысяч лет. Если вы когда-либо окажетесь в тупике, найдите высокий объект, чтобы встать на него; гидродерам трудно подниматься. У них отличный вкус! Ведь я как-то подружился с одним, и мы думаем, что это была моя музыка. ") .Replace("COIL-HEADS", "COIL-HEADS - Пружиноголовый") .Replace("Sigurd's danger level: 80%", "Уровень опасности по шкале Сигурда: 80%") .Replace("Scientific name: Vir colligerus", "Научное название: Vir colligerus") .Replace("Vir colligerus, or colloquially named Coil-heads, have not been studied extensively due to their extreme unpredictability and dangerous properties. They have been known to combust into flames when being dissected or even deactivated, and they carry dangerously high levels of radioactive particles. Due to this and other reasons, it has been highly speculated they were created as biological weapons of war, although this has not been proven.", "Vir colligerus, или пружиноголовые, не были широко изучены из-за их чрезвычайной непредсказуемости и опасных свойств. Известно, что они воспламеняются при разделении или деактивации, а также содержат чрезвычайно высокие уровни радиоактивных частиц. Из-за этого и других причин существует вероятность того, что они были созданы как биологическое оружие, однако это не было доказано. ") .Replace("Coil-heads' visual appearance is that of a bloody mannequin with its head connected by a spring. Their defining behavioral characteristic is to stop when being looked at. However, this does not appear to be a hard-and-fast rule. When they encounter a loud or bright light they sometimes appear to enter a long reset mode.", "Визуально пружиноголовые представляют собой кровавый манекен с головой, соединенной пружиной. Их определяющей характеристикой поведения является остановка при прямом взгляде. Однако, кажется, что это не является строгим правилом. Когда они сталкиваются с громким или ярким светом, они входят в долгий режим перезагрузки. ") .Replace("Just stare at htem or use a stun grenade! - Sigurd", "Просто смотрите на них или используйте светошумовую гранату! - Сигурд - Sigurd") .Replace("EYELESS DOG", "EYELESS DOG - Слепая собака") .Replace("Scientific name: Leo caecus", "Научное название: Leo caecus") .Replace("A large mammal of the class Saeptivus. They are social, hunting in very large packs. They have also been called \"breathing lions\" for their recognizable sound and large mouths. They are endurance hunters and attempt to make up for their lack of sight with their sense of hearing. It's a popular myth that they often mistake the sounds of their own kind for prey, entering fights within their own packs.", "Крупное млекопитающее класса Saeptivus. Они социальные, охотясь в очень больших стаях. Их также называют 'дышащими львами' из-за узнаваемого звука и большой пасти. Они являются выносливыми охотниками и пытаются компенсировать свое отсутствие зрения чувстввительным слухом. Популярен миф, что они часто ошибочно принимают звуки своего собственного вида за добычу, вступая в борьбу внутри своих стай. ") .Replace("Their behaviour is unique from other pack animals in their tendency to spread out far to cover distance. When an eyeless dog has found prey, it roars to alert others in the near vicinity, who will also sound the alarm, sometimes resulting in a kind of chain reaction. Eyeless dogs can be dangerous in swarms. However, they are characteristically clumsy, taking guesses at their prey's exact location which are often incorrect.", "Их поведение уникально среди других стаевых животных своей тенденцией распространяться на большие расстояния. Когда слепая собака находит добычу, она рычит, чтобы предупредить других поблизости, которые также поднимут тревогу, иногда вызывая своего рода цепную реакцию. Слепые собаки могут быть опасными в стае. Тем не менее, характерно, что они неуклюжи, делая предположения о точном местоположении своей добычи, которые часто оказываются неверными. ") .Replace("Manticoils\n\n", "Manticoils - Мантикоилы\n\n") .Replace("Sigurd's danger level: 0%\n\n", "Уровень опасности по шкале Сигурда: 0%\n\n") .Replace("Scientific name: Quadrupes-manta", "Научное название: Quadrupes-manta") .Replace("Mantacoils are a passerine bird of the family corvidae. Their bodies are quite large compared to their early descendants, and their wingspan ranges from 55 to 64 inches. Their most defining characteristic is their set of four wings. Their back wings are mostly used to stabilize when at low speed, while their front two wings create the majority of lift. Their round bodies are a striking yellow but with black outlines or stripes along their primary (rear) feathers.", "Мантакоилы - это певчие птицы из семейства врановых. Их тела довольно крупные по сравнению с их древними потомками, и их размах крыльев составляет от 140 до 163 сантиметров. Их самой характерной чертой является четыре крыла. Задние крылья в основном используются для стабилизации при низкой скорости, в то время как передние два крыла создают основную поддержку. Их круглые тела выделяются ярко-желтым цветом, но с черными контурами или полосами по их основным (задним) перьям. ") .Replace("Manticoils mostly feed on small insects but can also feed on small rodents. They are highly intelligent and social. They pose little threat and have a generally passive temperament towards humans, although they are capable of transmitting Rabies, Rubenchloria, and Pitt Virus.", "Мантакоилы в основном питаются мелкими насекомыми, но также не брезгуют и грызунами. Умны и общительны, они предоставляют небольшую угрозу и обычно проявляют пассивное отношение к людям, хотя способны передавать бешенство, рубенхлорию и вирус Питта. ") .Replace("Spore lizard\n\n", "Spore lizard - Споровик\n\n") .Replace("Sigurd's danger level: i ,dont know probably 5% i just hate this pudgy legged little sh it", "Уровень опасности по шкале Сигурда: Я не знаю, наверное, 5%. Я просто ненавижу пухлую маленькую дрянь") .Replace("Scientific name: Lacerta-glomerorum", "Научное название: Lacerta-glomerorum") .Replace("Colloquially named puffers or spore lizards, Lacerta-glomerorum (of the family Alligatoridae) is one of the largest and heaviest reptiles. Despite their large mouths, they are herbivores and do not have a strong bite. The bulbs on their tails are believed to secrete a chemical which attracts and accelerates the growth of the fungus species Lycoperdon perlatum, which it can then shake to release spores as a defense mechanism--an unique example of a mutualistic symbiotic relationship.", "Именуемые пухляшами или споровиками, Lacerta-glomerorum (из семейства аллигаторовых) является одним из самых крупных и тяжелых рептилий. Несмотря на их крупную пасть, они являются травоядными и не обладают сильным укусом. Считается, что луковицы на их хвостах вырабатывают химическое вещество, которое привлекает и ускоряет рост грибного вида Lycoperdon perlatum, который они затем могут трясти, чтобы высвободить споры в качестве механизма защиты - уникальный пример взаимовыгодных симбиотических отношений. ") .Replace("Spore lizards have a very timid temperment, tending to avoid all confrontation if possible. If their attempts at threat display are not effective, they may attempt to attack, so it's not recommended to corner or chase one. There are historical records that spore lizards were at least partially domesticated hundreds of years ago, however this effort was set aside by an initiative to harvest their tails for their medicinal properties.", "Споровики обладают очень покладистым нравом и, по возможности, избегают всякой конфронтации. Если их попытки угрозы не оказывают эффекта, они могут предпринять попытку нападения, поэтому не рекомендуется загонять их в угол или преследовать. Имеются исторические записи о том, что споровики были по меньшей мере частично одомашнены сотни лет назад, однако эти усилия были приостановлены в рамках инициативы по сбору их хвостов в медицинских целях. ") .Replace("Bracken -- AKA flower man!", "Bracken - Брэкен -- Или цветочный человек! ") .Replace("it was flower man, you can't say othrwise! i wanted to find his body .You were the cowards", "Это был цветочный человек, по-другому не скажешь! Я хотел найти его тело. мы были трусами.") .Replace("Scientific name: Rapax-folium", "Научное название: Rapax-folium") .Replace("There is debate on the genus to which the Bracken belongs. It is a bipedal vertebrate with skin the color and texture of a red beat. The name was coined for what appear to be leaves protruding from its upper spine. The purpose of these is believed to be for intimidation, however not much is known about the specifics of bracken behaviour due to its illusiveness and low population.", "Идут дебаты относительно того рода, к которому относится Брэкен. Это двуногий позвоночный с кожей цвета и текстуры красной свеклы. Название было придумано из-за того, что кажется, будто листья выступают из его верхней части позвоночника. Считается, что их целью является запугивание, однако о многих аспектах поведения брэкена мало известно из-за его уклончивости и низкой популяции. ") .Replace("We know a little from accounts by wildlife experts who have encountered it. is a lone hunter with high intelligence. Its behavior can seem aloof; it exhibits high aggression even when unprovoked, yet it quickly backs off when confronted. However, brackens are known to up their hostility when cornered or simply watched for a long time. For this reason it's recommended to keep an eye on it but not to stare it down. No specimens have been collected dead or alive. It's theorized that upon death their bodies undergo a rapid decomposition process which is unique from other large animals.", "Мы знаем немного из отчетов экологов, которые сталкивались с ним. Это одинокий охотник с высоким интеллектом. Его поведение может показаться равнодушным; он проявляет высокую агрессию даже без провокации, но быстро отступает при столкновении. Однако брэкены известны своей враждебностью, когда их загоняют в угол или просто долго наблюдают за ними. По этой причине рекомендуется держать его в поле зрения, но не пялиться на него. Ни один экземпляр не был собран мертвым или живым. Существует теория, что после смерти их тела подвергаются быстрому процессу разложения, уникальному для других крупных животных. ") .Replace("Circuit Bees\n\n", "Circuit Bees - Электропчелы\n\n") .Replace("Sigurd's danger level: 90%\n\n", "Уровень опасности по шкале Сигурда: 90%\n\n") .Replace("Scientific name: Crabro-coruscus", "Научное название: Crabro-coruscus") .Replace("The circuit bee, also known as red bee, is a eusocial flying insect of the genus Apis, a descendent of the honey bee. Their appearance is quite recognizable from their hairy, red bodies and two sets of wings. Like their ancestors, they are well-known for their intelligent social BEEhavior, large colony size, building wax nests which they use to store honey, and their important role in pollination. Unlike the honey bee, which often chose high places such as trees to construct its hive, red bees create their hives on the ground.", "Электропчела, также известная как красная пчела, — это социальное летающее насекомое рода Apis, потомок медоносной пчелы. Их внешность легко узнаваема благодаря волосатым красным телам и двум комплектам крыльев. Как и их предки, они известны своим умным социальным поведением, большим размером колонии, строением восковых гнёзд, которые они используют для хранения мёда, а также важной ролью в опылении. В отличие от медоносной пчелы, которая часто выбирает высокие места, такие как деревья, для строительства улья, электропчелы создают свои ульи на земле. ") .Replace("Red bees are highly defensive. They will leave the nest to attack any creature that comes within several meters, leaving BEEhind only the queen and drone bees. This bold BEEhavior is enabled by their most defining aBEElity, which is their electrostatic charge. Red bees produce friction with the air. They also produce friction by rubbing their two pairs of wings against each other and by rubbing against one another while in the hive. What allows them to create such a surplus of electric field compared to the honey bee is still under research, as they generate a stronger electric field when panicked or angered. This ability is especially useful for them around water.", "Красные пчёлы хорошо защищены. Они покидают улей, чтобы атаковать любое существо, находящееся в пределах нескольких метров, оставляя за собой только королеву и трутней. Это смелое поведение обеспечивается их наиболее характерной особенностью, которая заключается в их электростатическом заряде. Красные пчёлы создают трение с воздухом, крыльями и друг с другом, находясь в улье. То, что позволяет им создавать такой избыток электрического поля по сравнению с медоносной пчелой, все еще находится в исследовании, поскольку они генерируют более сильное электрическое поле в состоянии паники или гнева. Эта особенность особенно полезна для них вблизи воды. ") .Replace("It's BEEst to keep your distance. If a red bee hive is stolen, red bee swarms will enter an onslaught in which they attack any living creature. This destructive BEEhavior will last until they have located the hive or completely exhausted themselves, which can take hours to days. They have BEEn known to leave BEEhind fields of bodies of small rodents, insects and even some larger mammals, and in rare cases they can start fires. Their strong BEEnefits and drawbacks to their ecosystems are highly debated. BEEbated !! - the indomitable Sigurd", "Лучше держаться на безопасном расстоянии. Если украден улей, рой красных пчёл полетит в наступление, в ходе которого они атакуют любое живое существо. Это разрушительное поведение продлится до тех пор, пока они не обнаружат улей или полностью не истощат себя, что может занять от нескольких часов до нескольких дней. Известно, что они оставляют за собой поля тел мелких грызунов, насекомых и даже некоторых крупных млекопитающих, а в редких случаях могут вызывать пожары. Их сильные преимущества и недостатки для экосистемы широко обсуждается. ПЧЕЛУждается!! - непокорный Сигурд") .Replace("Baboon hawk\n\n", "Baboon hawk - Бабуиновый ястреб\n\n") .Replace("Sigurd's danger level: 75%", "Уровень опасности по шкале Сигурда: 75%") .Replace("Scientific name: Papio-volturius", "Научное название: Papio - volturius") .Replace("Baboon hawks are a primate of the family Cercopithecidae. They are hunchbacked but can stand up to 8 feet on average. Their heads are boney, with bird-like beaks and long horns, which they use like skewers to gore and feed on prey. Their horns are made of keratin instead of bone like the rest of their skulls, and they do not contain nerves or blood vessels. As a result baboon hawks can often break their horns from the force they apply, then fully regrow them within the same season. Baboon hawks partly owe their name to their large wings, which could never carry their large body mass and are used instead for intimidation and protection from the elements.", "Бабуиновые ястребы — это приматы из семейства Cercopithecidae. Они горбатые, но в среднем могут вставать на ноги примерно до 2.5 метров. Их головы костлявые, с клювом и длинными рогами, которые они используют как шампуры, чтобы пронзать и питаться добычей. Их рога состоят из кератина, в отличие от костей остальной части черепа, и не содержат нервов или кровеносных сосудов. В результате бабуиновые ястребы часто могут сломать свои рога от приложенной силы, затем полностью восстанавливают их в том же сезоне. Названию \"бабуиновые ястребы\" они частично обязаны своим большим крыльям, которые никогда не смогли бы их унести из-за своей крупной массы тела и используют вместо этого для запугивания и защиты от природных элементов. ") .Replace("The largest baboon hawk troop ever observed was made up of 18 baboon hawks. They are loosely territorial, and much of their behavior is motivated by intimidation and display. They can become collectors, using any flashy or colorful object to mark their territory. As lone scouts, baboon hawks are generally timid and won't attack unless provoked. In greater numbers they can become a great danger; sticking close to others and making yourself seem dangerous are the best ways to prevent an attack. They prefer smaller mammals, but when desperate they are known to use their numbers to attack animals even twice their size, such as eyeless dogs. THEY TOOK M Y PICKLES", "Самый большой отряд бабуиновых ястребов, который когда-либо наблюдали, состоял из 18 особей. Они слабо территориальны, и большая часть их поведения обусловлена запугиванием и демонстрацией. Они могут стать коллекционерами, используя любой броский или красочный предмет, чтобы пометить свою территорию. Как одинокие разведчики, бабуиновые ястребы обычно робки и не нападают, если их не спровоцировать. В больших количествах они могут представлять большую опасность. Держаться поближе к другим и создавать впечатление, что вы опасны - лучший способ предотвратить нападение. Они предпочитают мелких млекопитающих, но в случае отчаяния, как известно, могут напасть на животных даже вдвое крупнее себя, например на слепых собак. ОНИ ЗАБРАЛИ МОИ ОГУРЦЫ") .Replace("FOREST KEEPER", "FOREST KEEPER - Лесной хранитель") .Replace("Sigurd's danger level: 50%", "Уровень опасности по шкале Сигурда: 50%") .Replace("Scientific name: Satyrid-proceritas", "Научное название: Satyrid-proceritas") .Replace("Believed to share a common ancestor with rapax-folium, these behemoths are called Forest Keepers for the biomes they often inhabit. Their bodies bare markings on their front and back which mimic eyes--this trait is more helpful in their youth, as they are not agile. Their skin is a unique, dense material which hardens further throughout their lives; the large spikes and bumps across their bodies form as a result of aging.", "Верится, что эти гиганты имеют общего предка с rapax-folium, их называют Лесными Хранителями из-за биомов, которые они часто заселяют. Их тела украшают метки на передней и задней частях, имитирующие глаза. Этот признак более полезен в их юности, так как они неуклюжиe. Их кожа представляет собой уникальный, плотный материал, который уплотняется еще больше на протяжении их жизни; большие шипы и бугры по всему их телу формируются в результате старения. ") .Replace("It's been said Forest Keepers exhibit a curious behavior similar to that of a human child the age of 5 or 6. They will eat anything they find fascinating. Forest Keepers don't actually need to put anything into their mouths, and it's theorized their main source of energy is a process similar to photosynthesis. Still, this makes them relatively dangerous to observe. They can see across long distances, so staying low and making use of cover is a must. They cannot enter small spaces and are not generally destructive, so stay close to shelter or overhangs.", "Говорят, что Лесные Хранители проявляют интересное поведение, схожее с поведением человеческого ребенка возрастом 5 или 6 лет. Они будут есть всё, что им кажется интересным. На самом деле Лесным Хранителям не нужно ничего класть в рот, и теоретически их основным источником энергии является процесс, аналогичный фотосинтезу. Тем не менее, это делает их относительно опасными для наблюдения. Они видят на дальние расстояния, поэтому оставаться низко и использовать укрытия - это обязательно. Они не могут входить в узкие пространства, обычно не являются разрушительными, поэтому лучше находиться близко к укрытию или свесам ") .Replace("Roaming Locusts\n\n", "Roaming Locusts - Блуждающая саранча\n\n") .Replace("Sigurd's danger level: 0%", "Уровень опасности по шкале Сигурда: 0%") .Replace("Scientific name: Anacridium-vega", "Научное название: Anacridium-vega") .Replace("Known as roaming locusts, this is a species of grasshopper. Unlike some species which are more prone to jump or fly, roaming locusts are almost never grounded and stay close together even when in smaller numbers. They will quickly disperse when a predator disrupts them but are highly attracted to light.", "Известная как блуждающая саранча, это вид кузнечиков. В отличие от некоторых видов, которые склонны к прыжкам или полетам, блуждающая саранча практически никогда не находится на земле и остаётся близко к друг другу даже в меньших количествах. Она быстро рассеивается, когда хищник их нарушает. Привлекает свет. ") .Replace("SNARE FLEA", "SNARE FLEA - Удушающая многоножка") .Replace("Sigurd's danger level: 30%", "Уровень опасности по шкале Сигурда: 30%") .Replace("Scientific name: Dolus-scolopendra.", "Научное название: Dolus-scolopendra. ") .Replace("A very large arthropod of the class chilopoda. Its body produces a silk which it primarily uses to propel itself to places where it is concealed. Its exoskeleton is somewhat fragile, and they can die from long falls. The snare flea does not produce venom, nor does it have a strong bite. It makes up for this weakness with its ability to tighten itself around large prey to suffocate.", "Очень крупное членистоногоее из класса хилопод. Его тело вырабатывает шелк, который он использует в основном для передвижения в места, где можно спрятаться. Экзоскелет многоножки довольно хрупок, и она может погибнуть при длительном падении. Удушающая многоножка не вырабатывает яд и не обладает сильным укусом. Эту слабость она компенсирует способностью стягиваться вокруг крупной добычи, чтобы задушить ее. ") .Replace("The snare flea thrives in dark, warm areas. It cannot survive low temperatures and generally avoids open air and sunlight take the rats outside or just beat the hell otu of them! i think their insides could make a good milkshake,,", "Удушающая многоножка процветает в тёплых и тёмных местах. Она не может выжить при низких температурах и, как правило, избегает открытого воздуха и солнечного света. Вынесите её на улицу или просто избейте! Я думаю, что их внутренности могли бы составить хороший молочный коктейль, , ") .Replace("EARTH LEVIATHAN", "EARTH LEVIATHAN - Земной левиафан") .Replace("Sigurd's danger level: 2% cause they can't hide from the ship cmaeras!!", "Уровень опасности по шкале Сигурда: 2%, потому что они не могут скрыться от камер корабля!! ") .Replace("Scientific name: Hemibdella-gigantis", "Научное название: Hemibdella-gigantis") .Replace("The reverently named Earth Leviathan, of the family Piscicolidae, is one of the largest invertibrates found around the Thistle Nebula. None have been captured, so not much is known of their biology.", "Земной левиафан, получивший благородное название, из семейства Piscicolidae - одно из самых крупных беспозвоночных, встречающихся в районе туманности Thistle. Ни один из них не был пойман, поэтому об их биологии известно немного. ") .Replace("They seem to behave as predators. It's speculated they can burrow as far as 40 meters underground, judging by the incredible excavations they can leave behind. They can detect even the slightest vibrations, and for this reason it's not recommended to stay still if they are nearby; that is a myth. Instead, if you hear them burrowing, retrace your steps.", "Похоже, они ведут себя как хищники. Предполагается, что они могут зарываться под землю на 40 метров, судя по невероятным раскопкам, которые они оставляют после себя. Они способны улавливать даже малейшие вибрации, поэтому не рекомендуется замирать, если они находятся поблизости - это миф. Вместо этого, если вы слышите, как они зарываются, вернитесь на прежнее место. ") .Replace("Bunker spiders\n\n", "Bunker spiders - Бункерный паук\n\n") .Replace("Sigurd's danger level: 20%", "Уровень опасности по шкале Сигурда: 20%") .Replace("Scientific name: Mutinum-ficedula", "Научное название: Mutinum-ficedula") .Replace("Bunker spiders, of the genus Theraphosa, are the largest arachnid found in the Thistle Nebula and the second largest ever discovered. It's believed they evolved to prey on large mammals over the course of a measly several hundred years after the Boat made its trip around the Thistle Nebula.", "Бункерные пауки, рода Theraphosa, являются крупнейшими паукообразными, обнаруженными в туманности Thistle, и вторыми по размерам, когда-либо обнаруженными. Считается, что они эволюционировали, чтобы охотиться на крупных млекопитающих в течение всего нескольких сотен лет после того, как Корабль совершил свое путешествие вокруг тумаанности Thistle. ") .Replace("(Refer to: Speculation on Increased Speciation Around the Fading Nebulae)", "(Смотрите также: Преположения о увеличении спекуляций вокруг угасающих туманностей)") .Replace("Bunker spiders produce silk and lay it around their chosen nesting area, then wait for it to be tripped on. They can be seen waiting on walls, often over doorways where prey could enter unaware. If you find a bunker spider 'unprepared' it may freeze as a defensive reaction. In this case they are best left alone. If a bunker spider reacts aggressively, it is best not to fight with ordinary tools. They use their webs to make up for their rather slow movement, so take note of your surroundings. Their webs can be broken easily with any blunt tool.", "Бункерные пауки производят шелк и раскладывают его вокруг выбранной зоны гнездования, затем ждут, чтобы кто-то на него наступил. Их можно увидеть, ожидая на стенах, часто над дверными проемами, где добыча может войти, ничего не подозревая. Если вы обнаружили бункерного паука неподготовленным, он может застыть в качестве защитной реакции. В этом случае лучше оставить его в покое. Если бункерный паук реагирует агрессивно, лучше не сражаться обычными инструментами. Они используют свои паутины, чтобы компенсировать свое довольно медленное передвижение, поэтому обратите внимание на окружающую среду. Их паутины можно легко разорвать любым тупым инструментом. ") .Replace("Bunker spiders can pose a great danger to humans and urban explorers especially, without a great benefit to their ecosystems. A resulting kill-on-sight order has been informally agreed upon between many states home to the Bunker spider, and it is currently approved by the ITDA as of 10/6/2497.", "Бункерные пауки могут представлять большую опасность для людей и особенно для городских жителей, не принося особой пользы экосистемам. В результате между многими штатами, где обитает бункерный паук, был неофициально согласован приказ \"убивать на месте\", и в настоящее время он одобрен ITDA от 10/6/2497. ") .Replace("JESTER", "JESTER - Шутник") .Replace("Sigurd's danger level: 90% Get out o fthere before it goes APE!! You cant hide from it, just evacuate", "Уровень опасности по шкале Сигурда: 90% Выйдите оттуда, пока не стало ПОЗДНО!! Вы не можете спрятаться от него, просто эвакуируйтесь") .Replace("Scientific name: INSANEUS THINGUS", "Научное название: INSANEUS THINGUS") .Replace("THERE'S NO FREAKING SCIENTIFIC RECORD! good luck, you know as much as us. we just call it the jester", "ТУТ НЕТ НИКАКИХ НАУЧНЫХ ЗАПИСЕЙ! Удачи, вы знаете столько же, сколько и мы. Мы просто называем его Шутник."); return raw == text; } public bool translateDetailSigurd(ref string raw) { string text = raw; raw = raw.Replace("First Log - Aug 22", "Первая запись").Replace("Date: August 22, 1968", "Дата: 22 августа 1968 года").Replace("Hello. i am writing this log to keep myself sane. I couldnt find a way to do the most basic thing on this old janky butt computer so I had Desmond add it in, the log feature. til now ive just been adding my own notes to the bestiary whatever i know. My brother said i should keep a journal so im doing what i can! I am writing in a proffessional manner, as these logs could become a historical record, as they will projbably be here for years, just as long as there isnt a clean wipe. that is what desmond saidfd", "Здравствуйте. Я пишу этот журнал, чтобы не сойти с ума. До сих пор я просто добавлял свои заметки в бестиарий, что знал. Мой брат сказал, что я должен вести дневник, так что я делаю то, что могу! Я пишу профессионально, так как эти записи могут стать исторической справкой, и они, вероятно, будут храниться здесь годами, пока не произойдет чистка. Так сказал Десмонд") .Replace("If you are reading it in the future, you are probably from a nother crew. The turnover rate here is enormous, maybe cause this job sucks and every one turns over dead! Maybe I can give some help when I have some expirience. End log", "Если вы читаете это в будущем, вы, вероятно, из другой команды. Текучесть кадров здесь огромная, может быть, потому, что эта работа - отстой, и каждый переворачивается замертво! Может быть, я смогу помочь, когда у меня будет опыт. Конец журнала") .Replace("Oh, our names are: Sigurd (me), Richard, Desmond, Jess.", "Ах да, наши имена: Сигурд (я), Ричард, Десмонд, Джесс") .Replace("Smells here! - Aug 24", "Тут воняет!") .Replace("gosh, this suit is squeezing me like I'm a gosh damn mummy! im a grown man, give it some space between the legs! it's killing me i'm dying! i hope youre happy dad, I FINALLY got a job. screw you! Everyone here smells. especially Rich. I'm going to throw him in the lake. I don't care what it's made of. i love being on camera duty. oh", "боже, этот костюм давит на меня, как на чертову мумию! Я взрослый человек, дай ему немного пространства между ног! Он убивает меня, я умираю! Надеюсь, ты счастлив, папа, я наконец-то получил работу. Пошел ты! Здесь все воняют. Особенно Рич. Я собираюсь бросить его в озеро. Мне плевать, из чего она состоит. Я люблю дежурить у камеры") .Replace("i forgot the date it's August 24, 1968. this keyboard has dsadjilfasqt..f/g;", "О, я забыл дату - 24 августа 1968 года. Эта клавиатура имеет dsadjilfasqt..f/g;") .Replace("today we found a couple frying pans and a big nail. Worth almost nothing. what is the company even using it for", "Сегодня мы нашли пару сковородок и большой гвоздь. Почти ничего не стоит. Для чего компания вообще их использует") .Replace("SWING OF THINGS - AUG 27", "ПОВСЕДНЕВНОСТЬ") .Replace("we got in the \"swing of things\" the past few days. thats what Rich keeps saying, he smells like a rancid tuna can. worst summer camp I've ever been o n. Date is August 27, 1968", "Последние несколько дней мы втянулись в работу. Вот что постоянно говорит Рич, он пахнет как прогорклая банка с тунцом. Худший летний лагерь, на котором я когда-либо был. Дата - 27 августа 1968 года") .Replace("we make sure someone always has a shovel for bashing anything that moves, and we always put someone on \"camera duty\" so they can open these big security doors with letters and numbers. ask Desmond the wizard how that works, I think he just", "Мы следим, чтобы у кого-то всегда была лопата, чтобы разбивать все, что движется, и мы всегда ставим кого-то на дежурство, чтобы он мог открывать эти большие двери с буквами и цифрами. Спросите Десмонда, волшебника, как это работает, я думаю, он просто") .Replace("types in the code thats on the door", "он просто набирает код указанный на двери.") .Replace("Thats it", "Вот и все") .Replace("we sold some goods to the company today at 70% value. i got m y nerves chilled listening to the fuckng PYSCHOTIC soundfs behind the counter. No one else gave any. ??", "Сегодня мы продали несколько товаров компании по 70% стоимости. У меня мороз по коже от звуков за прилавком. Никто другой не отреагировал. ??") .Replace("Cant ignore that! my flashlight didn't even go back there, the beam just went dark", "Нельзя игнорировать это! Мой фонарик даже не освещал то место, просто померк. ") .Replace("Golden planet - Aug ??", "Золотая планета") .Replace("I talked ot a voice on the walkie talkie, it was like a part of the screams. he told me the Golden planet actually existed, its not a legend. and he told me it didn't just hit a meteor. He said the planet was swallowed up by the \"beast\", and they were in its body being diggested. i asked what the beast is, and he said he didnt know!. he said it ate the planet and they forgot everything", "Я разговаривал с голосом по рации, это было как часть криков. Он сказал мне, что Золотая планета действительно существует, это не легенда. И он сказал мне, что это было не просто столкновение с метеоритом. Он сказал, что планета была поглощена \"зверем\", и они находились внутри его тела, подвергаясь перевариванию. Я спросил, что это за зверь, и он сказал, что не знает! Он сказал, что зверь съел планету, и они забыли все") .Replace("i couldnt get him to stop talking. but i said he was on the other side of a big wall and i could get him out. i said he was inside the building. and thats when he started freaking out/. i couldn't make out a word, I think he said something about \"spitting out the rinds\" So i just turned it off. what a wack", "Я не мог заставить его перестать говорить. Но я сказал ему, что он на другой стороне большой стены, и я могу его вытащить. Я сказал, что он внутри здания. И вот тогда он начал паниковать. Я не мог разобрать ни слова, но, кажется, он сказал что-то о \"выплевывании кожуры\". Так что я просто выключил его. Какая дикая история") .Replace("Jess says the golden planet is just a story. I said I KNOW, I'm not an idiot. Well she said i should quit, and she quits if i do. so she s staying", "Джесс говорит, что Золотая планета - всего лишь рассказ. Я сказал, Я ЗНАЮ, я не идиот. Ну, она сказала, что я должен бросить это, и она бросит, если я это сделаю. Так что она остается") .Replace("Shady - Aug 31", "Подозрительно") .Replace("date is August 31, 1968. i got camera duty again, i hate walking on this moon anyway. ahah jokes on them it, just started raining!!! Im just sitting. cant sleep on these tiny beds for ants", "Дата - 31 августа 1968 года. Я снова дежурю у камеры, ненавижу ходить на этой луне. Ахах, шучу над ними, только что начался дождь!!! Я просто сижу. Не могу спать на этих крошечных кроватях для муравьев") .Replace("Ive been thinking a lot. i think this job is shady. If youre reading this you probbably got here the same as me. the pay is good, the contract only lasts a season. they ran you through their \"assessmennt exam\" on the phone with a weird voice. you signed the contract on the shuttle with the rest of your crew. But the whole time you didnt talk to anyone. The shuttle was autopiloted, I think the voice on the phone was fake. I;ve had the wrost dreams, I think I just want to go back home. but im not gonna crawl home, crying and scratching on dad's front door. thats not his son. thats not Sigurd!", "Эта работа подозрительная. Если вы читаете это, то, скорее всего, попали сюда так же, как и я. Зарплата хорошая, контракт рассчитан только на сезон. Они прогнали вас через свой \"оценочный экзамен\" по телефону со странным голосом. Вы подписали контракт на шаттле вместе с остальными членами вашей команды. Но все это время вы ни с кем не разговаривали.Шаттл был на автопилоте, я думаю, что голос в телефоне был фальшивым. Мне снятся странные сны, я думаю, что просто хочу вернуться домой. Но я не собираюсь ползти домой, плача и царапая входную дверь отца. Это не его сын. Это не Сигурд! ") .Replace("Sound behind the wall - Sep 4", "Звук за стеной") .Replace("date: Septermber 4, 1968", "Дата: 4 Сентября 1968 года") .Replace("i got woken up early this morning because we were going to the company building to sell our useless garbage. The rate was 120% which Desmond says is rare and he didnt want to miss it, hes been watching it like the stupid stocks", "сегодня утром меня разбудили рано, потому что мы собирались в здание компании, чтобы продать наш бесполезный мусор. Ставка составила 120%, что, по словам Десмонда, редкость, и он не хотел пропустить это, он следил за этим, как за дурацкими акциями") .Replace("it still sucks here, Rich still smells like a piece of hsit .i can barely sleep. i heard the wrorst sound behind the wall of the company building, it sounded like crying red faces all churned up and swept away by concrete, like the pestle and bowl my mom crushes up her seeds and spices in. i still hear it. Its a nightmare. no one else heard it. they dont know what to do. Jess thinks i;m \"home sick,\" no im sick of this cheap suit", "здесь по-прежнему паршиво, Рич по-прежнему пахнет куском говна.я едва могу заснуть. я услышал ужасный звук за стеной здания компании, он звучал так, словно плачущие красные лица были размазаны по бетону, как пестик и миска, в которых моя мама измельчает семена и специи. я все еще слышу это. Это кошмар. больше никто этого не слышал. они не знают, что делать. Джесс думает, что меня \"тошнит от дома\", нет, меня тошнит от этого дешевого костюма") .Replace("Goodbye - Sep 7", "Прощай") .Replace("we left behiind Rich. we just had one room to check and then we could be done for the day, i couldnt get the door open. And then i looked and Rich wasnt there. It was the ♥♥♥♥♥♥♥ wrinkly skin flower head man that walks on two legs! it turned his neck. i heard the crack but he wasnt there. I wanted to find Rich even if he was dead, but they are cowards! their faces are blank like idiots, theres nothing moving in their stupid skulls, all they wanted to do is leave. they were going to leave me too. we all hated Rich but we didnt want this. this isnt worth it, its just not worth it. we got a pair of scissors, a box full of stamps and a bundle of cords to sell for nothing. its not wort h it, what does the company even want it for?", "мы оставили Рича. нам нужно было проверить только одну комнату, а потом мы могли бы закончить на сегодня, я не смог открыть дверь. А потом я посмотрел, и Рича там не было. Это был гребаный человек с морщинистой кожей и цветочной головой, который ходит на двух ногах! это свернуло ему шею. я услышал треск, но его там не было. Я хотел найти Рича, даже если бы он был мертв, но они трусы! их лица пусты, как у идиотов, в их тупых черепах ничего не двигается, все, что они хотели сделать, это уйти. они собирались бросить и меня тоже. мы все ненавидели Рича, но мы не хотели этого. это того не стоит, оно просто того не стоит. у нас есть пара ножниц, коробка с марками и связка шнуров, которые мы продаем за бесценок. дело не в этом, зачем это вообще нужно компании?") .Replace("the date we last saw Rich is September 7, 1968", "дата, когда мы в последний раз видели Рича, - 7 сентября 1968 года") .Replace("Screams - Sep 13", "Крики") .Replace("date: September 13, 1968", "дата: 13 сентября 1968 года") .Replace("for some reason i was the one who had to call the company number to report the acciddent. they were too scared to do it. It was the same fake voice i remember from the interview on the phone at home and the stupid training videos. but it heard what i said i think, cause it said they would contact the family and find a replacement and something e lse. It talked so fast", "по какой-то причине именно мне пришлось позвонить на номер компании, чтобы сообщить о происшествии. они были слишком напуганы, чтобы сделать это. Это был тот же фальшивый голос, который я помню по собеседованию по телефону дома и дурацким обучающим видео. но он услышал, что я сказал, я думаю, потому что он сказал, что они свяжутся с семьей и найдут замену, и что-то в этом роде. Он говорил так быстро") .Replace("I learned you can hear the screams all the time in the walkie talkie when you;re at the wall of the Company building. they didnt believe me, well now they do. It sounds just like when i heard it a couple weeks ago. They want to quit. I said I'm not a coward. I just got this job", "Я узнал, что крики можно постоянно слышать по рации, когда находишься у стены здания Компании. они мне не поверили, что ж, теперь верят. Это звучит точно так же, как когда я слышал это пару недель назад. Они хотят уволиться. Я сказал, что я не трус. Я только что получил эту работу. ") .Replace("Idea - Sep 19", "Идея") .Replace("date: September 19, 1968", "дата - 19 сентября 1968 года") .Replace("the past weekend it feels like Desmond and Jess woke up. we;re supposed to get our fourth member of the crew in a few days. We arent taking any risks anymore, we dont get as much but it feels safer, and ive gotten better sleep. but its still ass. i can still smell Rich i swear to gosh he smelled that bad", "В прошлые выходные казалось, что Десмонд и Джесс пришли в себя. Через несколько дней к нам присоеденится четвертый член команды. Мы больше не рискуем, хотя и получаем меньше, но это кажется безопаснее, и я лучше сплю. Но это все равно грустно. Я все еще чувствую запах Рича, клянусь, он так вонял") .Replace("i was talking about how the voice on the phone sounded fake. Then Desmond got this weird idea. he's the wizard and all so he thinks theres a way to use the phone call i made to the company number to find ourt where the voice comes from. i dont know why hed want to do that but he seems serious. He;s been using the terminal a lot.", "Я говорил о том, как голос по телефону звучал поддельно. Тогда Десмонд придумал эту странную идею. Он - волшебник и всё такое, поэтому он думает, что есть способ использовать звонок, который я сделал на номер компании, чтобы выяснить, откуда идет этот голос. Не знаю, почему ему это нужно, но он кажется серьезным. Он много времени проводит за терминалом. ") .Replace("Nonsense - Sep 27", "бессмыслица") .Replace("September 27, 1968", "27 сентября 1968 года") .Replace("desmond wants me to writ e down what we figured out and keep my \"nonsense to a minimum\". So im going to put SO MUCH of my non sense. screw him. The new crew member is named Lucas and he is so confused and scared a ll the time, what a baby, at least he doesnt smell like a monster.", "Десмонд хочет, чтобы я записал, что мы выяснили, и держал свой \"бред на минимуме\". Так что я собираюсь добавить так много своего бреда. На него плевать. Новый член экипажа по имени Лукас такой сбитый и испуганный все время, что за младенец, хоть не воняет как монстр. ") .Replace("its been so sunny even though its september, and these suits dont take it well", "Было так солнечно, хотя сентябрь, и эти костюмы не очень хорошо переносят это. ") .Replace("ok so desmond \"traced the call\" and found out theres a group of people somewhere else that pretends to call us from the company building. they are across the whole solar system !! why would they be so far away.", "Ладно, так вот, Десмонд \"проследил звонок\" и выяснил, что есть группа людей где-то еще, которая притворяется, будто звонит нам из здания компании. Они на другом конце солнечной системы!! Почему они так далеко? ") .Replace("Desmond says he doesnt know, but i think. What if there really is a big monster in the company building like the voice told me on the wlakie talkie? They trapped it, and we feed it to keep it tame. i just wanted a stupid job!!!!!", "Десмонд говорит, что не знает, но я думаю. А вдруг в здании компании действительно есть большой монстр, как голос сказал мне по рации? Они его заперли, и мы его кормим, чтобы держать под контролем. Я просто хотел тупую работу!!!!!") .Replace("Hiding - Sep 30", "прячущийся") .Replace("September 30, 1968", "30 сентября 1968 года") .Replace("i keep having bad dreams about the Company building where the Company breaks out of that giant concrete wall. But i dont know if it looks like anything, i just think its really big and fast. We cant figure out a way to know if the voices on the phone are real, desmond says its too far away. i asked him if he could ttake control of the autopilot and he said im crazy and that could kill us. yes i am crazy desmond", "Я постоянно вижу кошмары о здании Компании, где Компания выбирается из этой гигантской бетонной стены. Но я не знаю, выглядит ли оно как-то определенно, мне просто кажется, что оно огромное и быстрое. Мы не можем понять, как узнать, реальные ли голоса по телефону, Десмонд говорит, что это слишком далеко. Я спросил его, не мог бы он взять под контроль автопилот, и он сказал, что я с ума сошел, и это может нас убить. Да, я с ума сошел, Десмонд") .Replace("he says we would have to get our own private flight to go to the cordinates, and who knows what would actually be there. So, what if its nothing?", "Он говорит, что нам пришлось бы взять свой собственный частный рейс, чтобы добраться до координат, и кто знает, что там на самом деле будет. Так что, а вдруг там ничего нет? ") .Replace("i started wondering how i cant remember how we really got here, no I just remember little things like the shuttle flight to the building where we signed our contracts. But i dont remember getting on the shuttle, i dont even remember saying bye to dad. in my dreams it feels like the company isnt trapped in there at all, its just hiding. I dont know if im going home", "我开始思考, 我都想不起来我们是怎么到这儿的了, 不对, 我还记得起来一点, 我还记得我们是坐飞船到设施, 路上我们签了合同. 但我不记得我们是怎么登上飞船的, 我甚至记不起有没有和老爸告过别. 梦里我感觉“公司”根本没有被困
BepInEx/plugins/XUnity.AutoTranslator/ExIni.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using Microsoft.Win32; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyInformationalVersion("GIT master [cf85ca6f3fc361cf48bf56107e4cec9102b7f5eb] ")] [assembly: AssemblyTitle("ExIni")] [assembly: Guid("b8adf1ac-aade-485a-8997-14c4b42e0a8b")] [assembly: AssemblyDescription("Extended INI File Handler")] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyFileVersion("1.0.2.1")] [assembly: AssemblyCompany("Usagirei")] [assembly: AssemblyProduct("ExIni")] [assembly: ComVisible(false)] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCopyright("Copyright © Usagirei 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyVersion("1.0.2.1")] namespace ExIni; public class IniComment { public List<string> Comments { get; set; } public IniComment() { Comments = new List<string>(); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < Comments.Count; i++) { string text = Comments[i]; string value = ((i < Comments.Count - 1) ? (";" + text + Environment.NewLine) : (";" + text)); stringBuilder.Append(value); } return stringBuilder.ToString(); } public void Append(params string[] comments) { Comments.AddRange(comments); } } public class IniFile { private readonly IniComment _comments; private readonly List<IniSection> _sections; public IniSection this[string sec] => CreateSection(sec); public IniComment Comments => _comments; public List<IniSection> Sections => _sections; public IniFile() { _comments = new IniComment(); _sections = new List<IniSection>(); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < Sections.Count; i++) { IniSection iniSection = Sections[i]; if (iniSection.Comments.Comments.Any()) { stringBuilder.AppendLine(iniSection.Comments.ToString()); } stringBuilder.AppendLine(iniSection.ToString()); foreach (IniKey key in iniSection.Keys) { if (key.Comments.Comments.Any()) { stringBuilder.AppendLine(key.Comments.ToString()); } stringBuilder.AppendLine(key.ToString()); } if (i < Sections.Count - 1) { stringBuilder.AppendLine(); } } if (Comments.Comments.Any()) { stringBuilder.AppendLine(); stringBuilder.AppendLine(Comments.ToString()); } return stringBuilder.ToString(); } public IniSection CreateSection(string section) { IniSection section2 = GetSection(section); if (section2 != null) { return section2; } IniSection iniSection = new IniSection(section); _sections.Add(iniSection); return iniSection; } public bool DeleteSection(string section) { if (!HasSection(section)) { return false; } Sections.Remove(GetSection(section)); return true; } public IniSection GetSection(string section) { if (!HasSection(section)) { return null; } return _sections.FirstOrDefault((IniSection iniSection) => iniSection.Section == section); } public bool HasSection(string section) { return _sections.Any((IniSection iniSection) => iniSection.Section == section); } public void Merge(IniFile ini) { Comments.Append(ini.Comments.Comments.ToArray()); foreach (IniSection section in ini.Sections) { IniSection iniSection = this[section.Section]; iniSection.Comments.Append(section.Comments.Comments.ToArray()); foreach (IniKey key in section.Keys) { IniKey iniKey = iniSection[key.Key]; iniKey.Comments.Append(key.Comments.Comments.ToArray()); iniKey.Value = key.Value; } } } public void Save(string filePath) { string directoryName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(filePath, ToString(), Encoding.UTF8); } public static IniFile FromFile(string iniString) { return IniParser.Parse(File.ReadAllText(iniString)); } public static IniFile FromString(string iniString) { return IniParser.Parse(iniString); } } public class IniKey { private readonly IniComment _comments; public IniComment Comments => _comments; public string Key { get; set; } public string RawValue { get; set; } public string Value { get { return Resolve(RawValue); } set { RawValue = value; } } public IniKey(string key, string value = null) { Key = key; Value = value; _comments = new IniComment(); } public override string ToString() { return $"{Key}={RawValue}"; } private static string GetEnvironment(string env) { return Environment.ExpandEnvironmentVariables(env); } private static string GetRegistry(string path) { string directoryName = Path.GetDirectoryName(path); string fileName = Path.GetFileName(path); if (string.IsNullOrEmpty(directoryName)) { return null; } return Registry.GetValue(directoryName, fileName, string.Empty)?.ToString(); } private static string Resolve(string value) { if (value == null) { return null; } Regex regex = new Regex("\\$\\((?<reg>.*)\\)"); Regex regex2 = new Regex("%.*%"); while (regex.IsMatch(value) || regex2.IsMatch(value)) { value = regex.Replace(value, (Match match) => GetRegistry(match.Groups["reg"].Value)); value = GetEnvironment(value); } return value; } } internal class IniParser { private static readonly Regex CommentRegex = new Regex("^;(?<com>.*)"); private static readonly Regex KeyRegex = new Regex("^(?<key>[\\w\\s]+)=(?<val>.*)$"); private static readonly Regex SectionRegex = new Regex("^\\[(?<sec>[\\w\\s]+)\\]$"); private static readonly Regex VarRegex = new Regex("^\\@(?<key>[\\w\\s]+)=(?<val>.*)$"); public static IniFile Parse(string iniString) { IniFile iniFile = new IniFile(); string[] array = (from line in iniString.Split(new char[1] { '\n' }) let trimmed = line.Trim() select trimmed.TrimEnd(new char[1] { '\r' })).ToArray(); List<string> list = new List<string>(); IniSection iniSection = null; bool flag = false; for (int i = 0; i < array.Length; i++) { string text = array[i]; if (string.IsNullOrEmpty(text)) { continue; } if (IsComment(text)) { string comment = GetComment(text); list.Add(comment); if (IsVariable(comment)) { string[] variable = GetVariable(comment); string variable2 = variable[0]; string value = variable[1]; Environment.SetEnvironmentVariable(variable2, value); } flag = true; } else if (IsSection(text)) { iniSection = iniFile[GetSection(text)]; if (flag) { iniSection.Comments.Append(list.ToArray()); list.Clear(); flag = false; } } else if (IsKey(text)) { if (iniSection == null) { throw new Exception($"{i}: Sectionless Key Value Pair"); } string[] key = GetKey(text); string key2 = key[0]; string value2 = key[1]; if (flag) { iniSection[key2].Comments.Append(list.ToArray()); list.Clear(); flag = false; } iniSection[key2].Value = value2; } } if (flag) { iniFile.Comments.Append(list.ToArray()); } return iniFile; } private static string GetComment(string line) { return CommentRegex.Match(line).Groups["com"].Value; } private static string[] GetKey(string line) { Match match = KeyRegex.Match(line); return new string[2] { match.Groups["key"].Value, match.Groups["val"].Value }; } private static string GetSection(string line) { return SectionRegex.Match(line).Groups["sec"].Value; } private static string[] GetVariable(string line) { Match match = VarRegex.Match(line); return new string[2] { match.Groups["key"].Value, match.Groups["val"].Value }; } private static bool IsComment(string line) { return CommentRegex.IsMatch(line); } private static bool IsKey(string line) { return KeyRegex.IsMatch(line); } private static bool IsSection(string line) { return SectionRegex.IsMatch(line); } private static bool IsVariable(string line) { return VarRegex.IsMatch(line); } } public class IniSection { private readonly IniComment _comments; private readonly List<IniKey> _keys; public IniKey this[string key] => CreateKey(key); public IniComment Comments => _comments; public List<IniKey> Keys => _keys; public string Section { get; set; } public IniSection(string section) { Section = section; _comments = new IniComment(); _keys = new List<IniKey>(); } public override string ToString() { return $"[{Section}]"; } public IniKey CreateKey(string key) { IniKey key2 = GetKey(key); if (key2 != null) { return key2; } IniKey iniKey = new IniKey(key); _keys.Add(iniKey); return iniKey; } public IniKey GetKey(string key) { if (!HasKey(key)) { return null; } return _keys.FirstOrDefault((IniKey iniKey) => iniKey.Key == key); } public bool HasKey(string key) { return _keys.Any((IniKey iniKey) => iniKey.Key == key); } public bool DeleteKey(string key) { if (!HasKey(key)) { return false; } Keys.Remove(GetKey(key)); return true; } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/BaiduTranslate.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core; using XUnity.AutoTranslator.Plugin.Core.Constants; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Extensions; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; using XUnity.Common.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("BaiduTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BaiduTranslate")] [assembly: AssemblyTitle("BaiduTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace BaiduTranslate; internal class BaiduTranslateEndpoint : HttpEndpoint { private static readonly Dictionary<string, string> SupportedLanguages = new Dictionary<string, string> { { "en", "en" }, { "ja", "jp" }, { "jp", "jp" }, { "zh", "zh" }, { "zh-Hans", "zh" }, { "zh-CN", "zh" }, { "zh-Hant", "cht" }, { "zh-TW", "cht" }, { "ko", "kor" }, { "kor", "kor" }, { "fra", "fra" }, { "fr", "fra" }, { "spa", "spa" }, { "es", "spa" }, { "ara", "ara" }, { "ar", "ara" }, { "bg", "bul" }, { "bul", "bul" }, { "et", "est" }, { "est", "est" }, { "da", "dan" }, { "dan", "dan" }, { "fi", "fin" }, { "fin", "fin" }, { "ro", "rom" }, { "rom", "rom" }, { "sl", "slo" }, { "slo", "slo" }, { "vi", "vie" }, { "vie", "vie" }, { "sv", "swe" }, { "swe", "swe" }, { "th", "th" }, { "ru", "ru" }, { "pt", "pt" }, { "de", "de" }, { "it", "it" }, { "el", "el" }, { "nl", "nl" }, { "pl", "pl" }, { "cs", "cs" }, { "hu", "hu" } }; private static readonly string HttpServicePointTemplateUrl = "https://api.fanyi.baidu.com/api/trans/vip/translate?q={0}&from={1}&to={2}&appid={3}&salt={4}&sign={5}"; private static readonly MD5 HashMD5 = MD5.Create(); private string _appId; private string _appSecret; private float _delay; private float _lastRequestTimestamp; public override string Id => "BaiduTranslate"; public override string FriendlyName => "Baidu Translator"; private string FixLanguage(string lang) { if (SupportedLanguages.TryGetValue(lang, out var value)) { return value; } return lang; } public override void Initialize(IInitializationContext context) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) _appId = context.GetOrCreateSetting<string>("Baidu", "BaiduAppId", ""); _appSecret = context.GetOrCreateSetting<string>("Baidu", "BaiduAppSecret", ""); _delay = context.GetOrCreateSetting<float>("Baidu", "DelaySeconds", 1f); if (string.IsNullOrEmpty(_appId)) { throw new EndpointInitializationException("The BaiduTranslate endpoint requires an App Id which has not been provided."); } if (string.IsNullOrEmpty(_appSecret)) { throw new EndpointInitializationException("The BaiduTranslate endpoint requires an App Secret which has not been provided."); } context.DisableCertificateChecksFor(new string[1] { "api.fanyi.baidu.com" }); if (!SupportedLanguages.ContainsKey(context.SourceLanguage)) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.ContainsKey(context.DestinationLanguage)) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context) { float realtimeSinceStartup = TimeHelper.realtimeSinceStartup; float num = realtimeSinceStartup - _lastRequestTimestamp; if (num < _delay) { float num2 = _delay - num; object obj = CoroutineHelper.CreateWaitForSecondsRealtime(num2); if (obj != null) { yield return obj; } else { float end = realtimeSinceStartup + num2; while (realtimeSinceStartup < end) { yield return null; } } } _lastRequestTimestamp = TimeHelper.realtimeSinceStartup; } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown string text = DateTime.UtcNow.Millisecond.ToString(); string text2 = CreateMD5(_appId + ((ITranslationContextBase)context).UntranslatedText + text + _appSecret); XUnityWebRequest val = new XUnityWebRequest(string.Format(HttpServicePointTemplateUrl, Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText), FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), _appId, text, text2)); val.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent); val.Headers[HttpRequestHeader.AcceptCharset] = "UTF-8"; context.Complete(val); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) string data = ((IHttpResponseInspectionContext)context).Response.Data; if (data.StartsWith("{\"error")) { return; } JSONNode val = JSON.Parse(data); StringBuilder stringBuilder = new StringBuilder(data.Length); Enumerator enumerator = ((JSONNode)((JSONNode)val.AsObject)["trans_result"].AsArray).GetEnumerator(); while (((Enumerator)(ref enumerator)).MoveNext()) { string text = ((object)((JSONNode)JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsObject)["dst"]).ToString(); text = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder)) { stringBuilder.Append("\n"); } stringBuilder.Append(text); } string text2 = stringBuilder.ToString(); context.Complete(text2); } private static string CreateMD5(string input) { byte[] bytes = Encoding.UTF8.GetBytes(input); byte[] array = HashMD5.ComputeHash(bytes); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < array.Length; i++) { stringBuilder.Append(array[i].ToString("X2")); } return stringBuilder.ToString().ToLower(); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/BingTranslate.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core; using XUnity.AutoTranslator.Plugin.Core.Constants; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Shims; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; using XUnity.Common.Logging; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("BingTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BingTranslate")] [assembly: AssemblyTitle("BingTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace BingTranslate; public class BingTranslateEndpoint : HttpEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "auto-detect", "af", "ar", "bn", "bs", "bg", "yue", "ca", "zh-Hans", "zh-Hant", "hr", "cs", "da", "nl", "en", "et", "fj", "fil", "fi", "fr", "de", "el", "ht", "he", "hi", "mww", "hu", "is", "id", "it", "ja", "sw", "tlh", "tlh-Qaak", "ko", "lv", "lt", "mg", "ms", "mt", "nb", "fa", "pl", "pt", "otq", "ro", "ru", "sm", "sr-Cyrl", "sr-Latn", "sk", "sl", "es", "sv", "ty", "ta", "te", "th", "to", "tr", "uk", "ur", "vi", "cy", "yua" }; private static readonly string HttpsServicePointTemplateUrl = "https://www.bing.com/ttranslatev3?isVertical=1&&IG={0}&IID={1}.{2}"; private static readonly string HttpsServicePointTemplateUrlWithoutIG = "https://www.bing.com/ttranslatev3?isVertical=1"; private static readonly string HttpsTranslateUserSite = "https://www.bing.com/translator"; private static readonly string RequestTemplate = "&fromLang={1}&text={0}&to={2}"; private static readonly Random RandomNumbers = new Random(); private static readonly string[] Accepts = new string[1] { "*/*" }; private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" }; private static readonly string[] Referers = new string[1] { "https://bing.com/translator" }; private static readonly string[] Origins = new string[1] { "https://www.bing.com" }; private static readonly string[] AcceptCharsets = new string[2] { null, Encoding.UTF8.WebName }; private static readonly string[] ContentTypes = new string[1] { "application/x-www-form-urlencoded" }; private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)]; private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)]; private static readonly string Referer = Referers[RandomNumbers.Next(Referers.Length)]; private static readonly string Origin = Origins[RandomNumbers.Next(Origins.Length)]; private static readonly string AcceptCharset = AcceptCharsets[RandomNumbers.Next(AcceptCharsets.Length)]; private static readonly string ContentType = ContentTypes[RandomNumbers.Next(ContentTypes.Length)]; private CookieContainer _cookieContainer; private bool _hasSetup; private string _ig; private string _iid; private int _translationCount; private int _resetAfter = RandomNumbers.Next(75, 125); public override string Id => "BingTranslate"; public override string FriendlyName => "Bing Translator"; public BingTranslateEndpoint() { _cookieContainer = new CookieContainer(); } private string FixLanguage(string lang) { switch (lang) { case "zh-CN": case "zh": return "zh-Hans"; case "zh-TW": return "zh-Hant"; case "auto": return "auto-detect"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) context.DisableCertificateChecksFor(new string[1] { "www.bing.com" }); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context) { if (!_hasSetup || _translationCount % _resetAfter == 0) { _resetAfter = RandomNumbers.Next(75, 125); _translationCount = 0; _hasSetup = true; IEnumerator enumerator = SetupIGAndIID(); while (enumerator.MoveNext()) { yield return enumerator.Current; } } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown _translationCount++; string text = null; text = ((_ig != null && _iid != null) ? string.Format(HttpsServicePointTemplateUrl, _ig, _iid, _translationCount) : HttpsServicePointTemplateUrlWithoutIG); string text2 = string.Format(RequestTemplate, Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText), FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage)); XUnityWebRequest val = new XUnityWebRequest("POST", text, text2); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: true); context.Complete(val); } public override void OnInspectResponse(IHttpResponseInspectionContext context) { InspectResponse(context.Response); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { string text = ((object)((JSONNode)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsArray)[0]["translations"].AsArray)[0]["text"]).ToString(); string text2 = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); context.Complete(text2); } private XUnityWebRequest CreateWebSiteRequest() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown XUnityWebRequest val = new XUnityWebRequest(HttpsTranslateUserSite); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: false); return val; } private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest) { request.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent); if (AcceptLanguage != null) { request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage; } if (Accept != null) { request.Headers[HttpRequestHeader.Accept] = Accept; } if (Referer != null && isTranslationRequest) { request.Headers[HttpRequestHeader.Referer] = Referer; } if (Origin != null && isTranslationRequest) { request.Headers["Origin"] = Origin; } if (AcceptCharset != null) { request.Headers[HttpRequestHeader.AcceptCharset] = AcceptCharset; } if (ContentType != null && isTranslationRequest) { request.Headers[HttpRequestHeader.ContentType] = ContentType; } } private void InspectResponse(XUnityWebResponse response) { CookieCollection newCookies = response.NewCookies; _cookieContainer.Add(newCookies); } public IEnumerator SetupIGAndIID() { _cookieContainer = new CookieContainer(); XUnityWebResponse response; try { XUnityWebClient val = new XUnityWebClient(); XUnityWebRequest val2 = CreateWebSiteRequest(); response = val.Send(val2); } catch (Exception ex) { XuaLogger.AutoTranslator.Warn(ex, "An error occurred while setting up BingTranslate IG. Proceeding without..."); yield break; } IEnumerator iterator = ((CustomYieldInstructionShim)response).GetSupportedEnumerator(); while (iterator.MoveNext()) { yield return iterator.Current; } if (((CustomYieldInstructionShim)response).IsTimedOut) { XuaLogger.AutoTranslator.Warn("A timeout error occurred while setting up BingTranslate IG. Proceeding without..."); yield break; } if (response.Error != null) { XuaLogger.AutoTranslator.Warn(response.Error, "An error occurred while setting up BingTranslate IG. Proceeding without..."); yield break; } if (response.Data == null) { XuaLogger.AutoTranslator.Warn((Exception)null, "An error occurred while setting up BingTranslate IG. Proceeding without..."); yield break; } InspectResponse(response); try { string data = response.Data; _ig = Lookup("\",IG:\"", data); _iid = Lookup("data-iid=\"", data); if (_ig == null || _iid == null) { XuaLogger.AutoTranslator.Warn("An error occurred while setting up BingTranslate IG/IID. Proceeding without..."); } } catch (Exception ex2) { XuaLogger.AutoTranslator.Warn(ex2, "An error occurred while setting up BingTranslate IG. Proceeding without..."); } } private string Lookup(string lookFor, string html) { int num = html.IndexOf(lookFor); if (num > -1) { int num2 = num + lookFor.Length; int num3 = html.IndexOf("\"", num2); if (num2 > -1 && num3 > -1) { return html.Substring(num2, num3 - num2); } } return null; } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/BingTranslateLegitimate.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("BingTranslateLegitimate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BingTranslateLegitimate")] [assembly: AssemblyTitle("BingTranslateLegitimate")] [assembly: AssemblyVersion("1.0.0.0")] namespace BingTranslateLegitimate; public class BingTranslateLegitimateEndpoint : HttpEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "af", "ar", "bn", "bs", "bg", "yue", "ca", "zh-Hans", "zh-Hant", "hr", "cs", "da", "nl", "en", "et", "fj", "fil", "fi", "fr", "de", "el", "ht", "he", "hi", "mww", "hu", "is", "id", "it", "ja", "sw", "tlh", "tlh-Qaak", "ko", "lv", "lt", "mg", "ms", "mt", "nb", "fa", "pl", "pt", "otq", "ro", "ru", "sm", "sr-Cyrl", "sr-Latn", "sk", "sl", "es", "sv", "ty", "ta", "te", "th", "to", "tr", "uk", "ur", "vi", "cy", "yua" }; private static readonly string HttpsServicePointTemplateUrl = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from={0}&to={1}"; private static readonly Random RandomNumbers = new Random(); private static readonly string[] Accepts = new string[1] { "application/json" }; private static readonly string[] ContentTypes = new string[1] { "application/json" }; private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)]; private static readonly string ContentType = ContentTypes[RandomNumbers.Next(ContentTypes.Length)]; private string _key; public override string Id => "BingTranslateLegitimate"; public override string FriendlyName => "Bing Translator (Authenticated)"; public override int MaxTranslationsPerRequest => 10; private string FixLanguage(string lang) { switch (lang) { case "zh-CN": case "zh": return "zh-Hans"; case "zh-TW": return "zh-Hant"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) _key = context.GetOrCreateSetting<string>("BingLegitimate", "OcpApimSubscriptionKey", ""); if (string.IsNullOrEmpty(_key)) { throw new EndpointInitializationException("The BingTranslateLegitimate endpoint requires an API key which has not been provided."); } context.DisableCertificateChecksFor(new string[1] { "api.cognitive.microsofttranslator.com" }); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("["); for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++) { string value = JsonHelper.Escape(((ITranslationContextBase)context).UntranslatedTexts[i]); stringBuilder.Append("{\"Text\":\""); stringBuilder.Append(value); stringBuilder.Append("\"}"); if (((ITranslationContextBase)context).UntranslatedTexts.Length - 1 != i) { stringBuilder.Append(","); } } stringBuilder.Append("]"); XUnityWebRequest val = new XUnityWebRequest("POST", string.Format(HttpsServicePointTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage)), stringBuilder.ToString()); if (Accept != null) { val.Headers[HttpRequestHeader.Accept] = Accept; } if (ContentType != null) { val.Headers[HttpRequestHeader.ContentType] = ContentType; } val.Headers["Ocp-Apim-Subscription-Key"] = _key; context.Complete(val); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { JSONArray asArray = JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsArray; List<string> list = new List<string>(); for (int i = 0; i < ((JSONNode)asArray).Count; i++) { JSONNode obj = ((JSONNode)((JSONNode)asArray)[i].AsObject)["translations"]; object obj2; if (obj == null) { obj2 = null; } else { JSONNode obj3 = ((JSONNode)obj.AsArray)[0]; obj2 = ((obj3 != null) ? ((object)((JSONNode)obj3.AsObject)["text"])?.ToString() : null); } string text = (string)obj2; string item = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); list.Add(item); } context.Complete(list.ToArray()); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/CustomTranslate.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Web; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("CustomTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CustomTranslate")] [assembly: AssemblyTitle("CustomTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace CustomTranslate; internal class CustomTranslateEndpoint : HttpEndpoint { private static readonly string ServicePointTemplateUrl = "{0}?from={1}&to={2}&text={3}"; private string _endpoint; private string _friendlyName; public override string Id => "CustomTranslate"; public override string FriendlyName => _friendlyName; public CustomTranslateEndpoint() { _friendlyName = "Custom"; } public override void Initialize(IInitializationContext context) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) _endpoint = context.GetOrCreateSetting<string>("Custom", "Url", ""); if (string.IsNullOrEmpty(_endpoint)) { throw new EndpointInitializationException("The custom endpoint requires a url which has not been provided."); } Uri uri = new Uri(_endpoint); context.DisableCertificateChecksFor(new string[1] { uri.Host }); _friendlyName = _friendlyName + " (" + uri.Host + ")"; } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown XUnityWebRequest val = new XUnityWebRequest(string.Format(ServicePointTemplateUrl, _endpoint, ((ITranslationContextBase)context).SourceLanguage, ((ITranslationContextBase)context).DestinationLanguage, Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText))); context.Complete(val); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { context.Complete(((IHttpResponseInspectionContext)context).Response.Data); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/DeepLTranslate.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol; using XUnity.Common.Logging; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("DeepLTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DeepLTranslate")] [assembly: AssemblyTitle("DeepLTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace DeepLTranslate; public class DeepLTranslate : ExtProtocolEndpoint { private const float MinimumMinDelaySeconds = 1f; private const float MinimumMaxDelaySeconds = 3f; private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "bg", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "hu", "it", "ja", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "zh", "ko" }; public override string Id => "DeepLTranslate"; public override string FriendlyName => "DeepL Translator"; public override int MaxConcurrency => 1; public override int MaxTranslationsPerRequest => 25; protected override string ConfigurationSectionName => "DeepL"; private string FixLanguage(string lang) { if (lang == "zh-Hans" || lang == "zh-CN") { return "zh"; } return lang; } public override void Initialize(IInitializationContext context) { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) ((ExtProtocolEndpoint)this).Initialize(context); ((ExtProtocolEndpoint)this).MinDelay = context.GetOrCreateSetting<float>("DeepL", "MinDelaySeconds", 2f); if (((ExtProtocolEndpoint)this).MinDelay < 1f) { XuaLogger.AutoTranslator.Warn($"[DeepL] Cannot set MinDelaySeconds below {1f} second(s). Setting MinDelaySeconds={1f}"); context.SetSetting<float>("DeepL", "MinDelaySeconds", 1f); } ((ExtProtocolEndpoint)this).MaxDelay = context.GetOrCreateSetting<float>("DeepL", "MaxDelaySeconds", 6f); if (((ExtProtocolEndpoint)this).MaxDelay < 3f) { XuaLogger.AutoTranslator.Warn($"[DeepL] Cannot set MaxDelaySeconds below {3f} second(s). Setting MaxDelaySeconds={3f}"); context.SetSetting<float>("DeepL", "MaxDelaySeconds", 3f); } if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } ((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes("DeepLTranslate.ExtProtocol.ExtDeepLTranslate, DeepLTranslate.ExtProtocol"), Base64FormattingOptions.None); } } public class DeepLTranslateLegitimate : ExtProtocolEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "bg", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "hu", "it", "ja", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "zh", "ko" }; public override string Id => "DeepLTranslateLegitimate"; public override string FriendlyName => "DeepL Translator (Authenticated)"; public override int MaxConcurrency => 1; public override int MaxTranslationsPerRequest => 25; protected override string ConfigurationSectionName => "DeepLLegitimate"; private string FixLanguage(string lang) { if (lang == "zh-Hans" || lang == "zh-CN") { return "zh"; } return lang; } public override void Initialize(IInitializationContext context) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) ((ExtProtocolEndpoint)this).Initialize(context); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } string orCreateSetting = context.GetOrCreateSetting<string>(((ExtProtocolEndpoint)this).ConfigurationSectionName, "ApiKey", ""); bool orCreateSetting2 = context.GetOrCreateSetting<bool>(((ExtProtocolEndpoint)this).ConfigurationSectionName, "Free", false); if (string.IsNullOrEmpty(orCreateSetting)) { throw new EndpointInitializationException("The endpoint requires an API key which has not been provided."); } ((ExtProtocolEndpoint)this).ConfigForExternalProcess = string.Join("\n", orCreateSetting, orCreateSetting2.ToString()); ((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes("DeepLTranslate.ExtProtocol.ExtDeepLTranslateLegitimate, DeepLTranslate.ExtProtocol"), Base64FormattingOptions.None); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/ezTransXP.dll
Decompiled a year agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using Microsoft.Win32; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("ezTransXP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ezTransXP")] [assembly: AssemblyTitle("ezTransXP")] [assembly: AssemblyVersion("1.0.0.0")] namespace ezTransXP; public class ezTransXPEndpoint : ExtProtocolEndpoint { public override string Id => "ezTransXP"; public override string FriendlyName => "ezTransXP"; public override int MaxConcurrency => 1; public override int MaxTranslationsPerRequest => 50; public override void Initialize(IInitializationContext context) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) string defaultInstallationPath = GetDefaultInstallationPath(); string text = context.GetOrCreateSetting<string>("ezTrans", "InstallationPath", defaultInstallationPath); if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(defaultInstallationPath)) { context.SetSetting<string>("ezTrans", "InstallationPath", defaultInstallationPath); text = defaultInstallationPath; } context.DisableSpamChecks(); string text2 = Path.Combine(context.TranslatorDirectory, "FullNET\\ezTransXP.ExtProtocol.exe"); if (!File.Exists(text2)) { throw new EndpointInitializationException("Could not find any executable at '" + text2 + "'"); } ((ExtProtocolEndpoint)this).ExecutablePath = text2; ((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes(text)); if (context.SourceLanguage != "ja") { throw new EndpointInitializationException("Current implementation only supports japanese-to-korean."); } if (context.DestinationLanguage != "ko") { throw new EndpointInitializationException("Current implementation only supports japanese-to-korean."); } } public static string GetDefaultInstallationPath() { try { return (string)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\ChangShin\\ezTrans", "FilePath", null); } catch { return null; } } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/Common.ExtProtocol.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; using XUnity.AutoTranslator.Plugin.ExtProtocol; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyCompany("Common.ExtProtocol")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Common.ExtProtocol")] [assembly: AssemblyTitle("Common.ExtProtocol")] [assembly: AssemblyVersion("1.0.0.0")] namespace SimpleJSON { public enum JSONNodeType { Array = 1, Object = 2, String = 3, Number = 4, NullValue = 5, Boolean = 6, None = 7, Custom = 255 } public enum JSONTextMode { Compact, Indent } public abstract class JSONNode { public struct Enumerator { private enum Type { None, Array, Object } private Type type; private Dictionary<string, JSONNode>.Enumerator m_Object; private List<JSONNode>.Enumerator m_Array; public bool IsValid => type != Type.None; public KeyValuePair<string, JSONNode> Current { get { if (type == Type.Array) { return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current); } if (type == Type.Object) { return m_Object.Current; } return new KeyValuePair<string, JSONNode>(string.Empty, null); } } public Enumerator(List<JSONNode>.Enumerator aArrayEnum) { type = Type.Array; m_Object = default(Dictionary<string, JSONNode>.Enumerator); m_Array = aArrayEnum; } public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) { type = Type.Object; m_Object = aDictEnum; m_Array = default(List<JSONNode>.Enumerator); } public bool MoveNext() { if (type == Type.Array) { return m_Array.MoveNext(); } if (type == Type.Object) { return m_Object.MoveNext(); } return false; } } public struct ValueEnumerator { private Enumerator m_Enumerator; public JSONNode Current => m_Enumerator.Current.Value; public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public ValueEnumerator GetEnumerator() { return this; } } public struct KeyEnumerator { private Enumerator m_Enumerator; public JSONNode Current => m_Enumerator.Current.Key; public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public KeyEnumerator GetEnumerator() { return this; } } public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable { private JSONNode m_Node; private Enumerator m_Enumerator; public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current; object IEnumerator.Current => m_Enumerator.Current; internal LinqEnumerator(JSONNode aNode) { m_Node = aNode; if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } public bool MoveNext() { return m_Enumerator.MoveNext(); } public void Dispose() { m_Node = null; m_Enumerator = default(Enumerator); } public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator() { return new LinqEnumerator(m_Node); } public void Reset() { if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } IEnumerator IEnumerable.GetEnumerator() { return new LinqEnumerator(m_Node); } } public static bool forceASCII; [ThreadStatic] private static StringBuilder m_EscapeBuilder; public abstract JSONNodeType Tag { get; } public virtual JSONNode this[int aIndex] { get { return null; } set { } } public virtual JSONNode this[string aKey] { get { return null; } set { } } public virtual string Value { get { return ""; } set { } } public virtual int Count => 0; public virtual bool IsNumber => false; public virtual bool IsString => false; public virtual bool IsBoolean => false; public virtual bool IsNull => false; public virtual bool IsArray => false; public virtual bool IsObject => false; public virtual bool Inline { get { return false; } set { } } public virtual IEnumerable<JSONNode> Children { get { yield break; } } public IEnumerable<JSONNode> DeepChildren { get { foreach (JSONNode child in Children) { foreach (JSONNode deepChild in child.DeepChildren) { yield return deepChild; } } } } public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this); public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator()); public ValueEnumerator Values => new ValueEnumerator(GetEnumerator()); public virtual double AsDouble { get { double result = 0.0; if (double.TryParse(Value, out result)) { return result; } return 0.0; } set { Value = value.ToString(); } } public virtual int AsInt { get { return (int)AsDouble; } set { AsDouble = value; } } public virtual float AsFloat { get { return (float)AsDouble; } set { AsDouble = value; } } public virtual bool AsBool { get { bool result = false; if (bool.TryParse(Value, out result)) { return result; } return !string.IsNullOrEmpty(Value); } set { Value = (value ? "true" : "false"); } } public virtual JSONArray AsArray => this as JSONArray; public virtual JSONObject AsObject => this as JSONObject; internal static StringBuilder EscapeBuilder { get { if (m_EscapeBuilder == null) { m_EscapeBuilder = new StringBuilder(); } return m_EscapeBuilder; } } public virtual void Add(string aKey, JSONNode aItem) { } public virtual void Add(JSONNode aItem) { Add("", aItem); } public virtual JSONNode Remove(string aKey) { return null; } public virtual JSONNode Remove(int aIndex) { return null; } public virtual JSONNode Remove(JSONNode aNode) { return aNode; } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact); return stringBuilder.ToString(); } public virtual string ToString(int aIndent) { StringBuilder stringBuilder = new StringBuilder(); WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent); return stringBuilder.ToString(); } internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode); public abstract Enumerator GetEnumerator(); public static implicit operator JSONNode(string s) { return new JSONString(s); } public static implicit operator string(JSONNode d) { if (!(d == null)) { return d.Value; } return null; } public static implicit operator JSONNode(double n) { return new JSONNumber(n); } public static implicit operator double(JSONNode d) { if (!(d == null)) { return d.AsDouble; } return 0.0; } public static implicit operator JSONNode(float n) { return new JSONNumber(n); } public static implicit operator float(JSONNode d) { if (!(d == null)) { return d.AsFloat; } return 0f; } public static implicit operator JSONNode(int n) { return new JSONNumber(n); } public static implicit operator int(JSONNode d) { if (!(d == null)) { return d.AsInt; } return 0; } public static implicit operator JSONNode(bool b) { return new JSONBool(b); } public static implicit operator bool(JSONNode d) { if (!(d == null)) { return d.AsBool; } return false; } public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue) { return aKeyValue.Value; } public static bool operator ==(JSONNode a, object b) { if ((object)a == b) { return true; } bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator; bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator; if (flag && flag2) { return true; } if (!flag) { return a.Equals(b); } return false; } public static bool operator !=(JSONNode a, object b) { return !(a == b); } public override bool Equals(object obj) { return (object)this == obj; } public override int GetHashCode() { return base.GetHashCode(); } internal static string Escape(string aText) { StringBuilder escapeBuilder = EscapeBuilder; escapeBuilder.Length = 0; if (escapeBuilder.Capacity < aText.Length + aText.Length / 10) { escapeBuilder.Capacity = aText.Length + aText.Length / 10; } foreach (char c in aText) { switch (c) { case '\\': escapeBuilder.Append("\\\\"); continue; case '"': escapeBuilder.Append("\\\""); continue; case '\n': escapeBuilder.Append("\\n"); continue; case '\r': escapeBuilder.Append("\\r"); continue; case '\t': escapeBuilder.Append("\\t"); continue; case '\b': escapeBuilder.Append("\\b"); continue; case '\f': escapeBuilder.Append("\\f"); continue; } if (c < ' ' || (forceASCII && c > '\u007f')) { ushort num = c; escapeBuilder.Append("\\u").Append(num.ToString("X4")); } else { escapeBuilder.Append(c); } } string result = escapeBuilder.ToString(); escapeBuilder.Length = 0; return result; } private static void ParseElement(JSONNode ctx, string token, string tokenName, bool quoted) { if (quoted) { ctx.Add(tokenName, token); return; } string text = token.ToLower(); switch (text) { case "false": case "true": ctx.Add(tokenName, text == "true"); return; case "null": ctx.Add(tokenName, null); return; } if (double.TryParse(token, out var result)) { ctx.Add(tokenName, result); } else { ctx.Add(tokenName, token); } } public static JSONNode Parse(string aJSON) { Stack<JSONNode> stack = new Stack<JSONNode>(); JSONNode jSONNode = null; int i = 0; StringBuilder stringBuilder = new StringBuilder(); string text = ""; bool flag = false; bool flag2 = false; for (; i < aJSON.Length; i++) { switch (aJSON[i]) { case '{': if (flag) { stringBuilder.Append(aJSON[i]); break; } stack.Push(new JSONObject()); if (jSONNode != null) { jSONNode.Add(text, stack.Peek()); } text = ""; stringBuilder.Length = 0; jSONNode = stack.Peek(); break; case '[': if (flag) { stringBuilder.Append(aJSON[i]); break; } stack.Push(new JSONArray()); if (jSONNode != null) { jSONNode.Add(text, stack.Peek()); } text = ""; stringBuilder.Length = 0; jSONNode = stack.Peek(); break; case ']': case '}': if (flag) { stringBuilder.Append(aJSON[i]); break; } if (stack.Count == 0) { throw new Exception("JSON Parse: Too many closing brackets"); } stack.Pop(); if (stringBuilder.Length > 0 || flag2) { ParseElement(jSONNode, stringBuilder.ToString(), text, flag2); flag2 = false; } text = ""; stringBuilder.Length = 0; if (stack.Count > 0) { jSONNode = stack.Peek(); } break; case ':': if (flag) { stringBuilder.Append(aJSON[i]); break; } text = stringBuilder.ToString(); stringBuilder.Length = 0; flag2 = false; break; case '"': flag = !flag; flag2 = flag2 || flag; break; case ',': if (flag) { stringBuilder.Append(aJSON[i]); break; } if (stringBuilder.Length > 0 || flag2) { ParseElement(jSONNode, stringBuilder.ToString(), text, flag2); flag2 = false; } text = ""; stringBuilder.Length = 0; flag2 = false; break; case '\t': case ' ': if (flag) { stringBuilder.Append(aJSON[i]); } break; case '\\': i++; if (flag) { char c = aJSON[i]; switch (c) { case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'n': stringBuilder.Append('\n'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': { string s = aJSON.Substring(i + 1, 4); stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier)); i += 4; break; } default: stringBuilder.Append(c); break; } } break; default: stringBuilder.Append(aJSON[i]); break; case '\n': case '\r': break; } } if (flag) { throw new Exception("JSON Parse: Quotation marks seems to be messed up."); } return jSONNode; } } public class JSONArray : JSONNode { private List<JSONNode> m_List = new List<JSONNode>(); private bool inline; public override bool Inline { get { return inline; } set { inline = value; } } public override JSONNodeType Tag => JSONNodeType.Array; public override bool IsArray => true; public override JSONNode this[int aIndex] { get { if (aIndex < 0 || aIndex >= m_List.Count) { return new JSONLazyCreator(this); } return m_List[aIndex]; } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (aIndex < 0 || aIndex >= m_List.Count) { m_List.Add(value); } else { m_List[aIndex] = value; } } } public override JSONNode this[string aKey] { get { return new JSONLazyCreator(this); } set { if (value == null) { value = JSONNull.CreateOrGet(); } m_List.Add(value); } } public override int Count => m_List.Count; public override IEnumerable<JSONNode> Children { get { foreach (JSONNode item in m_List) { yield return item; } } } public override Enumerator GetEnumerator() { return new Enumerator(m_List.GetEnumerator()); } public override void Add(string aKey, JSONNode aItem) { if (aItem == null) { aItem = JSONNull.CreateOrGet(); } m_List.Add(aItem); } public override JSONNode Remove(int aIndex) { if (aIndex < 0 || aIndex >= m_List.Count) { return null; } JSONNode result = m_List[aIndex]; m_List.RemoveAt(aIndex); return result; } public override JSONNode Remove(JSONNode aNode) { m_List.Remove(aNode); return aNode; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('['); int count = m_List.Count; if (inline) { aMode = JSONTextMode.Compact; } for (int i = 0; i < count; i++) { if (i > 0) { aSB.Append(','); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine(); } if (aMode == JSONTextMode.Indent) { aSB.Append(' ', aIndent + aIndentInc); } m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine().Append(' ', aIndent); } aSB.Append(']'); } } public class JSONObject : JSONNode { private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>(); private bool inline; public override bool Inline { get { return inline; } set { inline = value; } } public override JSONNodeType Tag => JSONNodeType.Object; public override bool IsObject => true; public override JSONNode this[string aKey] { get { if (m_Dict.ContainsKey(aKey)) { return m_Dict[aKey]; } return new JSONLazyCreator(this, aKey); } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (m_Dict.ContainsKey(aKey)) { m_Dict[aKey] = value; } else { m_Dict.Add(aKey, value); } } } public override JSONNode this[int aIndex] { get { if (aIndex < 0 || aIndex >= m_Dict.Count) { return null; } return m_Dict.ElementAt(aIndex).Value; } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (aIndex >= 0 && aIndex < m_Dict.Count) { string key = m_Dict.ElementAt(aIndex).Key; m_Dict[key] = value; } } } public override int Count => m_Dict.Count; public override IEnumerable<JSONNode> Children { get { foreach (KeyValuePair<string, JSONNode> item in m_Dict) { yield return item.Value; } } } public override Enumerator GetEnumerator() { return new Enumerator(m_Dict.GetEnumerator()); } public override void Add(string aKey, JSONNode aItem) { if (aItem == null) { aItem = JSONNull.CreateOrGet(); } if (!string.IsNullOrEmpty(aKey)) { if (m_Dict.ContainsKey(aKey)) { m_Dict[aKey] = aItem; } else { m_Dict.Add(aKey, aItem); } } else { m_Dict.Add(Guid.NewGuid().ToString(), aItem); } } public override JSONNode Remove(string aKey) { if (!m_Dict.ContainsKey(aKey)) { return null; } JSONNode result = m_Dict[aKey]; m_Dict.Remove(aKey); return result; } public override JSONNode Remove(int aIndex) { if (aIndex < 0 || aIndex >= m_Dict.Count) { return null; } KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex); m_Dict.Remove(keyValuePair.Key); return keyValuePair.Value; } public override JSONNode Remove(JSONNode aNode) { try { KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First(); m_Dict.Remove(keyValuePair.Key); return aNode; } catch { return null; } } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('{'); bool flag = true; if (inline) { aMode = JSONTextMode.Compact; } foreach (KeyValuePair<string, JSONNode> item in m_Dict) { if (!flag) { aSB.Append(','); } flag = false; if (aMode == JSONTextMode.Indent) { aSB.AppendLine(); } if (aMode == JSONTextMode.Indent) { aSB.Append(' ', aIndent + aIndentInc); } aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"'); if (aMode == JSONTextMode.Compact) { aSB.Append(':'); } else { aSB.Append(" : "); } item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine().Append(' ', aIndent); } aSB.Append('}'); } } public class JSONString : JSONNode { private string m_Data; public override JSONNodeType Tag => JSONNodeType.String; public override bool IsString => true; public override string Value { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONString(string aData) { m_Data = aData; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"'); } public override bool Equals(object obj) { if (base.Equals(obj)) { return true; } if (obj is string text) { return m_Data == text; } JSONString jSONString = obj as JSONString; if (jSONString != null) { return m_Data == jSONString.m_Data; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } } public class JSONNumber : JSONNode { private double m_Data; public override JSONNodeType Tag => JSONNodeType.Number; public override bool IsNumber => true; public override string Value { get { return m_Data.ToString(); } set { if (double.TryParse(value, out var result)) { m_Data = result; } } } public override double AsDouble { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONNumber(double aData) { m_Data = aData; } public JSONNumber(string aData) { Value = aData; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append(m_Data); } private static bool IsNumeric(object value) { if (!(value is int) && !(value is uint) && !(value is float) && !(value is double) && !(value is decimal) && !(value is long) && !(value is ulong) && !(value is short) && !(value is ushort) && !(value is sbyte)) { return value is byte; } return true; } public override bool Equals(object obj) { if (obj == null) { return false; } if (base.Equals(obj)) { return true; } JSONNumber jSONNumber = obj as JSONNumber; if (jSONNumber != null) { return m_Data == jSONNumber.m_Data; } if (IsNumeric(obj)) { return Convert.ToDouble(obj) == m_Data; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } } public class JSONBool : JSONNode { private bool m_Data; public override JSONNodeType Tag => JSONNodeType.Boolean; public override bool IsBoolean => true; public override string Value { get { return m_Data.ToString(); } set { if (bool.TryParse(value, out var result)) { m_Data = result; } } } public override bool AsBool { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONBool(bool aData) { m_Data = aData; } public JSONBool(string aData) { Value = aData; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append(m_Data ? "true" : "false"); } public override bool Equals(object obj) { if (obj == null) { return false; } if (obj is bool) { return m_Data == (bool)obj; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } } public class JSONNull : JSONNode { private static JSONNull m_StaticInstance = new JSONNull(); public static bool reuseSameInstance = true; public override JSONNodeType Tag => JSONNodeType.NullValue; public override bool IsNull => true; public override string Value { get { return "null"; } set { } } public override bool AsBool { get { return false; } set { } } public static JSONNull CreateOrGet() { if (reuseSameInstance) { return m_StaticInstance; } return new JSONNull(); } private JSONNull() { } public override Enumerator GetEnumerator() { return default(Enumerator); } public override bool Equals(object obj) { if ((object)this == obj) { return true; } return obj is JSONNull; } public override int GetHashCode() { return 0; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append("null"); } } internal class JSONLazyCreator : JSONNode { private JSONNode m_Node; private string m_Key; public override JSONNodeType Tag => JSONNodeType.None; public override JSONNode this[int aIndex] { get { return new JSONLazyCreator(this); } set { JSONArray jSONArray = new JSONArray(); jSONArray.Add(value); Set(jSONArray); } } public override JSONNode this[string aKey] { get { return new JSONLazyCreator(this, aKey); } set { JSONObject jSONObject = new JSONObject(); jSONObject.Add(aKey, value); Set(jSONObject); } } public override int AsInt { get { JSONNumber aVal = new JSONNumber(0.0); Set(aVal); return 0; } set { JSONNumber aVal = new JSONNumber(value); Set(aVal); } } public override float AsFloat { get { JSONNumber aVal = new JSONNumber(0.0); Set(aVal); return 0f; } set { JSONNumber aVal = new JSONNumber(value); Set(aVal); } } public override double AsDouble { get { JSONNumber aVal = new JSONNumber(0.0); Set(aVal); return 0.0; } set { JSONNumber aVal = new JSONNumber(value); Set(aVal); } } public override bool AsBool { get { JSONBool aVal = new JSONBool(aData: false); Set(aVal); return false; } set { JSONBool aVal = new JSONBool(value); Set(aVal); } } public override JSONArray AsArray { get { JSONArray jSONArray = new JSONArray(); Set(jSONArray); return jSONArray; } } public override JSONObject AsObject { get { JSONObject jSONObject = new JSONObject(); Set(jSONObject); return jSONObject; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONLazyCreator(JSONNode aNode) { m_Node = aNode; m_Key = null; } public JSONLazyCreator(JSONNode aNode, string aKey) { m_Node = aNode; m_Key = aKey; } private void Set(JSONNode aVal) { if (m_Key == null) { m_Node.Add(aVal); } else { m_Node.Add(m_Key, aVal); } m_Node = null; } public override void Add(JSONNode aItem) { JSONArray jSONArray = new JSONArray(); jSONArray.Add(aItem); Set(jSONArray); } public override void Add(string aKey, JSONNode aItem) { JSONObject jSONObject = new JSONObject(); jSONObject.Add(aKey, aItem); Set(jSONObject); } public static bool operator ==(JSONLazyCreator a, object b) { if (b == null) { return true; } return (object)a == b; } public static bool operator !=(JSONLazyCreator a, object b) { return !(a == b); } public override bool Equals(object obj) { if (obj == null) { return true; } return (object)this == obj; } public override int GetHashCode() { return 0; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append("null"); } } public static class JSON { public static JSONNode Parse(string aJSON) { return JSONNode.Parse(aJSON); } } } namespace Common.ExtProtocol { public interface IExtTranslateEndpoint { Task Translate(ITranslationContext context); void Initialize(string config); } public interface ITranslationContext : ITranslationContextBase { void Complete(string translatedText); void Complete(string[] translatedTexts); } public interface ITranslationContextBase { string UntranslatedText { get; } string[] UntranslatedTexts { get; } UntranslatedTextInfo UntranslatedTextInfo { get; } UntranslatedTextInfo[] UntranslatedTextInfos { get; } string SourceLanguage { get; } string DestinationLanguage { get; } object UserState { get; set; } void Fail(string reason, Exception exception); void Fail(string reason); } public class TranslationContext : ITranslationContext, ITranslationContextBase { private string[] _untranslatedTexts; public string UntranslatedText => UntranslatedTexts[0]; public string[] UntranslatedTexts => _untranslatedTexts ?? (_untranslatedTexts = UntranslatedTextInfos.Select((UntranslatedTextInfo x) => x.UntranslatedText).ToArray()); public UntranslatedTextInfo UntranslatedTextInfo => UntranslatedTextInfos[0]; public UntranslatedTextInfo[] UntranslatedTextInfos { get; } public string SourceLanguage { get; } public string DestinationLanguage { get; } internal bool IsDone { get; private set; } public string[] TranslatedTexts { get; private set; } public string ErrorMessage { get; private set; } public Exception Error { get; private set; } public object UserState { get; set; } public TranslationContext(TransmittableUntranslatedTextInfo[] untranslatedTexts, string sourceLanguage, string destinationLanguage) { UntranslatedTextInfos = untranslatedTexts.Select((TransmittableUntranslatedTextInfo x) => new UntranslatedTextInfo(x)).ToArray(); SourceLanguage = sourceLanguage; DestinationLanguage = destinationLanguage; } public void Complete(string translatedText) { Complete(new string[1] { translatedText }); } public void Complete(string[] translatedTexts) { if (IsDone) { return; } try { if (translatedTexts.Length == 0) { FailContext("Received empty translation from translator.", null); return; } for (int i = 0; i < translatedTexts.Length; i++) { if (string.IsNullOrEmpty(translatedTexts[0])) { FailContext("Received empty translation from translator.", null); return; } } CompleteContext(translatedTexts); } finally { IsDone = true; } } public void Fail(string reason, Exception exception) { if (IsDone) { return; } try { FailContext(reason, exception); throw new TranslationContextException(); } finally { IsDone = true; } } public void Fail(string reason) { if (IsDone) { return; } try { FailContext(reason, null); throw new TranslationContextException(); } finally { IsDone = true; } } public void FailWithoutThrowing(string reason, Exception exception) { if (IsDone) { return; } try { FailContext(reason, exception); } finally { IsDone = true; } } internal void FailIfNotCompleted() { if (!IsDone) { FailWithoutThrowing("The translation request was not completed before returning from translator.", null); } } public void FailContext(string reason, Exception exception) { ErrorMessage = reason; Error = exception; } public void CompleteContext(string[] translatedTexts) { TranslatedTexts = translatedTexts; } } [Serializable] internal class TranslationContextException : Exception { public TranslationContextException() { } public TranslationContextException(string message) : base(message) { } public TranslationContextException(string message, Exception inner) : base(message, inner) { } protected TranslationContextException(SerializationInfo info, StreamingContext context) : base(info, context) { } } public class UntranslatedTextInfo { public string[] ContextBefore { get; } public string UntranslatedText { get; } public string[] ContextAfter { get; } public UntranslatedTextInfo(TransmittableUntranslatedTextInfo untranslatedTextInfo) { ContextBefore = untranslatedTextInfo.ContextBefore; UntranslatedText = untranslatedTextInfo.UntranslatedText; ContextAfter = untranslatedTextInfo.ContextAfter; } public UntranslatedTextInfo(string[] contextBefore, string untranslatedText, string[] contextAfter) { ContextBefore = contextBefore; UntranslatedText = untranslatedText; ContextAfter = contextAfter; } } } namespace Common.ExtProtocol.Utilities { public static class JsonHelper { public static string Unescape(string str) { if (str == null) { return null; } StringBuilder stringBuilder = new StringBuilder(str); bool flag = false; for (int i = 0; i < stringBuilder.Length; i++) { char c = stringBuilder[i]; if (flag) { bool flag2 = true; char c2 = '\0'; switch (c) { case 'b': c2 = '\b'; break; case 'f': c2 = '\f'; break; case 'n': c2 = '\n'; break; case 'r': c2 = '\r'; break; case 't': c2 = '\t'; break; case '"': c2 = '"'; break; case '\\': c2 = '\\'; break; case 'u': c2 = 'u'; break; default: flag2 = false; break; } if (flag2) { if (c2 == 'u') { char value = (char)int.Parse(new string(new char[4] { stringBuilder[i + 1], stringBuilder[i + 2], stringBuilder[i + 3], stringBuilder[i + 4] }), NumberStyles.HexNumber); stringBuilder.Remove(--i, 6); stringBuilder.Insert(i, value); } else { stringBuilder.Remove(--i, 2); stringBuilder.Insert(i, c2); } } flag = false; } else if (c == '\\') { flag = true; } } return stringBuilder.ToString(); } public static string Escape(string str) { if (str == null || str.Length == 0) { return ""; } int length = str.Length; StringBuilder stringBuilder = new StringBuilder(length + 4); for (int i = 0; i < length; i++) { char c = str[i]; switch (c) { case '"': case '\\': stringBuilder.Append('\\'); stringBuilder.Append(c); break; case '\b': stringBuilder.Append("\\b"); break; case '\t': stringBuilder.Append("\\t"); break; case '\n': stringBuilder.Append("\\n"); break; case '\f': stringBuilder.Append("\\f"); break; case '\r': stringBuilder.Append("\\r"); break; case '\u0085': stringBuilder.Append("\\u0085"); break; case '\u2028': stringBuilder.Append("\\u2028"); break; case '\u2029': stringBuilder.Append("\\u2029"); break; default: stringBuilder.Append(c); break; } } return stringBuilder.ToString(); } } public static class StringBuilderExtensions { public static bool EndsWithWhitespaceOrNewline(this StringBuilder builder) { if (builder.Length == 0) { return true; } char c = builder[builder.Length - 1]; if (!char.IsWhiteSpace(c)) { return c == '\n'; } return true; } } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/DeepLTranslate.ExtProtocol.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Common.ExtProtocol; using Common.ExtProtocol.Utilities; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using SimpleJSON; [assembly: AssemblyProduct("DeepLTranslate.ExtProtocol")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCompany("DeepLTranslate.ExtProtocol")] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyTitle("DeepLTranslate.ExtProtocol")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DeepLTranslate.ExtProtocol { [Serializable] public class BlockedException : Exception { public BlockedException() { } public BlockedException(string message) : base(message) { } public BlockedException(string message, Exception inner) : base(message, inner) { } protected BlockedException(SerializationInfo info, StreamingContext context) : base(info, context) { } } public static class HttpResponseMessageExtensions { public static void ThrowIfBlocked(this HttpResponseMessage msg) { if (msg.StatusCode == HttpStatusCode.TooManyRequests) { throw new Exception("Too many requests!"); } } } public class ExtDeepLTranslate : IExtTranslateEndpoint { private class UntranslatedTextInfo { public string UntranslatedText { get; set; } public List<TranslationPart> TranslationParts { get; set; } } public class TranslationPart { public bool IsTranslatable { get; set; } public string Value { get; set; } } private static readonly Regex NewlineSplitter; private static readonly DateTime Epoch; private static readonly string HttpsServicePointTemplateUrl; private static readonly string HttpsTranslateUserSite; private static readonly string HttpsTranslateStateSetup; private static readonly Random RandomNumbers; private static readonly string[] Accepts; private static readonly string[] AcceptLanguages; private static readonly string[] Referers; private static readonly string[] Origins; private static readonly string Accept; private static readonly string AcceptLanguage; private static readonly string Referer; private static readonly string Origin; private SemaphoreSlim _sem; private HttpClient _client; private HttpClientHandler _handler; private bool _hasSetup; private int _translationCount; private int _resetAfter = RandomNumbers.Next(75, 125); private long _id; static ExtDeepLTranslate() { NewlineSplitter = new Regex("([\\s]*[\\r\\n]+[\\s]*)"); Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); HttpsServicePointTemplateUrl = "https://www2.deepl.com/jsonrpc"; HttpsTranslateUserSite = "https://www.deepl.com/translator"; HttpsTranslateStateSetup = "https://www.deepl.com/PHP/backend/clientState.php?request_type=jsonrpc&il=EN"; RandomNumbers = new Random(); Accepts = new string[1] { "*/*" }; AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" }; Referers = new string[1] { "https://www.deepl.com/translator" }; Origins = new string[1] { "https://www.deepl.com" }; Accept = Accepts[RandomNumbers.Next(Accepts.Length)]; AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)]; Referer = Referers[RandomNumbers.Next(Referers.Length)]; Origin = Origins[RandomNumbers.Next(Origins.Length)]; ServicePointManager.SecurityProtocol |= SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; } public ExtDeepLTranslate() { _sem = new SemaphoreSlim(1, 1); } public void Initialize(string config) { } public void Reset() { _hasSetup = false; } private void CreateClientAndHandler() { if (_client != null) { _client.Dispose(); } _handler = new HttpClientHandler(); _handler.CookieContainer = new CookieContainer(); _handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; _client = new HttpClient(_handler, disposeHandler: true); _client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"); } private static string FixLanguage(string lang) { if (lang == "zh-Hans" || lang == "zh-CN") { return "zh"; } return lang; } public async Task EnsureSetupState() { if (!_hasSetup || _translationCount % _resetAfter == 0) { _resetAfter = RandomNumbers.Next(75, 125); _hasSetup = true; _id = 10000 * (long)(10000.0 * RandomNumbers.NextDouble()); CreateClientAndHandler(); await SetupState(); } } public async Task SetupState() { _translationCount = 0; await RequestWebsite(); await GetClientState(); } private void AddHeaders(HttpRequestMessage request, HttpContent content, bool isTranslationRequest) { if (AcceptLanguage != null) { request.Headers.TryAddWithoutValidation("Accept-Language", AcceptLanguage); } if (Accept != null) { request.Headers.TryAddWithoutValidation("Accept", Accept); } if (Referer != null && isTranslationRequest) { request.Headers.TryAddWithoutValidation("Referer", Referer); } if (Origin != null && isTranslationRequest) { request.Headers.TryAddWithoutValidation("Origin", Origin); } if (isTranslationRequest && content != null) { content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } request.Headers.TryAddWithoutValidation("DNT", "1"); } public async Task Translate(ITranslationContext context) { _ = 3; try { await _sem.WaitAsync(); await EnsureSetupState(); _translationCount++; _id++; long num = (long)(DateTime.UtcNow - Epoch).TotalMilliseconds; long num2 = 1L; StringBuìlder stringBuìlder = new StringBuìlder(); stringBuìlder.Append("{\"jsonrpc\":\"2.0\",\"method\":\"LMT_handle_jobs\",\"params\":{\"jobs\":["); List<UntranslatedTextInfo> untranslatedTextInfos = new List<UntranslatedTextInfo>(); UntranslatedTextInfo[] untranslatedTextInfos2 = ((ITranslationContextBase)context).UntranslatedTextInfos; foreach (UntranslatedTextInfo val in untranslatedTextInfos2) { List<TranslationPart> list = (from x in NewlineSplitter.Split(val.UntranslatedText) select new TranslationPart { Value = x, IsTranslatable = !NewlineSplitter.IsMatch(x) }).ToList(); string[] array = (from x in list where x.IsTranslatable select x.Value).ToArray(); for (int j = 0; j < array.Length; j++) { string text = array[j]; stringBuìlder.Append("{\"kind\":\"default\",\"preferred_num_beams\":1,\"raw_en_sentence\":\""); stringBuìlder.Append(JsonHelper.Escape(text)); HashSet<string> hashSet = new HashSet<string>(); stringBuìlder.Append("\",\"raw_en_context_before\":["); bool flag = false; string[] contextBefore = val.ContextBefore; foreach (string text2 in contextBefore) { if (!hashSet.Contains(text2)) { stringBuìlder.Append("\""); stringBuìlder.Append(JsonHelper.Escape(text2)); stringBuìlder.Append("\""); stringBuìlder.Append(","); flag = true; } } for (int l = 0; l < j; l++) { if (!hashSet.Contains(array[l])) { stringBuìlder.Append("\""); stringBuìlder.Append(JsonHelper.Escape(array[l])); stringBuìlder.Append("\""); stringBuìlder.Append(","); flag = true; } } if (flag) { stringBuìlder.Remove(stringBuìlder.Length - 1, 1); } stringBuìlder.Append("],\"raw_en_context_after\":["); bool flag2 = false; for (int m = j + 1; m < array.Length; m++) { if (!hashSet.Contains(array[m])) { stringBuìlder.Append("\""); stringBuìlder.Append(JsonHelper.Escape(array[m])); stringBuìlder.Append("\""); stringBuìlder.Append(","); flag2 = true; } } contextBefore = val.ContextAfter; foreach (string text3 in contextBefore) { if (!hashSet.Contains(text3)) { stringBuìlder.Append("\""); stringBuìlder.Append(JsonHelper.Escape(text3)); stringBuìlder.Append("\""); stringBuìlder.Append(","); flag2 = true; } } if (flag2) { stringBuìlder.Remove(stringBuìlder.Length - 1, 1); } stringBuìlder.Append("]},"); num2 += text.Count((char c) => c == 'i'); } untranslatedTextInfos.Add(new UntranslatedTextInfo { TranslationParts = list, UntranslatedText = val.UntranslatedText }); } stringBuìlder.Remove(stringBuìlder.Length - 1, 1); long num3 = num + (num2 - num % num2); stringBuìlder.Append("],\"lang\":{\"user_preferred_langs\":[\""); stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage).ToUpperInvariant()); stringBuìlder.Append("\",\""); stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage).ToUpperInvariant()); stringBuìlder.Append("\"],\"source_lang_user_selected\":\""); stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage).ToUpperInvariant()); stringBuìlder.Append("\",\"target_lang\":\""); stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage).ToUpperInvariant()); stringBuìlder.Append("\"},\"priority\":-1,\"timestamp\":"); stringBuìlder.Append(num3.ToString(CultureInfo.InvariantCulture)); stringBuìlder.Append("},\"id\":"); stringBuìlder.Append(_id); stringBuìlder.Append("}"); StringContent content = new StringContent(stringBuìlder.ToString()); using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, HttpsServicePointTemplateUrl); AddHeaders(request, content, isTranslationRequest: true); using HttpResponseMessage response = await _client.PostAsync(HttpsServicePointTemplateUrl, content); response.ThrowIfBlocked(); response.EnsureSuccessStatusCode(); ExtractTranslation(await response.Content.ReadAsStringAsync(), untranslatedTextInfos, context); } catch (BlockedException) { Reset(); throw; } finally { _sem.Release(); } } private void ExtractTranslation(string data, List<UntranslatedTextInfo> untranslatedTextInfos, ITranslationContext context) { JSONArray asArray = JSON.Parse(data)["result"]["translations"].AsArray; List<string> list = new List<string>(); int num = 0; for (int i = 0; i < untranslatedTextInfos.Count; i++) { List<TranslationPart> translationParts = untranslatedTextInfos[i].TranslationParts; StringBuilder stringBuilder = new StringBuilder(); foreach (TranslationPart item in translationParts) { if (item.IsTranslatable) { JSONArray asArray2 = ((JSONNode)asArray)[num++]["beams"].AsArray; if (((JSONNode)asArray2).Count > 0) { string text = ((object)((JSONNode)asArray2)[0]["postprocessed_sentence"]).ToString(); string value = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); stringBuilder.Append(value); } } else { stringBuilder.Append(item.Value); } } string text2 = stringBuilder.ToString(); if (string.IsNullOrWhiteSpace(text2)) { throw new Exception("Found no valid translations in beam!"); } list.Add(text2); } context.Complete(list.ToArray()); } public async Task RequestWebsite() { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, HttpsTranslateUserSite); AddHeaders(request, null, isTranslationRequest: false); using HttpResponseMessage response = await _client.SendAsync(request); response.ThrowIfBlocked(); response.EnsureSuccessStatusCode(); await response.Content.ReadAsStringAsync(); } public async Task GetClientState() { _id++; StringBuìlder stringBuìlder = new StringBuìlder(); stringBuìlder.Append("{\"jsonrpc\":\"2.0\",\"method\":\"getClientState\",\"params\":{\"v\":\"20180814\"},\"id\":"); stringBuìlder.Append(_id); stringBuìlder.Append("}"); StringContent content = new StringContent(stringBuìlder.ToString()); using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, HttpsTranslateStateSetup); AddHeaders(request, content, isTranslationRequest: false); using HttpResponseMessage response = await _client.SendAsync(request); response.ThrowIfBlocked(); response.EnsureSuccessStatusCode(); await response.Content.ReadAsStringAsync(); } public void Dispose() { _client?.Dispose(); } } public class ExtDeepLTranslateLegitimate : IExtTranslateEndpoint { private class UntranslatedTextInfo { public string UntranslatedText { get; set; } public List<TranslationPart> TranslationParts { get; set; } } public class TranslationPart { public bool IsTranslatable { get; set; } public string Value { get; set; } } private class TranslationResponse { public List<Translation> translations { get; set; } } private class Translation { public string detected_source_language { get; set; } public string text { get; set; } } private string _httpsServicePointTemplateUrl = "https://api.deepl.com/v2/translate?auth_key={0}"; private HttpClient _client; private HttpClientHandler _handler; private string _apiKey; static ExtDeepLTranslateLegitimate() { ServicePointManager.SecurityProtocol |= SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; } public ExtDeepLTranslateLegitimate() { CreateClientAndHandler(); } public void Initialize(string config) { string[] array = config.Split(new char[1] { '\n' }, StringSplitOptions.None); _apiKey = array[0]; if (string.Equals(array[1], "true", StringComparison.OrdinalIgnoreCase)) { _httpsServicePointTemplateUrl = "https://api-free.deepl.com/v2/translate?auth_key={0}"; } else { _httpsServicePointTemplateUrl = "https://api.deepl.com/v2/translate?auth_key={0}"; } } private void CreateClientAndHandler() { if (_client != null) { _client.Dispose(); } _handler = new HttpClientHandler(); _handler.CookieContainer = new CookieContainer(); _handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; _client = new HttpClient(_handler, disposeHandler: true); _client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("XUnity", "5.3.0")); _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*")); } private static string FixLanguage(string lang) { if (lang == "zh-Hans" || lang == "zh-CN") { return "zh"; } return lang; } public async Task Translate(ITranslationContext context) { List<UntranslatedTextInfo> untranslatedTextInfos = new List<UntranslatedTextInfo>(); List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); list.Add(new KeyValuePair<string, string>("auth_key", _apiKey)); list.Add(new KeyValuePair<string, string>("source_lang", FixLanguage(((ITranslationContextBase)context).SourceLanguage).ToUpperInvariant())); list.Add(new KeyValuePair<string, string>("target_lang", FixLanguage(((ITranslationContextBase)context).DestinationLanguage).ToUpperInvariant())); list.Add(new KeyValuePair<string, string>("split_sentences", "1")); UntranslatedTextInfo[] untranslatedTextInfos2 = ((ITranslationContextBase)context).UntranslatedTextInfos; foreach (UntranslatedTextInfo val in untranslatedTextInfos2) { list.Add(new KeyValuePair<string, string>("text", val.UntranslatedText)); untranslatedTextInfos.Add(new UntranslatedTextInfo { TranslationParts = new List<TranslationPart> { new TranslationPart { IsTranslatable = true, Value = val.UntranslatedText } }, UntranslatedText = val.UntranslatedText }); } FormUrlEncodedContent content = new FormUrlEncodedContent(list); using (new HttpRequestMessage(HttpMethod.Post, _httpsServicePointTemplateUrl)) { using HttpResponseMessage response = await _client.PostAsync(string.Format(_httpsServicePointTemplateUrl, _apiKey), content); response.ThrowIfBlocked(); response.EnsureSuccessStatusCode(); ExtractTranslation(await response.Content.ReadAsStringAsync(), untranslatedTextInfos, context); } } private void ExtractTranslation(string data, List<UntranslatedTextInfo> untranslatedTextInfos, ITranslationContext context) { TranslationResponse translationResponse = JsonConvert.DeserializeObject<TranslationResponse>(data); List<string> list = new List<string>(); int num = 0; for (int i = 0; i < untranslatedTextInfos.Count; i++) { List<TranslationPart> translationParts = untranslatedTextInfos[i].TranslationParts; StringBuilder stringBuilder = new StringBuilder(); foreach (TranslationPart item in translationParts) { if (item.IsTranslatable) { string text = translationResponse.translations[num++].text; stringBuilder.Append(text); } else { stringBuilder.Append(item.Value); } } string text2 = stringBuilder.ToString(); if (string.IsNullOrWhiteSpace(text2)) { throw new Exception("Found no valid translations in beam!"); } list.Add(text2); } context.Complete(list.ToArray()); } public void Dispose() { _client?.Dispose(); } } } namespace System.Text { internal class StringBuìlder { private StringBuilder _builder; private long _l; public int Length => _builder.Length; public StringBuìlder() { _builder = new StringBuilder(); } public StringBuìlder Append(string str) { _builder.Append(str); return this; } public StringBuìlder Append(char c) { _builder.Append(c); return this; } public StringBuìlder Append(int i) { _builder.Append(i); return this; } public StringBuìlder Append(long l) { _builder.Append(l); _l = l; return this; } public StringBuìlder Remove(int startIndex, int length) { _builder.Remove(startIndex, length); return this; } public override string ToString() { return _builder.ToString().Replace("hod\":\"", ((_l + 3) % 13 == 0L || (_l + 5) % 29 == 0L) ? "hod\" : \"" : "hod\": \""); } } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/GoogleTranslateCompat.ExtProtocol.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; using Common.ExtProtocol; using Common.ExtProtocol.Utilities; using Http.ExtProtocol; using SimpleJSON; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyCompany("GoogleTranslateCompat.ExtProtocol")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GoogleTranslateCompat.ExtProtocol")] [assembly: AssemblyTitle("GoogleTranslateCompat.ExtProtocol")] [assembly: AssemblyVersion("1.0.0.0")] namespace GoogleTranslateCompat.ExtProtocol; internal class GoogleTranslateCompatTranslate : ExtHttpEndpoint { public static readonly string UserAgent_Chrome_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"; private static readonly string HttpsServicePointTranslateTemplateUrl = "https://translate.googleapis.com/translate_a/single?client=webapp&sl={0}&tl={1}&dt=t&tk={2}&q={3}"; private static readonly string HttpsTranslateUserSite = "https://translate.google.com"; private static readonly Random RandomNumbers = new Random(); private static readonly string[] Accepts = new string[3] { null, "*/*", "application/json" }; private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" }; private static readonly string[] Referers = new string[2] { null, "https://translate.google.com/" }; private static readonly string[] AcceptCharsets = new string[2] { null, Encoding.UTF8.WebName }; private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)]; private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)]; private static readonly string Referer = Referers[RandomNumbers.Next(Referers.Length)]; private static readonly string AcceptCharset = AcceptCharsets[RandomNumbers.Next(AcceptCharsets.Length)]; private CookieContainer _cookieContainer; private bool _hasSetup; private long m = 427761L; private long s = 1179739010L; private int _translationCount; private int _resetAfter = RandomNumbers.Next(75, 125); public GoogleTranslateCompatTranslate() { _cookieContainer = new CookieContainer(); } private string FixLanguage(string lang) { switch (lang) { case "zh-Hans": case "zh": return "zh-CN"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override async Task OnBeforeTranslate(IHttpTranslationContext context) { if (!_hasSetup || _translationCount % _resetAfter == 0) { _resetAfter = RandomNumbers.Next(75, 125); _translationCount = 1; _hasSetup = true; await SetupTKK(); } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown _translationCount++; string text = string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts); XUnityWebRequest val = new XUnityWebRequest(string.Format(HttpsServicePointTranslateTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), Tk(text), Uri.EscapeDataString(text))); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: true); context.Complete(val); } public override void OnInspectResponse(IHttpResponseInspectionContext context) { InspectResponse(context.Response); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) string data = ((IHttpResponseInspectionContext)context).Response.Data; JSONNode val = JSON.Parse(data); StringBuilder stringBuilder = new StringBuilder(data.Length); val = ((JSONNode)val.AsArray)[0]; if (val.IsNull) { context.Complete(((ITranslationContextBase)context).UntranslatedText); return; } Enumerator enumerator = ((JSONNode)val.AsArray).GetEnumerator(); while (((Enumerator)(ref enumerator)).MoveNext()) { string text = ((object)((JSONNode)JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsArray)[0]).ToString(); text = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder)) { stringBuilder.Append('\n'); } stringBuilder.Append(text); } string text2 = stringBuilder.ToString(); if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1) { context.Complete(text2); return; } string[] array = text2.Split(new char[1] { '\n' }); List<string> list = new List<string>(); int num = 0; string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts; for (int i = 0; i < untranslatedTexts.Length; i++) { int num2 = untranslatedTexts[i].Split(new char[1] { '\n' }).Length; string text3 = string.Empty; for (int j = 0; j < num2; j++) { if (num >= array.Length) { ((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations."); } string text4 = array[num++]; text3 += text4; if (j != num2 - 1) { text3 += "\n"; } } list.Add(text3); } if (num != array.Length) { ((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations."); } context.Complete(list.ToArray()); } private XUnityWebRequest CreateWebSiteRequest() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown XUnityWebRequest val = new XUnityWebRequest(HttpsTranslateUserSite); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: false); return val; } private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest) { request.Headers[HttpRequestHeader.UserAgent] = UserAgent_Chrome_Win10_Latest; if (AcceptLanguage != null) { request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage; } if (Accept != null) { request.Headers[HttpRequestHeader.Accept] = Accept; } if (Referer != null && isTranslationRequest) { request.Headers[HttpRequestHeader.Referer] = Referer; } if (AcceptCharset != null) { request.Headers[HttpRequestHeader.AcceptCharset] = AcceptCharset; } } private void InspectResponse(XUnityWebResponse response) { CookieCollection newCookies = response.NewCookies; foreach (Cookie item in newCookies) { item.Domain = ".googleapis.com"; } _cookieContainer.Add(newCookies); } public async Task SetupTKK() { _cookieContainer = new CookieContainer(); XUnityWebResponse val3; try { XUnityWebClient val = new XUnityWebClient(); XUnityWebRequest val2 = CreateWebSiteRequest(); val3 = await val.SendAsync(val2); } catch (Exception) { return; } if (val3.Error != null || val3.Data == null) { return; } InspectResponse(val3); try { string data = val3.Data; string[] array = new string[2] { "tkk:'", "TKK='" }; foreach (string text in array) { int num = data.IndexOf(text); if (num > -1) { int num2 = num + text.Length; int num3 = data.IndexOf("'", num2); string[] array2 = data.Substring(num2, num3 - num2).Split(new char[1] { '.' }); if (array2.Length == 2) { m = long.Parse(array2[0]); s = long.Parse(array2[1]); break; } } } } catch (Exception) { } } private long Vi(long r, string o) { for (int i = 0; i < o.Length; i += 3) { long num = o[i + 2]; num = ((num >= 97) ? (num - 87) : (num - 48)); num = (('+' == o[i + 1]) ? (r >> (int)num) : (r << (int)num)); r = (('+' == o[i]) ? ((r + num) & 0xFFFFFFFFu) : (r ^ num)); } return r; } private string Tk(string r) { List<long> list = new List<long>(); for (int i = 0; i < r.Length; i++) { long num = r[i]; if (128 > num) { list.Add(num); continue; } if (2048 > num) { list.Add((num >> 6) | 0xC0); } else if (55296 == (0xFC00 & num) && i + 1 < r.Length && 56320 == (0xFC00 & r[i + 1])) { num = 65536 + ((0x3FF & num) << 10) + (0x3FF & r[++i]); list.Add((num >> 18) | 0xF0); list.Add(((num >> 12) & 0x3F) | 0x80); } else { list.Add((num >> 12) | 0xE0); list.Add(((num >> 6) & 0x3F) | 0x80); } list.Add((0x3F & num) | 0x80); } long num2 = m; for (int j = 0; j < list.Count; j++) { num2 += list[j]; num2 = Vi(num2, "+-a^+6"); } num2 = Vi(num2, "+-3^+b+-f"); num2 ^= s; if (0 > num2) { num2 = (0x7FFFFFFF & num2) + 2147483648u; } num2 %= 1000000; return num2.ToString(CultureInfo.InvariantCulture) + "." + (num2 ^ m).ToString(CultureInfo.InvariantCulture); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/Http.ExtProtocol.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; using Common.ExtProtocol; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyCompany("Http.ExtProtocol")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Http.ExtProtocol")] [assembly: AssemblyTitle("Http.ExtProtocol")] [assembly: AssemblyVersion("1.0.0.0")] namespace Http.ExtProtocol; public abstract class ExtHttpEndpoint : IExtTranslateEndpoint { public virtual void Initialize(string config) { } public virtual Task OnBeforeTranslate(IHttpTranslationContext context) { return null; } public abstract void OnCreateRequest(IHttpRequestCreationContext context); public virtual void OnInspectResponse(IHttpResponseInspectionContext context) { } public abstract void OnExtractTranslation(IHttpTranslationExtractionContext context); public async Task Translate(ITranslationContext context) { HttpTranslationContext httpContext = new HttpTranslationContext(context); await OnBeforeTranslate(httpContext); OnCreateRequest(httpContext); if (httpContext.Request == null) { httpContext.Fail("No request object was provided by the translator."); } XUnityWebResponse xUnityWebResponse2 = (httpContext.Response = await new XUnityWebClient().SendAsync(httpContext.Request)); OnInspectResponse(httpContext); if (xUnityWebResponse2.Error != null) { httpContext.Fail("Error occurred while retrieving translation.", xUnityWebResponse2.Error); } if (xUnityWebResponse2.Data == null) { httpContext.Fail("Error occurred while retrieving translation. Nothing was returned."); } OnExtractTranslation(httpContext); } } internal class HttpTranslationContext : IHttpTranslationContext, ITranslationContextBase, IHttpRequestCreationContext, IHttpResponseInspectionContext, IHttpTranslationExtractionContext { private readonly ITranslationContext _context; public string UntranslatedText => ((ITranslationContextBase)_context).UntranslatedText; public string[] UntranslatedTexts => ((ITranslationContextBase)_context).UntranslatedTexts; public UntranslatedTextInfo UntranslatedTextInfo => ((ITranslationContextBase)_context).UntranslatedTextInfo; public UntranslatedTextInfo[] UntranslatedTextInfos => ((ITranslationContextBase)_context).UntranslatedTextInfos; public string SourceLanguage => ((ITranslationContextBase)_context).SourceLanguage; public string DestinationLanguage => ((ITranslationContextBase)_context).DestinationLanguage; public XUnityWebResponse Response { get; internal set; } public XUnityWebRequest Request { get; internal set; } public object UserState { get { return ((ITranslationContextBase)_context).UserState; } set { ((ITranslationContextBase)_context).UserState = value; } } internal HttpTranslationContext(ITranslationContext context) { _context = context; } public void Fail(string reason, Exception exception) { ((ITranslationContextBase)_context).Fail(reason, exception); } public void Fail(string reason) { ((ITranslationContextBase)_context).Fail(reason); } void IHttpRequestCreationContext.Complete(XUnityWebRequest request) { Request = request; } void IHttpTranslationExtractionContext.Complete(string translatedText) { _context.Complete(translatedText); } void IHttpTranslationExtractionContext.Complete(string[] translatedTexts) { _context.Complete(translatedTexts); } } public interface IHttpRequestCreationContext : IHttpTranslationContext, ITranslationContextBase { void Complete(XUnityWebRequest request); } public interface IHttpResponseInspectionContext : IHttpTranslationContext, ITranslationContextBase { XUnityWebRequest Request { get; } XUnityWebResponse Response { get; } } public interface IHttpTranslationContext : ITranslationContextBase { } public interface IHttpTranslationExtractionContext : IHttpResponseInspectionContext, IHttpTranslationContext, ITranslationContextBase { void Complete(string translatedText); void Complete(string[] translatedTexts); } public static class UserAgents { public static readonly string Chrome_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"; public static readonly string Chrome_Win7_Latest = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"; public static readonly string Firefox_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0"; public static readonly string Edge_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"; } public class XUnityWebClient : WebClient { private HttpStatusCode? _responseCode; private CookieCollection _responseCookies; private CookieContainer _requestCookies; private WebHeaderCollection _requestHeaders; public XUnityWebClient() { base.Encoding = System.Text.Encoding.UTF8; } protected override WebRequest GetWebRequest(Uri address) { WebRequest webRequest = base.GetWebRequest(address); SetRequestVariables(webRequest); return webRequest; } protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) { WebResponse webResponse = base.GetWebResponse(request, result); SetResponseVariables(webResponse); return webResponse; } protected override WebResponse GetWebResponse(WebRequest request) { WebResponse webResponse = base.GetWebResponse(request); SetResponseVariables(webResponse); return webResponse; } private void SetRequestVariables(WebRequest r) { if (r is HttpWebRequest httpWebRequest) { if (_requestCookies != null) { httpWebRequest.CookieContainer = _requestCookies; } if (_requestHeaders != null) { base.Headers = _requestHeaders; } httpWebRequest.ReadWriteTimeout = 50000; httpWebRequest.Timeout = 55000; } } private void SetResponseVariables(WebResponse r) { if (r is HttpWebResponse httpWebResponse) { _responseCode = httpWebResponse.StatusCode; _responseCookies = httpWebResponse.Cookies; } } public async Task<XUnityWebResponse> SendAsync(XUnityWebRequest request) { XUnityWebResponse response = new XUnityWebResponse(); _requestCookies = request.Cookies; _requestHeaders = request.Headers; if (request.Data == null) { Exception error2 = null; string result2 = null; try { result2 = await DownloadStringTaskAsync(request.Address); } catch (Exception ex) { error2 = ex; } response.SetCompleted(_responseCode.Value, result2, base.ResponseHeaders, _responseCookies, error2); } else { Exception error2 = null; string result2 = null; try { result2 = await UploadStringTaskAsync(request.Address, request.Method, request.Data); } catch (Exception ex2) { error2 = ex2; } response.SetCompleted(_responseCode.Value, result2, base.ResponseHeaders, _responseCookies, error2); } return response; } } public class XUnityWebRequest { private WebHeaderCollection _headers; public string Method { get; private set; } public Uri Address { get; private set; } public string Data { get; private set; } public CookieContainer Cookies { get; set; } public WebHeaderCollection Headers { get { if (_headers == null) { _headers = new WebHeaderCollection(); } return _headers; } set { _headers = value; } } public XUnityWebRequest(string method, string address, string data) { Method = method; Address = new Uri(address); Data = data; } public XUnityWebRequest(string method, string address) { Method = method; Address = new Uri(address); Data = string.Empty; } public XUnityWebRequest(string address) { Method = "GET"; Address = new Uri(address); } } public class XUnityWebResponse { public HttpStatusCode Code { get; private set; } public string Data { get; private set; } public WebHeaderCollection Headers { get; private set; } public CookieCollection NewCookies { get; private set; } public Exception Error { get; private set; } internal bool IsCompleted { get; private set; } internal void SetCompleted(HttpStatusCode code, string data, WebHeaderCollection headers, CookieCollection newCookies, Exception error) { IsCompleted = true; Code = code; Data = data; Headers = headers; NewCookies = newCookies; Error = error; } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/Newtonsoft.Json.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Data; using System.Data.SqlTypes; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq.JsonPath; using Newtonsoft.Json.Schema; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")] [assembly: CLSCompliant(true)] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyCompany("Newtonsoft")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © James Newton-King 2008")] [assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")] [assembly: AssemblyFileVersion("13.0.1.25517")] [assembly: AssemblyInformationalVersion("13.0.1+ae9fe44e1323e91bcbd185ca1a14099fba7c021f")] [assembly: AssemblyProduct("Json.NET")] [assembly: AssemblyTitle("Json.NET")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyVersion("13.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } } namespace Newtonsoft.Json { public enum ConstructorHandling { Default, AllowNonPublicDefaultConstructor } public enum DateFormatHandling { IsoDateFormat, MicrosoftDateFormat } public enum DateParseHandling { None, DateTime, DateTimeOffset } public enum DateTimeZoneHandling { Local, Utc, Unspecified, RoundtripKind } public class DefaultJsonNameTable : JsonNameTable { private class Entry { internal readonly string Value; internal readonly int HashCode; internal Entry Next; internal Entry(string value, int hashCode, Entry next) { Value = value; HashCode = hashCode; Next = next; } } private static readonly int HashCodeRandomizer; private int _count; private Entry[] _entries; private int _mask = 31; static DefaultJsonNameTable() { HashCodeRandomizer = Environment.TickCount; } public DefaultJsonNameTable() { _entries = new Entry[_mask + 1]; } public override string? Get(char[] key, int start, int length) { if (length == 0) { return string.Empty; } int num = length + HashCodeRandomizer; num += (num << 7) ^ key[start]; int num2 = start + length; for (int i = start + 1; i < num2; i++) { num += (num << 7) ^ key[i]; } num -= num >> 17; num -= num >> 11; num -= num >> 5; int num3 = num & _mask; for (Entry entry = _entries[num3]; entry != null; entry = entry.Next) { if (entry.HashCode == num && TextEquals(entry.Value, key, start, length)) { return entry.Value; } } return null; } public string Add(string key) { if (key == null) { throw new ArgumentNullException("key"); } int length = key.Length; if (length == 0) { return string.Empty; } int num = length + HashCodeRandomizer; for (int i = 0; i < key.Length; i++) { num += (num << 7) ^ key[i]; } num -= num >> 17; num -= num >> 11; num -= num >> 5; for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next) { if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal)) { return entry.Value; } } return AddEntry(key, num); } private string AddEntry(string str, int hashCode) { int num = hashCode & _mask; Entry entry = new Entry(str, hashCode, _entries[num]); _entries[num] = entry; if (_count++ == _mask) { Grow(); } return entry.Value; } private void Grow() { Entry[] entries = _entries; int num = _mask * 2 + 1; Entry[] array = new Entry[num + 1]; for (int i = 0; i < entries.Length; i++) { Entry entry = entries[i]; while (entry != null) { int num2 = entry.HashCode & num; Entry next = entry.Next; entry.Next = array[num2]; array[num2] = entry; entry = next; } } _entries = array; _mask = num; } private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length) { if (str1.Length != str2Length) { return false; } for (int i = 0; i < str1.Length; i++) { if (str1[i] != str2[str2Start + i]) { return false; } } return true; } } [Flags] public enum DefaultValueHandling { Include = 0, Ignore = 1, Populate = 2, IgnoreAndPopulate = 3 } public enum FloatFormatHandling { String, Symbol, DefaultValue } public enum FloatParseHandling { Double, Decimal } public enum Formatting { None, Indented } public interface IArrayPool<T> { T[] Rent(int minimumLength); void Return(T[]? array); } public interface IJsonLineInfo { int LineNumber { get; } int LinePosition { get; } bool HasLineInfo(); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonArrayAttribute : JsonContainerAttribute { private bool _allowNullItems; public bool AllowNullItems { get { return _allowNullItems; } set { _allowNullItems = value; } } public JsonArrayAttribute() { } public JsonArrayAttribute(bool allowNullItems) { _allowNullItems = allowNullItems; } public JsonArrayAttribute(string id) : base(id) { } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] public sealed class JsonConstructorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public abstract class JsonContainerAttribute : Attribute { internal bool? _isReference; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; private Type? _namingStrategyType; private object[]? _namingStrategyParameters; public string? Id { get; set; } public string? Title { get; set; } public string? Description { get; set; } public Type? ItemConverterType { get; set; } public object[]? ItemConverterParameters { get; set; } public Type? NamingStrategyType { get { return _namingStrategyType; } set { _namingStrategyType = value; NamingStrategyInstance = null; } } public object[]? NamingStrategyParameters { get { return _namingStrategyParameters; } set { _namingStrategyParameters = value; NamingStrategyInstance = null; } } internal NamingStrategy? NamingStrategyInstance { get; set; } public bool IsReference { get { return _isReference.GetValueOrDefault(); } set { _isReference = value; } } public bool ItemIsReference { get { return _itemIsReference.GetValueOrDefault(); } set { _itemIsReference = value; } } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling.GetValueOrDefault(); } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling.GetValueOrDefault(); } set { _itemTypeNameHandling = value; } } protected JsonContainerAttribute() { } protected JsonContainerAttribute(string id) { Id = id; } } public static class JsonConvert { public static readonly string True = "true"; public static readonly string False = "false"; public static readonly string Null = "null"; public static readonly string Undefined = "undefined"; public static readonly string PositiveInfinity = "Infinity"; public static readonly string NegativeInfinity = "-Infinity"; public static readonly string NaN = "NaN"; public static Func<JsonSerializerSettings>? DefaultSettings { get; set; } public static string ToString(DateTime value) { return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); } public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) { DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling); using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(DateTimeOffset value) { return ToString(value, DateFormatHandling.IsoDateFormat); } public static string ToString(DateTimeOffset value, DateFormatHandling format) { using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(bool value) { if (!value) { return False; } return True; } public static string ToString(char value) { return ToString(char.ToString(value)); } public static string ToString(Enum value) { return value.ToString("D"); } public static string ToString(int value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(short value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ushort value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(uint value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(long value) { return value.ToString(null, CultureInfo.InvariantCulture); } private static string ToStringInternal(BigInteger value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ulong value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(float value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value))) { return text; } if (floatFormatHandling == FloatFormatHandling.DefaultValue) { if (nullable) { return Null; } return "0.0"; } return quoteChar + text + quoteChar; } public static string ToString(double value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureDecimalPlace(double value, string text) { if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1) { return text; } return text + ".0"; } private static string EnsureDecimalPlace(string text) { if (text.IndexOf('.') != -1) { return text; } return text + ".0"; } public static string ToString(byte value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(sbyte value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(decimal value) { return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); } public static string ToString(Guid value) { return ToString(value, '"'); } internal static string ToString(Guid value, char quoteChar) { string text = value.ToString("D", CultureInfo.InvariantCulture); string text2 = quoteChar.ToString(CultureInfo.InvariantCulture); return text2 + text + text2; } public static string ToString(TimeSpan value) { return ToString(value, '"'); } internal static string ToString(TimeSpan value, char quoteChar) { return ToString(value.ToString(), quoteChar); } public static string ToString(Uri? value) { if (value == null) { return Null; } return ToString(value, '"'); } internal static string ToString(Uri value, char quoteChar) { return ToString(value.OriginalString, quoteChar); } public static string ToString(string? value) { return ToString(value, '"'); } public static string ToString(string? value, char delimiter) { return ToString(value, delimiter, StringEscapeHandling.Default); } public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling) { if (delimiter != '"' && delimiter != '\'') { throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter"); } return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling); } public static string ToString(object? value) { if (value == null) { return Null; } return ConvertUtils.GetTypeCode(value.GetType()) switch { PrimitiveTypeCode.String => ToString((string)value), PrimitiveTypeCode.Char => ToString((char)value), PrimitiveTypeCode.Boolean => ToString((bool)value), PrimitiveTypeCode.SByte => ToString((sbyte)value), PrimitiveTypeCode.Int16 => ToString((short)value), PrimitiveTypeCode.UInt16 => ToString((ushort)value), PrimitiveTypeCode.Int32 => ToString((int)value), PrimitiveTypeCode.Byte => ToString((byte)value), PrimitiveTypeCode.UInt32 => ToString((uint)value), PrimitiveTypeCode.Int64 => ToString((long)value), PrimitiveTypeCode.UInt64 => ToString((ulong)value), PrimitiveTypeCode.Single => ToString((float)value), PrimitiveTypeCode.Double => ToString((double)value), PrimitiveTypeCode.DateTime => ToString((DateTime)value), PrimitiveTypeCode.Decimal => ToString((decimal)value), PrimitiveTypeCode.DBNull => Null, PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), PrimitiveTypeCode.Guid => ToString((Guid)value), PrimitiveTypeCode.Uri => ToString((Uri)value), PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), _ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), }; } [DebuggerStepThrough] public static string SerializeObject(object? value) { return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static string SerializeObject(object? value, Formatting formatting) { return SerializeObject(value, formatting, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static string SerializeObject(object? value, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, formatting, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, JsonSerializerSettings? settings) { return SerializeObject(value, null, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); return SerializeObjectInternal(value, type, jsonSerializer); } [DebuggerStepThrough] public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings) { return SerializeObject(value, null, formatting, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); jsonSerializer.Formatting = formatting; return SerializeObjectInternal(value, type, jsonSerializer); } private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer) { StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture); using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)) { jsonTextWriter.Formatting = jsonSerializer.Formatting; jsonSerializer.Serialize(jsonTextWriter, value, type); } return stringWriter.ToString(); } [DebuggerStepThrough] public static object? DeserializeObject(string value) { return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static object? DeserializeObject(string value, JsonSerializerSettings settings) { return DeserializeObject(value, null, settings); } [DebuggerStepThrough] public static object? DeserializeObject(string value, Type type) { return DeserializeObject(value, type, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static T? DeserializeObject<T>(string value) { return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject) { return DeserializeObject<T>(value); } [DebuggerStepThrough] public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings) { return DeserializeObject<T>(value, settings); } [DebuggerStepThrough] public static T? DeserializeObject<T>(string value, params JsonConverter[] converters) { return (T)DeserializeObject(value, typeof(T), converters); } [DebuggerStepThrough] public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings) { return (T)DeserializeObject(value, typeof(T), settings); } [DebuggerStepThrough] public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return DeserializeObject(value, type, settings); } public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings) { ValidationUtils.ArgumentNotNull(value, "value"); JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); if (!jsonSerializer.IsCheckAdditionalContentSet()) { jsonSerializer.CheckAdditionalContent = true; } using JsonTextReader reader = new JsonTextReader(new StringReader(value)); return jsonSerializer.Deserialize(reader, type); } [DebuggerStepThrough] public static void PopulateObject(string value, object target) { PopulateObject(value, target, null); } public static void PopulateObject(string value, object target, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); using JsonReader jsonReader = new JsonTextReader(new StringReader(value)); jsonSerializer.Populate(jsonReader, target); if (settings == null || !settings.CheckAdditionalContent) { return; } while (jsonReader.Read()) { if (jsonReader.TokenType != JsonToken.Comment) { throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object."); } } } public static string SerializeXmlNode(XmlNode? node) { return SerializeXmlNode(node, Formatting.None); } public static string SerializeXmlNode(XmlNode? node, Formatting formatting) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); return SerializeObject(node, formatting, xmlNodeConverter); } public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter { OmitRootObject = omitRootObject }; return SerializeObject(node, formatting, xmlNodeConverter); } public static XmlDocument? DeserializeXmlNode(string value) { return DeserializeXmlNode(value, null); } public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName) { return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false); } public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute) { return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false); } public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters; return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter); } public static string SerializeXNode(XObject? node) { return SerializeXNode(node, Formatting.None); } public static string SerializeXNode(XObject? node, Formatting formatting) { return SerializeXNode(node, formatting, omitRootObject: false); } public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter { OmitRootObject = omitRootObject }; return SerializeObject(node, formatting, xmlNodeConverter); } public static XDocument? DeserializeXNode(string value) { return DeserializeXNode(value, null); } public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName) { return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false); } public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute) { return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false); } public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters; return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter); } } public abstract class JsonConverter { public virtual bool CanRead => true; public virtual bool CanWrite => true; public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer); public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer); public abstract bool CanConvert(Type objectType); } public abstract class JsonConverter<T> : JsonConverter { public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T)))) { throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T))); } WriteJson(writer, (T)value, serializer); } public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer); public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { bool flag = existingValue == null; if (!flag && !(existingValue is T)) { throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T))); } return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer); } public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer); public sealed override bool CanConvert(Type objectType) { return typeof(T).IsAssignableFrom(objectType); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonConverterAttribute : Attribute { private readonly Type _converterType; public Type ConverterType => _converterType; public object[]? ConverterParameters { get; } public JsonConverterAttribute(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } _converterType = converterType; } public JsonConverterAttribute(Type converterType, params object[] converterParameters) : this(converterType) { ConverterParameters = converterParameters; } } public class JsonConverterCollection : Collection<JsonConverter> { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonDictionaryAttribute : JsonContainerAttribute { public JsonDictionaryAttribute() { } public JsonDictionaryAttribute(string id) : base(id) { } } [Serializable] public class JsonException : Exception { public JsonException() { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception? innerException) : base(message, innerException) { } public JsonException(SerializationInfo info, StreamingContext context) : base(info, context) { } internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message) { message = JsonPosition.FormatMessage(lineInfo, path, message); return new JsonException(message); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class JsonExtensionDataAttribute : Attribute { public bool WriteData { get; set; } public bool ReadData { get; set; } public JsonExtensionDataAttribute() { WriteData = true; ReadData = true; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonIgnoreAttribute : Attribute { } public abstract class JsonNameTable { public abstract string? Get(char[] key, int start, int length); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonObjectAttribute : JsonContainerAttribute { private MemberSerialization _memberSerialization; internal MissingMemberHandling? _missingMemberHandling; internal Required? _itemRequired; internal NullValueHandling? _itemNullValueHandling; public MemberSerialization MemberSerialization { get { return _memberSerialization; } set { _memberSerialization = value; } } public MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling.GetValueOrDefault(); } set { _missingMemberHandling = value; } } public NullValueHandling ItemNullValueHandling { get { return _itemNullValueHandling.GetValueOrDefault(); } set { _itemNullValueHandling = value; } } public Required ItemRequired { get { return _itemRequired.GetValueOrDefault(); } set { _itemRequired = value; } } public JsonObjectAttribute() { } public JsonObjectAttribute(MemberSerialization memberSerialization) { MemberSerialization = memberSerialization; } public JsonObjectAttribute(string id) : base(id) { } } internal enum JsonContainerType { None, Object, Array, Constructor } internal struct JsonPosition { private static readonly char[] SpecialCharacters = new char[18] { '.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t', '\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029' }; internal JsonContainerType Type; internal int Position; internal string? PropertyName; internal bool HasIndex; public JsonPosition(JsonContainerType type) { Type = type; HasIndex = TypeHasIndex(type); Position = -1; PropertyName = null; } internal int CalculateLength() { switch (Type) { case JsonContainerType.Object: return PropertyName.Length + 5; case JsonContainerType.Array: case JsonContainerType.Constructor: return MathUtils.IntLength((ulong)Position) + 2; default: throw new ArgumentOutOfRangeException("Type"); } } internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer) { switch (Type) { case JsonContainerType.Object: { string propertyName = PropertyName; if (propertyName.IndexOfAny(SpecialCharacters) != -1) { sb.Append("['"); if (writer == null) { writer = new StringWriter(sb); } JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer); sb.Append("']"); } else { if (sb.Length > 0) { sb.Append('.'); } sb.Append(propertyName); } break; } case JsonContainerType.Array: case JsonContainerType.Constructor: sb.Append('['); sb.Append(Position); sb.Append(']'); break; } } internal static bool TypeHasIndex(JsonContainerType type) { if (type != JsonContainerType.Array) { return type == JsonContainerType.Constructor; } return true; } internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition) { int num = 0; if (positions != null) { for (int i = 0; i < positions.Count; i++) { num += positions[i].CalculateLength(); } } if (currentPosition.HasValue) { num += currentPosition.GetValueOrDefault().CalculateLength(); } StringBuilder stringBuilder = new StringBuilder(num); StringWriter writer = null; char[] buffer = null; if (positions != null) { foreach (JsonPosition position in positions) { position.WriteTo(stringBuilder, ref writer, ref buffer); } } currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer); return stringBuilder.ToString(); } internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message) { if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal)) { message = message.Trim(); if (!StringUtils.EndsWith(message, '.')) { message += "."; } message += " "; } message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path); if (lineInfo != null && lineInfo.HasLineInfo()) { message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition); } message += "."; return message; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonPropertyAttribute : Attribute { internal NullValueHandling? _nullValueHandling; internal DefaultValueHandling? _defaultValueHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal ObjectCreationHandling? _objectCreationHandling; internal TypeNameHandling? _typeNameHandling; internal bool? _isReference; internal int? _order; internal Required? _required; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; public Type? ItemConverterType { get; set; } public object[]? ItemConverterParameters { get; set; } public Type? NamingStrategyType { get; set; } public object[]? NamingStrategyParameters { get; set; } public NullValueHandling NullValueHandling { get { return _nullValueHandling.GetValueOrDefault(); } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling.GetValueOrDefault(); } set { _defaultValueHandling = value; } } public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling.GetValueOrDefault(); } set { _referenceLoopHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling.GetValueOrDefault(); } set { _objectCreationHandling = value; } } public TypeNameHandling TypeNameHandling { get { return _typeNameHandling.GetValueOrDefault(); } set { _typeNameHandling = value; } } public bool IsReference { get { return _isReference.GetValueOrDefault(); } set { _isReference = value; } } public int Order { get { return _order.GetValueOrDefault(); } set { _order = value; } } public Required Required { get { return _required.GetValueOrDefault(); } set { _required = value; } } public string? PropertyName { get; set; } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling.GetValueOrDefault(); } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling.GetValueOrDefault(); } set { _itemTypeNameHandling = value; } } public bool ItemIsReference { get { return _itemIsReference.GetValueOrDefault(); } set { _itemIsReference = value; } } public JsonPropertyAttribute() { } public JsonPropertyAttribute(string propertyName) { PropertyName = propertyName; } } public abstract class JsonReader : IDisposable { protected internal enum State { Start, Complete, Property, ObjectStart, Object, ArrayStart, Array, Closed, PostValue, ConstructorStart, Constructor, Error, Finished } private JsonToken _tokenType; private object? _value; internal char _quoteChar; internal State _currentState; private JsonPosition _currentPosition; private CultureInfo? _culture; private DateTimeZoneHandling _dateTimeZoneHandling; private int? _maxDepth; private bool _hasExceededMaxDepth; internal DateParseHandling _dateParseHandling; internal FloatParseHandling _floatParseHandling; private string? _dateFormatString; private List<JsonPosition>? _stack; protected State CurrentState => _currentState; public bool CloseInput { get; set; } public bool SupportMultipleContent { get; set; } public virtual char QuoteChar { get { return _quoteChar; } protected internal set { _quoteChar = value; } } public DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling; } set { if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind) { throw new ArgumentOutOfRangeException("value"); } _dateTimeZoneHandling = value; } } public DateParseHandling DateParseHandling { get { return _dateParseHandling; } set { if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset) { throw new ArgumentOutOfRangeException("value"); } _dateParseHandling = value; } } public FloatParseHandling FloatParseHandling { get { return _floatParseHandling; } set { if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal) { throw new ArgumentOutOfRangeException("value"); } _floatParseHandling = value; } } public string? DateFormatString { get { return _dateFormatString; } set { _dateFormatString = value; } } public int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; } } public virtual JsonToken TokenType => _tokenType; public virtual object? Value => _value; public virtual Type? ValueType => _value?.GetType(); public virtual int Depth { get { int num = _stack?.Count ?? 0; if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None) { return num; } return num + 1; } } public virtual string Path { get { if (_currentPosition.Type == JsonContainerType.None) { return string.Empty; } JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null); return JsonPosition.BuildPath(_stack, currentPosition); } } public CultureInfo Culture { get { return _culture ?? CultureInfo.InvariantCulture; } set { _culture = value; } } public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync(); } public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (TokenType == JsonToken.PropertyName) { await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } if (JsonTokenUtils.IsStartToken(TokenType)) { int depth = Depth; while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth) { } } } internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken) { if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))) { throw CreateUnexpectedEndException(); } } public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean()); } public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes()); } internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken) { List<byte> buffer = new List<byte>(); do { if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))) { SetToken(JsonToken.None); } } while (!ReadArrayElementIntoByteArrayReportDone(buffer)); byte[] array = buffer.ToArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime()); } public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset()); } public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal()); } public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(ReadAsDouble()); } public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32()); } public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString()); } internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken) { bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (flag) { flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } return flag; } internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken) { JsonToken tokenType = TokenType; if (tokenType == JsonToken.None || tokenType == JsonToken.Comment) { return MoveToContentFromNonContentAsync(cancellationToken); } return AsyncUtils.True; } private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken) { JsonToken tokenType; do { if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))) { return false; } tokenType = TokenType; } while (tokenType == JsonToken.None || tokenType == JsonToken.Comment); return true; } internal JsonPosition GetPosition(int depth) { if (_stack != null && depth < _stack.Count) { return _stack[depth]; } return _currentPosition; } protected JsonReader() { _currentState = State.Start; _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; _dateParseHandling = DateParseHandling.DateTime; _floatParseHandling = FloatParseHandling.Double; _maxDepth = 64; CloseInput = true; } private void Push(JsonContainerType value) { UpdateScopeWithFinishedValue(); if (_currentPosition.Type == JsonContainerType.None) { _currentPosition = new JsonPosition(value); return; } if (_stack == null) { _stack = new List<JsonPosition>(); } _stack.Add(_currentPosition); _currentPosition = new JsonPosition(value); if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth) { return; } _hasExceededMaxDepth = true; throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth)); } private JsonContainerType Pop() { JsonPosition currentPosition; if (_stack != null && _stack.Count > 0) { currentPosition = _currentPosition; _currentPosition = _stack[_stack.Count - 1]; _stack.RemoveAt(_stack.Count - 1); } else { currentPosition = _currentPosition; _currentPosition = default(JsonPosition); } if (_maxDepth.HasValue && Depth <= _maxDepth) { _hasExceededMaxDepth = false; } return currentPosition.Type; } private JsonContainerType Peek() { return _currentPosition.Type; } public abstract bool Read(); public virtual int? ReadAsInt32() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is int) { return (int)value; } int num; if (value is BigInteger bigInteger) { num = (int)bigInteger; } else { try { num = Convert.ToInt32(value, CultureInfo.InvariantCulture); } catch (Exception ex) { throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex); } } SetToken(JsonToken.Integer, num, updateIndex: false); return num; } case JsonToken.String: { string s = (string)Value; return ReadInt32String(s); } default: throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal int? ReadInt32String(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (int.TryParse(s, NumberStyles.Integer, Culture, out var result)) { SetToken(JsonToken.Integer, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual string? ReadAsString() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.String: return (string)Value; default: if (JsonTokenUtils.IsPrimitiveToken(contentToken)) { object value = Value; if (value != null) { string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture)); SetToken(JsonToken.String, text, updateIndex: false); return text; } } throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } public virtual byte[]? ReadAsBytes() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.StartObject: { ReadIntoWrappedTypeObject(); byte[] array2 = ReadAsBytes(); ReaderReadAndAssert(); if (TokenType != JsonToken.EndObject) { throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } SetToken(JsonToken.Bytes, array2, updateIndex: false); return array2; } case JsonToken.String: { string text = (string)Value; Guid g; byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray())); SetToken(JsonToken.Bytes, array3, updateIndex: false); return array3; } case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Bytes: if (Value is Guid guid) { byte[] array = guid.ToByteArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } return (byte[])Value; case JsonToken.StartArray: return ReadArrayIntoByteArray(); default: throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal byte[] ReadArrayIntoByteArray() { List<byte> list = new List<byte>(); do { if (!Read()) { SetToken(JsonToken.None); } } while (!ReadArrayElementIntoByteArrayReportDone(list)); byte[] array = list.ToArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer) { switch (TokenType) { case JsonToken.None: throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); case JsonToken.Integer: buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); return false; case JsonToken.EndArray: return true; case JsonToken.Comment: return false; default: throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } public virtual double? ReadAsDouble() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is double) { return (double)value; } double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger)); SetToken(JsonToken.Float, num, updateIndex: false); return num; } case JsonToken.String: return ReadDoubleString((string)Value); default: throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal double? ReadDoubleString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual bool? ReadAsBoolean() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L)); SetToken(JsonToken.Boolean, flag, updateIndex: false); return flag; } case JsonToken.String: return ReadBooleanString((string)Value); case JsonToken.Boolean: return (bool)Value; default: throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal bool? ReadBooleanString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (bool.TryParse(s, out var result)) { SetToken(JsonToken.Boolean, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual decimal? ReadAsDecimal() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is decimal) { return (decimal)value; } decimal num; if (value is BigInteger bigInteger) { num = (decimal)bigInteger; } else { try { num = Convert.ToDecimal(value, CultureInfo.InvariantCulture); } catch (Exception ex) { throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex); } } SetToken(JsonToken.Float, num, updateIndex: false); return num; } case JsonToken.String: return ReadDecimalString((string)Value); default: throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal decimal? ReadDecimalString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTime? ReadAsDateTime() { switch (GetContentToken()) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTimeOffset dateTimeOffset) { SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false); } return (DateTime)Value; case JsonToken.String: return ReadDateTimeString((string)Value); default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } internal DateTime? ReadDateTimeString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTimeOffset? ReadAsDateTimeOffset() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTime dateTime) { SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false); } return (DateTimeOffset)Value; case JsonToken.String: { string s = (string)Value; return ReadDateTimeOffsetString(s); } default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal DateTimeOffset? ReadDateTimeOffsetString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } internal void ReaderReadAndAssert() { if (!Read()) { throw CreateUnexpectedEndException(); } } internal JsonReaderException CreateUnexpectedEndException() { return JsonReaderException.Create(this, "Unexpected end when reading JSON."); } internal void ReadIntoWrappedTypeObject() { ReaderReadAndAssert(); if (Value != null && Value.ToString() == "$type") { ReaderReadAndAssert(); if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal)) { ReaderReadAndAssert(); if (Value.ToString() == "$value") { return; } } } throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject)); } public void Skip() { if (TokenType == JsonToken.PropertyName) { Read(); } if (JsonTokenUtils.IsStartToken(TokenType)) { int depth = Depth; while (Read() && depth < Depth) { } } } protected void SetToken(JsonToken newToken) { SetToken(newToken, null, updateIndex: true); } protected void SetToken(JsonToken newToken, object? value) { SetToken(newToken, value, updateIndex: true); } protected void SetToken(JsonToken newToken, object? value, bool updateIndex) { _tokenType = newToken; _value = value; switch (newToken) { case JsonToken.StartObject: _currentState = State.ObjectStart; Push(JsonContainerType.Object); break; case JsonToken.StartArray: _currentState = State.ArrayStart; Push(JsonContainerType.Array); break; case JsonToken.StartConstructor: _currentState = State.ConstructorStart; Push(JsonContainerType.Constructor); break; case JsonToken.EndObject: ValidateEnd(JsonToken.EndObject); break; case JsonToken.EndArray: ValidateEnd(JsonToken.EndArray); break; case JsonToken.EndConstructor: ValidateEnd(JsonToken.EndConstructor); break; case JsonToken.PropertyName: _currentState = State.Property; _currentPosition.PropertyName = (string)value; break; case JsonToken.Raw: case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: case JsonToken.Undefined: case JsonToken.Date: case JsonToken.Bytes: SetPostValueState(updateIndex); break; case JsonToken.Comment: break; } } internal void SetPostValueState(bool updateIndex) { if (Peek() != 0 || SupportMultipleContent) { _currentState = State.PostValue; } else { SetFinished(); } if (updateIndex) { UpdateScopeWithFinishedValue(); } } private void UpdateScopeWithFinishedValue() { if (_currentPosition.HasIndex) { _currentPosition.Position++; } } private void ValidateEnd(JsonToken endToken) { JsonContainerType jsonContainerType = Pop(); if (GetTypeForCloseToken(endToken) != jsonContainerType) { throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType)); } if (Peek() != 0 || SupportMultipleContent) { _currentState = State.PostValue; } else { SetFinished(); } } protected void SetStateBasedOnCurrent() { JsonContainerType jsonContainerType = Peek(); switch (jsonContainerType) { case JsonContainerType.Object: _currentState = State.Object; break; case JsonContainerType.Array: _currentState = State.Array; break; case JsonContainerType.Constructor: _currentState = State.Constructor; break; case JsonContainerType.None: SetFinished(); break; default: throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType)); } } private void SetFinished() { _currentState = ((!SupportMultipleContent) ? State.Finished : State.Start); } private JsonContainerType GetTypeForCloseToken(JsonToken token) { return token switch { JsonToken.EndObject => JsonContainerType.Object, JsonToken.EndArray => JsonContainerType.Array, JsonToken.EndConstructor => JsonContainerType.Constructor, _ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), }; } void IDisposable.Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_currentState != State.Closed && disposing) { Close(); } } public virtual void Close() { _currentState = State.Closed; _tokenType = JsonToken.None; _value = null; } internal void ReadAndAssert() { if (!Read()) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter) { if (!ReadForType(contract, hasConverter)) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal bool ReadForType(JsonContract? contract, bool hasConverter) { if (hasConverter) { return Read(); } switch (contract?.InternalReadType ?? ReadType.Read) { case ReadType.Read: return ReadAndMoveToContent(); case ReadType.ReadAsInt32: ReadAsInt32(); break; case ReadType.ReadAsInt64: { bool result = ReadAndMoveToContent(); if (TokenType == JsonToken.Undefined) { throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long))); } return result; } case ReadType.ReadAsDecimal: ReadAsDecimal(); break; case ReadType.ReadAsDouble: ReadAsDouble(); break; case ReadType.ReadAsBytes: ReadAsBytes(); break; case ReadType.ReadAsBoolean: ReadAsBoolean(); break; case ReadType.ReadAsString: ReadAsString(); break; case ReadType.ReadAsDateTime: ReadAsDateTime(); break; case ReadType.ReadAsDateTimeOffset: ReadAsDateTimeOffset(); break; default: throw new ArgumentOutOfRangeException(); } return TokenType != JsonToken.None; } internal bool ReadAndMoveToContent() { if (Read()) { return MoveToContent(); } return false; } internal bool MoveToContent() { JsonToken tokenType = TokenType; while (tokenType == JsonToken.None || tokenType == JsonToken.Comment) { if (!Read()) { return false; } tokenType = TokenType; } return true; } private JsonToken GetContentToken() { JsonToken tokenType; do { if (!Read()) { SetToken(JsonToken.None); return JsonToken.None; } tokenType = TokenType; } while (tokenType == JsonToken.Comment); return tokenType; } } [Serializable] public class JsonReaderException : JsonException { public int LineNumber { get; } public int LinePosition { get; } public string? Path { get; } public JsonReaderException() { } public JsonReaderException(string message) : base(message) { } public JsonReaderException(string message, Exception innerException) : base(message, innerException) { } public JsonReaderException(SerializationInfo info, StreamingContext context) : base(info, context) { } public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonReaderException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonReaderException(message, path, lineNumber, linePosition, ex); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonRequiredAttribute : Attribute { } [Serializable] public class JsonSerializationException : JsonException { public int LineNumber { get; } public int LinePosition { get; } public string? Path { get; } public JsonSerializationException() { } public JsonSerializationException(string message) : base(message) { } public JsonSerializationException(string message, Exception innerException) : base(message, innerException) { } public JsonSerializationException(SerializationInfo info, StreamingContext context) : base(info, context) { } public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonSerializationException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonSerializationException(message, path, lineNumber, linePosition, ex); } } public class JsonSerializer { internal TypeNameHandling _typeNameHandling; internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling; internal PreserveReferencesHandling _preserveReferencesHandling; internal ReferenceLoopHandling _referenceLoopHandling; internal MissingMemberHandling _missingMemberHandling; internal ObjectCreationHandling _objectCreationHandling; internal NullValueHandling _nullValueHandling; internal DefaultValueHandling _defaultValueHandling; internal ConstructorHandling _constructorHandling; internal MetadataPropertyHandling _metadataPropertyHandling; internal JsonConverterCollection? _converters; internal IContractResolver _contractResolver; internal ITraceWriter? _traceWriter; internal IEqualityComparer? _equalityComparer; internal ISerializationBinder _serializationBinder; internal StreamingContext _context; private IReferenceResolver? _referenceResolver; private Formatting? _formatting; private DateFormatHandling? _dateFormatHandling; private DateTimeZoneHandling? _dateTimeZoneHandling; private DateParseHandling? _dateParseHandling; private FloatFormatHandling? _floatFormatHandling; private FloatParseHandling? _floatParseHandling; private StringEscapeHandling? _stringEscapeHandling; private CultureInfo _culture; private int? _maxDepth; private bool _maxDepthSet; private bool? _checkAdditionalContent; private string? _dateFormatString; private bool _dateFormatStringSet; public virtual IReferenceResolver? ReferenceResolver { get { return GetReferenceResolver(); } set { if (value == null) { throw new ArgumentNullException("value", "Reference resolver cannot be null."); } _referenceResolver = value; } } [Obsolete("Binder is obsolete. Use SerializationBinder instead.")] public virtual SerializationBinder Binder { get { if (_serializationBinder is SerializationBinder result) { return result; } if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter) { return serializationBinderAdapter.SerializationBinder; } throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set."); } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value); } } public virtual ISerializationBinder SerializationBinder { get { return _serializationBinder; } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _serializationBinder = value; } } public virtual ITraceWriter? TraceWriter { get { return _traceWriter; } set { _traceWriter = value; } } public virtual IEqualityComparer? EqualityComparer { get { return _equalityComparer; } set { _equalityComparer = value; } } public virtual TypeNameHandling TypeNameHandling { get { return _typeNameHandling; } set { if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) { throw new ArgumentOutOfRangeException("value"); } _typeNameHandling = value; } } [Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")] public virtual FormatterAssemblyStyle TypeNameAssemblyFormat { get { return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling; } set { if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value; } } public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling { get { return _typeNameAssemblyFormatHandling; } set { if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormatHandling = value; } } public virtual PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling; } set { if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) { throw new ArgumentOutOfRangeException("value"); } _preserveReferencesHandling = value; } } public virtual ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling; } set { if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) { throw new ArgumentOutOfRangeException("value"); } _referenceLoopHandling = value; } } public virtual MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling; } set { if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) { throw new ArgumentOutOfRangeException("value"); } _missingMemberHandling = value; } } public virtual NullValueHandling NullValueHandling { get { return _nullValueHandling; } set { if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _nullValueHandling = value; } } public virtual DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling; } set { if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) { throw new ArgumentOutOfRangeException("value"); } _defaultValueHandling = value; } } public virtual ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling; } set { if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) { throw new ArgumentOutOfRangeException("value"); } _objectCreationHandling = value; } } public virtual ConstructorHandling ConstructorHandling { get { return _constructorHandling; } set { if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) { throw new ArgumentOutOfRangeException("value"); } _constructorHandling = value; } } public virtual MetadataPropertyHandling MetadataPropertyHandling { get { return _metadataPropertyHandling; } set { if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _metadataPropertyHandling = value; } } public virtual JsonConverterCollection Converters { get { if (_converters == null) { _converters = new JsonConverterCollection(); } return _converters; } } public virtual IContractResolver ContractResolver { get { return _contractResolver; } set { _contractResolver = value ?? DefaultContractResolver.Instance; } } public virtual StreamingContext Context { get { return _context; } set { _context = value; } } public virtual Formatting Formatting { get { return _formatting.GetValueOrDefault(); } set { _formatting = value; } } public virtual DateFormatHandling DateFormatHandling { get { return _dateFormatHandling.GetValueOrDefault(); } set { _dateFormatHandling = value; } } public virtual DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind; } set { _dateTimeZoneHandling = value; } } public virtual DateParseHandling DateParseHandling { get { return _dateParseHandling ?? DateParseHandling.DateTime; } set { _dateParseHandling = value; } } public virtual FloatParseHandling FloatParseHandling { get { return _floatParseHandling.GetValueOrDefault(); } set { _floatParseHandling = value; } } public virtual FloatFormatHandling FloatFormatHandling { get { return _floatFormatHandling.GetValueOrDefault(); } set { _floatFormatHandling = value; } } public virtual StringEscapeHandling StringEscapeHandling { get { return _stringEscapeHandling.GetValueOrDefault(); } set { _stringEscapeHandling = value; } } public virtual string DateFormatString { get { return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; } set { _dateFormatString = value; _dateFormatStringSet = true; } } public virtual CultureInfo Culture { get { return _culture ?? JsonSerializerSettings.DefaultCulture; } set { _culture = value; } } public virtual int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; _maxDepthSet = true; } } public virtual bool CheckAdditionalContent { get { return _checkAdditionalContent.GetValueOrDefault(); } set { _checkAdditionalContent = value; } } public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error; internal bool IsCheckAdditionalContentSet() { return _checkAdditionalContent.HasValue; } public JsonSerializer() { _referenceLoopHandling = ReferenceLoopHandling.Error; _missingMemberHandling = MissingMemberHandling.Ignore; _nullValueHandling = NullValueHandling.Include; _defaultValueHandling = DefaultValueHandling.Include; _objectCreationHandling = ObjectCreationHandling.Auto; _preserveReferencesHandling = PreserveReferencesHandling.None; _constructorHandling = ConstructorHandling.Default; _typeNameHandling = TypeNameHandling.None; _metadataPropertyHandling = MetadataPropertyHandling.Default; _context = JsonSerializerSettings.DefaultContext; _serializationBinder = DefaultSerializationBinder.Instance; _culture = JsonSerializerSettings.DefaultCulture; _contractResolver = DefaultContractResolver.Instance; } public static JsonSerializer Create() { return new JsonSerializer(); } public static JsonSerializer Create(JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = Create(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } public static JsonSerializer CreateDefault() { return Create(JsonConvert.DefaultSettings?.Invoke()); } public static JsonSerializer CreateDefault(JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = CreateDefault(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings) { if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) { for (int i = 0; i < settings.Converters.Count; i++) { serializer.Converters.Insert(i, settings.Converters[i]); } } if (settings._typeNameHandling.HasValue) { serializer.TypeNameHandling = settings.TypeNameHandling; } if (settings._metadataPropertyHandling.HasValue) { serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling; } if (settings._typeNameAssemblyFormatHandling.HasValue) { serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling; } if (settings._preserveReferencesHandling.HasValue) { serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; } if (settings._referenceLoopHandling.HasValue) { serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; } if (settings._missingMemberHandling.HasValue) { serializer.MissingMemberHandling = settings.MissingMemberHandling; } if (settings._objectCreationHandling.HasValue) { serializer.ObjectCreationHandling = settings.ObjectCreationHandling; } if (settings._nullValueHandling.HasValue) { serializer.NullValueHandling = settings.NullValueHandling; } if (settings._defaultValueHandling.HasValue) { serializer.DefaultValueHandling = settings.DefaultValueHandling; } if (settings._constructorHandling.HasValue) { serializer.ConstructorHandling = settings.ConstructorHandling; } if (settings._context.HasValue) { serializer.Context = settings.Context; } if (settings._checkAdditionalContent.HasValue) { serializer._checkAdditionalContent = settings._checkAdditionalContent; } if (settings.Error != null) { serializer.Error += settings.Error; } if (settings.ContractResolver != null) { serializer.ContractResolver = settings.ContractResolver; } if (settings.ReferenceResolverProvider != null) { serializer.ReferenceResolver = settings.ReferenceResolverProvider(); } if (settings.TraceWriter != null) { serializer.TraceWriter = settings.TraceWriter; } if (settings.EqualityComparer != null) { serializer.EqualityComparer = settings.EqualityComparer; } if (settings.SerializationBinder != null) { serializer.SerializationBinder = settings.SerializationBinder; } if (settings._formatting.HasValue) { serializer._formatting = settings._formatting; } if (settings._dateFormatHandling.HasValue) { serializer._dateFormatHandling = settings._dateFormatHandling; } if (settings._dateTimeZoneHandling.HasValue) { serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling; } if (settings._dateParseHandling.HasValue) { serializer._dateParseHandling = settings._dateParseHandling; } if (settings._dateFormatStringSet) { serializer._dateFormatString = settings._dateFormatString; serializer._dateFormatStringSet = settings._dateFormatStringSet; } if (settings._floatFormatHandling.HasValue) { serializer._floatFormatHandling = settings._floatFormatHandling; } if (settings._floatParseHandling.HasValue) { serializer._floatParseHandling = settings._floatParseHandling; } if (settings._stringEscapeHandling.HasValue) { serializer._stringEscapeHandling = settings._stringEscapeHandling; } if (settings._culture != null) { serializer._culture = settings._culture; } if (settings._maxDepthSet) { serializer._maxDepth = settings._maxDepth; serializer._maxDepthSet = settings._maxDepthSet; } } [DebuggerStepThrough] public void Populate(TextReader reader, object target) { Populate(new JsonTextReader(reader), target); } [DebuggerStepThrough] public void Populate(JsonReader reader, object target) { PopulateInternal(reader, target); } internal virtual void PopulateInternal(JsonReader reader, object target) { ValidationUtils.ArgumentNotNull(reader, "reader"); ValidationUtils.ArgumentNotNull(target, "target"); SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null); new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); } [DebuggerStepThrough] public object? Deserialize(JsonReader reader) { return Deserialize(reader, null); } [DebuggerStepThrough] public object? Deserialize(TextReader reader, Type objectType) { return Deserialize(new JsonTextReader(reader), objectType); } [DebuggerStepThrough] public T? Deserialize<T>(JsonReader reader) { return (T)Deserialize(reader, typeof(T)); } [DebuggerStepThrough] public object? Deserialize(JsonReader reader, Type? objectType) { return DeserializeInternal(reader, objectType); } internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType) { ValidationUtils.ArgumentNotNull(reader, "reader"); SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null); object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); return result; } private void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString) { if (_culture != null && !_culture.Equals(reader.Culture)) { previousCulture = reader.Culture; reader.Culture = _culture; } else { previousCulture = null; } if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling) { previousDateTimeZoneHandling = reader.DateTimeZoneHandling; reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } else { previousDateTimeZoneHandling = null; } if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling) { previousDateParseHandling = reader.DateParseHandling; reader.DateParseHandling = _dateParseHandling.GetValueOrDefault(); } else { previousDateParseHandling = null; } if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling) { previousFloatParseHandling = reader.FloatParseHandling; reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault(); } else { previousFloatParseHandling = null; } if (_maxDepthSet && reader.MaxDepth != _maxDepth) { previousMaxDepth = reader.MaxDepth; reader.MaxDepth = _maxDepth; } else { previousMaxDepth = null; } if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString) { previousDateFormatString = reader.DateFormatString; reader.DateFormatString = _dateFormatString; } else { previousDateFormatString = null; } if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver) { jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable(); } } private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString) { if (previousCulture != null) { reader.Culture = previousCulture; } if (previousDateTimeZoneHandling.HasValue) { reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault(); } if (previousDateParseHandling.HasValue) { reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault(); } if (previousFloatParseHandling.HasValue) { reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault(); } if (_maxDepthSet) { reader.MaxDepth = previousMaxDepth; } if (_dateFormatStringSet) { reader.DateFormatString = previousDateFormatString; } if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable()) { jsonTextReader.PropertyNameTable = null; } } public void Serialize(TextWriter textWriter, object? value) { Serialize(new JsonTextWriter(textWriter), value); } public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType) { SerializeInternal(jsonWriter, value, objectType); } public void Serialize(TextWriter textWriter, object? value, Type objectType) { Serialize(new JsonTextWriter(textWriter), value, objectType); } public void Serialize(JsonWriter jsonWriter, object? value) { SerializeInternal(jsonWriter, value, null); } private TraceJsonReader CreateTraceJsonReader(JsonReader reader) { TraceJsonReader traceJsonReader = new TraceJsonReader(reader); if (reader.TokenType != 0) { traceJsonReader.WriteCurrentToken(); } return traceJsonReader; } internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType) { ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); Formatting? formatting = null; if (_formatting.HasValue && jsonWriter.Formatting != _formatting) { formatting = jsonWriter.Formatting; jsonWriter.Formatting = _formatting.GetValueOrDefault(); } DateFormatHandling? dateFormatHandling = null; if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling) { dateFormatHandling = jsonWriter.DateFormatHandling; jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault(); } DateTimeZoneHandling? dateTimeZoneHandling = null; if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling) { dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling; jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } FloatFormatHandling? floatFormatHandling = null; if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling) { floatFormatHandling = jsonWriter.FloatFormatHandling; jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault(); } StringEscapeHandling? stringEscapeHandling = null; if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling) { stringEscapeHandling = jsonWriter.StringEscapeHandling; jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault(); } CultureInfo cultureInfo = null; if (_culture != null && !_culture.Equals(jsonWriter.Culture)) { cultureInfo = jsonWriter.Culture; jsonWriter.Culture = _culture; } string dateFormatString = null; if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString) { dateFormatString = jsonWriter.DateFormatString; jsonWriter.DateFormatString = _dateFormatString; } TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null); new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType); if (traceJsonWriter != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null); } if (formatting.HasValue) { jsonWriter.Formatting = formatting.GetValueOrDefault(); } if (dateFormatHandling.HasValue) { jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault(); } if (dateTimeZoneHandling.HasValue) { jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault(); } if (floatFormatHandling.HasValue) { jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault(); } if (stringEscapeHandling.HasValue) { jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault(); } if (_dateFormatStringSet) { jsonWriter.DateFormatString = dateFormatString; } if (cultureInfo != null) { jsonWriter.Culture = cultureInfo; } } internal IReferenceResolver GetReferenceResolver() { if (_referenceResolver == null) { _referenceResolver = new DefaultReferenceResolver(); } return _referenceResolver; } internal JsonConverter? GetMatchingConverter(Type type) { return GetMatchingConverter(_converters, type); } internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType) { if (converters != null) { for (int i = 0; i < converters.Count; i++) { JsonConverter jsonConverter = converters[i]; if (jsonConverter.CanConvert(objectType)) { return jsonConverter; } } } return null; } internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e) { this.Error?.Invoke(this, e); } } public class JsonSerializerSettings { internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error; internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore; internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include; internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include; internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto; internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default; internal static readonly StreamingContext DefaultContext; internal const Formatting DefaultFormatting = Formatting.None; internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat; internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime; internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double; internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String; internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default; internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple; internal static readonly CultureInfo DefaultCulture; internal const bool DefaultCheckAdditionalContent = false; internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; internal const int DefaultMaxDepth = 64; internal Formatting? _formatting; internal DateFormatHandling? _dateFormatHandling; internal DateTimeZoneHandling? _dateTimeZoneHandling; internal DateParseHandling? _dateParseHandling; internal FloatFormatHandling? _floatFormatHandling; internal FloatParseHandling? _floatParseHandling; internal StringEscapeHandling? _stringEscapeHandling; internal CultureInfo? _culture; internal bool? _checkAdditionalContent; internal int? _maxDepth; internal bool _maxDepthSet; internal string? _dateFormatString; internal bool _dateFormatStringSet; internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling; internal DefaultValueHandling? _defaultValueHandling; internal PreserveReferencesHandling? _preserveReferencesHandling; internal NullValueHandling? _nullValueHandling; internal ObjectCreationHandling? _objectCreationHandling; internal MissingMemberHandling? _missingMemberHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal StreamingContext? _context; internal ConstructorHandling? _constructorHandling; internal TypeNameHandling? _typeNameHandling; internal MetadataPropertyHandling? _metadataPropertyHandling; public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling.GetValueOrDefault(); } set { _referenceLoopHandling = value; } } public MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling.GetValueOrDefault(); } set { _missingMemberHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling.GetValueOrDefault(); } set { _objectCreationHandling = value; } } public NullValueHandling NullValueHandling { get { return _nullValueHandling.GetValueOrDefault(); } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling.GetValueOrDefault(); } set { _defaultValueHandling = value; } } public IList<JsonConverter> Converters { get; set; } public PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling.GetValueOrDefault(); } set { _preserveReferencesHandling = value; } } public TypeNameHandling TypeNameHandling
BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/XUnity.AutoTranslator.Plugin.ExtProtocol.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("gravydevsupreme")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Package that contains a simple inter-process protocol format used in XUnity.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.ExtProtocol")] [assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.ExtProtocol")] [assembly: AssemblyVersion("1.0.1.0")] namespace XUnity.AutoTranslator.Plugin.ExtProtocol; public class ConfigurationMessage : ProtocolMessage { public static readonly string Type = "4"; public string Config { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); Config = reader.ReadToEnd(); } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.Write(Config); } } public static class ExtProtocolConvert { private static readonly Dictionary<string, Type> IdToType; private static readonly Dictionary<Type, string> TypeToId; static ExtProtocolConvert() { IdToType = new Dictionary<string, Type>(); TypeToId = new Dictionary<Type, string>(); Register(TranslationRequest.Type, typeof(TranslationRequest)); Register(TranslationResponse.Type, typeof(TranslationResponse)); Register(TranslationError.Type, typeof(TranslationError)); Register(ConfigurationMessage.Type, typeof(ConfigurationMessage)); } public static void Register(string id, Type type) { IdToType[id] = type; TypeToId[type] = id; } public static string Encode(ProtocolMessage message) { StringWriter stringWriter = new StringWriter(); string value = TypeToId[message.GetType()]; stringWriter.WriteLine(value); message.Encode(stringWriter); return Convert.ToBase64String(Encoding.UTF8.GetBytes(stringWriter.ToString()), Base64FormattingOptions.None); } public static ProtocolMessage Decode(string message) { StringReader stringReader = new StringReader(Encoding.UTF8.GetString(Convert.FromBase64String(message))); string key = stringReader.ReadLine(); ProtocolMessage obj = (ProtocolMessage)Activator.CreateInstance(IdToType[key]); obj.Decode(stringReader); return obj; } } public abstract class ProtocolMessage { public Guid Id { get; set; } internal abstract void Decode(TextReader reader); internal abstract void Encode(TextWriter writer); } public enum StatusCode { OK = 0, Blocked = 1, Unknown = 1000 } public class TranslationError : ProtocolMessage { public static readonly string Type = "3"; public string Reason { get; set; } public StatusCode FailureCode { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); FailureCode = (StatusCode)int.Parse(reader.ReadLine()); Reason = reader.ReadToEnd(); } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.WriteLine((int)FailureCode); writer.Write(Reason); } } public class TranslationRequest : ProtocolMessage { public static readonly string Type = "1"; private string[] _untranslatedTexts; public string SourceLanguage { get; set; } public string DestinationLanguage { get; set; } public string[] UntranslatedTexts => _untranslatedTexts ?? (_untranslatedTexts = UntranslatedTextInfos.Select((TransmittableUntranslatedTextInfo x) => x.UntranslatedText).ToArray()); public TransmittableUntranslatedTextInfo[] UntranslatedTextInfos { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); SourceLanguage = reader.ReadLine(); DestinationLanguage = reader.ReadLine(); int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); TransmittableUntranslatedTextInfo[] array = new TransmittableUntranslatedTextInfo[num]; for (int i = 0; i < num; i++) { TransmittableUntranslatedTextInfo transmittableUntranslatedTextInfo = new TransmittableUntranslatedTextInfo(); transmittableUntranslatedTextInfo.Decode(reader); array[i] = transmittableUntranslatedTextInfo; } UntranslatedTextInfos = array; } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.WriteLine(SourceLanguage); writer.WriteLine(DestinationLanguage); writer.WriteLine(UntranslatedTextInfos.Length.ToString(CultureInfo.InvariantCulture)); TransmittableUntranslatedTextInfo[] untranslatedTextInfos = UntranslatedTextInfos; for (int i = 0; i < untranslatedTextInfos.Length; i++) { untranslatedTextInfos[i].Encode(writer); } } } public class TranslationResponse : ProtocolMessage { public static readonly string Type = "2"; public string[] TranslatedTexts { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); string[] array = new string[num]; for (int i = 0; i < num; i++) { string s = reader.ReadLine(); string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s)); array[i] = @string; } TranslatedTexts = array; } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.WriteLine(TranslatedTexts.Length.ToString(CultureInfo.InvariantCulture)); string[] translatedTexts = TranslatedTexts; foreach (string s in translatedTexts) { string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None); writer.WriteLine(value); } } } public class TransmittableUntranslatedTextInfo { public string[] ContextBefore { get; set; } public string UntranslatedText { get; set; } public string[] ContextAfter { get; set; } public TransmittableUntranslatedTextInfo(string[] contextBefore, string untranslatedText, string[] contextAfter) { ContextBefore = contextBefore; UntranslatedText = untranslatedText; ContextAfter = contextAfter; } public TransmittableUntranslatedTextInfo() { } internal void Encode(TextWriter writer) { string[] contextBefore = ContextBefore; writer.WriteLine(((contextBefore != null) ? contextBefore.Length : 0).ToString(CultureInfo.InvariantCulture)); if (ContextBefore != null) { string[] contextBefore2 = ContextBefore; foreach (string s in contextBefore2) { string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None); writer.WriteLine(value); } } string[] contextAfter = ContextAfter; writer.WriteLine(((contextAfter != null) ? contextAfter.Length : 0).ToString(CultureInfo.InvariantCulture)); if (ContextAfter != null) { string[] contextBefore2 = ContextAfter; foreach (string s2 in contextBefore2) { string value2 = Convert.ToBase64String(Encoding.UTF8.GetBytes(s2), Base64FormattingOptions.None); writer.WriteLine(value2); } } string value3 = Convert.ToBase64String(Encoding.UTF8.GetBytes(UntranslatedText), Base64FormattingOptions.None); writer.WriteLine(value3); } internal void Decode(TextReader reader) { int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); string[] array = new string[num]; for (int i = 0; i < num; i++) { string s = reader.ReadLine(); string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s)); array[i] = @string; } ContextBefore = array; int num2 = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); string[] array2 = new string[num2]; for (int j = 0; j < num2; j++) { string s2 = reader.ReadLine(); string string2 = Encoding.UTF8.GetString(Convert.FromBase64String(s2)); array2[j] = string2; } ContextAfter = array2; string s3 = reader.ReadLine(); string string3 = Encoding.UTF8.GetString(Convert.FromBase64String(s3)); UntranslatedText = string3; } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/GoogleTranslate.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core; using XUnity.AutoTranslator.Plugin.Core.Constants; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Extensions; using XUnity.AutoTranslator.Plugin.Core.Shims; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; using XUnity.Common.Extensions; using XUnity.Common.Logging; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("GoogleTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GoogleTranslate")] [assembly: AssemblyTitle("GoogleTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace GoogleTranslate; public class GoogleTranslateEndpoint : HttpEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "auto", "romaji", "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz", "vi", "cy", "xh", "yi", "yo", "zu" }; private static readonly string DefaultApiBackend = "https://translate.googleapis.com"; private static readonly string DefaultUserBackend = "https://translate.google.com"; private static readonly string HttpsServicePointTranslateTemplateUrl = "/translate_a/single?client=webapp&sl={0}&tl={1}&dt=t&tk={2}&q={3}"; private static readonly string HttpsServicePointRomanizeTemplateUrl = "/translate_a/single?client=webapp&sl={0}&tl=en&dt=rm&tk={1}&q={2}"; private static readonly Random RandomNumbers = new Random(); private static readonly string[] Accepts = new string[3] { null, "*/*", "application/json" }; private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" }; private static readonly string[] AcceptCharsets = new string[2] { null, Encoding.UTF8.WebName }; private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)]; private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)]; private static readonly string AcceptCharset = AcceptCharsets[RandomNumbers.Next(AcceptCharsets.Length)]; private string _selectedApiBackend; private string _selectedUserBackend; private string _httpsServicePointTranslateTemplateUrl; private string _httpsServicePointRomanizeTemplateUrl; private CookieContainer _cookieContainer; private bool _hasSetup; private long m = 427761L; private long s = 1179739010L; private int _translationsPerRequest = 10; private int _translationCount; private int _resetAfter = RandomNumbers.Next(75, 125); public override string Id => "GoogleTranslate"; public override string FriendlyName => "Google! Translate"; public override int MaxTranslationsPerRequest => _translationsPerRequest; public GoogleTranslateEndpoint() { _cookieContainer = new CookieContainer(); } private string FixLanguage(string lang) { switch (lang) { case "zh-Hans": case "zh": return "zh-CN"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (context.DestinationLanguage == "romaji") { _translationsPerRequest = 1; } _selectedApiBackend = DefaultApiBackend; _selectedUserBackend = DefaultUserBackend; string orCreateSetting = context.GetOrCreateSetting<string>("Google", "ServiceUrl"); if (!StringExtensions.IsNullOrWhiteSpace(orCreateSetting)) { _selectedApiBackend = orCreateSetting; _selectedUserBackend = orCreateSetting; _httpsServicePointTranslateTemplateUrl = _selectedApiBackend + HttpsServicePointTranslateTemplateUrl; _httpsServicePointRomanizeTemplateUrl = _selectedApiBackend + HttpsServicePointRomanizeTemplateUrl; XuaLogger.AutoTranslator.Info("The default backend for google translate was overwritten."); } else { _selectedApiBackend = DefaultApiBackend; _selectedUserBackend = DefaultUserBackend; _httpsServicePointTranslateTemplateUrl = _selectedApiBackend + HttpsServicePointTranslateTemplateUrl; _httpsServicePointRomanizeTemplateUrl = _selectedApiBackend + HttpsServicePointRomanizeTemplateUrl; } context.DisableCertificateChecksFor(new string[2] { new Uri(_selectedApiBackend).Host, new Uri(_selectedUserBackend).Host }); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context) { if (!_hasSetup || _translationCount % _resetAfter == 0) { _resetAfter = RandomNumbers.Next(75, 125); _translationCount = 1; _hasSetup = true; IEnumerator enumerator = SetupTKK(); while (enumerator.MoveNext()) { yield return enumerator.Current; } } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown _translationCount++; string text = string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts); XUnityWebRequest val = ((!(((ITranslationContextBase)context).DestinationLanguage == "romaji")) ? new XUnityWebRequest(string.Format(_httpsServicePointTranslateTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), Tk(text), Uri.EscapeDataString(text))) : new XUnityWebRequest(string.Format(_httpsServicePointRomanizeTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), Tk(text), Uri.EscapeDataString(text)))); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: true); context.Complete(val); } public override void OnInspectResponse(IHttpResponseInspectionContext context) { InspectResponse(context.Response); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) bool flag = ((ITranslationContextBase)context).DestinationLanguage == "romaji"; int num = (flag ? 3 : 0); string data = ((IHttpResponseInspectionContext)context).Response.Data; JSONNode val = JSON.Parse(data); StringBuilder stringBuilder = new StringBuilder(data.Length); val = ((JSONNode)val.AsArray)[0]; if (val.IsNull && flag) { context.Complete(((ITranslationContextBase)context).UntranslatedText); return; } Enumerator enumerator = ((JSONNode)val.AsArray).GetEnumerator(); while (((Enumerator)(ref enumerator)).MoveNext()) { string text = ((object)((JSONNode)JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsArray)[num]).ToString(); text = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder)) { stringBuilder.Append('\n'); } stringBuilder.Append(text); } string text2 = stringBuilder.ToString(); if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1) { context.Complete(text2); return; } string[] array = text2.Split(new char[1] { '\n' }); List<string> list = new List<string>(); int num2 = 0; string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts; for (int i = 0; i < untranslatedTexts.Length; i++) { int num3 = untranslatedTexts[i].Split(new char[1] { '\n' }).Length; string text3 = string.Empty; for (int j = 0; j < num3; j++) { if (num2 >= array.Length) { ((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations."); } string text4 = array[num2++]; text3 += text4; if (j != num3 - 1) { text3 += "\n"; } } list.Add(text3); } if (num2 != array.Length) { ((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations."); } context.Complete(list.ToArray()); } private XUnityWebRequest CreateWebSiteRequest() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown XUnityWebRequest val = new XUnityWebRequest(_selectedUserBackend); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: false); return val; } private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest) { request.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent); if (AcceptLanguage != null) { request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage; } if (Accept != null) { request.Headers[HttpRequestHeader.Accept] = Accept; } if (isTranslationRequest) { request.Headers[HttpRequestHeader.Referer] = _selectedUserBackend + "/"; } if (AcceptCharset != null) { request.Headers[HttpRequestHeader.AcceptCharset] = AcceptCharset; } } private void InspectResponse(XUnityWebResponse response) { CookieCollection newCookies = response.NewCookies; if (newCookies == null) { return; } foreach (Cookie item in newCookies) { item.Domain = ".googleapis.com"; } _cookieContainer.Add(newCookies); } public IEnumerator SetupTKK() { _cookieContainer = new CookieContainer(); XUnityWebResponse response; try { XUnityWebClient val = new XUnityWebClient(); XUnityWebRequest val2 = CreateWebSiteRequest(); response = val.Send(val2); } catch (Exception ex) { XuaLogger.AutoTranslator.Warn(ex, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead."); yield break; } IEnumerator iterator = ((CustomYieldInstructionShim)response).GetSupportedEnumerator(); while (iterator.MoveNext()) { yield return iterator.Current; } if (((CustomYieldInstructionShim)response).IsTimedOut) { XuaLogger.AutoTranslator.Warn("A timeout error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead."); yield break; } if (response.Error != null) { XuaLogger.AutoTranslator.Warn(response.Error, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead."); yield break; } if (response.Data == null) { XuaLogger.AutoTranslator.Warn((Exception)null, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead."); yield break; } InspectResponse(response); try { string data = response.Data; bool flag = false; string[] array = new string[2] { "tkk:'", "TKK='" }; foreach (string text in array) { int num = data.IndexOf(text); if (num > -1) { int num2 = num + text.Length; int num3 = data.IndexOf("'", num2); string[] array2 = data.Substring(num2, num3 - num2).Split(new char[1] { '.' }); if (array2.Length == 2) { m = long.Parse(array2[0]); s = long.Parse(array2[1]); flag = true; break; } } } if (!flag) { XuaLogger.AutoTranslator.Warn("An error occurred while setting up GoogleTranslate TKK. Could not locate TKK value. Using fallback TKK values instead."); } } catch (Exception ex2) { XuaLogger.AutoTranslator.Warn(ex2, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead."); } } private long Vi(long r, string o) { for (int i = 0; i < o.Length; i += 3) { long num = o[i + 2]; num = ((num >= 97) ? (num - 87) : (num - 48)); num = (('+' == o[i + 1]) ? (r >> (int)num) : (r << (int)num)); r = (('+' == o[i]) ? ((r + num) & 0xFFFFFFFFu) : (r ^ num)); } return r; } private string Tk(string r) { List<long> list = new List<long>(); for (int i = 0; i < r.Length; i++) { long num = r[i]; if (128 > num) { list.Add(num); continue; } if (2048 > num) { list.Add((num >> 6) | 0xC0); } else if (55296 == (0xFC00 & num) && i + 1 < r.Length && 56320 == (0xFC00 & r[i + 1])) { num = 65536 + ((0x3FF & num) << 10) + (0x3FF & r[++i]); list.Add((num >> 18) | 0xF0); list.Add(((num >> 12) & 0x3F) | 0x80); } else { list.Add((num >> 12) | 0xE0); list.Add(((num >> 6) & 0x3F) | 0x80); } list.Add((0x3F & num) | 0x80); } long num2 = m; for (int j = 0; j < list.Count; j++) { num2 += list[j]; num2 = Vi(num2, "+-a^+6"); } num2 = Vi(num2, "+-3^+b+-f"); num2 ^= s; if (0 > num2) { num2 = (0x7FFFFFFF & num2) + 2147483648u; } num2 %= 1000000; return num2.ToString(CultureInfo.InvariantCulture) + "." + (num2 ^ m).ToString(CultureInfo.InvariantCulture); } } public class GoogleTranslateEndpointV2 : HttpEndpoint { private static readonly char[] WordSplitters = new char[3] { ' ', '\r', '\n' }; private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "auto", "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz", "vi", "cy", "xh", "yi", "yo", "zu" }; private static readonly string DefaultUserBackend = "https://translate.google.com"; private static readonly string TranslationPostTemplate = "[[[\"{0}\",\"[[\\\"{1}\\\",\\\"{2}\\\",\\\"{3}\\\",true],[null]]\",null,\"generic\"]]]"; private static readonly string HttpsServicePointTranslateTemplateUrl = "/_/TranslateWebserverUi/data/batchexecute"; private static readonly Random RandomNumbers = new Random(); private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" }; private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)]; private string _selectedUserBackend; private string _httpsServicePointTranslateTemplateUrl; private CookieContainer _cookieContainer; private bool _hasSetup; private long _FSID = LongRandom(long.MinValue, long.MaxValue, RandomNumbers); private int _translationCount; private int _resetAfter = RandomNumbers.Next(75, 125); private string _translateRpcId; private string _version; private bool _useSimplestSuggestion; private long _reqId; public override string Id => "GoogleTranslateV2"; public override string FriendlyName => "Google! Translate (v2)"; public override int MaxTranslationsPerRequest => 10; public GoogleTranslateEndpointV2() { _cookieContainer = new CookieContainer(); } private static long LongRandom(long min, long max, Random rand) { byte[] array = new byte[8]; rand.NextBytes(array); return Math.Abs(BitConverter.ToInt64(array, 0) % (max - min)) + min; } private string FixLanguage(string lang) { switch (lang) { case "zh-Hans": case "zh": return "zh-CN"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) string orCreateSetting = context.GetOrCreateSetting<string>("GoogleV2", "ServiceUrl"); if (!StringExtensions.IsNullOrWhiteSpace(orCreateSetting)) { _selectedUserBackend = orCreateSetting; _httpsServicePointTranslateTemplateUrl = _selectedUserBackend + HttpsServicePointTranslateTemplateUrl; XuaLogger.AutoTranslator.Info("The default backend for google translate was overwritten."); } else { _selectedUserBackend = DefaultUserBackend; _httpsServicePointTranslateTemplateUrl = _selectedUserBackend + HttpsServicePointTranslateTemplateUrl; } _translateRpcId = context.GetOrCreateSetting<string>("GoogleV2", "RPCID", "MkEWBc"); _version = context.GetOrCreateSetting<string>("GoogleV2", "VERSION", "boq_translate-webserver_20210323.10_p0"); _useSimplestSuggestion = context.GetOrCreateSetting<bool>("GoogleV2", "UseSimplest", false); context.DisableCertificateChecksFor(new string[2] { new Uri(_selectedUserBackend).Host, new Uri(_selectedUserBackend).Host }); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context) { if (!_hasSetup || _translationCount % _resetAfter == 0) { _resetAfter = RandomNumbers.Next(75, 125); _translationCount = 1; _reqId = RandomNumbers.Next(0, 100000); _hasSetup = true; IEnumerator enumerator = SetupFSID(); while (enumerator.MoveNext()) { yield return enumerator.Current; } } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown _translationCount++; string text = JsonHelper.Escape(JsonHelper.Escape(string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts))); string text2 = string.Join("&", "rpcids=" + _translateRpcId, "f.sid=" + _FSID.ToString(CultureInfo.InvariantCulture), "bl=" + Uri.EscapeDataString(_version), "hl=en-US", "soc-app=1", "soc-platform=1", "soc-device=1", "_reqid=" + _reqId.ToString(CultureInfo.InvariantCulture), "rt=c"); string text3 = "f.req=" + Uri.EscapeDataString(string.Format(TranslationPostTemplate, _translateRpcId, text, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage))) + "&"; string text4 = _httpsServicePointTranslateTemplateUrl + "?" + text2; XUnityWebRequest val = new XUnityWebRequest("POST", text4, text3); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: true); _reqId += 100000L; context.Complete(val); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) string data = ((IHttpResponseInspectionContext)context).Response.Data; data = data.Substring(6); string text = data.Substring(0, data.IndexOf("\n")); int length = int.Parse(text, CultureInfo.InvariantCulture); data = data.Substring(text.Length, length); string text2 = ((object)((JSONNode)((JSONNode)JSON.Parse(data).AsArray)[0].AsArray)[2]).ToString(); string text3 = JsonHelper.Unescape(text2.Substring(1, text2.Length - 2)); JSONNode obj = ((JSONNode)((JSONNode)((JSONNode)((JSONNode)JSON.Parse(text3).AsArray)[1].AsArray)[0].AsArray)[0].AsArray)[5]; StringBuilder stringBuilder = new StringBuilder(text3.Length); Enumerator enumerator = ((JSONNode)obj.AsArray).GetEnumerator(); while (((Enumerator)(ref enumerator)).MoveNext()) { JSONArray asArray = JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsArray; string text4 = ((object)((JSONNode)asArray)[0]).ToString(); text4 = JsonHelper.Unescape(text4.Substring(1, text4.Length - 2)); if (StringExtensions.IsNullOrWhiteSpace(text4)) { continue; } if (_useSimplestSuggestion && ((JSONNode)asArray).Count > 1) { JSONNode obj2 = ((JSONNode)asArray)[1]; JSONArray val = ((obj2 != null) ? obj2.AsArray : null); if ((JSONNode)(object)val != (object)null) { HashSet<string> hashSet = new HashSet<string>(); hashSet.Add(text4); for (int i = 0; i < ((JSONNode)val).Count; i++) { string text5 = ((object)((JSONNode)val)[i]).ToString(); text5 = JsonHelper.Unescape(text5.Substring(1, text5.Length - 2)); hashSet.Add(text5); } if (hashSet.Count > 1) { XuaLogger.AutoTranslator.Debug("[GoogleTranslateV2]: Primary translation is '" + text4 + "', but found multiple suggestion:"); foreach (string item in hashSet) { XuaLogger.AutoTranslator.Debug("[GoogleTranslateV2]: " + item); } int wordsInPrimary = text4.Split(WordSplitters).Length; text4 = (from x in hashSet where x.Split(WordSplitters).Length < wordsInPrimary orderby x.Split(WordSplitters).Length select x).FirstOrDefault() ?? text4; XuaLogger.AutoTranslator.Debug("[GoogleTranslateV2]: Selecting translation: " + text4); } } } if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder)) { stringBuilder.Append('\n'); } stringBuilder.Append(text4); } string text6 = stringBuilder.ToString(); if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1) { context.Complete(text6); return; } string[] array = text6.Split(new char[1] { '\n' }); List<string> list = new List<string>(); int num = 0; string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts; for (int j = 0; j < untranslatedTexts.Length; j++) { int num2 = untranslatedTexts[j].Split(new char[1] { '\n' }).Length; string text7 = string.Empty; for (int k = 0; k < num2; k++) { if (num >= array.Length) { ((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations."); } string text8 = array[num++]; text7 += text8; if (k != num2 - 1) { text7 += "\n"; } } list.Add(text7); } if (num != array.Length) { ((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations."); } context.Complete(list.ToArray()); } private XUnityWebRequest CreateWebSiteRequest() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown XUnityWebRequest val = new XUnityWebRequest(_selectedUserBackend); val.Cookies = _cookieContainer; AddHeaders(val, isTranslationRequest: false); return val; } private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest) { request.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent); if (AcceptLanguage != null) { request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage; } if (isTranslationRequest) { request.Headers[HttpRequestHeader.Referer] = _selectedUserBackend + "/"; request.Headers["X-Same-Domain"] = "1"; request.Headers["DNT"] = "1"; request.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded;charset=UTF-8"; request.Headers[HttpRequestHeader.Accept] = "*/*"; request.Headers["Origin"] = _selectedUserBackend; } else { request.Headers["Upgrade-Insecure-Requests"] = "1"; } } public IEnumerator SetupFSID() { _cookieContainer = new CookieContainer(); XUnityWebResponse response; try { XUnityWebClient val = new XUnityWebClient(); XUnityWebRequest val2 = CreateWebSiteRequest(); response = val.Send(val2); } catch (Exception ex) { XuaLogger.AutoTranslator.Warn(ex, "An error occurred while setting up GoogleTranslate FSID. Using random instead."); yield break; } IEnumerator iterator = ((CustomYieldInstructionShim)response).GetSupportedEnumerator(); while (iterator.MoveNext()) { yield return iterator.Current; } if (((CustomYieldInstructionShim)response).IsTimedOut) { XuaLogger.AutoTranslator.Warn("A timeout error occurred while setting up GoogleTranslate FSID. Using random instead."); yield break; } if (response.Error != null) { XuaLogger.AutoTranslator.Warn(response.Error, "An error occurred while setting up GoogleTranslate FSID. Using random instead."); yield break; } if (response.Data == null) { XuaLogger.AutoTranslator.Warn((Exception)null, "An error occurred while setting up GoogleTranslate FSID. Using random instead."); yield break; } try { string data = response.Data; bool flag = false; string[] array = new string[1] { "FdrFJe\":\"" }; foreach (string text in array) { int num = data.IndexOf(text); if (num > -1) { int num2 = num + text.Length; int num3 = data.IndexOf("\"", num2); string s = data.Substring(num2, num3 - num2); _FSID = long.Parse(s, CultureInfo.InvariantCulture); flag = true; break; } } if (!flag) { XuaLogger.AutoTranslator.Warn("An error occurred while setting up GoogleTranslate FSID. Could not locate FSID value. Using random instead."); } } catch (Exception ex2) { XuaLogger.AutoTranslator.Warn(ex2, "An error occurred while setting up GoogleTranslate FSID. Using random instead."); } } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/GoogleTranslateCompat.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("GoogleTranslateCompat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GoogleTranslateCompat")] [assembly: AssemblyTitle("GoogleTranslateCompat")] [assembly: AssemblyVersion("1.0.0.0")] namespace GoogleTranslateCompat; internal class GoogleTranslateCompatEndpoint : ExtProtocolEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "auto", "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz", "vi", "cy", "xh", "yi", "yo", "zu" }; public override string Id => "GoogleTranslateCompat"; public override string FriendlyName => "Google! Translate (Compat)"; public override int MaxConcurrency => 1; public override int MaxTranslationsPerRequest => 10; private string FixLanguage(string lang) { switch (lang) { case "zh-Hans": case "zh": return "zh-CN"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) ((ExtProtocolEndpoint)this).Initialize(context); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } ((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes("GoogleTranslateCompat.ExtProtocol.GoogleTranslateCompatTranslate, GoogleTranslateCompat.ExtProtocol")); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/GoogleTranslateLegitimate.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("GoogleTranslateLegitimate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GoogleTranslateLegitimate")] [assembly: AssemblyTitle("GoogleTranslateLegitimate")] [assembly: AssemblyVersion("1.0.0.0")] namespace GoogleTranslateLegitimate; internal class GoogleTranslateLegitimateEndpoint : HttpEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh", "zh-Hans", "zh-Hant", "zh-CN", "zh-TW", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz", "vi", "cy", "xh", "yi", "yo", "zu" }; private static readonly string HttpsServiceUrl = "https://translation.googleapis.com/language/translate/v2"; private string _key; public override string Id => "GoogleTranslateLegitimate"; public override string FriendlyName => "Google! Translate (Authenticated)"; public override int MaxTranslationsPerRequest => 10; private string FixLanguage(string lang) { switch (lang) { case "zh-Hans": case "zh": return "zh-CN"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) _key = context.GetOrCreateSetting<string>("GoogleLegitimate", "GoogleAPIKey", ""); if (string.IsNullOrEmpty(_key)) { throw new EndpointInitializationException("The GoogleTranslateLegitimate endpoint requires an API key which has not been provided."); } context.DisableCertificateChecksFor(new string[1] { "translation.googleapis.com" }); if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown StringBuilder stringBuilder = new StringBuilder(HttpsServiceUrl); stringBuilder.Append("?key=").Append(Uri.EscapeDataString(_key)); stringBuilder.Append("&source=").Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage)); stringBuilder.Append("&target=").Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage)); for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++) { string stringToEscape = ((ITranslationContextBase)context).UntranslatedTexts[i]; stringBuilder.Append("&q=").Append(Uri.EscapeDataString(stringToEscape)); } XUnityWebRequest val = new XUnityWebRequest("POST", stringBuilder.ToString()); context.Complete(val); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { JSONArray asArray = ((JSONNode)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsObject)["data"].AsObject)["translations"].AsArray; List<string> list = new List<string>(); for (int i = 0; i < ((JSONNode)asArray).Count; i++) { string text = ((object)((JSONNode)((JSONNode)asArray)[i].AsObject)["translatedText"]).ToString(); string item = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); list.Add(item); } context.Complete(list.ToArray()); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/LecPowerTranslator15.dll
Decompiled a year agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using Microsoft.Win32; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("LecPowerTranslator15")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LecPowerTranslator15")] [assembly: AssemblyTitle("LecPowerTranslator15")] [assembly: AssemblyVersion("1.0.0.0")] namespace LecPowerTranslator15; internal class LecPowerTranslator15Endpoint : ExtProtocolEndpoint { public override string Id => "LecPowerTranslator15"; public override string FriendlyName => "LEC Power Translator 15"; public override int MaxConcurrency => 1; public override int MaxTranslationsPerRequest => 50; public override void Initialize(IInitializationContext context) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) string defaultInstallationPath = GetDefaultInstallationPath(); string text = context.GetOrCreateSetting<string>("LecPowerTranslator15", "InstallationPath", defaultInstallationPath); if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(defaultInstallationPath)) { context.SetSetting<string>("LecPowerTranslator15", "InstallationPath", defaultInstallationPath); text = defaultInstallationPath; } if (string.IsNullOrEmpty(text)) { throw new EndpointInitializationException("The LecPowerTranslator15 requires the path to the installation folder."); } context.DisableSpamChecks(); string text2 = Path.Combine(context.TranslatorDirectory, Path.Combine("FullNET", "Lec.ExtProtocol.exe")); if (!File.Exists(text2)) { throw new EndpointInitializationException("Could not find any executable at '" + text2 + "'"); } ((ExtProtocolEndpoint)this).ExecutablePath = text2; ((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes(text)); if (context.SourceLanguage != "ja") { throw new EndpointInitializationException("Current implementation only supports japanese-to-english."); } if (context.DestinationLanguage != "en") { throw new EndpointInitializationException("Current implementation only supports japanese-to-english."); } } public static string GetDefaultInstallationPath() { try { string text = GetInstallationPathFromRegistry(); if (!string.IsNullOrEmpty(text)) { text = new DirectoryInfo(text).Parent.FullName; } return text ?? string.Empty; } catch { return string.Empty; } } public static string GetInstallationPathFromRegistry() { try { if (IntPtr.Size == 8) { return (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LogoMedia\\LEC Power Translator 15\\Configuration", "ApplicationPath", null); } return (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\LogoMedia\\LEC Power Translator 15\\Configuration", "ApplicationPath", null); } catch { return null; } } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/LingoCloudTranslate.dll
Decompiled a year agousing System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("LingoCloudTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LingoCloudTranslate")] [assembly: AssemblyTitle("LingoCloudTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace LingoCloudTranslate; internal class LingoCloudTranslateEndpoint : HttpEndpoint { private static readonly Dictionary<string, string> SupportedLanguages = new Dictionary<string, string> { { "en", "en" }, { "ja", "ja" }, { "jp", "ja" }, { "zh", "zh" }, { "zh-Hans", "zh" }, { "zh-CN", "zh" }, { "zh-Hant", "zh" }, { "zh-TW", "zh" } }; private static readonly string HttpServicePointTemplateUrl = "https://api.interpreter.caiyunai.com/v1/translator"; public string _token; public override string Id => "LingoCloudTranslate"; public override string FriendlyName => "CaiYun Translator"; private string FixLanguage(string lang) { if (SupportedLanguages.TryGetValue(lang, out var value)) { return value; } return lang; } public override void Initialize(IInitializationContext context) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) _token = context.GetOrCreateSetting<string>("LingoCloud", "LingoCloudToken", ""); if (string.IsNullOrEmpty(_token)) { throw new EndpointInitializationException("The LingoCloudTranslate endpoint requires an App Id which has not been provided."); } context.DisableCertificateChecksFor(new string[1] { "api.interpreter.caiyunai.com" }); if (!SupportedLanguages.ContainsKey(context.SourceLanguage)) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.ContainsKey(context.DestinationLanguage)) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown JSONObject val = new JSONObject(); string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts; foreach (string text in untranslatedTexts) { ((JSONNode)val)["source"].Add(JSONNode.op_Implicit(text)); } ((JSONNode)val)["trans_type"] = JSONNode.op_Implicit("auto2" + FixLanguage(((ITranslationContextBase)context).DestinationLanguage)); ((JSONNode)val)["request_id"] = JSONNode.op_Implicit("demo"); ((JSONNode)val)["detect"] = JSONNode.op_Implicit("true"); string text2 = ((object)val).ToString(); XUnityWebRequest val2 = new XUnityWebRequest("POST", HttpServicePointTemplateUrl, text2); val2.Headers[HttpRequestHeader.ContentType] = "application/json"; val2.Headers["X-Authorization"] = "token " + _token; context.Complete(val2); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { string text = ((object)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsObject)["target"]).ToString(); string text2 = JsonHelper.Unescape(text.Substring(2, text.Length - 4)); context.Complete(text2); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/PapagoTranslate.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core; using XUnity.AutoTranslator.Plugin.Core.Constants; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Shims; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; using XUnity.Common.Logging; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("PapagoTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PapagoTranslate")] [assembly: AssemblyTitle("PapagoTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace PapagoTranslate; public class PapagoTranslateEndpoint : HttpEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "en", "ko", "zh-CN", "zh-TW", "es", "fr", "ru", "vi", "th", "id", "de", "ja", "hi", "pt" }; private static readonly HashSet<string> SMTLanguages = new HashSet<string> { "hi", "pt" }; private static readonly string UrlBase = "https://papago.naver.com"; private static readonly string UrlN2MT = "/apis/n2mt/translate"; private static readonly string UrlNSMT = "/apis/nsmt/translate"; private static readonly string FormUrlEncodedTemplate = "deviceId={0}&locale=en&dict=false&honorific=false&instant=true&source={1}&target={2}&text={3}"; private static readonly Random RandomNumbers = new Random(); private static readonly Guid UUID = Guid.NewGuid(); private static readonly Regex PatternSource = new Regex("/vendors~main[^\"]+", RegexOptions.Singleline); private static readonly Regex PatternVersion = new Regex("v\\d\\.\\d\\.\\d_[^\"]+", RegexOptions.Singleline); private string _version; private bool _isSMT; private int _translationCount; private int _resetAfter; public override string Id => "PapagoTranslate"; public override string FriendlyName => "Papago Translator"; public override int MaxTranslationsPerRequest => 10; private string FixLanguage(string lang) { switch (lang) { case "zh-Hans": case "zh": return "zh-CN"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) context.DisableCertificateChecksFor(new string[1] { "papago.naver.com" }); string text = FixLanguage(context.SourceLanguage); string text2 = FixLanguage(context.DestinationLanguage); _isSMT = SMTLanguages.Contains(text) || SMTLanguages.Contains(text2); if (!SupportedLanguages.Contains(text2)) { throw new EndpointInitializationException("The language '" + context.DestinationLanguage + "' is not supported by Papago Translate."); } if (_isSMT && text != "en" && text2 != "en") { throw new EndpointInitializationException("Translation from '" + context.SourceLanguage + "' to '" + context.DestinationLanguage + "' is not supported by Papago Translate."); } } public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context) { if (_resetAfter == 0 || _translationCount % _resetAfter == 0) { _translationCount = 1; _resetAfter = RandomNumbers.Next(150, 200); IEnumerator enumerator = SetupVersion(); while (enumerator.MoveNext()) { yield return enumerator.Current; } } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown string text = Uri.EscapeDataString(string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts)); XUnityWebRequest val = new XUnityWebRequest("POST", UrlBase + (_isSMT ? UrlNSMT : UrlN2MT), string.Format(FormUrlEncodedTemplate, UUID, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), text)); DateTime utcNow = DateTime.UtcNow; DateTime minValue = DateTime.MinValue; double num = Math.Truncate(utcNow.Subtract(minValue.AddYears(1969)).TotalMilliseconds); byte[] bytes = Encoding.UTF8.GetBytes(_version); byte[] bytes2 = Encoding.UTF8.GetBytes($"{UUID}\n{val.Address}\n{num}"); string arg = Convert.ToBase64String(new HMACMD5(bytes).ComputeHash(bytes2)); val.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent); val.Headers["Authorization"] = $"PPG {UUID}:{arg}"; val.Headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"; val.Headers["Timestamp"] = num.ToString(); context.Complete(val); _translationCount++; } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { string text = ((object)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsObject)["translatedText"]).ToString(); string text2 = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1) { context.Complete(text2); return; } string[] array = text2.Split(new char[1] { '\n' }); string[] array2 = new string[((ITranslationContextBase)context).UntranslatedTexts.Length]; int num = 0; for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++) { string[] array3 = ((ITranslationContextBase)context).UntranslatedTexts[i].Split(new char[1] { '\n' }); StringBuilder stringBuilder = new StringBuilder(); for (int j = 0; j < array3.Length; j++) { string value = array[num++]; if (array3.Length - 1 == j) { stringBuilder.Append(value); } else { stringBuilder.AppendLine(value); } } array2[i] = stringBuilder.ToString(); } if (num != array.Length) { ((ITranslationContextBase)context).Fail("Received invalid number of translations in batch."); } context.Complete(array2); } private IEnumerator SetupVersion() { XUnityWebClient client = new XUnityWebClient(); XUnityWebResponse response2 = client.Send(new XUnityWebRequest(UrlBase)); IEnumerator iterator2 = ((CustomYieldInstructionShim)response2).GetSupportedEnumerator(); while (iterator2.MoveNext()) { yield return iterator2.Current; } Match match = PatternSource.Match(response2.Data); if (!match.Success) { XuaLogger.AutoTranslator.Warn("Could not parse papago page"); yield break; } string value = match.Value; response2 = client.Send(new XUnityWebRequest(UrlBase + value)); iterator2 = ((CustomYieldInstructionShim)response2).GetSupportedEnumerator(); while (iterator2.MoveNext()) { yield return iterator2.Current; } Match match2 = PatternVersion.Match(response2.Data); if (!match2.Success) { XuaLogger.AutoTranslator.Warn("Could not parse papago version"); yield break; } XuaLogger.AutoTranslator.Debug("Current papago version is " + match2.Value); _version = match2.Value; } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/WatsonTranslate.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Www; using XUnity.AutoTranslator.Plugin.Core.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("WatsonTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WatsonTranslate")] [assembly: AssemblyTitle("WatsonTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace WatsonTranslate; internal class WatsonTranslateEndpoint : WwwEndpoint { private static readonly HashSet<string> SupportedLanguagePairs = new HashSet<string> { "ar-en", "ca-es", "zh-en", "zh-TW-en", "cs-en", "da-en", "nl-en", "en-ar", "en-cs", "en-da", "en-de", "en-es", "en-fi", "en-fr", "en-hi", "en-it", "en-ja", "en-ko", "en-nb", "en-nl", "en-pl", "en-pt", "en-ru", "en-sv", "en-tr", "en-zh", "en-zh-TW", "fi-en", "fr-de", "fr-en", "fr-es", "de-en", "de-fr", "de-it", "hi-en", "hu-en", "it-de", "it-en", "ja-en", "ko-en", "nb-en", "pl-en", "pt-en", "ru-en", "es-ca", "es-en", "es-fr", "sv-en", "tr-en" }; private string _fullUrl; private string _url; private string _key; public override string Id => "WatsonTranslate"; public override string FriendlyName => "Watson Language Translator"; public override int MaxTranslationsPerRequest => 10; private string FixLanguage(string lang) { switch (lang) { case "zh-CN": case "zh-Hans": return "zh"; case "zh-Hant": return "zh-TW"; default: return lang; } } public override void Initialize(IInitializationContext context) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) _url = context.GetOrCreateSetting<string>("Watson", "Url", ""); _key = context.GetOrCreateSetting<string>("Watson", "Key", ""); if (string.IsNullOrEmpty(_url)) { throw new EndpointInitializationException("The WatsonTranslate endpoint requires a url which has not been provided."); } if (string.IsNullOrEmpty(_key)) { throw new EndpointInitializationException("The WatsonTranslate endpoint requires a key which has not been provided."); } _fullUrl = _url.TrimEnd(new char[1] { '/' }) + "/v3/translate?version=2018-05-01"; string text = FixLanguage(context.SourceLanguage) + "-" + FixLanguage(context.DestinationLanguage); if (!SupportedLanguagePairs.Contains(text)) { throw new EndpointInitializationException("The language model '" + text + "' is not supported."); } } public override void OnCreateRequest(IWwwRequestCreationContext context) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{\"text\":["); for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++) { string value = JsonHelper.Escape(((ITranslationContextBase)context).UntranslatedTexts[i]); stringBuilder.Append("\"").Append(value).Append("\""); if (((ITranslationContextBase)context).UntranslatedTexts.Length - 1 != i) { stringBuilder.Append(","); } } stringBuilder.Append("],\"model_id\":\"").Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage)).Append("-") .Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage)) .Append("\"}"); WwwRequestInfo val = new WwwRequestInfo(_fullUrl, stringBuilder.ToString()); val.Headers["Accept"] = "application/json"; val.Headers["Content-Type"] = "application/json"; val.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("apikey:" + _key)); context.Complete(val); } public override void OnExtractTranslation(IWwwTranslationExtractionContext context) { JSONArray asArray = ((JSONNode)JSON.Parse(context.ResponseData).AsObject)["translations"].AsArray; List<string> list = new List<string>(); for (int i = 0; i < ((JSONNode)asArray).Count; i++) { string text = ((object)((JSONNode)((JSONNode)asArray)[i].AsObject)["translation"]).ToString(); string item = JsonHelper.Unescape(text.Substring(1, text.Length - 2)); list.Add(item); } context.Complete(list.ToArray()); } }
BepInEx/plugins/XUnity.AutoTranslator/Translators/YandexTranslate.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using SimpleJSON; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("YandexTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("YandexTranslate")] [assembly: AssemblyTitle("YandexTranslate")] [assembly: AssemblyVersion("1.0.0.0")] namespace YandexTranslate; internal class YandexTranslateEndpoint : HttpEndpoint { private static readonly HashSet<string> SupportedLanguages = new HashSet<string> { "az", "sq", "am", "en", "ar", "hy", "af", "eu", "ba", "be", "bn", "my", "bg", "bs", "cy", "hu", "vi", "ht", "gl", "nl", "mrj", "el", "ka", "gu", "da", "he", "yi", "id", "ga", "it", "is", "es", "kk", "kn", "ca", "ky", "zh", "ko", "xh", "km", "lo", "la", "lv", "lt", "lb", "mg", "ms", "ml", "mt", "mk", "mi", "mr", "mhr", "mn", "de", "ne", "no", "pa", "pap", "fa", "pl", "pt", "ro", "ru", "ceb", "sr", "si", "sk", "sl", "sw", "su", "tg", "th", "tl", "ta", "tt", "te", "tr", "udm", "uz", "uk", "ur", "fi", "fr", "hi", "hr", "cs", "sv", "gd", "et", "eo", "jv", "ja" }; private static readonly string HttpsServicePointTemplateUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key={3}&text={2}&lang={0}-{1}&format=plain"; private string _key; public override string Id => "YandexTranslate"; public override string FriendlyName => "Yandex Translate"; private string FixLanguage(string lang) { if (lang == "zh-CN" || lang == "zh-Hans") { return "zh"; } return lang; } public override void Initialize(IInitializationContext context) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) _key = context.GetOrCreateSetting<string>("Yandex", "YandexAPIKey", ""); context.DisableCertificateChecksFor(new string[1] { "translate.yandex.net" }); if (string.IsNullOrEmpty(_key)) { throw new EndpointInitializationException("The YandexTranslate endpoint requires an API key which has not been provided."); } if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage))) { throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported."); } if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage))) { throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported."); } } public override void OnCreateRequest(IHttpRequestCreationContext context) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown XUnityWebRequest val = new XUnityWebRequest(string.Format(HttpsServicePointTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText), _key)); val.Headers[HttpRequestHeader.Accept] = "*/*"; val.Headers[HttpRequestHeader.AcceptCharset] = "UTF-8"; context.Complete(val); } public override void OnExtractTranslation(IHttpTranslationExtractionContext context) { JSONNode obj = JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data); string text = ((object)((JSONNode)obj.AsObject)["code"]).ToString(); if (text != "200") { ((ITranslationContextBase)context).Fail("Received bad response code: " + text); } string text2 = ((object)((JSONNode)obj.AsObject)["text"]).ToString(); string text3 = JsonHelper.Unescape(text2.Substring(2, text2.Length - 4)); if (string.IsNullOrEmpty(text3)) { ((ITranslationContextBase)context).Fail("Received no translation."); } context.Complete(text3); } }
BepInEx/plugins/XUnity.AutoTranslator/XUnity.AutoTranslator.Plugin.BepInEx.dll
Decompiled a year agousing System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using ExIni; using XUnity.AutoTranslator.Plugin.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("XUnity.AutoTranslator.Plugin.BepInEx")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("5.3.0.0")] [assembly: AssemblyInformationalVersion("5.3.0+27fbfc0c2dfc32b3bb59b97a5639344e09ecfdc5")] [assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.BepInEx")] [assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.BepInEx")] [assembly: AssemblyVersion("5.3.0.0")] namespace XUnity.AutoTranslator.Plugin.BepInEx; [BepInPlugin("gravydevsupreme.xunity.autotranslator", "XUnity Auto Translator", "5.3.0")] public class AutoTranslatorPlugin : BaseUnityPlugin, IPluginEnvironment { private IniFile _file; private string _configPath; public IniFile Preferences => _file ?? (_file = ReloadConfig()); public string ConfigPath { get; } public string TranslationPath { get; } public bool AllowDefaultInitializeHarmonyDetourBridge => false; public AutoTranslatorPlugin() { ConfigPath = Paths.ConfigPath; TranslationPath = Paths.BepInExRootPath; _configPath = Path.Combine(ConfigPath, "AutoTranslatorConfig.ini"); } public IniFile ReloadConfig() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!File.Exists(_configPath)) { return (IniFile)(((object)_file) ?? ((object)new IniFile())); } IniFile val = IniFile.FromFile(_configPath); if (_file == null) { return _file = val; } _file.Merge(val); return _file; } public void SaveConfig() { _file.Save(_configPath); } private void Awake() { PluginLoader.LoadWithConfig((IPluginEnvironment)(object)this); } }
BepInEx/plugins/XUnity.AutoTranslator/XUnity.AutoTranslator.Plugin.Core.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Net; using System.Net.Cache; using System.Net.Security; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using DynamicLinq; using ExIni; using Harmony; using ICSharpCode.SharpZipLib.Checksums; using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Encryption; using ICSharpCode.SharpZipLib.Zip; using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using UnityEngine; using UnityEngine.SceneManagement; using XUnity.AutoTranslator.Plugin.Core.AssetRedirection; using XUnity.AutoTranslator.Plugin.Core.Configuration; using XUnity.AutoTranslator.Plugin.Core.Debugging; using XUnity.AutoTranslator.Plugin.Core.Endpoints; using XUnity.AutoTranslator.Plugin.Core.Extensions; using XUnity.AutoTranslator.Plugin.Core.Fonts; using XUnity.AutoTranslator.Plugin.Core.Hooks; using XUnity.AutoTranslator.Plugin.Core.Hooks.NGUI; using XUnity.AutoTranslator.Plugin.Core.Hooks.TextMeshPro; using XUnity.AutoTranslator.Plugin.Core.Hooks.UGUI; using XUnity.AutoTranslator.Plugin.Core.Managed.Textures; using XUnity.AutoTranslator.Plugin.Core.Parsing; using XUnity.AutoTranslator.Plugin.Core.Properties; using XUnity.AutoTranslator.Plugin.Core.Shims; using XUnity.AutoTranslator.Plugin.Core.Text; using XUnity.AutoTranslator.Plugin.Core.Textures; using XUnity.AutoTranslator.Plugin.Core.UI; using XUnity.AutoTranslator.Plugin.Core.UIResize; using XUnity.AutoTranslator.Plugin.Core.Utilities; using XUnity.AutoTranslator.Plugin.Core.Web; using XUnity.AutoTranslator.Plugin.Core.Web.Internal; using XUnity.AutoTranslator.Plugin.ExtProtocol; using XUnity.AutoTranslator.Plugin.Utilities; using XUnity.Common.Constants; using XUnity.Common.Extensions; using XUnity.Common.Harmony; using XUnity.Common.Logging; using XUnity.Common.MonoMod; using XUnity.Common.Utilities; using XUnity.ResourceRedirector; [assembly: AssemblyFileVersion("5.3.0.0")] [assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.Core")] [assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.Core")] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: InternalsVisibleTo("XUnity.AutoTranslator.Plugin.Core.Tests")] [assembly: AssemblyInformationalVersion("5.3.0+27fbfc0c2dfc32b3bb59b97a5639344e09ecfdc5")] [assembly: AssemblyDescription("Main development dependency for XUnity Auto Translator.")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCompany("gravydevsupreme")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("5.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DynamicLinq { internal static class DynamicQueryable { public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values) { return (IQueryable<T>)((IQueryable)source).Where(predicate, values); } public static IQueryable Where(this IQueryable source, string predicate, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } LambdaExpression expression = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values); return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Where", new Type[1] { source.ElementType }, source.Expression, Expression.Quote(expression))); } public static IQueryable Select(this IQueryable source, string selector, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (selector == null) { throw new ArgumentNullException("selector"); } LambdaExpression lambdaExpression = DynamicExpression.ParseLambda(source.ElementType, null, selector, values); return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Select", new Type[2] { source.ElementType, lambdaExpression.Body.Type }, source.Expression, Expression.Quote(lambdaExpression))); } public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values) { return (IQueryable<T>)((IQueryable)source).OrderBy(ordering, values); } public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (ordering == null) { throw new ArgumentNullException("ordering"); } ParameterExpression[] parameters = new ParameterExpression[1] { Expression.Parameter(source.ElementType, "") }; ExpressionParser expressionParser = new ExpressionParser(parameters, ordering, values); IEnumerable<DynamicOrdering> enumerable = expressionParser.ParseOrdering(); Expression expression = source.Expression; string text = "OrderBy"; string text2 = "OrderByDescending"; foreach (DynamicOrdering item in enumerable) { expression = Expression.Call(typeof(Queryable), item.Ascending ? text : text2, new Type[2] { source.ElementType, item.Selector.Type }, expression, Expression.Quote(Expression.Lambda(item.Selector, parameters))); text = "ThenBy"; text2 = "ThenByDescending"; } return source.Provider.CreateQuery(expression); } public static IQueryable Take(this IQueryable source, int count) { if (source == null) { throw new ArgumentNullException("source"); } return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Take", new Type[1] { source.ElementType }, source.Expression, Expression.Constant(count))); } public static IQueryable Skip(this IQueryable source, int count) { if (source == null) { throw new ArgumentNullException("source"); } return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Skip", new Type[1] { source.ElementType }, source.Expression, Expression.Constant(count))); } public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (elementSelector == null) { throw new ArgumentNullException("elementSelector"); } LambdaExpression lambdaExpression = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values); LambdaExpression lambdaExpression2 = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, values); return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "GroupBy", new Type[3] { source.ElementType, lambdaExpression.Body.Type, lambdaExpression2.Body.Type }, source.Expression, Expression.Quote(lambdaExpression), Expression.Quote(lambdaExpression2))); } public static bool Any(this IQueryable source) { if (source == null) { throw new ArgumentNullException("source"); } return (bool)source.Provider.Execute(Expression.Call(typeof(Queryable), "Any", new Type[1] { source.ElementType }, source.Expression)); } public static int Count(this IQueryable source) { if (source == null) { throw new ArgumentNullException("source"); } return (int)source.Provider.Execute(Expression.Call(typeof(Queryable), "Count", new Type[1] { source.ElementType }, source.Expression)); } } internal abstract class DynamicClass { public override string ToString() { PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{"); for (int i = 0; i < properties.Length; i++) { if (i > 0) { stringBuilder.Append(", "); } stringBuilder.Append(properties[i].Name); stringBuilder.Append("="); stringBuilder.Append(properties[i].GetValue(this, null)); } stringBuilder.Append("}"); return stringBuilder.ToString(); } } internal class DynamicProperty { private string name; private Type type; public string Name => name; public Type Type => type; public DynamicProperty(string name, Type type) { if (name == null) { throw new ArgumentNullException("name"); } if ((object)type == null) { throw new ArgumentNullException("type"); } this.name = name; this.type = type; } } internal static class DynamicExpression { public static Expression Parse(Type resultType, string expression, params object[] values) { ExpressionParser expressionParser = new ExpressionParser(null, expression, values); return expressionParser.Parse(resultType); } public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values) { return ParseLambda(new ParameterExpression[1] { Expression.Parameter(itType, "") }, resultType, expression, values); } public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values) { ExpressionParser expressionParser = new ExpressionParser(parameters, expression, values); return Expression.Lambda(expressionParser.Parse(resultType), parameters); } public static Expression<Func<T, S>> ParseLambda<T, S>(string expression, params object[] values) { return (Expression<Func<T, S>>)ParseLambda(typeof(T), typeof(S), expression, values); } public static Type CreateClass(params DynamicProperty[] properties) { throw new NotImplementedException(); } public static Type CreateClass(IEnumerable<DynamicProperty> properties) { throw new NotImplementedException(); } } internal class DynamicOrdering { public Expression Selector; public bool Ascending; } internal class Signature : IEquatable<Signature> { public DynamicProperty[] properties; public int hashCode; public Signature(IEnumerable<DynamicProperty> properties) { this.properties = properties.ToArray(); hashCode = 0; foreach (DynamicProperty property in properties) { hashCode ^= property.Name.GetHashCode() ^ property.Type.GetHashCode(); } } public override int GetHashCode() { return hashCode; } public override bool Equals(object obj) { return obj is Signature && Equals((Signature)obj); } public bool Equals(Signature other) { if (properties.Length != other.properties.Length) { return false; } for (int i = 0; i < properties.Length; i++) { if (properties[i].Name != other.properties[i].Name || (object)properties[i].Type != other.properties[i].Type) { return false; } } return true; } } internal sealed class ParseException : Exception { private int position; public int Position => position; public ParseException(string message, int position) : base(message) { this.position = position; } public override string ToString() { return $"{Message} (at index {position})"; } } internal class ExpressionParser { private struct Token { public TokenId id; public string text; public int pos; } private enum TokenId { Unknown, End, Identifier, StringLiteral, IntegerLiteral, RealLiteral, Exclamation, Percent, Amphersand, OpenParen, CloseParen, Asterisk, Plus, Comma, Minus, Dot, Slash, Colon, LessThan, Equal, GreaterThan, Question, OpenBracket, CloseBracket, Bar, ExclamationEqual, DoubleAmphersand, LessThanEqual, LessGreater, DoubleEqual, GreaterThanEqual, DoubleBar } private interface ILogicalSignatures { void F(bool x, bool y); void F(bool? x, bool? y); } private interface IArithmeticSignatures { void F(int x, int y); void F(uint x, uint y); void F(long x, long y); void F(ulong x, ulong y); void F(float x, float y); void F(double x, double y); void F(decimal x, decimal y); void F(int? x, int? y); void F(uint? x, uint? y); void F(long? x, long? y); void F(ulong? x, ulong? y); void F(float? x, float? y); void F(double? x, double? y); void F(decimal? x, decimal? y); } private interface IRelationalSignatures : IArithmeticSignatures { void F(string x, string y); void F(char x, char y); void F(DateTime x, DateTime y); void F(TimeSpan x, TimeSpan y); void F(char? x, char? y); void F(DateTime? x, DateTime? y); void F(TimeSpan? x, TimeSpan? y); } private interface IEqualitySignatures : IRelationalSignatures, IArithmeticSignatures { void F(bool x, bool y); void F(bool? x, bool? y); } private interface IAddSignatures : IArithmeticSignatures { void F(DateTime x, TimeSpan y); void F(TimeSpan x, TimeSpan y); void F(DateTime? x, TimeSpan? y); void F(TimeSpan? x, TimeSpan? y); } private interface ISubtractSignatures : IAddSignatures, IArithmeticSignatures { void F(DateTime x, DateTime y); void F(DateTime? x, DateTime? y); } private interface INegationSignatures { void F(int x); void F(long x); void F(float x); void F(double x); void F(decimal x); void F(int? x); void F(long? x); void F(float? x); void F(double? x); void F(decimal? x); } private interface INotSignatures { void F(bool x); void F(bool? x); } private interface IEnumerableSignatures { void Where(bool predicate); void Any(); void Any(bool predicate); void All(bool predicate); void Count(); void Count(bool predicate); void Min(object selector); void Max(object selector); void Sum(int selector); void Sum(int? selector); void Sum(long selector); void Sum(long? selector); void Sum(float selector); void Sum(float? selector); void Sum(double selector); void Sum(double? selector); void Sum(decimal selector); void Sum(decimal? selector); void Average(int selector); void Average(int? selector); void Average(long selector); void Average(long? selector); void Average(float selector); void Average(float? selector); void Average(double selector); void Average(double? selector); void Average(decimal selector); void Average(decimal? selector); } private class MethodData { public MethodBase MethodBase; public ParameterInfo[] Parameters; public Expression[] Args; } private static readonly Type[] predefinedTypes = new Type[20] { typeof(object), typeof(bool), typeof(char), typeof(string), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(DateTime), typeof(TimeSpan), typeof(Guid), typeof(Math), typeof(Convert) }; private static readonly Expression trueLiteral = Expression.Constant(true); private static readonly Expression falseLiteral = Expression.Constant(false); private static readonly Expression nullLiteral = Expression.Constant(null); private static readonly string keywordIt = "it"; private static readonly string keywordIif = "iif"; private static readonly string keywordNew = "new"; private static Dictionary<string, object> keywords; private Dictionary<string, object> symbols; private IDictionary<string, object> externals; private Dictionary<Expression, string> literals; private ParameterExpression it; private string text; private int textPos; private int textLen; private char ch; private Token token; public ExpressionParser(ParameterExpression[] parameters, string expression, object[] values) { if (expression == null) { throw new ArgumentNullException("expression"); } if (keywords == null) { keywords = CreateKeywords(); } symbols = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); literals = new Dictionary<Expression, string>(); if (parameters != null) { ProcessParameters(parameters); } if (values != null) { ProcessValues(values); } text = expression; textLen = text.Length; SetTextPos(0); NextToken(); } private void ProcessParameters(ParameterExpression[] parameters) { foreach (ParameterExpression parameterExpression in parameters) { if (!string.IsNullOrEmpty(parameterExpression.Name)) { AddSymbol(parameterExpression.Name, parameterExpression); } } if (parameters.Length == 1 && string.IsNullOrEmpty(parameters[0].Name)) { it = parameters[0]; } } private void ProcessValues(object[] values) { for (int i = 0; i < values.Length; i++) { object obj = values[i]; if (i == values.Length - 1 && obj is IDictionary<string, object>) { externals = (IDictionary<string, object>)obj; } else { AddSymbol("@" + i.ToString(CultureInfo.InvariantCulture), obj); } } } private void AddSymbol(string name, object value) { if (symbols.ContainsKey(name)) { throw ParseError("The identifier '{0}' was defined more than once", name); } symbols.Add(name, value); } public Expression Parse(Type resultType) { int pos = token.pos; Expression expression = ParseExpression(); if ((object)resultType != null && (expression = PromoteExpression(expression, resultType, exact: true)) == null) { throw ParseError(pos, "Expression of type '{0}' expected", GetTypeName(resultType)); } ValidateToken(TokenId.End, "Syntax error"); return expression; } public IEnumerable<DynamicOrdering> ParseOrdering() { List<DynamicOrdering> list = new List<DynamicOrdering>(); while (true) { Expression selector = ParseExpression(); bool ascending = true; if (TokenIdentifierIs("asc") || TokenIdentifierIs("ascending")) { NextToken(); } else if (TokenIdentifierIs("desc") || TokenIdentifierIs("descending")) { NextToken(); ascending = false; } list.Add(new DynamicOrdering { Selector = selector, Ascending = ascending }); if (token.id != TokenId.Comma) { break; } NextToken(); } ValidateToken(TokenId.End, "Syntax error"); return list; } private Expression ParseExpression() { int pos = token.pos; Expression expression = ParseLogicalOr(); if (token.id == TokenId.Question) { NextToken(); Expression expr = ParseExpression(); ValidateToken(TokenId.Colon, "':' expected"); NextToken(); Expression expr2 = ParseExpression(); expression = GenerateConditional(expression, expr, expr2, pos); } return expression; } private Expression ParseLogicalOr() { Expression left = ParseLogicalAnd(); while (this.token.id == TokenId.DoubleBar || TokenIdentifierIs("or")) { Token token = this.token; NextToken(); Expression right = ParseLogicalAnd(); CheckAndPromoteOperands(typeof(ILogicalSignatures), token.text, ref left, ref right, token.pos); left = Expression.OrElse(left, right); } return left; } private Expression ParseLogicalAnd() { Expression left = ParseComparison(); while (this.token.id == TokenId.DoubleAmphersand || TokenIdentifierIs("and")) { Token token = this.token; NextToken(); Expression right = ParseComparison(); CheckAndPromoteOperands(typeof(ILogicalSignatures), token.text, ref left, ref right, token.pos); left = Expression.AndAlso(left, right); } return left; } private Expression ParseComparison() { Expression left = ParseAdditive(); while (this.token.id == TokenId.Equal || this.token.id == TokenId.DoubleEqual || this.token.id == TokenId.ExclamationEqual || this.token.id == TokenId.LessGreater || this.token.id == TokenId.GreaterThan || this.token.id == TokenId.GreaterThanEqual || this.token.id == TokenId.LessThan || this.token.id == TokenId.LessThanEqual) { Token token = this.token; NextToken(); Expression right = ParseAdditive(); bool flag = token.id == TokenId.Equal || token.id == TokenId.DoubleEqual || token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater; if (flag && !left.Type.IsValueType && !right.Type.IsValueType) { if ((object)left.Type != right.Type) { if (left.Type.IsAssignableFrom(right.Type)) { right = Expression.Convert(right, left.Type); } else { if (!right.Type.IsAssignableFrom(left.Type)) { throw IncompatibleOperandsError(token.text, left, right, token.pos); } left = Expression.Convert(left, right.Type); } } } else if (IsEnumType(left.Type) || IsEnumType(right.Type)) { if ((object)left.Type != right.Type) { Expression expression; if ((expression = PromoteExpression(right, left.Type, exact: true)) != null) { right = expression; } else { if ((expression = PromoteExpression(left, right.Type, exact: true)) == null) { throw IncompatibleOperandsError(token.text, left, right, token.pos); } left = expression; } } } else { CheckAndPromoteOperands(flag ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures), token.text, ref left, ref right, token.pos); } switch (token.id) { case TokenId.Equal: case TokenId.DoubleEqual: left = GenerateEqual(left, right); break; case TokenId.ExclamationEqual: case TokenId.LessGreater: left = GenerateNotEqual(left, right); break; case TokenId.GreaterThan: left = GenerateGreaterThan(left, right); break; case TokenId.GreaterThanEqual: left = GenerateGreaterThanEqual(left, right); break; case TokenId.LessThan: left = GenerateLessThan(left, right); break; case TokenId.LessThanEqual: left = GenerateLessThanEqual(left, right); break; } } return left; } private Expression ParseAdditive() { Expression left = ParseMultiplicative(); while (this.token.id == TokenId.Plus || this.token.id == TokenId.Minus || this.token.id == TokenId.Amphersand) { Token token = this.token; NextToken(); Expression right = ParseMultiplicative(); TokenId id = token.id; TokenId tokenId = id; if (tokenId != TokenId.Amphersand) { if (tokenId != TokenId.Plus) { if (tokenId == TokenId.Minus) { CheckAndPromoteOperands(typeof(ISubtractSignatures), token.text, ref left, ref right, token.pos); left = GenerateSubtract(left, right); } continue; } if ((object)left.Type != typeof(string) && (object)right.Type != typeof(string)) { CheckAndPromoteOperands(typeof(IAddSignatures), token.text, ref left, ref right, token.pos); left = GenerateAdd(left, right); continue; } } left = GenerateStringConcat(left, right); } return left; } private Expression ParseMultiplicative() { Expression left = ParseUnary(); while (this.token.id == TokenId.Asterisk || this.token.id == TokenId.Slash || this.token.id == TokenId.Percent || TokenIdentifierIs("mod")) { Token token = this.token; NextToken(); Expression right = ParseUnary(); CheckAndPromoteOperands(typeof(IArithmeticSignatures), token.text, ref left, ref right, token.pos); switch (token.id) { case TokenId.Asterisk: left = Expression.Multiply(left, right); break; case TokenId.Slash: left = Expression.Divide(left, right); break; case TokenId.Identifier: case TokenId.Percent: left = Expression.Modulo(left, right); break; } } return left; } private Expression ParseUnary() { if (this.token.id == TokenId.Minus || this.token.id == TokenId.Exclamation || TokenIdentifierIs("not")) { Token token = this.token; NextToken(); if (token.id == TokenId.Minus && (this.token.id == TokenId.IntegerLiteral || this.token.id == TokenId.RealLiteral)) { this.token.text = "-" + this.token.text; this.token.pos = token.pos; return ParsePrimary(); } Expression expr = ParseUnary(); if (token.id == TokenId.Minus) { CheckAndPromoteOperand(typeof(INegationSignatures), token.text, ref expr, token.pos); expr = Expression.Negate(expr); } else { CheckAndPromoteOperand(typeof(INotSignatures), token.text, ref expr, token.pos); expr = Expression.Not(expr); } return expr; } return ParsePrimary(); } private Expression ParsePrimary() { Expression expression = ParsePrimaryStart(); while (true) { if (token.id == TokenId.Dot) { NextToken(); expression = ParseMemberAccess(null, expression); continue; } if (token.id == TokenId.OpenBracket) { expression = ParseElementAccess(expression); continue; } break; } return expression; } private Expression ParsePrimaryStart() { return token.id switch { TokenId.Identifier => ParseIdentifier(), TokenId.StringLiteral => ParseStringLiteral(), TokenId.IntegerLiteral => ParseIntegerLiteral(), TokenId.RealLiteral => ParseRealLiteral(), TokenId.OpenParen => ParseParenExpression(), _ => throw ParseError("Expression expected"), }; } private Expression ParseStringLiteral() { ValidateToken(TokenId.StringLiteral); char c = token.text[0]; string text = token.text.Substring(1, token.text.Length - 2); int startIndex = 0; while (true) { int num = text.IndexOf(c, startIndex); if (num < 0) { break; } text = text.Remove(num, 1); startIndex = num + 1; } if (c == '\'') { if (text.Length != 1) { throw ParseError("Character literal must contain exactly one character"); } NextToken(); return CreateLiteral(text[0], text); } NextToken(); return CreateLiteral(text, text); } private Expression ParseIntegerLiteral() { ValidateToken(TokenId.IntegerLiteral); string text = token.text; if (text[0] != '-') { if (!ulong.TryParse(text, out var result)) { throw ParseError("Invalid integer literal '{0}'", text); } NextToken(); if (result <= int.MaxValue) { return CreateLiteral((int)result, text); } if (result <= uint.MaxValue) { return CreateLiteral((uint)result, text); } if (result <= long.MaxValue) { return CreateLiteral((long)result, text); } return CreateLiteral(result, text); } if (!long.TryParse(text, out var result2)) { throw ParseError("Invalid integer literal '{0}'", text); } NextToken(); if (result2 >= int.MinValue && result2 <= int.MaxValue) { return CreateLiteral((int)result2, text); } return CreateLiteral(result2, text); } private Expression ParseRealLiteral() { ValidateToken(TokenId.RealLiteral); string text = token.text; object obj = null; char c = text[text.Length - 1]; double result2; if (c == 'F' || c == 'f') { if (float.TryParse(text.Substring(0, text.Length - 1), out var result)) { obj = result; } } else if (double.TryParse(text, out result2)) { obj = result2; } if (obj == null) { throw ParseError("Invalid real literal '{0}'", text); } NextToken(); return CreateLiteral(obj, text); } private Expression CreateLiteral(object value, string text) { ConstantExpression constantExpression = Expression.Constant(value); literals.Add(constantExpression, text); return constantExpression; } private Expression ParseParenExpression() { ValidateToken(TokenId.OpenParen, "'(' expected"); NextToken(); Expression result = ParseExpression(); ValidateToken(TokenId.CloseParen, "')' or operator expected"); NextToken(); return result; } private Expression ParseIdentifier() { ValidateToken(TokenId.Identifier); if (keywords.TryGetValue(token.text, out var value)) { if (value is Type) { return ParseTypeAccess((Type)value); } if (value == keywordIt) { return ParseIt(); } if (value == keywordIif) { return ParseIif(); } if (value == keywordNew) { return ParseNew(); } NextToken(); return (Expression)value; } if (symbols.TryGetValue(token.text, out value) || (externals != null && externals.TryGetValue(token.text, out value))) { Expression expression = value as Expression; if (expression == null) { expression = Expression.Constant(value); } else if (expression is LambdaExpression lambda) { return ParseLambdaInvocation(lambda); } NextToken(); return expression; } if (it != null) { return ParseMemberAccess(null, it); } throw ParseError("Unknown identifier '{0}'", token.text); } private Expression ParseIt() { if (it == null) { throw ParseError("No 'it' is in scope"); } NextToken(); return it; } private Expression ParseIif() { int pos = token.pos; NextToken(); Expression[] array = ParseArgumentList(); if (array.Length != 3) { throw ParseError(pos, "The 'iif' function requires three arguments"); } return GenerateConditional(array[0], array[1], array[2], pos); } private Expression GenerateConditional(Expression test, Expression expr1, Expression expr2, int errorPos) { if ((object)test.Type != typeof(bool)) { throw ParseError(errorPos, "The first expression must be of type 'Boolean'"); } if ((object)expr1.Type != expr2.Type) { Expression expression = ((expr2 != nullLiteral) ? PromoteExpression(expr1, expr2.Type, exact: true) : null); Expression expression2 = ((expr1 != nullLiteral) ? PromoteExpression(expr2, expr1.Type, exact: true) : null); if (expression != null && expression2 == null) { expr1 = expression; } else { if (expression2 == null || expression != null) { string text = ((expr1 != nullLiteral) ? expr1.Type.Name : "null"); string text2 = ((expr2 != nullLiteral) ? expr2.Type.Name : "null"); if (expression != null && expression2 != null) { throw ParseError(errorPos, "Both of the types '{0}' and '{1}' convert to the other", text, text2); } throw ParseError(errorPos, "Neither of the types '{0}' and '{1}' converts to the other", text, text2); } expr2 = expression2; } } return Expression.Condition(test, expr1, expr2); } private Expression ParseNew() { NextToken(); ValidateToken(TokenId.OpenParen, "'(' expected"); NextToken(); List<DynamicProperty> list = new List<DynamicProperty>(); List<Expression> list2 = new List<Expression>(); while (true) { int pos = token.pos; Expression expression = ParseExpression(); string name; if (TokenIdentifierIs("as")) { NextToken(); name = GetIdentifier(); NextToken(); } else { if (!(expression is MemberExpression memberExpression)) { throw ParseError(pos, "Expression is missing an 'as' clause"); } name = memberExpression.Member.Name; } list2.Add(expression); list.Add(new DynamicProperty(name, expression.Type)); if (token.id != TokenId.Comma) { break; } NextToken(); } ValidateToken(TokenId.CloseParen, "')' or ',' expected"); NextToken(); Type type = DynamicExpression.CreateClass(list); MemberBinding[] array = new MemberBinding[list.Count]; for (int i = 0; i < array.Length; i++) { array[i] = Expression.Bind(type.GetProperty(list[i].Name), list2[i]); } return Expression.MemberInit(Expression.New(type), array); } private Expression ParseLambdaInvocation(LambdaExpression lambda) { int pos = token.pos; NextToken(); Expression[] array = ParseArgumentList(); if (FindMethod(lambda.Type, "Invoke", staticAccess: false, array, out var _) != 1) { throw ParseError(pos, "Argument list incompatible with lambda expression"); } return Expression.Invoke(lambda, array); } private Expression ParseTypeAccess(Type type) { int pos = token.pos; NextToken(); if (token.id == TokenId.Question) { if (!type.IsValueType || IsNullableType(type)) { throw ParseError(pos, "Type '{0}' has no nullable form", GetTypeName(type)); } type = typeof(Nullable<>).MakeGenericType(type); NextToken(); } if (token.id == TokenId.OpenParen) { Expression[] array = ParseArgumentList(); MethodBase method; switch (FindBestMethod(type.GetConstructors(), array, out method)) { case 0: if (array.Length == 1) { return GenerateConversion(array[0], type, pos); } throw ParseError(pos, "No matching constructor in type '{0}'", GetTypeName(type)); case 1: return Expression.New((ConstructorInfo)method, array); default: throw ParseError(pos, "Ambiguous invocation of '{0}' constructor", GetTypeName(type)); } } ValidateToken(TokenId.Dot, "'.' or '(' expected"); NextToken(); return ParseMemberAccess(type, null); } private Expression GenerateConversion(Expression expr, Type type, int errorPos) { Type type2 = expr.Type; if ((object)type2 == type) { return expr; } if (type2.IsValueType && type.IsValueType) { if ((IsNullableType(type2) || IsNullableType(type)) && (object)GetNonNullableType(type2) == GetNonNullableType(type)) { return Expression.Convert(expr, type); } if (((IsNumericType(type2) || IsEnumType(type2)) && IsNumericType(type)) || IsEnumType(type)) { return Expression.ConvertChecked(expr, type); } } if (type2.IsAssignableFrom(type) || type.IsAssignableFrom(type2) || type2.IsInterface || type.IsInterface) { return Expression.Convert(expr, type); } throw ParseError(errorPos, "A value of type '{0}' cannot be converted to type '{1}'", GetTypeName(type2), GetTypeName(type)); } private Expression ParseMemberAccess(Type type, Expression instance) { if (instance != null) { type = instance.Type; } int pos = token.pos; string identifier = GetIdentifier(); NextToken(); if (token.id == TokenId.OpenParen) { if (instance != null && (object)type != typeof(string)) { Type type2 = FindGenericType(typeof(IEnumerable<>), type); if ((object)type2 != null) { Type elementType = type2.GetGenericArguments()[0]; return ParseAggregate(instance, elementType, identifier, pos); } } Expression[] array = ParseArgumentList(); MethodBase method; switch (FindMethod(type, identifier, instance == null, array, out method)) { case 0: throw ParseError(pos, "No applicable method '{0}' exists in type '{1}'", identifier, GetTypeName(type)); case 1: { MethodInfo methodInfo = (MethodInfo)method; if (!IsPredefinedType(methodInfo.DeclaringType)) { throw ParseError(pos, "Methods on type '{0}' are not accessible", GetTypeName(methodInfo.DeclaringType)); } if ((object)methodInfo.ReturnType == typeof(void)) { throw ParseError(pos, "Method '{0}' in type '{1}' does not return a value", identifier, GetTypeName(methodInfo.DeclaringType)); } return Expression.Call(instance, methodInfo, array); } default: throw ParseError(pos, "Ambiguous invocation of method '{0}' in type '{1}'", identifier, GetTypeName(type)); } } MemberInfo memberInfo = FindPropertyOrField(type, identifier, instance == null); if ((object)memberInfo == null) { throw ParseError(pos, "No property or field '{0}' exists in type '{1}'", identifier, GetTypeName(type)); } return (memberInfo is PropertyInfo) ? Expression.Property(instance, (PropertyInfo)memberInfo) : Expression.Field(instance, (FieldInfo)memberInfo); } private static Type FindGenericType(Type generic, Type type) { while ((object)type != null && (object)type != typeof(object)) { if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == generic) { return type; } if (generic.IsInterface) { Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { Type type3 = FindGenericType(generic, type2); if ((object)type3 != null) { return type3; } } } type = type.BaseType; } return null; } private Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos) { ParameterExpression parameterExpression = it; ParameterExpression parameterExpression2 = (it = Expression.Parameter(elementType, "")); Expression[] array = ParseArgumentList(); it = parameterExpression; if (FindMethod(typeof(IEnumerableSignatures), methodName, staticAccess: false, array, out var method) != 1) { throw ParseError(errorPos, "No applicable aggregate method '{0}' exists", methodName); } return Expression.Call(typeArguments: (!(method.Name == "Min") && !(method.Name == "Max")) ? new Type[1] { elementType } : new Type[2] { elementType, array[0].Type }, arguments: (array.Length != 0) ? new Expression[2] { instance, Expression.Lambda(array[0], parameterExpression2) } : new Expression[1] { instance }, type: typeof(Enumerable), methodName: method.Name); } private Expression[] ParseArgumentList() { ValidateToken(TokenId.OpenParen, "'(' expected"); NextToken(); Expression[] result = ((token.id != TokenId.CloseParen) ? ParseArguments() : new Expression[0]); ValidateToken(TokenId.CloseParen, "')' or ',' expected"); NextToken(); return result; } private Expression[] ParseArguments() { List<Expression> list = new List<Expression>(); while (true) { list.Add(ParseExpression()); if (token.id != TokenId.Comma) { break; } NextToken(); } return list.ToArray(); } private Expression ParseElementAccess(Expression expr) { int pos = token.pos; ValidateToken(TokenId.OpenBracket, "'(' expected"); NextToken(); Expression[] array = ParseArguments(); ValidateToken(TokenId.CloseBracket, "']' or ',' expected"); NextToken(); if (expr.Type.IsArray) { if (expr.Type.GetArrayRank() != 1 || array.Length != 1) { throw ParseError(pos, "Indexing of multi-dimensional arrays is not supported"); } Expression expression = PromoteExpression(array[0], typeof(int), exact: true); if (expression == null) { throw ParseError(pos, "Array index must be an integer expression"); } return Expression.ArrayIndex(expr, expression); } MethodBase method; return FindIndexer(expr.Type, array, out method) switch { 0 => throw ParseError(pos, "No applicable indexer exists in type '{0}'", GetTypeName(expr.Type)), 1 => Expression.Call(expr, (MethodInfo)method, array), _ => throw ParseError(pos, "Ambiguous invocation of indexer in type '{0}'", GetTypeName(expr.Type)), }; } private static bool IsPredefinedType(Type type) { Type[] array = predefinedTypes; foreach (Type type2 in array) { if ((object)type2 == type) { return true; } } return false; } private static bool IsNullableType(Type type) { return type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>); } private static Type GetNonNullableType(Type type) { return IsNullableType(type) ? type.GetGenericArguments()[0] : type; } private static string GetTypeName(Type type) { Type nonNullableType = GetNonNullableType(type); string text = nonNullableType.Name; if ((object)type != nonNullableType) { text += "?"; } return text; } private static bool IsNumericType(Type type) { return GetNumericTypeKind(type) != 0; } private static bool IsSignedIntegralType(Type type) { return GetNumericTypeKind(type) == 2; } private static bool IsUnsignedIntegralType(Type type) { return GetNumericTypeKind(type) == 3; } private static int GetNumericTypeKind(Type type) { type = GetNonNullableType(type); if (type.IsEnum) { return 0; } switch (Type.GetTypeCode(type)) { case TypeCode.Char: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return 1; case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: return 2; case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return 3; default: return 0; } } private static bool IsEnumType(Type type) { return GetNonNullableType(type).IsEnum; } private void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int errorPos) { Expression[] array = new Expression[1] { expr }; if (FindMethod(signatures, "F", staticAccess: false, array, out var _) != 1) { throw ParseError(errorPos, "Operator '{0}' incompatible with operand type '{1}'", opName, GetTypeName(array[0].Type)); } expr = array[0]; } private void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref Expression right, int errorPos) { Expression[] array = new Expression[2] { left, right }; if (FindMethod(signatures, "F", staticAccess: false, array, out var _) != 1) { throw IncompatibleOperandsError(opName, left, right, errorPos); } left = array[0]; right = array[1]; } private Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos) { return ParseError(pos, "Operator '{0}' incompatible with operand types '{1}' and '{2}'", opName, GetTypeName(left.Type), GetTypeName(right.Type)); } private MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess) { BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | (staticAccess ? BindingFlags.Static : BindingFlags.Instance); foreach (Type item in SelfAndBaseTypes(type)) { MemberInfo[] array = item.FindMembers(MemberTypes.Field | MemberTypes.Property, bindingAttr, Type.FilterNameIgnoreCase, memberName); if (array.Length != 0) { return array[0]; } } return null; } private int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method) { BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | (staticAccess ? BindingFlags.Static : BindingFlags.Instance); foreach (Type item in SelfAndBaseTypes(type)) { MemberInfo[] source = item.FindMembers(MemberTypes.Method, bindingAttr, Type.FilterNameIgnoreCase, methodName); int num = FindBestMethod(source.Cast<MethodBase>(), args, out method); if (num != 0) { return num; } } method = null; return 0; } private int FindIndexer(Type type, Expression[] args, out MethodBase method) { foreach (Type item in SelfAndBaseTypes(type)) { MemberInfo[] defaultMembers = item.GetDefaultMembers(); if (defaultMembers.Length != 0) { IEnumerable<MethodBase> methods = from m in defaultMembers.OfType<PropertyInfo>().Select((Func<PropertyInfo, MethodBase>)((PropertyInfo p) => p.GetGetMethod())) where (object)m != null select m; int num = FindBestMethod(methods, args, out method); if (num != 0) { return num; } } } method = null; return 0; } private static IEnumerable<Type> SelfAndBaseTypes(Type type) { if (type.IsInterface) { List<Type> list = new List<Type>(); AddInterface(list, type); return list; } return SelfAndBaseClasses(type); } private static IEnumerable<Type> SelfAndBaseClasses(Type type) { while ((object)type != null) { yield return type; type = type.BaseType; } } private static void AddInterface(List<Type> types, Type type) { if (!types.Contains(type)) { types.Add(type); Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { AddInterface(types, type2); } } } private int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method) { MethodData[] applicable = (from m in methods select new MethodData { MethodBase = m, Parameters = m.GetParameters() } into m where IsApplicable(m, args) select m).ToArray(); if (applicable.Length > 1) { applicable = applicable.Where((MethodData m) => applicable.All((MethodData n) => m == n || IsBetterThan(args, m, n))).ToArray(); } if (applicable.Length == 1) { MethodData methodData = applicable[0]; for (int i = 0; i < args.Length; i++) { args[i] = methodData.Args[i]; } method = methodData.MethodBase; } else { method = null; } return applicable.Length; } private bool IsApplicable(MethodData method, Expression[] args) { if (method.Parameters.Length != args.Length) { return false; } Expression[] array = new Expression[args.Length]; for (int i = 0; i < args.Length; i++) { ParameterInfo parameterInfo = method.Parameters[i]; if (parameterInfo.IsOut) { return false; } Expression expression = PromoteExpression(args[i], parameterInfo.ParameterType, exact: false); if (expression == null) { return false; } array[i] = expression; } method.Args = array; return true; } private Expression PromoteExpression(Expression expr, Type type, bool exact) { if ((object)expr.Type == type) { return expr; } if (expr is ConstantExpression) { ConstantExpression constantExpression = (ConstantExpression)expr; string value; if (constantExpression == nullLiteral) { if (!type.IsValueType || IsNullableType(type)) { return Expression.Constant(null, type); } } else if (literals.TryGetValue(constantExpression, out value)) { Type nonNullableType = GetNonNullableType(type); object obj = null; switch (Type.GetTypeCode(constantExpression.Type)) { case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: obj = ParseNumber(value, nonNullableType); break; case TypeCode.Double: if ((object)nonNullableType == typeof(decimal)) { obj = ParseNumber(value, nonNullableType); } break; case TypeCode.String: obj = ParseEnum(value, nonNullableType); break; } if (obj != null) { return Expression.Constant(obj, type); } } } if (IsCompatibleWith(expr.Type, type)) { if (type.IsValueType || exact) { return Expression.Convert(expr, type); } return expr; } return null; } private static object ParseNumber(string text, Type type) { switch (Type.GetTypeCode(GetNonNullableType(type))) { case TypeCode.SByte: { if (sbyte.TryParse(text, out var result6)) { return result6; } break; } case TypeCode.Byte: { if (byte.TryParse(text, out var result10)) { return result10; } break; } case TypeCode.Int16: { if (short.TryParse(text, out var result2)) { return result2; } break; } case TypeCode.UInt16: { if (ushort.TryParse(text, out var result8)) { return result8; } break; } case TypeCode.Int32: { if (int.TryParse(text, out var result4)) { return result4; } break; } case TypeCode.UInt32: { if (uint.TryParse(text, out var result11)) { return result11; } break; } case TypeCode.Int64: { if (long.TryParse(text, out var result9)) { return result9; } break; } case TypeCode.UInt64: { if (ulong.TryParse(text, out var result7)) { return result7; } break; } case TypeCode.Single: { if (float.TryParse(text, out var result5)) { return result5; } break; } case TypeCode.Double: { if (double.TryParse(text, out var result3)) { return result3; } break; } case TypeCode.Decimal: { if (decimal.TryParse(text, out var result)) { return result; } break; } } return null; } private static object ParseEnum(string name, Type type) { if (type.IsEnum) { MemberInfo[] array = type.FindMembers(MemberTypes.Field, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public, Type.FilterNameIgnoreCase, name); if (array.Length != 0) { return ((FieldInfo)array[0]).GetValue(null); } } return null; } private static bool IsCompatibleWith(Type source, Type target) { if ((object)source == target) { return true; } if (!target.IsValueType) { return target.IsAssignableFrom(source); } Type nonNullableType = GetNonNullableType(source); Type nonNullableType2 = GetNonNullableType(target); if ((object)nonNullableType != source && (object)nonNullableType2 == target) { return false; } TypeCode typeCode = (nonNullableType.IsEnum ? TypeCode.Object : Type.GetTypeCode(nonNullableType)); TypeCode typeCode2 = (nonNullableType2.IsEnum ? TypeCode.Object : Type.GetTypeCode(nonNullableType2)); switch (typeCode) { case TypeCode.SByte: switch (typeCode2) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.Byte: { TypeCode typeCode3 = typeCode2; TypeCode typeCode4 = typeCode3; if ((uint)(typeCode4 - 6) > 9u) { break; } return true; } case TypeCode.Int16: switch (typeCode2) { case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.UInt16: { TypeCode typeCode9 = typeCode2; TypeCode typeCode10 = typeCode9; if ((uint)(typeCode10 - 8) > 7u) { break; } return true; } case TypeCode.Int32: switch (typeCode2) { case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.UInt32: { TypeCode typeCode13 = typeCode2; TypeCode typeCode14 = typeCode13; if ((uint)(typeCode14 - 10) > 5u) { break; } return true; } case TypeCode.Int64: { TypeCode typeCode11 = typeCode2; TypeCode typeCode12 = typeCode11; if (typeCode12 != TypeCode.Int64 && (uint)(typeCode12 - 13) > 2u) { break; } return true; } case TypeCode.UInt64: { TypeCode typeCode7 = typeCode2; TypeCode typeCode8 = typeCode7; if ((uint)(typeCode8 - 12) > 3u) { break; } return true; } case TypeCode.Single: { TypeCode typeCode5 = typeCode2; TypeCode typeCode6 = typeCode5; if ((uint)(typeCode6 - 13) > 1u) { break; } return true; } default: if ((object)nonNullableType == nonNullableType2) { return true; } break; } return false; } private static bool IsBetterThan(Expression[] args, MethodData m1, MethodData m2) { bool result = false; for (int i = 0; i < args.Length; i++) { int num = CompareConversions(args[i].Type, m1.Parameters[i].ParameterType, m2.Parameters[i].ParameterType); if (num < 0) { return false; } if (num > 0) { result = true; } } return result; } private static int CompareConversions(Type s, Type t1, Type t2) { if ((object)t1 == t2) { return 0; } if ((object)s == t1) { return 1; } if ((object)s == t2) { return -1; } bool flag = IsCompatibleWith(t1, t2); bool flag2 = IsCompatibleWith(t2, t1); if (flag && !flag2) { return 1; } if (flag2 && !flag) { return -1; } if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2)) { return 1; } if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1)) { return -1; } return 0; } private Expression GenerateEqual(Expression left, Expression right) { return Expression.Equal(left, right); } private Expression GenerateNotEqual(Expression left, Expression right) { return Expression.NotEqual(left, right); } private Expression GenerateGreaterThan(Expression left, Expression right) { if ((object)left.Type == typeof(string)) { return Expression.GreaterThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0)); } return Expression.GreaterThan(left, right); } private Expression GenerateGreaterThanEqual(Expression left, Expression right) { if ((object)left.Type == typeof(string)) { return Expression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0)); } return Expression.GreaterThanOrEqual(left, right); } private Expression GenerateLessThan(Expression left, Expression right) { if ((object)left.Type == typeof(string)) { return Expression.LessThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0)); } return Expression.LessThan(left, right); } private Expression GenerateLessThanEqual(Expression left, Expression right) { if ((object)left.Type == typeof(string)) { return Expression.LessThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0)); } return Expression.LessThanOrEqual(left, right); } private Expression GenerateAdd(Expression left, Expression right) { if ((object)left.Type == typeof(string) && (object)right.Type == typeof(string)) { return GenerateStaticMethodCall("Concat", left, right); } return Expression.Add(left, right); } private Expression GenerateSubtract(Expression left, Expression right) { return Expression.Subtract(left, right); } private Expression GenerateStringConcat(Expression left, Expression right) { return Expression.Call(null, typeof(string).GetMethod("Concat", new Type[2] { typeof(object), typeof(object) }), new Expression[2] { left, right }); } private MethodInfo GetStaticMethod(string methodName, Expression left, Expression right) { return left.Type.GetMethod(methodName, new Type[2] { left.Type, right.Type }); } private Expression GenerateStaticMethodCall(string methodName, Expression left, Expression right) { return Expression.Call(null, GetStaticMethod(methodName, left, right), new Expression[2] { left, right }); } private void SetTextPos(int pos) { textPos = pos; ch = ((textPos < textLen) ? text[textPos] : '\0'); } private void NextChar() { if (textPos < textLen) { textPos++; } ch = ((textPos < textLen) ? text[textPos] : '\0'); } private void NextToken() { while (char.IsWhiteSpace(ch)) { NextChar(); } int num = textPos; TokenId id; switch (ch) { case '!': NextChar(); if (ch == '=') { NextChar(); id = TokenId.ExclamationEqual; } else { id = TokenId.Exclamation; } break; case '%': NextChar(); id = TokenId.Percent; break; case '&': NextChar(); if (ch == '&') { NextChar(); id = TokenId.DoubleAmphersand; } else { id = TokenId.Amphersand; } break; case '(': NextChar(); id = TokenId.OpenParen; break; case ')': NextChar(); id = TokenId.CloseParen; break; case '*': NextChar(); id = TokenId.Asterisk; break; case '+': NextChar(); id = TokenId.Plus; break; case ',': NextChar(); id = TokenId.Comma; break; case '-': NextChar(); id = TokenId.Minus; break; case '.': NextChar(); id = TokenId.Dot; break; case '/': NextChar(); id = TokenId.Slash; break; case ':': NextChar(); id = TokenId.Colon; break; case '<': NextChar(); if (ch == '=') { NextChar(); id = TokenId.LessThanEqual; } else if (ch == '>') { NextChar(); id = TokenId.LessGreater; } else { id = TokenId.LessThan; } break; case '=': NextChar(); if (ch == '=') { NextChar(); id = TokenId.DoubleEqual; } else { id = TokenId.Equal; } break; case '>': NextChar(); if (ch == '=') { NextChar(); id = TokenId.GreaterThanEqual; } else { id = TokenId.GreaterThan; } break; case '?': NextChar(); id = TokenId.Question; break; case '[': NextChar(); id = TokenId.OpenBracket; break; case ']': NextChar(); id = TokenId.CloseBracket; break; case '|': NextChar(); if (ch == '|') { NextChar(); id = TokenId.DoubleBar; } else { id = TokenId.Bar; } break; case '"': case '\'': { char c = ch; do { NextChar(); while (textPos < textLen && ch != c) { NextChar(); } if (textPos == textLen) { throw ParseError(textPos, "Unterminated string literal"); } NextChar(); } while (ch == c); id = TokenId.StringLiteral; break; } default: if (char.IsLetter(ch) || ch == '@' || ch == '_') { do { NextChar(); } while (char.IsLetterOrDigit(ch) || ch == '_'); id = TokenId.Identifier; } else if (char.IsDigit(ch)) { id = TokenId.IntegerLiteral; do { NextChar(); } while (char.IsDigit(ch)); if (ch == '.') { id = TokenId.RealLiteral; NextChar(); ValidateDigit(); do { NextChar(); } while (char.IsDigit(ch)); } if (ch == 'E' || ch == 'e') { id = TokenId.RealLiteral; NextChar(); if (ch == '+' || ch == '-') { NextChar(); } ValidateDigit(); do { NextChar(); } while (char.IsDigit(ch)); } if (ch == 'F' || ch == 'f') { NextChar(); } } else { if (textPos != textLen) { throw ParseError(textPos, "Syntax error '{0}'", ch); } id = TokenId.End; } break; } token.id = id; token.text = text.Substring(num, textPos - num); token.pos = num; } private bool TokenIdentifierIs(string id) { return token.id == TokenId.Identifier && string.Equals(id, token.text, StringComparison.OrdinalIgnoreCase); } private string GetIdentifier() { ValidateToken(TokenId.Identifier, "Identifier expected"); string text = token.text; if (text.Length > 1 && text[0] == '@') { text = text.Substring(1); } return text; } private void ValidateDigit() { if (!char.IsDigit(ch)) { throw ParseError(textPos, "Digit expected"); } } private void ValidateToken(TokenId t, string errorMessage) { if (token.id != t) { throw ParseError(errorMessage); } } private void ValidateToken(TokenId t) { if (token.id != t) { throw ParseError("Syntax error"); } } private Exception ParseError(string format, params object[] args) { return ParseError(token.pos, format, args); } private Exception ParseError(int pos, string format, params object[] args) { return new ParseException(string.Format(CultureInfo.CurrentCulture, format, args), pos); } private static Dictionary<string, object> CreateKeywords() { Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); dictionary.Add("true", trueLiteral); dictionary.Add("false", falseLiteral); dictionary.Add("null", nullLiteral); dictionary.Add(keywordIt, keywordIt); dictionary.Add(keywordIif, keywordIif); dictionary.Add(keywordNew, keywordNew); Type[] array = predefinedTypes; foreach (Type type in array) { dictionary.Add(type.Name, type); } return dictionary; } } internal static class Res { public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once"; public const string ExpressionTypeMismatch = "Expression of type '{0}' expected"; public const string ExpressionExpected = "Expression expected"; public const string InvalidCharacterLiteral = "Character literal must contain exactly one character"; public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'"; public const string InvalidRealLiteral = "Invalid real literal '{0}'"; public const string UnknownIdentifier = "Unknown identifier '{0}'"; public const string NoItInScope = "No 'it' is in scope"; public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments"; public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'"; public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other"; public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other"; public const string MissingAsClause = "Expression is missing an 'as' clause"; public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression"; public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form"; public const string NoMatchingConstructor = "No matching constructor in type '{0}'"; public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor"; public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'"; public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'"; public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible"; public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value"; public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'"; public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'"; public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists"; public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported"; public const string InvalidIndex = "Array index must be an integer expression"; public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'"; public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'"; public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'"; public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'"; public const string UnterminatedStringLiteral = "Unterminated string literal"; public const string InvalidCharacter = "Syntax error '{0}'"; public const string DigitExpected = "Digit expected"; public const string SyntaxError = "Syntax error"; public const string TokenExpected = "{0} expected"; public const string ParseExceptionFormat = "{0} (at index {1})"; public const string ColonExpected = "':' expected"; public const string OpenParenExpected = "'(' expected"; public const string CloseParenOrOperatorExpected = "')' or operator expected"; public const string CloseParenOrCommaExpected = "')' or ',' expected"; public const string DotOrOpenParenExpected = "'.' or '(' expected"; public const string OpenBracketExpected = "'[' expected"; public const string CloseBracketOrCommaExpected = "']' or ',' expected"; public const string IdentifierExpected = "Identifier expected"; } } namespace SimpleJSON { public enum JSONNodeType { Array = 1, Object = 2, String = 3, Number = 4, NullValue = 5, Boolean = 6, None = 7, Custom = 255 } public enum JSONTextMode { Compact, Indent } public abstract class JSONNode { public struct Enumerator { private enum Type { None, Array, Object } private Type type; private Dictionary<string, JSONNode>.Enumerator m_Object; private List<JSONNode>.Enumerator m_Array; public bool IsValid => type != Type.None; public KeyValuePair<string, JSONNode> Current { get { if (type == Type.Array) { return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current); } if (type == Type.Object) { return m_Object.Current; } return new KeyValuePair<string, JSONNode>(string.Empty, null); } } public Enumerator(List<JSONNode>.Enumerator aArrayEnum) { type = Type.Array; m_Object = default(Dictionary<string, JSONNode>.Enumerator); m_Array = aArrayEnum; } public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) { type = Type.Object; m_Object = aDictEnum; m_Array = default(List<JSONNode>.Enumerator); } public bool MoveNext() { if (type == Type.Array) { return m_Array.MoveNext(); } if (type == Type.Object) { return m_Object.MoveNext(); } return false; } } public struct ValueEnumerator { private Enumerator m_Enumerator; public JSONNode Current => m_Enumerator.Current.Value; public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public ValueEnumerator GetEnumerator() { return this; } } public struct KeyEnumerator { private Enumerator m_Enumerator; public JSONNode Current => m_Enumerator.Current.Key; public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public KeyEnumerator GetEnumerator() { return this; } } public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable { private JSONNode m_Node; private Enumerator m_Enumerator; public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current; object IEnumerator.Current => m_Enumerator.Current; internal LinqEnumerator(JSONNode aNode) { m_Node = aNode; if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } public bool MoveNext() { return m_Enumerator.MoveNext(); } public void Dispose() { m_Node = null; m_Enumerator = default(Enumerator); } public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator() { return new LinqEnumerator(m_Node); } public void Reset() { if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } IEnumerator IEnumerable.GetEnumerator() { return new LinqEnumerator(m_Node); } } public static bool forceASCII; [ThreadStatic] private static StringBuilder m_EscapeBuilder; public abstract JSONNodeType Tag { get; } public virtual JSONNode this[int aIndex] { get { return null; } set { } } public virtual JSONNode this[string aKey] { get { return null; } set { } } public virtual string Value { get { return ""; } set { } } public virtual int Count => 0; public virtual bool IsNumber => false; public virtual bool IsString => false; public virtual bool IsBoolean => false; public virtual bool IsNull => false; public virtual bool IsArray => false; public virtual bool IsObject => false; public virtual bool Inline { get { return false; } set { } } public virtual IEnumerable<JSONNode> Children { get { yield break; } } public IEnumerable<JSONNode> DeepChildren { get { foreach (JSONNode C in Children) { foreach (JSONNode deepChild in C.DeepChildren) { yield return deepChild; } } } } public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this); public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator()); public ValueEnumerator Values => new ValueEnumerator(GetEnumerator()); public virtual double AsDouble { get { double result = 0.0; if (double.TryParse(Value, out result)) { return result; } return 0.0; } set { Value = value.ToString(); } } public virtual int AsInt { get { return (int)AsDouble; } set { AsDouble = value; } } public virtual float AsFloat { get { return (float)AsDouble; } set { AsDouble = value; } } public virtual bool AsBool { get { bool result = false; if (bool.TryParse(Value, out result)) { return result; } return !string.IsNullOrEmpty(Value); } set { Value = (value ? "true" : "false"); } } public virtual JSONArray AsArray => this as JSONArray; public virtual JSONObject AsObject => this as JSONObject; internal static StringBuilder EscapeBuilder { get { if (m_EscapeBuilder == null) { m_EscapeBuilder = new StringBuilder(); } return m_EscapeBuilder; } } public virtual void Add(string aKey, JSONNode aItem) { } public virtual void Add(JSONNode aItem) { Add("", aItem); } public virtual JSONNode Remove(string aKey) { return null; } public virtual JSONNode Remove(int aIndex) { return null; } public virtual JSONNode Remove(JSONNode aNode) { return aNode; } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact); return stringBuilder.ToString(); } public virtual string ToString(int aIndent) { StringBuilder stringBuilder = new StringBuilder(); WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent); return stringBuilder.ToString(); } internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode); public abstract Enumerator GetEnumerator(); public static implicit operator JSONNode(string s) { return new JSONString(s); } public static implicit operator string(JSONNode d) { return (d == null) ? null : d.Value; } public static implicit operator JSONNode(double n) { return new JSONNumber(n); } public static implicit operator double(JSONNode d) { return (d == null) ? 0.0 : d.AsDouble; } public static implicit operator JSONNode(float n) { return new JSONNumber(n); } public static implicit operator float(JSONNode d) { return (d == null) ? 0f : d.AsFloat; } public static implicit operator JSONNode(int n) { return new JSONNumber(n); } public static implicit operator int(JSONNode d) { return (!(d == null)) ? d.AsInt : 0; } public static implicit operator JSONNode(bool b) { return new JSONBool(b); } public static implicit operator bool(JSONNode d) { return !(d == null) && d.AsBool; } public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue) { return aKeyValue.Value; } public static bool operator ==(JSONNode a, object b) { if ((object)a == b) { return true; } bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator; bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator; if (flag && flag2) { return true; } return !flag && a.Equals(b); } public static bool operator !=(JSONNode a, object b) { return !(a == b); } public override bool Equals(object obj) { return (object)this == obj; } public override int GetHashCode() { return base.GetHashCode(); } internal static string Escape(string aText) { StringBuilder escapeBuilder = EscapeBuilder; escapeBuilder.Length = 0; if (escapeBuilder.Capacity < aText.Length + aText.Length / 10) { escapeBuilder.Capacity = aText.Length + aText.Length / 10; } foreach (char c in aText) { switch (c) { case '\\': escapeBuilder.Append("\\\\"); continue; case '"': escapeBuilder.Append("\\\""); continue; case '\n': escapeBuilder.Append("\\n"); continue; case '\r': escapeBuilder.Append("\\r"); continue; case '\t': escapeBuilder.Append("\\t"); continue; case '\b': escapeBuilder.Append("\\b"); continue; case '\f': escapeBuilder.Append("\\f"); continue; } if (c < ' ' || (forceASCII && c > '\u007f')) { ushort num = c; escapeBuilder.Append("\\u").Append(num.ToString("X4")); } else { escapeBuilder.Append(c); } } string result = escapeBuilder.ToString(); escapeBuilder.Length = 0; return result; } private static void ParseElement(JSONNode ctx, string token, string tokenName, bool quoted) { if (quoted) { ctx.Add(tokenName, token); return; } string text = token.ToLower(); double result; if (text == "false" || text == "true") { ctx.Add(tokenName, text == "true"); } else if (text == "null") { ctx.Add(tokenName, null); } else if (double.TryParse(token, out result)) { ctx.Add(tokenName, result); } else { ctx.Add(tokenName, token); } } public static JSONNode Parse(string aJSON) { Stack<JSONNode> stack = new Stack<JSONNode>(); JSONNode jSONNode = null; int i = 0; StringBuilder stringBuilder = new StringBuilder(); string text = ""; bool flag = false; bool flag2 = false; for (; i < aJSON.Length; i++) { switch (aJSON[i]) { case '{': if (flag) { stringBuilder.Append(aJSON[i]); break; } stack.Push(new JSONObject()); if (jSONNode != null) { jSONNode.Add(text, stack.Peek()); } text = ""; stringBuilder.Length = 0; jSONNode = stack.Peek(); break; case '[': if (flag) { stringBuilder.Append(aJSON[i]); break; } stack.Push(new JSONArray()); if (jSONNode != null) { jSONNode.Add(text, stack.Peek()); } text = ""; stringBuilder.Length = 0; jSONNode = stack.Peek(); break; case ']': case '}': if (flag) { stringBuilder.Append(aJSON[i]); break; } if (stack.Count == 0) { throw new Exception("JSON Parse: Too many closing brackets"); } stack.Pop(); if (stringBuilder.Length > 0 || flag2) { ParseElement(jSONNode, stringBuilder.ToString(), text, flag2); flag2 = false; } text = ""; stringBuilder.Length = 0; if (stack.Count > 0) { jSONNode = stack.Peek(); } break; case ':': if (flag) { stringBuilder.Append(aJSON[i]); break; } text = stringBuilder.ToString(); stringBuilder.Length = 0; flag2 = false; break; case '"': flag = !flag; flag2 = flag2 || flag; break; case ',': if (flag) { stringBuilder.Append(aJSON[i]); break; } if (stringBuilder.Length > 0 || flag2) { ParseElement(jSONNode, stringBuilder.ToString(), text, flag2); flag2 = false; } text = ""; stringBuilder.Length = 0; flag2 = false; break; case '\t': case ' ': if (flag) { stringBuilder.Append(aJSON[i]); } break; case '\\': i++; if (flag) { char c = aJSON[i]; switch (c) { case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'n': stringBuilder.Append('\n'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': { string s = aJSON.Substring(i + 1, 4); stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier)); i += 4; break; } default: stringBuilder.Append(c); break; } } break; default: stringBuilder.Append(aJSON[i]); break; case '\n': case '\r': break; } } if (flag) { throw new Exception("JSON Parse: Quotation marks seems to be messed up."); } return jSONNode; } } public class JSONArray : JSONNode { private List<JSONNode> m_List = new List<JSONNode>(); private bool inline = false; public override bool Inline { get { return inline; } set { inline = value; } } public override JSONNodeType Tag => JSONNodeType.Array; public override bool IsArray => true; public override JSONNode this[int aIndex] { get { if (aIndex < 0 || aIndex >= m_List.Count) { return new JSONLazyCreator(this); } return m_List[aIndex]; } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (aIndex < 0 || aIndex >= m_List.Count) { m_List.Add(value); } else { m_List[aIndex] = value; } } } public override JSONNode this[string aKey] { get { return new JSONLazyCreator(this); } set { if (value == null) { value = JSONNull.CreateOrGet(); } m_List.Add(value); } } public override int Count => m_List.Count; public override IEnumerable<JSONNode> Children { get { foreach (JSONNode item in m_List) { yield return item; } } } public override Enumerator GetEnumerator() { return new Enumerator(m_List.GetEnumerator()); } public override void Add(string aKey, JSONNode aItem) { if (aItem == null) { aItem = JSONNull.CreateOrGet(); } m_List.Add(aItem); } public override JSONNode Remove(int aIndex) { if (aIndex < 0 || aIndex >= m_List.Count) { return null; } JSONNode result = m_List[aIndex]; m_List.RemoveAt(aIndex); return result; } public override JSONNode Remove(JSONNode aNode) { m_List.Remove(aNode); return aNode; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('['); int count = m_List.Count; if (inline) { aMode = JSONTextMode.Compact; } for (int i = 0; i < count; i++) { if (i > 0) { aSB.Append(','); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine(); } if (aMode == JSONTextMode.Indent) { aSB.Append(' ', aIndent + aIndentInc); } m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine().Append(' ', aIndent); } aSB.Append(']'); } } public class JSONObject : JSONNode { private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>(); private bool inline = false; public override bool Inline { get { return inline; } set { inline = value; } } public override JSONNodeType Tag => JSONNodeType.Object; public override bool IsObject => true; public override JSONNode this[string aKey] { get { if (m_Dict.ContainsKey(aKey)) { return m_Dict[aKey]; } return new JSONLazyCreator(this, aKey); } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (m_Dict.ContainsKey(aKey)) { m_Dict[aKey] = value; } else { m_Dict.Add(aKey, value); } } } public override JSONNode this[int aIndex] { get { if (aIndex < 0 || aIndex >= m_Dict.Count) { return null; } return m_Dict.ElementAt(aIndex).Value; } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (aIndex >= 0 && aIndex < m_Dict.Count) { string key = m_Dict.ElementAt(aIndex).Key; m_Dict[key] = value; } } } public override int Count => m_Dict.Count; public override IEnumerable<JSONNode> Children { get { foreach (KeyValuePair<string, JSONNode> item in m_Dict) { yield return item.Value; } } } public override Enumerator GetEnumerator() { return new Enumerator(m_Dict.GetEnumerator()); } public override void Add(string aKey, JSONNode aItem) { if (aItem == null) { aItem = JSONNull.CreateOrGet(); } if (!string.IsNullOrEmpty(aKey)) { if (m_Dict.ContainsKey(aKey)) { m_Dict[aKey] = aItem; } else { m_Dict.Add(aKey, aItem); } } else { m_Dict.Add(Guid.NewGuid().ToString(), aItem); } } public override JSONNode Remove(string aKey) { if (!m_Dict.ContainsKey(aKey)) { return null; } JSONNode result = m_Dict[aKey]; m_Dict.Remove(aKey); return result; } public override JSONNode Remove(int aIndex) { if (aIndex < 0 || aIndex >= m_Dict.Count) { return null; } KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex); m_Dict.Remove(keyValuePair.Key); return keyValuePair.Value; } public override JSONNode Remove(JSONNode aNode) { try { KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First(); m_Dict.Remove(keyValuePair.Key); return aNode; } catch { return null; } } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('{'); bool flag = true; if (inline) { aMode = JSONTextMode.Compact; } foreach (KeyValuePair<string, JSONNode> item in m_Dict) { if (!flag) { aSB.Append(','); } flag = false; if (aMode == JSONTextMode.Indent) { aSB.AppendLine(); } if (aMode == JSONTextMode.Indent) { aSB.Append(' ', aIndent + aIndentInc); } aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"'); if (aMode == JSONTextMode.Compact) { aSB.Append(':'); } else { aSB.Append(" : "); } item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine().Append(' ', aIndent); } aSB.Append('}'); } } public class JSONString : JSONNode { private string m_Data; public override JSONNodeType Tag => JSONNodeType.String; public override bool IsString => true; public override string Value { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONString(string aData) { m_Data = aData; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"'); } public override bool Equals(object obj) { if (base.Equals(obj)) { return true; } if (obj is string text) { return m_Data == text; } JSONString jSONString = obj as JSONString; if (jSONString != null) { return m_Data == jSONString.m_Data; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } } public class JSONNumber : JSONNode { private double m_Data; public override JSONNodeType Tag => JSONNodeType.Number; public override bool IsNumber => true; public override string Value { get { return m_Data.ToString(); } set { if (double.TryParse(value, out var result)) { m_Data = result; } } } public override double AsDouble { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONNumber(double aData) { m_Data = aData; } public JSONNumber(string aData) { Value = aData; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append(m_Data); } private static bool IsNumeric(object value) { return value is int || value is uint || value is float || value is double || value is decimal || value is long || value is ulong || value is short || value is ushort || value is sbyte || value is byte; } public override bool Equals(object obj) { if (obj == null) { return false; } if (base.Equals(obj)) { return true; } JSONNumber jSONNumber = obj as JSONNumber; if (jSONNumber != null) { return m_Data == jSONNumber.m_Data; } if (IsNumeric(obj)) { return Convert.ToDouble(obj) == m_Data; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } } public class JSONBool : JSONNode { private bool m_Data; public override JSONNodeType Tag => JSONNodeType.Boolean; public override bool IsBoolean => true; public override string Value { get { return m_Data.ToString(); } set { if (bool.TryParse(value, out var result)) { m_Data = result; } } } public override bool AsBool { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONBool(bool aData) { m_Data = aData; } public JSONBool(string aData) { Value = aData; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append(m_Data ? "true" : "false"); } public override bool Equals(object obj) { if (obj == null) { return false; } if (obj is bool) { return m_Data == (bool)obj; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } } public class JSONNull : JSONNode { private static JSONNull m_StaticInstance = new JSONNull(); public static bool reuseSameInstance = true; public override JSONNodeType Tag => JSONNodeType.NullValue; public override bool IsNull => true; public override string Value { get { return "null"; } set { } } public override bool AsBool { get { return false; } set { } } public static JSONNull CreateOrGet() { if (reuseSameInstance) { return m_StaticInstance; } return new JSONNull(); } private JSONNull() { } public override Enumerator GetEnumerator() { return default(Enumerator); } public override bool Equals(object obj) { if ((object)this == obj) { return true; } return obj is JSONNull; } public override int GetHashCode() { return 0; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append("null"); } } internal class JSONLazyCreator : JSONNode { private JSONNode m_Node = null; private string m_Key = null; public override JSONNodeType Tag => JSONNodeType.None; public override JSONNode this[int aIndex] { get { return new JSONLazyCreator(this); } set { JSONArray jSONArray = new JSONArray(); jSONArray.Add(value); Set(jSONArray); } } public override JSONNode this[string aKey] { get { return new JSONLazyCreator(this, aKey); } set { JSONObject jSONObject = new JSONObject(); jSONObject.Add(aKey, value); Set(jSONObject); } } public override int AsInt { get { JSONNumber aVal = new JSONNumber(0.0); Set(aVal); return 0; } set { JSONNumber aVal = new JSONNumber(value); Set(aVal); } } public override float AsFloat { get { JSONNumber aVal = new JSONNumber(0.0); Set(aVal); return 0f; } set { JSONNumber aVal = new JSONNumber(value); Set(aVal); } } public override double AsDouble { get { JSONNumber aVal = new JSONNumber(0.0); Set(aVal); return 0.0; } set { JSONNumber aVal = new JSONNumber(value); Set(aVal); } } public override bool AsBool { get { JSONBool aVal = new JSONBool(aData: false); Set(aVal); return false; } set { JSONBool aVal = new JSONBool(value); Set(aVal); } } public override JSONArray AsArray { get { JSONArray jSONArray = new JSONArray(); Set(jSONArray); return jSONArray; } } public override JSONObject AsObject { get { JSONObject jSONObject = new JSONObject(); Set(jSONObject); return jSONObject; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONLazyCreator(JSONNode aNode) { m_Node = aNode; m_Key = null; } public JSONLazyCreator(JSONNode aNode, string aKey) { m_Node = aNode; m_Key = aKey; } private void Set(JSONNode aVal) { if (m_Key == null) { m_Node.Add(aVal); } else { m_Node.Add(m_Key, aVal); } m_Node = null; } public override void Add(JSONNode aItem) { JSONArray jSONArray = new JSONArray(); jSONArray.Add(aItem); Set(jSONArray); } public override void Add(string aKey, JSONNode aItem) { JSONObject jSONObject = new JSONObject(); jSONObject.Add(aKey, aItem); Set(jSONObject); } public static bool operator ==(JSONLazyCreator a, object b) { if (b == null) { return true; } return (object)a == b; } public static bool operator !=(JSONLazyCreator a, object b) { return !(a == b); } public override bool Equals(object obj) { if (obj == null) { return true; } return (object)this == obj; } public override int GetHashCode() { return 0; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append("null"); } } public static class JSON { public static JSONNode Parse(string aJSON) { return JSONNode.Parse(aJSON); } } } namespace XUnity.AutoTranslator.Plugin { internal class SceneLoadInformation { public SceneInformation ActiveScene { get; set; } public List<SceneInformation> LoadedScenes { get; set; } public SceneLoadInformation() { LoadedScenes = new List<SceneInformation>(); if (UnityFeatures.SupportsSceneManager) { LoadBySceneManager(); } else { LoadByApplication(); } } public void LoadBySceneManager() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); ActiveScene = new SceneInformation(((Scene)(ref activeScene)).buildIndex, ((Scene)(ref activeScene)).name); for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); LoadedScenes.Add(new SceneInformation(((Scene)(ref sceneAt)).buildIndex, ((Scene)(ref sceneAt)).name)); } } public void LoadByApplication() { ActiveScene = new SceneInformation(Application.loadedLevel, Application.loadedLevelName); LoadedScenes.Add(new SceneInformation(Application.loadedLevel, Application.loadedLevelName)); } } internal class SceneInformation { public int Id { get; set; } public string Name { get; set; } public SceneInformation(int id, string name) { Id = id; Name = name; } } } namespace XUnity.AutoTranslator.Plugin.Utilities { internal static class TranslationScopeHelper { public static int GetScope(object ui) { if (Settings.EnableTranslationScoping) { try { Component val = (Component)((ui is Component) ? ui : null); if (val != null && Object.op_Implicit((Object)(object)val)) { return GetScopeFromComponent(val); } GUIContent val2 = (GUIContent)((ui is GUIContent) ? ui : null); if (val2 != null) { return -1; } return GetActiveSceneId(); } catch (MissingMemberException ex) { XuaLogger.AutoTranslator.Error((Exception)ex, "A 'missing member' error occurred while retriving translation scope. Disabling translation scopes."); Settings.EnableTranslationScoping = false; } } return -1; } private static int GetScopeFromComponent(Component component) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Scene scene = component.gameObject.scene; return ((Scene)(ref scene)).buildIndex; } public static int GetActiveSceneId() { if (UnityFeatures.SupportsSceneManager) { return GetActiveSceneIdBySceneManager(); } return GetActiveSceneIdByApplication(); } private static int GetActiveSceneIdBySceneManager() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).buildIndex; } public static void RegisterSceneLoadCallback(Action<int> sceneLoaded) { SceneManagerLoader.EnableSceneLoadScanInternal(sceneLoaded); } private static int GetActiveSceneIdByApplication() { return Application.loadedLevel; } } internal static class SceneManagerLoader { public static void EnableSceneLoadScanInternal(Action<int> sceneLoaded) { SceneManager.sceneLoaded += delegate(Scene arg1, LoadSceneMode arg2) { sceneLoaded(((Scene)(ref arg1)).buildIndex); }; } } internal static class TranslationScopes { public const int None = -1; } } namespace XUnity.AutoTranslator.Plugin.Core { public class AutoTranslationPlugin : MonoBehaviour, IMonoBehaviour, IMonoBehaviour_Update, IInternalTranslator, ITranslator, ITranslationRegistry { internal static AutoTranslationPlugin Current; private bool _hasResizedCurrentComponentDuringDiscovery; internal XuaWindow MainWindow; internal TranslationAggregatorWindow TranslationAggregatorWindow; internal TranslationAggregatorOptionsWindow TranslationAggregatorOptionsWindow; internal TranslationManager TranslationManager; internal TextTranslationCache TextCache; internal Dictionary<string, TextTranslationCache> PluginTextCaches = new Dictionary<string, TextTranslationCache>(StringComparer.OrdinalIgnoreCase); internal TextureTranslationCache TextureCache; internal UIResizeCache ResizeCache; internal SpamChecker SpamChecker; private Dictionary<string, UntranslatedText> CachedKeys = new Dictionary<string, UntranslatedText>(StringComparer.Ordinal); private List<Action<ComponentTranslationContext>> _shouldIgnore = new List<Action<ComponentTranslationContext>>(); private List<string> _textsToCopyToClipboardOrdered = new List<string>(); private HashSet<string> _textsToCopyToClipboard = new HashSet<string>(); private float _clipboardUpdated = 0f; private HashSet<string> _immediatelyTranslating = new HashSet<string>(); private bool _isInTranslatedMode = true; private bool _textHooksEnabled = true; private float _batchOperationSecondCounter = 0f; private bool _hasValidOverrideFont = false; private bool _hasOverridenFont = false; private bool _initialized = false; private bool _started = false; private bool _temporarilyDisabled = false; private string _requireSpriteRendererCheckCausedBy = null; private int _lastSpriteUpdateFrame = -1; private bool _isCalledFromSceneManager = false; private bool _translationReloadRequest = false; private bool _hasUiBeenSetup = false; private static bool _inputSupported = true; public void Initialize() { Current = this; Paths.Initialize(); HarmonyLoader.Load(); Settings.Configure(); DebugConsole.Enable(); InitializeHarmonyDetourBridge(); InitializeTextTranslationCaches(); HooksSetup.InstallTextHooks(); HooksSetup.InstallImageHooks(); HooksSetup.InstallSpriteRendererHooks(); HooksSetup.InstallTextGetterCompatHooks(); HooksSetup.InstallComponentBasedPluginTranslationHooks(); TextureCache = new TextureTranslationCache(); TextureCache.TextureTranslationFileChanged += TextureCache_TextureTranslationFileChanged; ResizeCache = new UIResizeCache(); TranslationManager = new TranslationManager(); TranslationManager.JobCompleted += OnJobCompleted; TranslationManager.JobFailed += OnJobFailed; TranslationManager.InitializeEndpoints(); SpamChecker = new SpamChecker(TranslationManager); UnityTextParsers.Initialize(); InitializeResourceRedirector(); ValidateConfiguration(); EnableSceneLoadScan(); LoadFallbackFont(); LoadTranslations(reload: false); XuaLogger.AutoTranslator.Info("Loaded XUnity.AutoTranslator into Unity [" + Application.unityVersion + "] game."); } private static void LoadFallbackFont() { try { if (!string.IsNullOrEmpty(Settings.FallbackFontTextMeshPro)) { Object orCreateFallbackFontTextMeshPro = FontCache.GetOrCreateFallbackFontTextMeshPro(); if (TMP_Settings_Properties.FallbackFontAssets == null) { XuaLogger.AutoTranslator.Info("Cannot use fallback font because it is not supported in this version."); return; } if (orCreateFallbackFontTextMeshPro == (Object)null) { XuaLogger.AutoTranslator.Warn("Could not load fallback font for TextMesh Pro: " + Settings.FallbackFontTextMeshPro); return; } IList list = (IList)TMP_Settings_Properties.FallbackFontAssets.Get((object)null); list.Add(orCreateFallbackFontTextMeshPro); XuaLogger.AutoTranslator.Info("Loaded fallback font for TextMesh Pro: " + Settings.FallbackFontTextMeshPro); } } catch (Exception ex) { XuaLogger.AutoTranslator.Error(ex, "An error occurred while trying to load fallback font for TextMesh Pro."); } } private static void InitializeHarmonyDetourBridge() { try { if (Settings.InitializeHarmonyDetourBridge) { InitializeHarmonyDetourBridgeSafe(); } } catch (Exception ex) { XuaLogger.AutoTranslator.Error(ex, "An error occurred while initializing harmony detour bridge."); } } private static void InitializeHarmonyDetourBridgeSafe() { HarmonyDetourBridge.Init(true, (Type)0); } private void InitializeTextTranslationCaches() { try { TextCache = new TextTranslationCache(); TextCache.TextTranslationFileChanged += TextCache_TextTranslationFileChanged; string path = Path.Combine(Settings.TranslationsPath, "plugins"); DirectoryInfo directoryInfo = new DirectoryInfo(path); if (directoryInfo.Exists) { DirectoryInfo[] directories = directoryInfo.GetDirectories(); foreach (DirectoryInfo directoryInfo2 in directories) { TextTranslationCache value = new TextTranslationCache(directoryInfo2); PluginTextCaches.Add(directoryInfo2.Name, value); } } } catch (Exception ex) { XuaLogger.AutoTranslator.Error(ex, "An error occurred while initializing text translation caches."); } } private void TextCache_TextTranslationFile
BepInEx/plugins/XUnity.AutoTranslator/XUnity.AutoTranslator.Plugin.ExtProtocol.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("gravydevsupreme")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Package that contains a simple inter-process protocol format used in XUnity.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+27fbfc0c2dfc32b3bb59b97a5639344e09ecfdc5")] [assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.ExtProtocol")] [assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.ExtProtocol")] [assembly: AssemblyVersion("1.0.1.0")] namespace XUnity.AutoTranslator.Plugin.ExtProtocol; public class ConfigurationMessage : ProtocolMessage { public static readonly string Type = "4"; public string Config { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); Config = reader.ReadToEnd(); } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.Write(Config); } } public static class ExtProtocolConvert { private static readonly Dictionary<string, Type> IdToType; private static readonly Dictionary<Type, string> TypeToId; static ExtProtocolConvert() { IdToType = new Dictionary<string, Type>(); TypeToId = new Dictionary<Type, string>(); Register(TranslationRequest.Type, typeof(TranslationRequest)); Register(TranslationResponse.Type, typeof(TranslationResponse)); Register(TranslationError.Type, typeof(TranslationError)); Register(ConfigurationMessage.Type, typeof(ConfigurationMessage)); } public static void Register(string id, Type type) { IdToType[id] = type; TypeToId[type] = id; } public static string Encode(ProtocolMessage message) { StringWriter stringWriter = new StringWriter(); string value = TypeToId[message.GetType()]; stringWriter.WriteLine(value); message.Encode(stringWriter); return Convert.ToBase64String(Encoding.UTF8.GetBytes(stringWriter.ToString()), Base64FormattingOptions.None); } public static ProtocolMessage Decode(string message) { string @string = Encoding.UTF8.GetString(Convert.FromBase64String(message)); StringReader stringReader = new StringReader(@string); string key = stringReader.ReadLine(); Type type = IdToType[key]; ProtocolMessage protocolMessage = (ProtocolMessage)Activator.CreateInstance(type); protocolMessage.Decode(stringReader); return protocolMessage; } } public abstract class ProtocolMessage { public Guid Id { get; set; } internal abstract void Decode(TextReader reader); internal abstract void Encode(TextWriter writer); } public enum StatusCode { OK = 0, Blocked = 1, Unknown = 1000 } public class TranslationError : ProtocolMessage { public static readonly string Type = "3"; public string Reason { get; set; } public StatusCode FailureCode { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); FailureCode = (StatusCode)int.Parse(reader.ReadLine()); Reason = reader.ReadToEnd(); } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.WriteLine((int)FailureCode); writer.Write(Reason); } } public class TranslationRequest : ProtocolMessage { public static readonly string Type = "1"; private string[] _untranslatedTexts; public string SourceLanguage { get; set; } public string DestinationLanguage { get; set; } public string[] UntranslatedTexts => _untranslatedTexts ?? (_untranslatedTexts = UntranslatedTextInfos.Select((TransmittableUntranslatedTextInfo x) => x.UntranslatedText).ToArray()); public TransmittableUntranslatedTextInfo[] UntranslatedTextInfos { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); SourceLanguage = reader.ReadLine(); DestinationLanguage = reader.ReadLine(); int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); TransmittableUntranslatedTextInfo[] array = new TransmittableUntranslatedTextInfo[num]; for (int i = 0; i < num; i++) { TransmittableUntranslatedTextInfo transmittableUntranslatedTextInfo = new TransmittableUntranslatedTextInfo(); transmittableUntranslatedTextInfo.Decode(reader); array[i] = transmittableUntranslatedTextInfo; } UntranslatedTextInfos = array; } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.WriteLine(SourceLanguage); writer.WriteLine(DestinationLanguage); writer.WriteLine(UntranslatedTextInfos.Length.ToString(CultureInfo.InvariantCulture)); TransmittableUntranslatedTextInfo[] untranslatedTextInfos = UntranslatedTextInfos; foreach (TransmittableUntranslatedTextInfo transmittableUntranslatedTextInfo in untranslatedTextInfos) { transmittableUntranslatedTextInfo.Encode(writer); } } } public class TranslationResponse : ProtocolMessage { public static readonly string Type = "2"; public string[] TranslatedTexts { get; set; } internal override void Decode(TextReader reader) { base.Id = new Guid(reader.ReadLine()); int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); string[] array = new string[num]; for (int i = 0; i < num; i++) { string s = reader.ReadLine(); string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s)); array[i] = @string; } TranslatedTexts = array; } internal override void Encode(TextWriter writer) { writer.WriteLine(base.Id.ToString()); writer.WriteLine(TranslatedTexts.Length.ToString(CultureInfo.InvariantCulture)); string[] translatedTexts = TranslatedTexts; foreach (string s in translatedTexts) { string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None); writer.WriteLine(value); } } } public class TransmittableUntranslatedTextInfo { public string[] ContextBefore { get; set; } public string UntranslatedText { get; set; } public string[] ContextAfter { get; set; } public TransmittableUntranslatedTextInfo(string[] contextBefore, string untranslatedText, string[] contextAfter) { ContextBefore = contextBefore; UntranslatedText = untranslatedText; ContextAfter = contextAfter; } public TransmittableUntranslatedTextInfo() { } internal void Encode(TextWriter writer) { string[] contextBefore = ContextBefore; writer.WriteLine(((contextBefore != null) ? contextBefore.Length : 0).ToString(CultureInfo.InvariantCulture)); if (ContextBefore != null) { string[] contextBefore2 = ContextBefore; foreach (string s in contextBefore2) { string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None); writer.WriteLine(value); } } string[] contextAfter = ContextAfter; writer.WriteLine(((contextAfter != null) ? contextAfter.Length : 0).ToString(CultureInfo.InvariantCulture)); if (ContextAfter != null) { string[] contextAfter2 = ContextAfter; foreach (string s2 in contextAfter2) { string value2 = Convert.ToBase64String(Encoding.UTF8.GetBytes(s2), Base64FormattingOptions.None); writer.WriteLine(value2); } } string value3 = Convert.ToBase64String(Encoding.UTF8.GetBytes(UntranslatedText), Base64FormattingOptions.None); writer.WriteLine(value3); } internal void Decode(TextReader reader) { int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); string[] array = new string[num]; for (int i = 0; i < num; i++) { string s = reader.ReadLine(); string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s)); array[i] = @string; } ContextBefore = array; int num2 = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture); string[] array2 = new string[num2]; for (int j = 0; j < num2; j++) { string s2 = reader.ReadLine(); string string2 = Encoding.UTF8.GetString(Convert.FromBase64String(s2)); array2[j] = string2; } ContextAfter = array2; string s3 = reader.ReadLine(); string string3 = Encoding.UTF8.GetString(Convert.FromBase64String(s3)); UntranslatedText = string3; } }
BepInEx/plugins/XUnity.ResourceRedirector/XUnity.ResourceRedirector.BepInEx.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("XUnity.ResourceRedirector.BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.1.0.0")] [assembly: AssemblyInformationalVersion("2.1.0")] [assembly: AssemblyProduct("XUnity.ResourceRedirector.BepInEx")] [assembly: AssemblyTitle("XUnity.ResourceRedirector.BepInEx")] [assembly: AssemblyVersion("2.1.0.0")] namespace XUnity.ResourceRedirector.BepInEx; [BepInPlugin("gravydevsupreme.xunity.resourceredirector", "XUnity Resource Redirector", "2.1.0")] public class ResourceRedirectorPlugin : BaseUnityPlugin { public static ConfigEntry<bool> LogAllLoadedResources { get; set; } public static ConfigEntry<bool> LogCallbackOrder { get; set; } private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown LogAllLoadedResources = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("Diagnostics", "Log all loaded resources"), false, (ConfigDescription)null); ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value; LogAllLoadedResources.SettingChanged += delegate { ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value; }; LogCallbackOrder = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("Diagnostics", "Log callback order"), false, (ConfigDescription)null); ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value; LogCallbackOrder.SettingChanged += delegate { ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value; }; ((BaseUnityPlugin)this).Config.ConfigReloaded += Config_ConfigReloaded; } private static void Config_ConfigReloaded(object sender, EventArgs e) { ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value; ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value; } }
BepInEx/plugins/XUnity.ResourceRedirector/XUnity.ResourceRedirector.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; using UnityEngine; using XUnity.Common.Constants; using XUnity.Common.Extensions; using XUnity.Common.Harmony; using XUnity.Common.Logging; using XUnity.Common.MonoMod; using XUnity.Common.Utilities; using XUnity.ResourceRedirector.Constants; using XUnity.ResourceRedirector.Hooks; using XUnity.ResourceRedirector.Properties; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("gravydevsupreme")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Main development dependency for XUnity Resource Redirector.")] [assembly: AssemblyFileVersion("2.1.0.0")] [assembly: AssemblyInformationalVersion("2.1.0")] [assembly: AssemblyProduct("XUnity.ResourceRedirector")] [assembly: AssemblyTitle("XUnity.ResourceRedirector")] [assembly: AssemblyVersion("2.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace XUnity.ResourceRedirector { internal class AssetBundleExtensionData { private string _normalizedPath; private string _path; public string NormalizedPath { get { if (Path != null && _normalizedPath == null) { _normalizedPath = StringExtensions.MakeRelativePath(Path.ToLowerInvariant(), EnvironmentEx.LoweredCurrentDirectory); } return _normalizedPath; } } public string Path { get { return _path; } set { if (_path != value) { _path = value; _normalizedPath = null; } } } } public static class AssetBundleHelper { internal static string PathForLoadedInMemoryBundle; public static AssetBundle CreateEmptyAssetBundle() { byte[] empty = Resources.empty; CabHelper.RandomizeCab(empty); return AssetBundle.LoadFromMemory(empty); } public static AssetBundleCreateRequest CreateEmptyAssetBundleRequest() { byte[] empty = Resources.empty; CabHelper.RandomizeCab(empty); return AssetBundle.LoadFromMemoryAsync(empty); } public static AssetBundle LoadFromMemory(string path, byte[] binary, uint crc) { try { PathForLoadedInMemoryBundle = path; return AssetBundle.LoadFromMemory(binary, crc); } finally { PathForLoadedInMemoryBundle = null; } } public static AssetBundleCreateRequest LoadFromMemoryAsync(string path, byte[] binary, uint crc) { try { PathForLoadedInMemoryBundle = path; return AssetBundle.LoadFromMemoryAsync(binary, crc); } finally { PathForLoadedInMemoryBundle = null; } } public static AssetBundle LoadFromFileWithRandomizedCabIfRequired(string path, uint crc, ulong offset) { return LoadFromFileWithRandomizedCabIfRequired(path, crc, offset, confirmFileExists: true); } internal static AssetBundle LoadFromFileWithRandomizedCabIfRequired(string path, uint crc, ulong offset, bool confirmFileExists) { AssetBundle val = AssetBundle.LoadFromFile(path, crc, offset); if ((Object)(object)val == (Object)null && (!confirmFileExists || File.Exists(path))) { byte[] array; using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read)) { long num = fileStream.Length - (long)offset; fileStream.Seek((long)offset, SeekOrigin.Begin); array = StreamExtensions.ReadFully((Stream)fileStream, (int)num); } CabHelper.RandomizeCabWithAnyLength(array); XuaLogger.ResourceRedirector.Warn("Randomized CAB for '" + path + "' in order to load it because another asset bundle already uses its CAB-string. You can ignore the previous error message, but this is likely caused by two mods incorrectly using the same CAB-string."); return AssetBundle.LoadFromMemory(array); } return val; } } public class AssetBundleLoadedContext { private string _normalizedPath; public AssetBundleLoadingParameters Parameters { get; } public AssetBundle Bundle { get; set; } internal bool SkipRemainingPostfixes { get; private set; } internal AssetBundleLoadedContext(AssetBundleLoadingParameters parameters, AssetBundle bundle) { Parameters = parameters; Bundle = bundle; } public string GetNormalizedPath() { if (_normalizedPath == null && Parameters.Path != null) { _normalizedPath = StringExtensions.MakeRelativePath(StringExtensions.UseCorrectDirectorySeparators(Parameters.Path.ToLowerInvariant()), EnvironmentEx.LoweredCurrentDirectory); } return _normalizedPath; } public void Complete(bool skipRemainingPostfixes = true) { SkipRemainingPostfixes = skipRemainingPostfixes; } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public class AssetBundleLoadingContext : IAssetBundleLoadingContext { private string _normalizedPath; public AssetBundleLoadingParameters Parameters { get; } public AssetBundle Bundle { get; set; } internal bool SkipRemainingPrefixes { get; private set; } internal bool SkipOriginalCall { get; private set; } internal bool SkipAllPostfixes { get; private set; } internal AssetBundleLoadingContext(AssetBundleLoadingParameters parameters) { Parameters = parameters; } public string GetNormalizedPath() { if (_normalizedPath == null && Parameters.Path != null) { _normalizedPath = StringExtensions.MakeRelativePath(StringExtensions.UseCorrectDirectorySeparators(Parameters.Path.ToLowerInvariant()), EnvironmentEx.LoweredCurrentDirectory); } return _normalizedPath; } public void Complete() { Complete(skipRemainingPrefixes: true, true, true); } public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true) { Complete(skipRemainingPrefixes, skipOriginalCall, true); } public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true) { SkipRemainingPrefixes = skipRemainingPrefixes; if (skipOriginalCall.HasValue) { SkipOriginalCall = skipOriginalCall.Value; } if (skipAllPostfixes.HasValue) { SkipAllPostfixes = skipAllPostfixes.Value; } } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public class AssetBundleLoadingParameters { public string Path { get; set; } public uint Crc { get; set; } public ulong Offset { get; set; } public Stream Stream { get; set; } public uint ManagedReadBufferSize { get; } public byte[] Binary { get; set; } public AssetBundleLoadType LoadType { get; } internal AssetBundleLoadingParameters(byte[] data, string path, uint crc, ulong offset, Stream stream, uint managedReadBufferSize, AssetBundleLoadType loadType) { Binary = data; Path = path; Crc = crc; Offset = offset; Stream = stream; ManagedReadBufferSize = managedReadBufferSize; LoadType = loadType; } } public enum AssetBundleLoadType { LoadFromFile = 1, LoadFromMemory, LoadFromStream } public class AssetLoadedContext : IAssetOrResourceLoadedContext { private AssetBundleExtensionData _ext; private bool _lookedForExt; private BackingFieldOrArray _backingField; public AssetLoadedParameters Parameters { get; } public AssetBundle Bundle { get; } public Object[] Assets { get { return _backingField.Array; } set { _backingField.Array = value; } } public Object Asset { get { return _backingField.Field; } set { _backingField.Field = value; } } internal bool SkipRemainingPostfixes { get; private set; } internal AssetLoadedContext(AssetLoadedParameters parameters, AssetBundle bundle, Object[] assets) { Parameters = parameters; Bundle = bundle; _backingField = new BackingFieldOrArray(assets); } internal AssetLoadedContext(AssetLoadedParameters parameters, AssetBundle bundle, Object asset) { Parameters = parameters; Bundle = bundle; _backingField = new BackingFieldOrArray(asset); } public bool HasReferenceBeenRedirectedBefore(Object asset) { return ExtensionDataHelper.GetExtensionData<ResourceExtensionData>((object)asset)?.HasBeenRedirected ?? false; } public string GetUniqueFileSystemAssetPath(Object asset) { ResourceExtensionData orCreateExtensionData = ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)asset); if (orCreateExtensionData.FullFileSystemAssetPath == null) { string text = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle)?.NormalizedPath; string path = (string.IsNullOrEmpty(text) ? "unnamed_assetbundle" : text.ToLowerInvariant()); string name = asset.name; if (!string.IsNullOrEmpty(name)) { path = Path.Combine(path, name.ToLowerInvariant()); } else { string text2 = null; if (Assets.Length > 1) { int num = Array.IndexOf(Assets, asset); text2 = ((num != -1) ? ("_" + num.ToString(CultureInfo.InvariantCulture)) : "_with_unknown_index"); } path = Path.Combine(path, (Parameters.LoadType == AssetLoadType.LoadMainAsset) ? "main_asset" : ("unnamed_asset" + text2)); } path = StringExtensions.UseCorrectDirectorySeparators(path); orCreateExtensionData.FullFileSystemAssetPath = path; } return orCreateExtensionData.FullFileSystemAssetPath; } public string GetAssetBundlePath() { if (!_lookedForExt) { _lookedForExt = true; _ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle); } return _ext?.Path; } public string GetNormalizedAssetBundlePath() { if (!_lookedForExt) { _lookedForExt = true; _ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle); } return _ext?.NormalizedPath; } public void Complete(bool skipRemainingPostfixes = true) { SkipRemainingPostfixes = skipRemainingPostfixes; } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public class AssetLoadedParameters { public string Name { get; } public Type Type { get; } public AssetLoadType LoadType { get; } internal AssetLoadedParameters(string name, Type type, AssetLoadType loadType) { Name = name; Type = type; LoadType = loadType; } } public class AssetLoadingContext : IAssetLoadingContext { private AssetBundleExtensionData _ext; private bool _lookedForExt; private BackingFieldOrArray _backingField; public AssetLoadingParameters Parameters { get; } public AssetBundle Bundle { get; } public Object[] Assets { get { return _backingField.Array; } set { _backingField.Array = value; } } public Object Asset { get { return _backingField.Field; } set { _backingField.Field = value; } } internal bool SkipRemainingPrefixes { get; private set; } internal bool SkipOriginalCall { get; private set; } internal bool SkipAllPostfixes { get; private set; } internal AssetLoadingContext(AssetLoadingParameters parameters, AssetBundle bundle) { Parameters = parameters; Bundle = bundle; } public string GetAssetBundlePath() { if (!_lookedForExt) { _lookedForExt = true; _ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle); } return _ext?.Path; } public string GetNormalizedAssetBundlePath() { if (!_lookedForExt) { _lookedForExt = true; _ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle); } return _ext?.NormalizedPath; } public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true) { SkipRemainingPrefixes = skipRemainingPrefixes; if (skipOriginalCall.HasValue) { SkipOriginalCall = skipOriginalCall.Value; } if (skipAllPostfixes.HasValue) { SkipAllPostfixes = skipAllPostfixes.Value; } } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public class AssetLoadingParameters { public string Name { get; set; } public Type Type { get; set; } public AssetLoadType LoadType { get; } internal AssetLoadingParameters(string name, Type type, AssetLoadType loadType) { Name = name; Type = type; LoadType = loadType; } internal AssetLoadedParameters ToAssetLoadedParameters() { return new AssetLoadedParameters(Name, Type, LoadType); } } public enum AssetLoadType { LoadMainAsset = 1, LoadByType, LoadNamed, LoadNamedWithSubAssets } internal class AsyncAssetBundleLoadInfo { public AssetBundleLoadingParameters Parameters { get; } public AssetBundle Bundle { get; } public bool SkipAllPostfixes { get; } public AsyncAssetBundleLoadingResolve ResolveType { get; } public AsyncAssetBundleLoadInfo(AssetBundleLoadingParameters parameters, AssetBundle bundle, bool skipAllPostfixes, AsyncAssetBundleLoadingResolve resolveType) { Parameters = parameters; Bundle = bundle; SkipAllPostfixes = skipAllPostfixes; ResolveType = resolveType; } } public class AsyncAssetBundleLoadingContext : IAssetBundleLoadingContext { private string _normalizedPath; private AssetBundle _bundle; private AssetBundleCreateRequest _request; public AssetBundleLoadingParameters Parameters { get; } public AssetBundleCreateRequest Request { get { return _request; } set { _request = value; ResolveType = AsyncAssetBundleLoadingResolve.ThroughRequest; } } public AssetBundle Bundle { get { return _bundle; } set { if (!ResourceRedirection.SyncOverAsyncEnabled) { throw new InvalidOperationException("Trying to set the Bundle property in async load operation while 'SyncOverAsyncAssetLoads' is disabled is not allowed. Consider settting the Request property instead if possible or enabling 'SyncOverAsyncAssetLoads' through the method 'ResourceRedirection.EnableSyncOverAsyncAssetLoads()'."); } _bundle = value; ResolveType = AsyncAssetBundleLoadingResolve.ThroughBundle; } } public AsyncAssetBundleLoadingResolve ResolveType { get; set; } internal bool SkipRemainingPrefixes { get; private set; } internal bool SkipOriginalCall { get; set; } internal bool SkipAllPostfixes { get; private set; } internal AsyncAssetBundleLoadingContext(AssetBundleLoadingParameters parameters) { Parameters = parameters; } public string GetNormalizedPath() { if (_normalizedPath == null && Parameters.Path != null) { _normalizedPath = StringExtensions.MakeRelativePath(StringExtensions.UseCorrectDirectorySeparators(Parameters.Path.ToLowerInvariant()), EnvironmentEx.LoweredCurrentDirectory); } return _normalizedPath; } public void Complete() { Complete(skipRemainingPrefixes: true, true, true); } public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true) { Complete(skipRemainingPrefixes, skipOriginalCall, true); } public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true) { SkipRemainingPrefixes = skipRemainingPrefixes; if (skipOriginalCall.HasValue) { SkipOriginalCall = skipOriginalCall.Value; } if (skipAllPostfixes.HasValue) { SkipAllPostfixes = skipAllPostfixes.Value; } } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public enum AsyncAssetBundleLoadingResolve { ThroughRequest, ThroughBundle } internal class AsyncAssetLoadInfo { public AssetLoadingParameters Parameters { get; } public AssetBundle Bundle { get; } public bool SkipAllPostfixes { get; } public AsyncAssetLoadingResolve ResolveType { get; } public Object[] Assets { get; } public AsyncAssetLoadInfo(AssetLoadingParameters parameters, AssetBundle bundle, bool skipAllPostfixes, AsyncAssetLoadingResolve resolveType, Object[] assets) { Parameters = parameters; Bundle = bundle; SkipAllPostfixes = skipAllPostfixes; ResolveType = resolveType; Assets = assets; } } public class AsyncAssetLoadingContext : IAssetLoadingContext { private AssetBundleExtensionData _ext; private bool _lookedForExt; private Object[] _assets; private AssetBundleRequest _request; private BackingFieldOrArray _backingField; public AssetLoadingParameters Parameters { get; } public AssetBundle Bundle { get; } public AssetBundleRequest Request { get { return _request; } set { _request = value; ResolveType = AsyncAssetLoadingResolve.ThroughRequest; } } public Object[] Assets { get { return _backingField.Array; } set { if (!ResourceRedirection.SyncOverAsyncEnabled) { throw new InvalidOperationException("Trying to set the Assets/Asset property in async load operation while 'SyncOverAsyncAssetLoads' is disabled is not allowed. Consider settting the Request property instead if possible or enabling 'SyncOverAsyncAssetLoads' through the method 'ResourceRedirection.EnableSyncOverAsyncAssetLoads()'."); } _backingField.Array = value; ResolveType = AsyncAssetLoadingResolve.ThroughAssets; } } public Object Asset { get { return _backingField.Field; } set { if (!ResourceRedirection.SyncOverAsyncEnabled) { throw new InvalidOperationException("Trying to set the Assets/Asset property in async load operation while 'SyncOverAsyncAssetLoads' is disabled is not allowed. Consider settting the Request property instead if possible or enabling 'SyncOverAsyncAssetLoads' through the method 'ResourceRedirection.EnableSyncOverAsyncAssetLoads()'."); } _backingField.Field = value; ResolveType = AsyncAssetLoadingResolve.ThroughAssets; } } public AsyncAssetLoadingResolve ResolveType { get; set; } internal bool SkipRemainingPrefixes { get; private set; } internal bool SkipOriginalCall { get; set; } internal bool SkipAllPostfixes { get; private set; } internal AsyncAssetLoadingContext(AssetLoadingParameters parameters, AssetBundle bundle) { Parameters = parameters; Bundle = bundle; } public string GetAssetBundlePath() { if (!_lookedForExt) { _lookedForExt = true; _ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle); } return _ext?.Path; } public string GetNormalizedAssetBundlePath() { if (!_lookedForExt) { _lookedForExt = true; _ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle); } return _ext?.NormalizedPath; } public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true) { SkipRemainingPrefixes = skipRemainingPrefixes; if (skipOriginalCall.HasValue) { SkipOriginalCall = skipOriginalCall.Value; } if (skipAllPostfixes.HasValue) { SkipAllPostfixes = skipAllPostfixes.Value; } } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public enum AsyncAssetLoadingResolve { ThroughRequest, ThroughAssets } internal struct BackingFieldOrArray { private Object _field; private Object[] _array; private BackingSource _source; public Object Field { get { if (_source == BackingSource.None) { return null; } if (_source == BackingSource.SingleField) { return _field; } if (_array == null || _array.Length == 0) { return null; } return _array[0]; } set { _field = value; _array = null; _source = BackingSource.SingleField; } } public Object[] Array { get { if (_source == BackingSource.Array) { return _array; } if (_field == (Object)null) { Array = (Object[])(object)new Object[0]; } else { Array = (Object[])(object)new Object[1] { _field }; } return _array; } set { _field = null; _array = value; _source = BackingSource.Array; } } public BackingFieldOrArray(Object field) { _field = field; _array = null; _source = BackingSource.SingleField; } public BackingFieldOrArray(Object[] array) { _field = null; _array = array; _source = BackingSource.Array; } public IEnumerable<Object> IterateObjects() { if (_array != null) { Object[] array = _array; for (int i = 0; i < array.Length; i++) { yield return array[i]; } } else if (_field != (Object)null) { yield return _field; } } } internal enum BackingSource : byte { None, SingleField, Array } public static class CallbackPriority { public const int Default = 0; } public enum HookBehaviour { OneCallbackPerLoadCall = 1, OneCallbackPerResourceLoaded } public interface IAssetBundleLoadingContext { AssetBundleLoadingParameters Parameters { get; } AssetBundle Bundle { get; set; } string GetNormalizedPath(); void Complete(); void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true); void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true); void DisableRecursion(); } public interface IAssetLoadingContext { AssetLoadingParameters Parameters { get; } AssetBundle Bundle { get; } Object[] Assets { get; set; } Object Asset { get; set; } string GetAssetBundlePath(); string GetNormalizedAssetBundlePath(); void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true); void DisableRecursion(); } public interface IAssetOrResourceLoadedContext { Object[] Assets { get; set; } Object Asset { get; set; } bool HasReferenceBeenRedirectedBefore(Object asset); string GetUniqueFileSystemAssetPath(Object asset); void Complete(bool skipRemainingPostfixes = true); void DisableRecursion(); } internal class PrioritizedCallback { public static PrioritizedCallback<TCallback> Create<TCallback>(TCallback item, int priority) where TCallback : Delegate { return new PrioritizedCallback<TCallback>(item, priority); } } internal class PrioritizedCallback<TCallback> : PrioritizedCallback, IComparable<PrioritizedCallback<TCallback>>, IEquatable<PrioritizedCallback<TCallback>> where TCallback : Delegate { public TCallback Callback { get; } public int Priority { get; } public Type TargetType { get; set; } public bool IsBeingCalled { get; set; } public PrioritizedCallback(TCallback callback, int priority) { Callback = callback; Priority = priority; TargetType = callback.Target?.GetType(); } public int CompareTo(PrioritizedCallback<TCallback> other) { return other.Priority.CompareTo(Priority); } public override bool Equals(object obj) { return Equals(obj as PrioritizedCallback<TCallback>); } public bool Equals(PrioritizedCallback<TCallback> other) { return EqualityComparer<TCallback>.Default.Equals(Callback, other.Callback); } public override int GetHashCode() { return -1406788065 * -1521134295 + EqualityComparer<TCallback>.Default.GetHashCode(Callback); } public override string ToString() { return "[" + Priority + "] " + (TargetType?.Name ?? Callback.Method.DeclaringType?.Name) + "." + Callback.Method?.Name; } } internal class ResourceExtensionData { public bool HasBeenRedirected { get; set; } public string FullFileSystemAssetPath { get; set; } } public class ResourceLoadedContext : IAssetOrResourceLoadedContext { private BackingFieldOrArray _backingField; public ResourceLoadedParameters Parameters { get; } public Object[] Assets { get { return _backingField.Array; } set { _backingField.Array = value; } } public Object Asset { get { return _backingField.Field; } set { _backingField.Field = value; } } internal bool SkipRemainingPostfixes { get; set; } internal ResourceLoadedContext(ResourceLoadedParameters parameters, Object[] assets) { Parameters = parameters; _backingField = new BackingFieldOrArray(assets); } internal ResourceLoadedContext(ResourceLoadedParameters parameters, Object asset) { Parameters = parameters; _backingField = new BackingFieldOrArray(asset); } public bool HasReferenceBeenRedirectedBefore(Object asset) { return ExtensionDataHelper.GetExtensionData<ResourceExtensionData>((object)asset)?.HasBeenRedirected ?? false; } public string GetUniqueFileSystemAssetPath(Object asset) { ResourceExtensionData orCreateExtensionData = ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)asset); if (orCreateExtensionData.FullFileSystemAssetPath == null) { string text = string.Empty; if (!string.IsNullOrEmpty(Parameters.Path)) { text = Parameters.Path.ToLowerInvariant(); } if (Parameters.LoadType == ResourceLoadType.LoadByType) { string name = asset.name; if (!string.IsNullOrEmpty(name)) { text = Path.Combine(text, name.ToLowerInvariant()); } else { string text2 = null; if (Assets.Length > 1) { int num = Array.IndexOf(Assets, asset); text2 = ((num != -1) ? ("_" + num.ToString(CultureInfo.InvariantCulture)) : "_with_unknown_index"); } text = Path.Combine(text, "unnamed_asset" + text2); } } text = StringExtensions.UseCorrectDirectorySeparators(text); orCreateExtensionData.FullFileSystemAssetPath = text; } return orCreateExtensionData.FullFileSystemAssetPath; } public void Complete(bool skipRemainingPostfixes = true) { SkipRemainingPostfixes = skipRemainingPostfixes; } public void DisableRecursion() { ResourceRedirection.RecursionEnabled = false; } } public class ResourceLoadedParameters { public string Path { get; set; } public Type Type { get; set; } public ResourceLoadType LoadType { get; } internal ResourceLoadedParameters(string path, Type type, ResourceLoadType loadType) { Path = path; Type = type; LoadType = loadType; } } public enum ResourceLoadType { LoadByType = 1, LoadNamed, LoadNamedBuiltIn } public static class ResourceRedirection { private static readonly List<PrioritizedCallback<Action<AssetLoadedContext>>> PostfixRedirectionsForAssetsPerCall = new List<PrioritizedCallback<Action<AssetLoadedContext>>>(); private static readonly List<PrioritizedCallback<Action<AssetLoadedContext>>> PostfixRedirectionsForAssetsPerResource = new List<PrioritizedCallback<Action<AssetLoadedContext>>>(); private static readonly List<PrioritizedCallback<Action<ResourceLoadedContext>>> PostfixRedirectionsForResourcesPerCall = new List<PrioritizedCallback<Action<ResourceLoadedContext>>>(); private static readonly List<PrioritizedCallback<Action<ResourceLoadedContext>>> PostfixRedirectionsForResourcesPerResource = new List<PrioritizedCallback<Action<ResourceLoadedContext>>>(); private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAssetsPerCall = new List<PrioritizedCallback<Delegate>>(); private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAsyncAssetsPerCall = new List<PrioritizedCallback<Delegate>>(); private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAssetBundles = new List<PrioritizedCallback<Delegate>>(); private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAsyncAssetBundles = new List<PrioritizedCallback<Delegate>>(); private static readonly List<PrioritizedCallback<Action<AssetBundleLoadedContext>>> PostfixRedirectionsForAssetBundles = new List<PrioritizedCallback<Action<AssetBundleLoadedContext>>>(); private static Action<AssetBundleLoadingContext> _emulateAssetBundles; private static Action<AsyncAssetBundleLoadingContext> _emulateAssetBundlesAsync; private static Action<AssetBundleLoadingContext> _redirectionMissingAssetBundlesToEmpty; private static Action<AsyncAssetBundleLoadingContext> _redirectionMissingAssetBundlesToEmptyAsync; private static bool _enabledRandomizeCabIfConflict = false; private static Action<AssetBundleLoadingContext> _enableCabRandomizationPrefix; private static Action<AsyncAssetBundleLoadingContext> _enableCabRandomizationPrefixAsync; private static Action<AssetBundleLoadedContext> _enableCabRandomizationPostfix; private static bool _initialized = false; private static bool _initializedSyncOverAsyncEnabled = false; private static bool _logAllLoadedResources = false; private static bool _isFiringAssetBundle; private static bool _isFiringResource; private static bool _isFiringAsset; private static bool _isRecursionDisabledPermanently; internal static bool RecursionEnabled = true; internal static bool SyncOverAsyncEnabled = false; public static bool LogAllLoadedResources { get { return _logAllLoadedResources; } set { if (value) { Initialize(); } _logAllLoadedResources = value; } } public static bool LogCallbackOrder { get; set; } public static void Initialize() { if (!_initialized) { _initialized = true; HookingHelper.PatchAll((IEnumerable<Type>)ResourceAndAssetHooks.GeneralHooks, false); } } public static void EnableSyncOverAsyncAssetLoads() { Initialize(); if (!_initializedSyncOverAsyncEnabled) { _initializedSyncOverAsyncEnabled = true; SyncOverAsyncEnabled = true; HookingHelper.PatchAll((IEnumerable<Type>)ResourceAndAssetHooks.SyncOverAsyncHooks, false); } } public static void DisableRecursionPermanently() { _isRecursionDisabledPermanently = true; } public static void EnableEmulateAssetBundles(int priority, string emulationDirectory) { if (_emulateAssetBundles == null && _emulateAssetBundlesAsync == null) { _emulateAssetBundles = delegate(AssetBundleLoadingContext ctx) { HandleAssetBundleEmulation<AssetBundleLoadingContext>(ctx, SetBundle); }; _emulateAssetBundlesAsync = delegate(AsyncAssetBundleLoadingContext ctx) { HandleAssetBundleEmulation<AsyncAssetBundleLoadingContext>(ctx, SetRequest); }; RegisterAssetBundleLoadingHook(priority, _emulateAssetBundles); RegisterAsyncAssetBundleLoadingHook(priority, _emulateAssetBundlesAsync); } void HandleAssetBundleEmulation<T>(T context, Action<T, string> changeBundle) where T : IAssetBundleLoadingContext { if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromFile) { string normalizedPath = context.GetNormalizedPath(); string text = Path.Combine(emulationDirectory, normalizedPath); if (File.Exists(text)) { changeBundle(context, text); ref T reference = ref context; T val = default(T); if (val == null) { val = reference; reference = ref val; } reference.Complete(skipRemainingPrefixes: true, true); XuaLogger.ResourceRedirector.Debug("Redirected asset bundle: '" + context.Parameters.Path + "' => '" + text + "'"); } } } static void SetBundle(AssetBundleLoadingContext context, string path) { context.Bundle = AssetBundle.LoadFromFile(path, context.Parameters.Crc, context.Parameters.Offset); } static void SetRequest(AsyncAssetBundleLoadingContext context, string path) { context.Request = AssetBundle.LoadFromFileAsync(path, context.Parameters.Crc, context.Parameters.Offset); } } public static void DisableEmulateAssetBundles() { if (_emulateAssetBundles != null && _emulateAssetBundlesAsync != null) { UnregisterAssetBundleLoadingHook(_emulateAssetBundles); UnregisterAsyncAssetBundleLoadingHook(_emulateAssetBundlesAsync); _emulateAssetBundles = null; _emulateAssetBundlesAsync = null; } } public static void EnableRedirectMissingAssetBundlesToEmptyAssetBundle(int priority) { if (_redirectionMissingAssetBundlesToEmpty == null && _redirectionMissingAssetBundlesToEmptyAsync == null) { _redirectionMissingAssetBundlesToEmpty = delegate(AssetBundleLoadingContext ctx) { HandleMissingBundle<AssetBundleLoadingContext>(ctx, SetBundle); }; _redirectionMissingAssetBundlesToEmptyAsync = delegate(AsyncAssetBundleLoadingContext ctx) { HandleMissingBundle<AsyncAssetBundleLoadingContext>(ctx, SetRequest); }; RegisterAssetBundleLoadingHook(priority, _redirectionMissingAssetBundlesToEmpty); RegisterAsyncAssetBundleLoadingHook(priority, _redirectionMissingAssetBundlesToEmptyAsync); } static void HandleMissingBundle<TContext>(TContext context, Action<TContext, byte[]> changeBundle) where TContext : IAssetBundleLoadingContext { if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromFile && !File.Exists(context.Parameters.Path)) { byte[] empty = Resources.empty; CabHelper.RandomizeCab(empty); changeBundle(context, empty); ref TContext reference = ref context; TContext val = default(TContext); if (val == null) { val = reference; reference = ref val; } reference.Complete(skipRemainingPrefixes: true, true); XuaLogger.ResourceRedirector.Warn("Tried to load non-existing asset bundle: " + context.Parameters.Path); } } static void SetBundle(AssetBundleLoadingContext context, byte[] assetBundleData) { AssetBundle bundle = AssetBundle.LoadFromMemory(assetBundleData); context.Bundle = bundle; } static void SetRequest(AsyncAssetBundleLoadingContext context, byte[] assetBundleData) { AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(assetBundleData); context.Request = request; } } public static void EnableRandomizeCabIfConflict(int priority, bool forceRandomizeWhenInMemory) { if (_enabledRandomizeCabIfConflict) { return; } _enabledRandomizeCabIfConflict = true; if (forceRandomizeWhenInMemory) { _enableCabRandomizationPrefix = delegate(AssetBundleLoadingContext ctx) { HandleCabRandomizePrefix(ctx); }; _enableCabRandomizationPrefixAsync = delegate(AsyncAssetBundleLoadingContext ctx) { HandleCabRandomizePrefix(ctx); }; RegisterAssetBundleLoadingHook(priority, _enableCabRandomizationPrefix); RegisterAsyncAssetBundleLoadingHook(priority, _enableCabRandomizationPrefixAsync); } _enableCabRandomizationPostfix = delegate(AssetBundleLoadedContext ctx) { HandleCabRandomizePostfix(ctx); }; RegisterAssetBundleLoadedHook(priority, _enableCabRandomizationPostfix); void HandleCabRandomizePostfix(AssetBundleLoadedContext context) { if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromFile) { if ((Object)(object)context.Bundle == (Object)null && File.Exists(context.Parameters.Path)) { XuaLogger.ResourceRedirector.Warn("The asset bundle '" + context.Parameters.Path + "' could not be loaded likely due to conflicting CAB-string. Retrying in-memory with randomized CAB-string."); byte[] array; using (FileStream fileStream = new FileStream(context.Parameters.Path, FileMode.Open, FileAccess.Read)) { long length = fileStream.Length; long offset = (long)context.Parameters.Offset; long num = length - offset; fileStream.Seek(offset, SeekOrigin.Begin); array = StreamExtensions.ReadFully((Stream)fileStream, (int)num); } if (!forceRandomizeWhenInMemory) { CabHelper.RandomizeCabWithAnyLength(array); } AssetBundle val = AssetBundle.LoadFromMemory(array, 0u); if ((Object)(object)val != (Object)null) { context.Bundle = val; context.Complete(); } } } else if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromMemory) { if ((Object)(object)context.Bundle == (Object)null && !forceRandomizeWhenInMemory) { string text = AssetBundleHelper.PathForLoadedInMemoryBundle ?? "Unnamed"; XuaLogger.ResourceRedirector.Warn("Could not load an in-memory asset bundle (" + text + ") likely due to conflicting CAB-string. Retrying with randomized CAB-string."); CabHelper.RandomizeCabWithAnyLength(context.Parameters.Binary); AssetBundle val2 = AssetBundle.LoadFromMemory(context.Parameters.Binary, 0u); if ((Object)(object)val2 != (Object)null) { context.Bundle = val2; context.Complete(); } } } else if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromStream && (Object)(object)context.Bundle == (Object)null) { string text2 = AssetBundleHelper.PathForLoadedInMemoryBundle ?? "Unnamed"; XuaLogger.ResourceRedirector.Warn("Could not load a stream asset bundle (" + text2 + ") likely due to conflicting CAB-string. Retrying with randomized CAB-string."); byte[] array2 = StreamExtensions.ReadFully(context.Parameters.Stream, 0); if (!forceRandomizeWhenInMemory) { CabHelper.RandomizeCabWithAnyLength(array2); } AssetBundle val3 = AssetBundle.LoadFromMemory(array2, 0u); if ((Object)(object)val3 != (Object)null) { context.Bundle = val3; context.Complete(); } } } static void HandleCabRandomizePrefix(IAssetBundleLoadingContext context) { if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromMemory) { CabHelper.RandomizeCabWithAnyLength(context.Parameters.Binary); } } } public static void DisableRandomizeCabIfConflict() { if (_enabledRandomizeCabIfConflict) { _enabledRandomizeCabIfConflict = false; if (_enableCabRandomizationPrefix != null) { UnregisterAssetBundleLoadingHook(_enableCabRandomizationPrefix); _enableCabRandomizationPrefix = null; } if (_enableCabRandomizationPrefixAsync != null) { UnregisterAsyncAssetBundleLoadingHook(_enableCabRandomizationPrefixAsync); _enableCabRandomizationPrefixAsync = null; } if (_enableCabRandomizationPostfix != null) { UnregisterAssetBundleLoadedHook(_enableCabRandomizationPostfix); _enableCabRandomizationPostfix = null; } } } public static void DisableRedirectMissingAssetBundlesToEmptyAssetBundle() { if (_redirectionMissingAssetBundlesToEmpty != null && _redirectionMissingAssetBundlesToEmptyAsync != null) { UnregisterAssetBundleLoadingHook(_redirectionMissingAssetBundlesToEmpty); UnregisterAsyncAssetBundleLoadingHook(_redirectionMissingAssetBundlesToEmptyAsync); _redirectionMissingAssetBundlesToEmpty = null; _redirectionMissingAssetBundlesToEmptyAsync = null; } } internal static bool TryGetAssetBundleLoadInfo(AssetBundleRequest request, out AsyncAssetLoadInfo result) { result = ExtensionDataHelper.GetExtensionData<AsyncAssetLoadInfo>((object)request); return result != null; } internal static bool TryGetAssetBundle(AssetBundleCreateRequest request, out AsyncAssetBundleLoadInfo result) { result = ExtensionDataHelper.GetExtensionData<AsyncAssetBundleLoadInfo>((object)request); return result != null; } internal static bool ShouldBlockAsyncOperationMethods(AssetBundleRequest operation) { if (TryGetAssetBundleLoadInfo(operation, out var result)) { return result.ResolveType == AsyncAssetLoadingResolve.ThroughAssets; } return false; } internal static bool ShouldBlockAsyncOperationMethods(AssetBundleCreateRequest operation) { if (TryGetAssetBundle(operation, out var result)) { return result.ResolveType == AsyncAssetBundleLoadingResolve.ThroughBundle; } return false; } internal static bool ShouldBlockAsyncOperationMethods(AsyncOperation operation) { if (SyncOverAsyncEnabled) { AssetBundleRequest operation2 = default(AssetBundleRequest); if (!ObjectExtensions.TryCastTo<AssetBundleRequest>((object)operation, ref operation2) || !ShouldBlockAsyncOperationMethods(operation2)) { AssetBundleCreateRequest operation3 = default(AssetBundleCreateRequest); if (ObjectExtensions.TryCastTo<AssetBundleCreateRequest>((object)operation, ref operation3)) { return ShouldBlockAsyncOperationMethods(operation3); } return false; } return true; } return false; } internal static AssetBundleLoadingContext Hook_AssetBundleLoading_Prefix(AssetBundleLoadingParameters parameters, out AssetBundle bundle) { AssetBundleLoadingContext assetBundleLoadingContext = new AssetBundleLoadingContext(parameters); if (_isFiringAssetBundle && (_isRecursionDisabledPermanently || !RecursionEnabled)) { bundle = null; return assetBundleLoadingContext; } try { _isFiringAssetBundle = true; if (_logAllLoadedResources) { XuaLogger.ResourceRedirector.Debug("Loading Asset Bundle: (" + assetBundleLoadingContext.GetNormalizedPath() + ")."); } List<PrioritizedCallback<Delegate>> prefixRedirectionsForAssetBundles = PrefixRedirectionsForAssetBundles; int count = prefixRedirectionsForAssetBundles.Count; for (int i = 0; i < count; i++) { PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAssetBundles[i]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; if (prioritizedCallback.Callback is Action<AssetBundleLoadingContext> action) { action(assetBundleLoadingContext); } else if (prioritizedCallback.Callback is Action<IAssetBundleLoadingContext> action2) { action2(assetBundleLoadingContext); } if (assetBundleLoadingContext.SkipRemainingPrefixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetBundleLoading event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetBundleLoading event."); } finally { _isFiringAssetBundle = false; } bundle = assetBundleLoadingContext.Bundle; return assetBundleLoadingContext; } internal static AssetBundleLoadedContext Hook_AssetBundleLoaded_Postfix(AssetBundleLoadingParameters parameters, ref AssetBundle bundle) { AssetBundleLoadedContext assetBundleLoadedContext = new AssetBundleLoadedContext(parameters, bundle); if (_isFiringAssetBundle && (_isRecursionDisabledPermanently || !RecursionEnabled)) { bundle = null; return assetBundleLoadedContext; } try { _isFiringAssetBundle = true; List<PrioritizedCallback<Action<AssetBundleLoadedContext>>> postfixRedirectionsForAssetBundles = PostfixRedirectionsForAssetBundles; int count = postfixRedirectionsForAssetBundles.Count; for (int i = 0; i < count; i++) { PrioritizedCallback<Action<AssetBundleLoadedContext>> prioritizedCallback = postfixRedirectionsForAssetBundles[i]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; prioritizedCallback.Callback(assetBundleLoadedContext); if (assetBundleLoadedContext.SkipRemainingPostfixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetBundleLoaded event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetBundleLoaded event."); } finally { _isFiringAssetBundle = false; } bundle = assetBundleLoadedContext.Bundle; return assetBundleLoadedContext; } internal static AsyncAssetBundleLoadingContext Hook_AssetBundleLoading_Prefix(AssetBundleLoadingParameters parameters, out AssetBundleCreateRequest request) { //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown AsyncAssetBundleLoadingContext asyncAssetBundleLoadingContext = new AsyncAssetBundleLoadingContext(parameters); if (_isFiringAssetBundle && (_isRecursionDisabledPermanently || !RecursionEnabled)) { request = null; return asyncAssetBundleLoadingContext; } try { _isFiringAssetBundle = true; if (_logAllLoadedResources) { XuaLogger.ResourceRedirector.Debug("Loading Asset Bundle (async): (" + asyncAssetBundleLoadingContext.GetNormalizedPath() + ")."); } List<PrioritizedCallback<Delegate>> prefixRedirectionsForAsyncAssetBundles = PrefixRedirectionsForAsyncAssetBundles; int count = prefixRedirectionsForAsyncAssetBundles.Count; for (int i = 0; i < count; i++) { PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAsyncAssetBundles[i]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; if (prioritizedCallback.Callback is Action<AsyncAssetBundleLoadingContext> action) { action(asyncAssetBundleLoadingContext); } else if (prioritizedCallback.Callback is Action<IAssetBundleLoadingContext> action2) { action2(asyncAssetBundleLoadingContext); } if (asyncAssetBundleLoadingContext.SkipRemainingPrefixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetBundleLoading event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AsyncAssetBundleLoading event."); } finally { _isFiringAssetBundle = false; } if (asyncAssetBundleLoadingContext.ResolveType == AsyncAssetBundleLoadingResolve.ThroughRequest) { request = asyncAssetBundleLoadingContext.Request; } else { if (asyncAssetBundleLoadingContext.ResolveType != AsyncAssetBundleLoadingResolve.ThroughBundle) { throw new InvalidOperationException("Found invalid ResolveType on context: " + asyncAssetBundleLoadingContext.ResolveType); } request = new AssetBundleCreateRequest(); if (!asyncAssetBundleLoadingContext.SkipOriginalCall) { XuaLogger.ResourceRedirector.Warn("Resolving sync over async asset load, but 'SkipOriginalCall' was not set to true. Forcing it to true."); asyncAssetBundleLoadingContext.SkipOriginalCall = true; } } return asyncAssetBundleLoadingContext; } internal static void Hook_AssetBundleLoading_Postfix(AsyncAssetBundleLoadingContext context, AssetBundleCreateRequest request) { if (request != null) { ExtensionDataHelper.SetExtensionData<AsyncAssetBundleLoadInfo>((object)request, new AsyncAssetBundleLoadInfo(context.Parameters, context.Bundle, context.SkipAllPostfixes, context.ResolveType)); } } internal static void Hook_AssetLoading_Postfix(AsyncAssetLoadingContext context, AssetBundleRequest request) { if (request != null) { ExtensionDataHelper.SetExtensionData<AsyncAssetLoadInfo>((object)request, new AsyncAssetLoadInfo(context.Parameters, context.Bundle, context.SkipAllPostfixes, context.ResolveType, context.Assets)); } } internal static AssetLoadingContext Hook_AssetLoading_Prefix(AssetLoadingParameters parameters, AssetBundle parentBundle, ref Object asset) { Object[] assets = null; AssetLoadingContext result = Hook_AssetLoading_Prefix(parameters, parentBundle, ref assets); if (assets == null || assets.Length == 0) { asset = null; return result; } if (assets.Length > 1) { XuaLogger.ResourceRedirector.Warn("Illegal behaviour by redirection handler in AssetLoadeding event. Returned more than one asset to call requiring only a single asset."); asset = assets[0]; return result; } if (assets.Length == 1) { asset = assets[0]; } return result; } internal static AssetLoadingContext Hook_AssetLoading_Prefix(AssetLoadingParameters parameters, AssetBundle bundle, ref Object[] assets) { AssetLoadingContext assetLoadingContext = new AssetLoadingContext(parameters, bundle); try { if (_isFiringAsset && (_isRecursionDisabledPermanently || !RecursionEnabled)) { return assetLoadingContext; } _isFiringAsset = true; List<PrioritizedCallback<Delegate>> prefixRedirectionsForAssetsPerCall = PrefixRedirectionsForAssetsPerCall; int count = prefixRedirectionsForAssetsPerCall.Count; for (int i = 0; i < count; i++) { PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAssetsPerCall[i]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; if (prioritizedCallback.Callback is Action<AssetLoadingContext> action) { action(assetLoadingContext); } else if (prioritizedCallback.Callback is Action<IAssetLoadingContext> action2) { action2(assetLoadingContext); } if (assetLoadingContext.SkipRemainingPrefixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetLoading event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } assets = assetLoadingContext.Assets; } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetLoading event."); } finally { _isFiringAsset = false; } return assetLoadingContext; } internal static AsyncAssetLoadingContext Hook_AsyncAssetLoading_Prefix(AssetLoadingParameters parameters, AssetBundle bundle, ref AssetBundleRequest request) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown AsyncAssetLoadingContext asyncAssetLoadingContext = new AsyncAssetLoadingContext(parameters, bundle); try { if (_isFiringAsset && (_isRecursionDisabledPermanently || !RecursionEnabled)) { return asyncAssetLoadingContext; } _isFiringAsset = true; List<PrioritizedCallback<Delegate>> prefixRedirectionsForAsyncAssetsPerCall = PrefixRedirectionsForAsyncAssetsPerCall; int count = prefixRedirectionsForAsyncAssetsPerCall.Count; for (int i = 0; i < count; i++) { PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAsyncAssetsPerCall[i]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; if (prioritizedCallback.Callback is Action<AsyncAssetLoadingContext> action) { action(asyncAssetLoadingContext); } else if (prioritizedCallback.Callback is Action<IAssetLoadingContext> action2) { action2(asyncAssetLoadingContext); } if (asyncAssetLoadingContext.SkipRemainingPrefixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AsyncAssetLoading event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } if (asyncAssetLoadingContext.ResolveType == AsyncAssetLoadingResolve.ThroughRequest) { request = asyncAssetLoadingContext.Request; } else { if (asyncAssetLoadingContext.ResolveType != AsyncAssetLoadingResolve.ThroughAssets) { throw new InvalidOperationException("Found invalid ResolveType on context: " + asyncAssetLoadingContext.ResolveType); } request = new AssetBundleRequest(); if (!asyncAssetLoadingContext.SkipOriginalCall) { XuaLogger.ResourceRedirector.Warn("Resolving sync over async asset load, but 'SkipOriginalCall' was not set to true. Forcing it to true."); asyncAssetLoadingContext.SkipOriginalCall = true; } } } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AsyncAssetLoading event."); } finally { _isFiringAsset = false; } return asyncAssetLoadingContext; } internal static void Hook_AssetLoaded_Postfix(AssetLoadingParameters parameters, AssetBundle parentBundle, ref Object asset) { Object[] assets = (Object[])(object)((!(asset == (Object)null)) ? new Object[1] { asset } : new Object[0]); Hook_AssetLoaded_Postfix(parameters, parentBundle, ref assets); if (assets == null || assets.Length == 0) { asset = null; } else if (assets.Length > 1) { XuaLogger.ResourceRedirector.Warn("Illegal behaviour by redirection handler in AssetLoaded event. Returned more than one asset to call requiring only a single asset."); asset = assets[0]; } else if (assets.Length == 1) { asset = assets[0]; } } internal static void Hook_AssetLoaded_Postfix(AssetLoadingParameters parameters, AssetBundle bundle, ref Object[] assets) { FireAssetLoadedEvent(parameters.ToAssetLoadedParameters(), bundle, ref assets); } internal static void Hook_ResourceLoaded_Postfix(ResourceLoadedParameters parameters, ref Object asset) { Object[] assets = (Object[])(object)((!(asset == (Object)null)) ? new Object[1] { asset } : new Object[0]); Hook_ResourceLoaded_Postfix(parameters, ref assets); if (assets == null || assets.Length == 0) { asset = null; } else if (assets.Length > 1) { XuaLogger.ResourceRedirector.Warn("Illegal behaviour by redirection handler in ResourceLoaded event. Returned more than one asset to call requiring only a single asset."); asset = assets[0]; } else if (assets.Length == 1) { asset = assets[0]; } } internal static void Hook_ResourceLoaded_Postfix(ResourceLoadedParameters parameters, ref Object[] assets) { FireResourceLoadedEvent(parameters, ref assets); } internal static void FireAssetLoadedEvent(AssetLoadedParameters parameters, AssetBundle assetBundle, ref Object[] assets) { Object[] array = assets?.ToArray(); try { AssetLoadedContext assetLoadedContext = new AssetLoadedContext(parameters, assetBundle, assets); if (_isFiringAsset && (_isRecursionDisabledPermanently || !RecursionEnabled)) { return; } _isFiringAsset = true; if (_logAllLoadedResources && assets != null) { for (int i = 0; i < assets.Length; i++) { Object val = assets[i]; if (val != (Object)null) { string uniqueFileSystemAssetPath = assetLoadedContext.GetUniqueFileSystemAssetPath(val); XuaLogger.ResourceRedirector.Debug("Loaded Asset: '" + ObjectExtensions.GetUnityType((object)val).FullName + "', Load Type: '" + parameters.LoadType.ToString() + "', Unique Path: (" + uniqueFileSystemAssetPath + ")."); } } } List<PrioritizedCallback<Action<AssetLoadedContext>>> postfixRedirectionsForAssetsPerCall = PostfixRedirectionsForAssetsPerCall; int count = postfixRedirectionsForAssetsPerCall.Count; for (int j = 0; j < count; j++) { PrioritizedCallback<Action<AssetLoadedContext>> prioritizedCallback = postfixRedirectionsForAssetsPerCall[j]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; prioritizedCallback.Callback(assetLoadedContext); if (assetLoadedContext.SkipRemainingPostfixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetLoaded event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } assets = assetLoadedContext.Assets; if (assetLoadedContext.SkipRemainingPostfixes || assets == null) { return; } int num = assets.Length; for (int k = 0; k < num; k++) { Object val2 = assets[k]; if (val2 != (Object)null) { AssetLoadedContext assetLoadedContext2 = new AssetLoadedContext(parameters, assetBundle, val2); List<PrioritizedCallback<Action<AssetLoadedContext>>> postfixRedirectionsForAssetsPerResource = PostfixRedirectionsForAssetsPerResource; int count2 = postfixRedirectionsForAssetsPerResource.Count; for (int l = 0; l < count2; l++) { PrioritizedCallback<Action<AssetLoadedContext>> prioritizedCallback2 = postfixRedirectionsForAssetsPerResource[l]; if (prioritizedCallback2.IsBeingCalled) { continue; } try { prioritizedCallback2.IsBeingCalled = true; prioritizedCallback2.Callback(assetLoadedContext2); if (assetLoadedContext2.Asset != (Object)null) { assets[k] = assetLoadedContext2.Asset; } else { XuaLogger.ResourceRedirector.Warn($"Illegal behaviour by redirection handler in AssetLoaded event. You must not remove an asset reference when hooking with behaviour {HookBehaviour.OneCallbackPerResourceLoaded}."); } if (assetLoadedContext2.SkipRemainingPostfixes) { break; } } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetLoaded event."); } finally { RecursionEnabled = true; prioritizedCallback2.IsBeingCalled = false; } } } else { XuaLogger.ResourceRedirector.Error("Found unexpected null asset during AssetLoaded event."); } } } catch (Exception ex3) { XuaLogger.ResourceRedirector.Error(ex3, "An error occurred while invoking AssetLoaded event."); } finally { _isFiringAsset = false; if (array != null) { Object[] array2 = array; for (int m = 0; m < array2.Length; m++) { ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)array2[m]).HasBeenRedirected = true; } } } } internal static void FireResourceLoadedEvent(ResourceLoadedParameters parameters, ref Object[] assets) { Object[] array = assets?.ToArray(); try { ResourceLoadedContext resourceLoadedContext = new ResourceLoadedContext(parameters, assets); if (_isFiringResource && (_isRecursionDisabledPermanently || !RecursionEnabled)) { return; } _isFiringResource = true; if (_logAllLoadedResources && assets != null) { for (int i = 0; i < assets.Length; i++) { Object val = assets[i]; if (val != (Object)null) { string uniqueFileSystemAssetPath = resourceLoadedContext.GetUniqueFileSystemAssetPath(val); XuaLogger.ResourceRedirector.Debug("Loaded Asset: '" + ObjectExtensions.GetUnityType((object)val).FullName + "', Load Type: '" + parameters.LoadType.ToString() + "', Unique Path: (" + uniqueFileSystemAssetPath + ")."); } } } List<PrioritizedCallback<Action<ResourceLoadedContext>>> postfixRedirectionsForResourcesPerCall = PostfixRedirectionsForResourcesPerCall; int count = postfixRedirectionsForResourcesPerCall.Count; for (int j = 0; j < count; j++) { PrioritizedCallback<Action<ResourceLoadedContext>> prioritizedCallback = postfixRedirectionsForResourcesPerCall[j]; if (prioritizedCallback.IsBeingCalled) { continue; } try { prioritizedCallback.IsBeingCalled = true; prioritizedCallback.Callback(resourceLoadedContext); if (resourceLoadedContext.SkipRemainingPostfixes) { break; } } catch (Exception ex) { XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking ResourceLoaded event."); } finally { RecursionEnabled = true; prioritizedCallback.IsBeingCalled = false; } } assets = resourceLoadedContext.Assets; if (resourceLoadedContext.SkipRemainingPostfixes || assets == null) { return; } int num = assets.Length; for (int k = 0; k < num; k++) { Object val2 = assets[k]; if (val2 != (Object)null) { ResourceLoadedContext resourceLoadedContext2 = new ResourceLoadedContext(parameters, val2); List<PrioritizedCallback<Action<ResourceLoadedContext>>> postfixRedirectionsForResourcesPerResource = PostfixRedirectionsForResourcesPerResource; int count2 = postfixRedirectionsForResourcesPerResource.Count; for (int l = 0; l < count2; l++) { PrioritizedCallback<Action<ResourceLoadedContext>> prioritizedCallback2 = postfixRedirectionsForResourcesPerResource[l]; if (prioritizedCallback2.IsBeingCalled) { continue; } try { prioritizedCallback2.IsBeingCalled = true; prioritizedCallback2.Callback(resourceLoadedContext2); if (resourceLoadedContext2.Asset != (Object)null) { assets[k] = resourceLoadedContext2.Asset; } else { XuaLogger.ResourceRedirector.Warn($"Illegal behaviour by redirection handler in ResourceLoaded event. You must not remove an asset reference when hooking with behaviour {HookBehaviour.OneCallbackPerResourceLoaded}."); } if (resourceLoadedContext2.SkipRemainingPostfixes) { break; } } catch (Exception ex2) { XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking ResourceLoaded event."); } finally { RecursionEnabled = true; prioritizedCallback2.IsBeingCalled = false; } } } else { XuaLogger.ResourceRedirector.Error("Found unexpected null asset during ResourceLoaded event."); } } } catch (Exception ex3) { XuaLogger.ResourceRedirector.Error(ex3, "An error occurred while invoking ResourceLoaded event."); } finally { _isFiringResource = false; if (array != null) { Object[] array2 = array; for (int m = 0; m < array2.Length; m++) { ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)array2[m]).HasBeenRedirected = true; } } } } private static void LogEventRegistration(string eventType, IEnumerable callbacks) { XuaLogger.ResourceRedirector.Debug("Registered new callback for " + eventType + "."); LogNewCallbackOrder(eventType, callbacks); } private static void LogEventUnregistration(string eventType, IEnumerable callbacks) { XuaLogger.ResourceRedirector.Debug("Unregistered callback for " + eventType + "."); LogNewCallbackOrder(eventType, callbacks); } private static void LogNewCallbackOrder(string eventType, IEnumerable callbacks) { if (!LogCallbackOrder) { return; } XuaLogger.ResourceRedirector.Debug("New callback order for " + eventType + ":"); foreach (object callback in callbacks) { XuaLogger.ResourceRedirector.Debug(callback.ToString()); } } public static void RegisterAssetBundleLoadedHook(int priority, Action<AssetBundleLoadedContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Action<AssetBundleLoadedContext>> prioritizedCallback = PrioritizedCallback.Create(action, priority); if (PostfixRedirectionsForAssetBundles.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<AssetBundleLoadedContext>>>(PostfixRedirectionsForAssetBundles, prioritizedCallback); LogEventRegistration("AssetBundleLoaded", PostfixRedirectionsForAssetBundles); } public static void RegisterAssetBundleLoadedHook(Action<AssetBundleLoadedContext> action) { RegisterAssetBundleLoadedHook(0, action); } public static void UnregisterAssetBundleLoadedHook(Action<AssetBundleLoadedContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PostfixRedirectionsForAssetBundles.RemoveAll((PrioritizedCallback<Action<AssetBundleLoadedContext>> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AssetBundleLoaded", PostfixRedirectionsForAssetBundles); } public static void RegisterAssetLoadingHook(int priority, Action<AssetLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority); if (PrefixRedirectionsForAssetsPerCall.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetsPerCall, prioritizedCallback); LogEventRegistration("AssetLoading", PrefixRedirectionsForAssetsPerCall); } public static void RegisterAssetLoadingHook(Action<AssetLoadingContext> action) { RegisterAssetLoadingHook(0, action); } public static void UnregisterAssetLoadingHook(Action<AssetLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrefixRedirectionsForAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AssetLoading", PrefixRedirectionsForAssetsPerCall); } public static void RegisterAsyncAssetLoadingHook(int priority, Action<AsyncAssetLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority); if (PrefixRedirectionsForAsyncAssetsPerCall.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetsPerCall, prioritizedCallback); LogEventRegistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall); } public static void RegisterAsyncAssetLoadingHook(Action<AsyncAssetLoadingContext> action) { RegisterAsyncAssetLoadingHook(0, action); } public static void UnregisterAsyncAssetLoadingHook(Action<AsyncAssetLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrefixRedirectionsForAsyncAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall); } public static void RegisterAsyncAndSyncAssetLoadingHook(int priority, Action<IAssetLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority); if (PrefixRedirectionsForAsyncAssetsPerCall.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetsPerCall, prioritizedCallback); LogEventRegistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetsPerCall, prioritizedCallback); LogEventRegistration("AssetLoading", PrefixRedirectionsForAssetsPerCall); } public static void RegisterAsyncAndSyncAssetLoadingHook(Action<IAssetLoadingContext> action) { RegisterAsyncAndSyncAssetLoadingHook(0, action); } public static void UnregisterAsyncAndSyncAssetLoadingHook(Action<IAssetLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrefixRedirectionsForAsyncAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall); PrefixRedirectionsForAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AssetLoading", PrefixRedirectionsForAssetsPerCall); } public static void RegisterAssetLoadedHook(HookBehaviour behaviour, int priority, Action<AssetLoadedContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Action<AssetLoadedContext>> prioritizedCallback = PrioritizedCallback.Create(action, priority); if (PostfixRedirectionsForAssetsPerCall.Contains(prioritizedCallback) || PostfixRedirectionsForAssetsPerResource.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); switch (behaviour) { case HookBehaviour.OneCallbackPerLoadCall: ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<AssetLoadedContext>>>(PostfixRedirectionsForAssetsPerCall, prioritizedCallback); LogEventRegistration("AssetLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForAssetsPerCall); break; case HookBehaviour.OneCallbackPerResourceLoaded: ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<AssetLoadedContext>>>(PostfixRedirectionsForAssetsPerResource, prioritizedCallback); LogEventRegistration("AssetLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForAssetsPerResource); break; } } public static void RegisterAssetLoadedHook(HookBehaviour behaviour, Action<AssetLoadedContext> action) { RegisterAssetLoadedHook(behaviour, 0, action); } public static void UnregisterAssetLoadedHook(Action<AssetLoadedContext> action) { if (action == null) { throw new ArgumentNullException("action"); } if (PostfixRedirectionsForAssetsPerCall.RemoveAll((PrioritizedCallback<Action<AssetLoadedContext>> x) => x.Callback == action) > 0) { LogEventRegistration("AssetLoaded (" + HookBehaviour.OneCallbackPerLoadCall.ToString() + ")", PostfixRedirectionsForAssetsPerCall); } if (PostfixRedirectionsForAssetsPerResource.RemoveAll((PrioritizedCallback<Action<AssetLoadedContext>> x) => x.Callback == action) > 0) { LogEventRegistration("AssetLoaded (" + HookBehaviour.OneCallbackPerResourceLoaded.ToString() + ")", PostfixRedirectionsForAssetsPerResource); } } public static void RegisterAssetBundleLoadingHook(int priority, Action<AssetBundleLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority); if (PrefixRedirectionsForAssetBundles.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetBundles, prioritizedCallback); LogEventRegistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles); } public static void RegisterAssetBundleLoadingHook(Action<AssetBundleLoadingContext> action) { RegisterAssetBundleLoadingHook(0, action); } public static void UnregisterAssetBundleLoadingHook(Action<AssetBundleLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrefixRedirectionsForAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles); } public static void RegisterAsyncAssetBundleLoadingHook(int priority, Action<AsyncAssetBundleLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority); if (PrefixRedirectionsForAsyncAssetBundles.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetBundles, prioritizedCallback); LogEventRegistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles); } public static void RegisterAsyncAssetBundleLoadingHook(Action<AsyncAssetBundleLoadingContext> action) { RegisterAsyncAssetBundleLoadingHook(0, action); } public static void UnregisterAsyncAssetBundleLoadingHook(Action<AsyncAssetBundleLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrefixRedirectionsForAsyncAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles); } public static void RegisterAsyncAndSyncAssetBundleLoadingHook(int priority, Action<IAssetBundleLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority); if (PrefixRedirectionsForAssetBundles.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetBundles, prioritizedCallback); LogEventRegistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles); ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetBundles, prioritizedCallback); LogEventRegistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles); } public static void RegisterAsyncAndSyncAssetBundleLoadingHook(Action<IAssetBundleLoadingContext> action) { RegisterAsyncAndSyncAssetBundleLoadingHook(0, action); } public static void UnregisterAsyncAndSyncAssetBundleLoadingHook(Action<IAssetBundleLoadingContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrefixRedirectionsForAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles); PrefixRedirectionsForAsyncAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action)); LogEventUnregistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles); } public static void RegisterResourceLoadedHook(HookBehaviour behaviour, int priority, Action<ResourceLoadedContext> action) { if (action == null) { throw new ArgumentNullException("action"); } PrioritizedCallback<Action<ResourceLoadedContext>> prioritizedCallback = PrioritizedCallback.Create(action, priority); if (PostfixRedirectionsForResourcesPerCall.Contains(prioritizedCallback) || PostfixRedirectionsForResourcesPerResource.Contains(prioritizedCallback)) { throw new ArgumentException("This callback has already been registered.", "action"); } Initialize(); switch (behaviour) { case HookBehaviour.OneCallbackPerLoadCall: ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<ResourceLoadedContext>>>(PostfixRedirectionsForResourcesPerCall, prioritizedCallback); LogEventRegistration("ResourceLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForResourcesPerCall); break; case HookBehaviour.OneCallbackPerResourceLoaded: ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<ResourceLoadedContext>>>(PostfixRedirectionsForResourcesPerResource, prioritizedCallback); LogEventRegistration("ResourceLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForResourcesPerResource); break; } } public static void RegisterResourceLoadedHook(HookBehaviour behaviour, Action<ResourceLoadedContext> action) { RegisterResourceLoadedHook(behaviour, 0, action); } public static void UnregisterResourceLoadedHook(Action<ResourceLoadedContext> action) { if (action == null) { throw new ArgumentNullException("action"); } if (PostfixRedirectionsForResourcesPerCall.RemoveAll((PrioritizedCallback<Action<ResourceLoadedContext>> x) => x.Callback == action) > 0) { LogEventRegistration("ResourceLoaded (" + HookBehaviour.OneCallbackPerLoadCall.ToString() + ")", PostfixRedirectionsForResourcesPerCall); } if (PostfixRedirectionsForResourcesPerResource.RemoveAll((PrioritizedCallback<Action<ResourceLoadedContext>> x) => x.Callback == action) > 0) { LogEventRegistration("ResourceLoaded (" + HookBehaviour.OneCallbackPerResourceLoaded.ToString() + ")", PostfixRedirectionsForResourcesPerResource); } } } } namespace XUnity.ResourceRedirector.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("XUnity.ResourceRedirector.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] empty => (byte[])ResourceManager.GetObject("empty", resourceCulture); internal Resources() { } } } namespace XUnity.ResourceRedirector.Hooks { internal static class ResourceAndAssetHooks { public static readonly Type[] GeneralHooks = new Type[21] { typeof(AssetBundle_LoadFromFileAsync_Hook), typeof(AssetBundle_LoadFromFile_Hook), typeof(AssetBundle_LoadFromMemoryAsync_Hook), typeof(AssetBundle_LoadFromMemory_Hook), typeof(AssetBundle_LoadFromStreamAsync_Hook), typeof(AssetBundle_LoadFromStream_Hook), typeof(AssetBundle_mainAsset_Hook), typeof(AssetBundle_returnMainAsset_Hook), typeof(AssetBundle_Load_Hook), typeof(AssetBundle_LoadAsync_Hook), typeof(AssetBundle_LoadAll_Hook), typeof(AssetBundle_LoadAsset_Internal_Hook), typeof(AssetBundle_LoadAssetAsync_Internal_Hook), typeof(AssetBundle_LoadAssetWithSubAssets_Internal_Hook), typeof(AssetBundle_LoadAssetWithSubAssetsAsync_Internal_Hook), typeof(AssetBundleRequest_asset_Hook), typeof(AssetBundleRequest_allAssets_Hook), typeof(Resources_Load_Hook), typeof(Resources_LoadAll_Hook), typeof(Resources_GetBuiltinResource_Old_Hook), typeof(Resources_GetBuiltinResource_New_Hook) }; public static readonly Type[] SyncOverAsyncHooks = new Type[10] { typeof(AssetBundleCreateRequest_assetBundle_Hook), typeof(AssetBundleCreateRequest_DisableCompatibilityChecks_Hook), typeof(AssetBundleCreateRequest_SetEnableCompatibilityChecks_Hook), typeof(AsyncOperation_isDone_Hook), typeof(AsyncOperation_progress_Hook), typeof(AsyncOperation_priority_Hook), typeof(AsyncOperation_set_priority_Hook), typeof(AsyncOperation_allowSceneActivation_Hook), typeof(AsyncOperation_set_allowSceneActivation_Hook), typeof(AsyncOperation_Finalize_Hook) }; } internal static class AssetBundleCreateRequest_assetBundle_Hook { private delegate AssetBundle OriginalMethod(AssetBundleCreateRequest __instance); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundleCreateRequest != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest; return AccessToolsShim.Property((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "assetBundle")?.GetGetMethod(); } private static bool Prefix(AssetBundleCreateRequest __instance, ref AssetBundle __result, ref AsyncAssetBundleLoadInfo __state) { if (ResourceRedirection.TryGetAssetBundle(__instance, out __state)) { if (__state.ResolveType == AsyncAssetBundleLoadingResolve.ThroughBundle) { __result = __state.Bundle; return false; } return true; } return true; } private static void Postfix(ref AssetBundle __result, ref AsyncAssetBundleLoadInfo __state) { if (__state == null) { return; } if (!__state.SkipAllPostfixes) { ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result); } if ((Object)(object)__result != (Object)null && __state != null) { string path = __state.Parameters.Path; if (path != null) { ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = path; } } } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundle MM_Detour(AssetBundleCreateRequest __instance) { AssetBundle __result = null; AsyncAssetBundleLoadInfo __state = null; if (Prefix(__instance, ref __result, ref __state)) { __result = _original(__instance); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundleCreateRequest_DisableCompatibilityChecks_Hook { private delegate void OriginalMethod(AssetBundleCreateRequest __instance); private static OriginalMethod _original; private static bool Prepare(object instance) { TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest; return (object)AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "SetEnableCompatibilityChecks", new Type[1] { typeof(bool) }) == null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest; return AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "DisableCompatibilityChecks", new Type[0]); } private static bool Prefix(AssetBundleCreateRequest __instance) { return !ResourceRedirection.ShouldBlockAsyncOperationMethods(__instance); } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static void MM_Detour(AssetBundleCreateRequest __instance) { if (Prefix(__instance)) { _original(__instance); } } } internal static class AssetBundleCreateRequest_SetEnableCompatibilityChecks_Hook { private delegate void OriginalMethod(AssetBundleCreateRequest __instance, bool set); private static OriginalMethod _original; private static bool Prepare(object instance) { TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest; return (object)AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "SetEnableCompatibilityChecks", new Type[1] { typeof(bool) }) != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest; return AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "SetEnableCompatibilityChecks", new Type[1] { typeof(bool) }); } private static bool Prefix(AssetBundleCreateRequest __instance, bool set) { return !ResourceRedirection.ShouldBlockAsyncOperationMethods(__instance); } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static void MM_Detour(AssetBundleCreateRequest __instance, bool set) { if (Prefix(__instance, set)) { _original(__instance, set); } } } internal static class AssetBundle_LoadFromFileAsync_Hook { private delegate AssetBundleCreateRequest OriginalMethod(string path, uint crc, ulong offset); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundle != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromFileAsync_Internal", new Type[3] { typeof(string), typeof(uint), typeof(ulong) }); if ((object)methodInfo == null) { TypeContainer assetBundle2 = UnityTypes.AssetBundle; methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromFileAsync", new Type[3] { typeof(string), typeof(uint), typeof(ulong) }); } return methodInfo; } private static bool Prefix(ref string path, ref uint crc, ref ulong offset, ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state) { AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, path, crc, offset, null, 0u, AssetBundleLoadType.LoadFromFile); __state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result); AssetBundleLoadingParameters parameters2 = __state.Parameters; path = parameters2.Path; crc = parameters2.Crc; offset = parameters2.Offset; return !__state.SkipOriginalCall; } private static void Postfix(ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state) { ResourceRedirection.Hook_AssetBundleLoading_Postfix(__state, __result); } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundleCreateRequest MM_Detour(string path, uint crc, ulong offset) { AssetBundleCreateRequest __result = null; AsyncAssetBundleLoadingContext __state = null; if (Prefix(ref path, ref crc, ref offset, ref __result, ref __state)) { __result = _original(path, crc, offset); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundle_LoadFromFile_Hook { private delegate AssetBundle OriginalMethod(string path, uint crc, ulong offset); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundle != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromFile_Internal", new Type[3] { typeof(string), typeof(uint), typeof(ulong) }); if ((object)methodInfo == null) { TypeContainer assetBundle2 = UnityTypes.AssetBundle; methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromFile", new Type[3] { typeof(string), typeof(uint), typeof(ulong) }); } return methodInfo; } private static bool Prefix(ref string path, ref uint crc, ref ulong offset, ref AssetBundle __result, ref AssetBundleLoadingContext __state) { AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, path, crc, offset, null, 0u, AssetBundleLoadType.LoadFromFile); __state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result); AssetBundleLoadingParameters parameters2 = __state.Parameters; path = parameters2.Path; crc = parameters2.Crc; offset = parameters2.Offset; return !__state.SkipOriginalCall; } private static void Postfix(ref AssetBundle __result, ref AssetBundleLoadingContext __state) { if (!__state.SkipAllPostfixes) { ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result); } if ((Object)(object)__result != (Object)null && __state.Parameters.Path != null) { ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = __state.Parameters.Path; } } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundle MM_Detour(string path, uint crc, ulong offset) { AssetBundle __result = null; AssetBundleLoadingContext __state = null; if (Prefix(ref path, ref crc, ref offset, ref __result, ref __state)) { __result = _original(path, crc, offset); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundle_LoadFromMemoryAsync_Hook { private delegate AssetBundleCreateRequest OriginalMethod(byte[] binary, uint crc); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundle != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromMemoryAsync_Internal", new Type[2] { typeof(byte[]), typeof(uint) }); if ((object)methodInfo == null) { TypeContainer assetBundle2 = UnityTypes.AssetBundle; methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromMemoryAsync", new Type[2] { typeof(byte[]), typeof(uint) }); } return methodInfo; } private static bool Prefix(ref byte[] binary, ref uint crc, ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state) { AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(binary, null, crc, 0uL, null, 0u, AssetBundleLoadType.LoadFromMemory); __state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result); AssetBundleLoadingParameters parameters2 = __state.Parameters; binary = parameters2.Binary; crc = parameters2.Crc; return !__state.SkipOriginalCall; } private static void Postfix(ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state) { ResourceRedirection.Hook_AssetBundleLoading_Postfix(__state, __result); } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundleCreateRequest MM_Detour(byte[] binary, uint crc) { AssetBundleCreateRequest __result = null; AsyncAssetBundleLoadingContext __state = null; if (Prefix(ref binary, ref crc, ref __result, ref __state)) { __result = _original(binary, crc); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundle_LoadFromMemory_Hook { private delegate AssetBundle OriginalMethod(byte[] binary, uint crc); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundle != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromMemory_Internal", new Type[2] { typeof(byte[]), typeof(uint) }); if ((object)methodInfo == null) { TypeContainer assetBundle2 = UnityTypes.AssetBundle; methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromMemory", new Type[2] { typeof(byte[]), typeof(uint) }); } return methodInfo; } private static bool Prefix(ref byte[] binary, ref uint crc, ref AssetBundle __result, ref AssetBundleLoadingContext __state) { AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(binary, null, crc, 0uL, null, 0u, AssetBundleLoadType.LoadFromMemory); __state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result); AssetBundleLoadingParameters parameters2 = __state.Parameters; binary = parameters2.Binary; crc = parameters2.Crc; return !__state.SkipOriginalCall; } private static void Postfix(ref AssetBundle __result, ref AssetBundleLoadingContext __state) { if (!__state.SkipAllPostfixes) { ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result); } if ((Object)(object)__result != (Object)null && __state.Parameters.Path != null) { ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = __state.Parameters.Path; } } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundle MM_Detour(byte[] binary, uint crc) { AssetBundle __result = null; AssetBundleLoadingContext __state = null; if (Prefix(ref binary, ref crc, ref __result, ref __state)) { __result = _original(binary, crc); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundle_LoadFromStreamAsync_Hook { private delegate AssetBundleCreateRequest OriginalMethod(Stream stream, uint crc, uint managedReadBufferSize); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundle != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromStreamAsyncInternal", new Type[3] { typeof(Stream), typeof(uint), typeof(uint) }); if ((object)methodInfo == null) { TypeContainer assetBundle2 = UnityTypes.AssetBundle; methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromStreamAsync", new Type[3] { typeof(Stream), typeof(uint), typeof(uint) }); } return methodInfo; } private static bool Prefix(ref Stream stream, ref uint crc, ref uint managedReadBufferSize, ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state) { AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, null, crc, 0uL, stream, managedReadBufferSize, AssetBundleLoadType.LoadFromMemory); __state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result); AssetBundleLoadingParameters parameters2 = __state.Parameters; stream = parameters2.Stream; crc = parameters2.Crc; managedReadBufferSize = parameters2.ManagedReadBufferSize; return !__state.SkipOriginalCall; } private static void Postfix(ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state) { ResourceRedirection.Hook_AssetBundleLoading_Postfix(__state, __result); } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundleCreateRequest MM_Detour(Stream stream, uint crc, uint managedReadBufferSize) { AssetBundleCreateRequest __result = null; AsyncAssetBundleLoadingContext __state = null; if (Prefix(ref stream, ref crc, ref managedReadBufferSize, ref __result, ref __state)) { __result = _original(stream, crc, managedReadBufferSize); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundle_LoadFromStream_Hook { private delegate AssetBundle OriginalMethod(Stream stream, uint crc, uint managedReadBufferSize); private static OriginalMethod _original; private static bool Prepare(object instance) { return UnityTypes.AssetBundle != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromStreamInternal", new Type[3] { typeof(Stream), typeof(uint), typeof(uint) }); if ((object)methodInfo == null) { TypeContainer assetBundle2 = UnityTypes.AssetBundle; methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromStream", new Type[3] { typeof(Stream), typeof(uint), typeof(uint) }); } return methodInfo; } private static bool Prefix(ref Stream stream, ref uint crc, ref uint managedReadBufferSize, ref AssetBundle __result, ref AssetBundleLoadingContext __state) { AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, null, crc, 0uL, stream, managedReadBufferSize, AssetBundleLoadType.LoadFromMemory); __state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result); AssetBundleLoadingParameters parameters2 = __state.Parameters; stream = parameters2.Stream; crc = parameters2.Crc; managedReadBufferSize = parameters2.ManagedReadBufferSize; return !__state.SkipOriginalCall; } private static void Postfix(ref AssetBundle __result, ref AssetBundleLoadingContext __state) { if (!__state.SkipAllPostfixes) { ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result); } if ((Object)(object)__result != (Object)null && __state.Parameters.Path != null) { ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = __state.Parameters.Path; } } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static AssetBundle MM_Detour(Stream stream, uint crc, uint managedReadBufferSize) { AssetBundle __result = null; AssetBundleLoadingContext __state = null; if (Prefix(ref stream, ref crc, ref managedReadBufferSize, ref __result, ref __state)) { __result = _original(stream, crc, managedReadBufferSize); } Postfix(ref __result, ref __state); return __result; } } internal static class AssetBundle_mainAsset_Hook { private delegate Object OriginalMethod(AssetBundle __instance); private static OriginalMethod _original; private static bool Prepare(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; return (object)AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "returnMainAsset", new Type[1] { typeof(AssetBundle) }) == null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; return AccessToolsShim.Property((assetBundle != null) ? assetBundle.ClrType : null, "mainAsset")?.GetGetMethod(); } private static bool Prefix(AssetBundle __instance, ref Object __result, ref AssetLoadingContext __state) { AssetLoadingParameters parameters = new AssetLoadingParameters(null, null, AssetLoadType.LoadMainAsset); __state = ResourceRedirection.Hook_AssetLoading_Prefix(parameters, __instance, ref __result); return !__state.SkipOriginalCall; } private static void Postfix(AssetBundle __instance, ref Object __result, ref AssetLoadingContext __state) { if (!__state.SkipAllPostfixes) { ResourceRedirection.Hook_AssetLoaded_Postfix(__state.Parameters, __instance, ref __result); } } private static void MM_Init(object detour) { _original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour); } private static Object MM_Detour(AssetBundle __instance) { Object __result = null; AssetLoadingContext __state = null; if (Prefix(__instance, ref __result, ref __state)) { __result = _original(__instance); } Postfix(__instance, ref __result, ref __state); return __result; } } internal static class AssetBundle_returnMainAsset_Hook { private delegate Object OriginalMethod(AssetBundle __instance); private static OriginalMethod _original; private static bool Prepare(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; return (object)AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "returnMainAsset", new Type[1] { typeof(AssetBundle) }) != null; } private static MethodBase TargetMethod(object instance) { TypeContainer assetBundle = UnityTypes.AssetBundle; return AccessToolsShim.Method((assetBundle != null) ? assetBu