Decompiled source of Enhanced Prefab Loader v6.0.1
BepInEx/patchers/EnhancedPrefabLoader/CollectionWeaver.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using CollectionWeaver.Core; using CollectionWeaver.Extensions; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; using Mono.Collections.Generic; using MonoMod.Cil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CollectionWeaver")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+3e2b65ea5843d010d4d0ded79adad4982bc89e1b")] [assembly: AssemblyProduct("CollectionWeaver")] [assembly: AssemblyTitle("CollectionWeaver")] [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] [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; } } [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 CollectionWeaver { public static class ListInterceptor<T> { private static readonly ConcurrentDictionary<string, ListInterceptorHandler<T>> handlerCache = new ConcurrentDictionary<string, ListInterceptorHandler<T>>(); public static List<ListInterceptorHandler<T>> Handlers { get; private set; } = new List<ListInterceptorHandler<T>>(); public static void InvokeInsert(List<T> list, int index, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Insert(list, index, value, fieldName); return; } try { list.Insert(index, value); } catch (Exception ex) { throw new Exception("Error in Insert for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeIndexOf(List<T> list, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.IndexOf(list, value, fieldName); } try { return list.IndexOf(value); } catch (Exception ex) { throw new Exception("Error in IndexOf for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeRemoveAt(List<T> list, int index, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.RemoveAt(list, index, fieldName); return; } try { list.RemoveAt(index); } catch (Exception ex) { throw new Exception("Error in RemoveAt for field '" + fieldName + "': " + ex.Message, ex); } } public static T InvokeGet_Item(List<T> list, int index, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.GetItem(list, index, fieldName); } try { return list[index]; } catch (Exception ex) { throw new Exception("Error in Get_Item for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeSet_Item(List<T> list, int index, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.SetItem(list, index, value, fieldName); return; } try { list[index] = value; } catch (Exception ex) { throw new Exception("Error in Set_Item for field '" + fieldName + "': " + ex.Message, ex); } } public static List<T>.Enumerator InvokeGetEnumerator(List<T> list, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.GetEnumerator(list, fieldName); } try { return list.GetEnumerator(); } catch (Exception ex) { throw new Exception("Error in GetEnumerator for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeAdd(List<T> list, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Add(list, value, fieldName); return; } try { list.Add(value); } catch (Exception ex) { throw new Exception("Error in Add for field '" + fieldName + "': " + ex.Message, ex); } } public static bool InvokeRemove(List<T> list, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.Remove(list, value, fieldName); } try { return list.Remove(value); } catch (Exception ex) { throw new Exception("Error in Remove for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeGet_Count(List<T> list, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.Count(list, fieldName); } try { return list.Count; } catch (Exception ex) { throw new Exception("Error in Get_Count for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeClear(List<T> list, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Clear(list, fieldName); return; } try { list.Clear(); } catch (Exception ex) { throw new Exception("Error in Clear for field '" + fieldName + "': " + ex.Message, ex); } } public static bool InvokeContains(List<T> list, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.Contains(list, value, fieldName); } try { return list.Contains(value); } catch (Exception ex) { throw new Exception("Error in Contains for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeCopyTo(List<T> list, T[] array, int arrayIndex, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.CopyTo(list, array, arrayIndex, fieldName); return; } try { list.CopyTo(array, arrayIndex); } catch (Exception ex) { throw new Exception("Error in CopyTo for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeAddRange(List<T> list, IEnumerable<T> values, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.AddRange(list, values, fieldName); return; } try { list.AddRange(values); } catch (Exception ex) { throw new Exception("Error in AddRange for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeInsertRange(List<T> list, int index, IEnumerable<T> values, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.InsertRange(list, index, values, fieldName); return; } try { list.InsertRange(index, values); } catch (Exception ex) { throw new Exception("Error in InsertRange for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeRemoveRange(List<T> list, int index, int count, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.RemoveRange(list, index, count, fieldName); return; } try { list.RemoveRange(index, count); } catch (Exception ex) { throw new Exception("Error in RemoveRange for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeLastIndexOf(List<T> list, T value, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.LastIndexOf(list, value, fieldName); } try { return list.LastIndexOf(value); } catch (Exception ex) { throw new Exception("Error in LastIndexOf for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeSort(List<T> list, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Sort(list, fieldName); return; } try { list.Sort(); } catch (Exception ex) { throw new Exception("Error in Sort for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeSort(List<T> list, Comparison<T> comparison, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Sort(list, comparison, fieldName); return; } try { list.Sort(comparison); } catch (Exception ex) { throw new Exception("Error in Sort(Comparison) for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeSort(List<T> list, IComparer<T> comparer, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Sort(list, comparer, fieldName); return; } try { list.Sort(comparer); } catch (Exception ex) { throw new Exception("Error in Sort(IComparer) for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeReverse(List<T> list, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Reverse(list, fieldName); return; } try { list.Reverse(); } catch (Exception ex) { throw new Exception("Error in Reverse for field '" + fieldName + "': " + ex.Message, ex); } } public static void InvokeReverse(List<T> list, int index, int count, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { handler.Reverse(list, index, count, fieldName); return; } try { list.Reverse(index, count); } catch (Exception ex) { throw new Exception("Error in Reverse(int, int) for field '" + fieldName + "': " + ex.Message, ex); } } public static bool InvokeExists(List<T> list, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.Exists(list, predicate, fieldName); } try { return list.Exists(predicate); } catch (Exception ex) { throw new Exception("Error in Exists for field '" + fieldName + "': " + ex.Message, ex); } } public static T InvokeFind(List<T> list, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.Find(list, predicate, fieldName); } try { return list.Find(predicate); } catch (Exception ex) { throw new Exception("Error in Find for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeFindIndex(List<T> list, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindIndex(list, predicate, fieldName); } try { return list.FindIndex(predicate); } catch (Exception ex) { throw new Exception("Error in FindIndex for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeFindIndex(List<T> list, int index, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindIndex(list, index, predicate, fieldName); } try { return list.FindIndex(index, predicate); } catch (Exception ex) { throw new Exception("Error in FindIndex(int) for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeFindIndex(List<T> list, int index, int count, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindIndex(list, index, count, predicate, fieldName); } try { return list.FindIndex(index, count, predicate); } catch (Exception ex) { throw new Exception("Error in FindIndex(int, int) for field '" + fieldName + "': " + ex.Message, ex); } } public static T InvokeFindLast(List<T> list, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindLast(list, predicate, fieldName); } try { return list.FindLast(predicate); } catch (Exception ex) { throw new Exception("Error in FindLast for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeFindLastIndex(List<T> list, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindLastIndex(list, predicate, fieldName); } try { return list.FindLastIndex(predicate); } catch (Exception ex) { throw new Exception("Error in FindLastIndex for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeFindLastIndex(List<T> list, int index, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindLastIndex(list, index, predicate, fieldName); } try { return list.FindLastIndex(index, predicate); } catch (Exception ex) { throw new Exception("Error in FindLastIndex(int) for field '" + fieldName + "': " + ex.Message, ex); } } public static int InvokeFindLastIndex(List<T> list, int index, int count, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.FindLastIndex(list, index, count, predicate, fieldName); } try { return list.FindLastIndex(index, count, predicate); } catch (Exception ex) { throw new Exception("Error in FindLastIndex(int, int) for field '" + fieldName + "': " + ex.Message, ex); } } public static bool InvokeTrueForAll(List<T> list, Predicate<T> predicate, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.TrueForAll(list, predicate, fieldName); } try { return list.TrueForAll(predicate); } catch (Exception ex) { throw new Exception("Error in TrueForAll for field '" + fieldName + "': " + ex.Message, ex); } } public static T[] InvokeToArray(List<T> list, string fieldName) { ListInterceptorHandler<T> handler = GetHandler(fieldName); if (handler != null) { return handler.ToArray(list, fieldName); } try { return list.ToArray(); } catch (Exception ex) { throw new Exception("Error in ToArray for field '" + fieldName + "': " + ex.Message, ex); } } private static ListInterceptorHandler<T>? GetHandler(string fieldName) { return handlerCache.GetOrAdd(fieldName, delegate(string fn) { string fn2 = fn; return Handlers.FirstOrDefault((ListInterceptorHandler<T> h) => h.ShouldHandleCall(fn2)); }); } } } namespace CollectionWeaver.IL { public class ILWeaver { private readonly WeaverOptions weaverOptions; private readonly MethodWeaver methodWeaver; public ILWeaver(WeaverOptions weaverOptions) { this.weaverOptions = weaverOptions; methodWeaver = new MethodWeaver(this.weaverOptions); } public WeaverResult Weave(AssemblyDefinition assembly) { ModuleDefinition mainModule = assembly.MainModule; WeaverResult weaverResult = new WeaverResult(); foreach (TypeDefinition item in from t in ModuleDefinitionRocks.GetAllTypes(mainModule) where t.IsClassType() select t) { foreach (MethodDefinition item2 in ((IEnumerable<MethodDefinition>)item.Methods).Where((MethodDefinition m) => m.HasBody)) { weaverResult.Merge(methodWeaver.Weave(item2)); } } return weaverResult; } } public class MethodWeaver { [CompilerGenerated] private WeaverOptions <options>P; private readonly NameResolver nameResolver; private readonly Dictionary<string, (GenericInstanceType, TypeDefinition)> interceptorTypeCache; private readonly Dictionary<string, MethodReference> interceptorMethodRefCache; public MethodWeaver(WeaverOptions options) { <options>P = options; nameResolver = new NameResolver(); interceptorTypeCache = new Dictionary<string, (GenericInstanceType, TypeDefinition)>(); interceptorMethodRefCache = new Dictionary<string, MethodReference>(); base..ctor(); } public WeaverResult Weave(MethodDefinition method) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown MethodBodyRocks.SimplifyMacros(method.Body); ILContext val = new ILContext(method); try { ILCursor val2 = new ILCursor(val); WeaverResult weaverResult = new WeaverResult(); string scope = ((MemberReference)method.DeclaringType).Name + "." + ((MemberReference)method).Name; MethodReference targetMethodRef = null; while (val2.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction instr) => ILPatternMatchingExt.MatchCallOrCallvirt(instr, ref targetMethodRef) })) { if (targetMethodRef == null || !((MemberReference)targetMethodRef).DeclaringType.IsSupportedCollectionType()) { continue; } GenericInstanceType genericInstanceType = ((MemberReference)targetMethodRef).DeclaringType.GetGenericInstanceType(); string name; if (genericInstanceType == null) { weaverResult.AddSkipped(scope, ((MemberReference)targetMethodRef).FullName, "Non-generic collection type"); } else if (!nameResolver.TryResolveName(val2.Clone(), ((IEnumerable<TypeReference>)genericInstanceType.GenericArguments).ToArray(), out name)) { weaverResult.AddSkipped(scope, ((MemberReference)targetMethodRef).FullName, "Unresolvable name"); } else { if (!<options>P.IsFieldIncluded(name)) { continue; } TypeDefinition interceptorTypeDef = GetInterceptorTypeDef(val2.Module, genericInstanceType); if (interceptorTypeDef == null) { weaverResult.AddSkipped(scope, name, "No interceptor found"); continue; } MethodReference interceptorMethodRef = GetInterceptorMethodRef(val2.Module, interceptorTypeDef, targetMethodRef, genericInstanceType); if (interceptorMethodRef == null) { weaverResult.AddSkipped(scope, name, "No matching interceptor method found"); continue; } PatchCollectionCall(val2, interceptorMethodRef, name); weaverResult.AddPatched(scope, name, (MethodReference)(object)method); } } MethodBodyRocks.OptimizeMacros(method.Body); return weaverResult; } finally { ((IDisposable)val)?.Dispose(); } } private void PatchCollectionCall(ILCursor cursor, MethodReference interceptorMethodRef, string declaredName) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) ILCursor cursor2 = cursor; List<Instruction> list = ((IEnumerable<Instruction>)cursor2.Method.Body.Instructions).Where((Instruction instr) => instr.Operand == cursor2.Next).ToList(); ILLabel val = cursor2.MarkLabel(); cursor2.Emit(OpCodes.Ldstr, declaredName).Remove().Emit(OpCodes.Call, interceptorMethodRef); foreach (Instruction item in list) { item.Operand = val.Target; } } private TypeDefinition? GetInterceptorTypeDef(ModuleDefinition module, GenericInstanceType collectionType) { if (!interceptorTypeCache.TryGetValue(((MemberReference)collectionType).FullName, out (GenericInstanceType, TypeDefinition) value)) { Type interceptorRuntimeType = GetInterceptorRuntimeType(collectionType); if ((object)interceptorRuntimeType == null) { return null; } GenericInstanceType obj = TypeReferenceRocks.MakeGenericInstanceType(module.ImportReference(interceptorRuntimeType), ((IEnumerable<TypeReference>)collectionType.GenericArguments).ToArray()); TypeDefinition item = ((TypeReference)obj).Resolve(); value = (obj, item); interceptorTypeCache[((MemberReference)collectionType).FullName] = value; } return value.Item2; } private MethodReference? GetInterceptorMethodRef(ModuleDefinition module, TypeDefinition? interceptorTypeDef, MethodReference targetMethod, GenericInstanceType collectionType) { MethodReference targetMethod2 = targetMethod; GenericInstanceType collectionType2 = collectionType; MethodDefinition val = ((interceptorTypeDef != null) ? ((IEnumerable<MethodDefinition>)interceptorTypeDef.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name.EndsWith(((MemberReference)targetMethod2).Name, StringComparison.OrdinalIgnoreCase) && ((MethodReference)m).Parameters.Count - 2 == targetMethod2.Parameters.Count && ((IEnumerable<ParameterDefinition>)((MethodReference)m).Parameters).Skip(1).Take(((MethodReference)m).Parameters.Count - 2).Zip((IEnumerable<ParameterDefinition>)targetMethod2.Parameters, (ParameterDefinition interceptorParam, ParameterDefinition methodParam) => ((ParameterReference)interceptorParam).ParameterType.IsEquivalentTo(((ParameterReference)methodParam).ParameterType, collectionType2)) .All((bool match) => match))) : null); if (val == null) { return null; } string text = string.Join("|", ((IEnumerable<ParameterDefinition>)targetMethod2.Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).FullName)); string key = ((MemberReference)collectionType2).FullName + "::" + ((MemberReference)targetMethod2).Name + "::" + text; if (!interceptorMethodRefCache.TryGetValue(key, out MethodReference value)) { value = module.ImportReference((MethodReference)(object)val); ((MemberReference)value).DeclaringType = (TypeReference)(object)interceptorTypeCache[((MemberReference)collectionType2).FullName].Item1; interceptorMethodRefCache[key] = value; } return value; } private Type? GetInterceptorRuntimeType(GenericInstanceType? genericInstanceType) { string text = ((genericInstanceType != null) ? ((MemberReference)((TypeReference)genericInstanceType).GetElementType()).FullName : null); if (text == "System.Collections.Generic.List`1" || text == "System.Collections.Generic.IList`1") { return typeof(ListInterceptor<>); } return null; } } internal class NameResolver { internal bool TryResolveName(ILCursor cursor, TypeReference[] targetGenericArguments, out string name) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown ILCursor cursor2 = cursor; TypeReference[] targetGenericArguments2 = targetGenericArguments; string name2 = ((MemberReference)cursor2.Method).Name; Instruction next = cursor2.Next; name = $"{name2}_unk_{((next != null) ? next.Offset : 0)}"; if (cursor2.Next == null) { return false; } Instruction next2 = cursor2.Next; while (cursor2.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[1] { (Instruction instr) => instr.MatchCollectionLoad(cursor2.Method, targetGenericArguments2) })) { if (cursor2.Next == null) { return false; } int stackCount = 1; if (!TryTraceToTarget(cursor2.Next, next2, ref stackCount) || stackCount != 0) { continue; } if (cursor2.Previous.OpCode.IsFieldLoad()) { FieldReference val = (FieldReference)cursor2.Previous.Operand; name = ((MemberReference)((MemberReference)val).DeclaringType).Name + "." + ((MemberReference)val).Name; return true; } if (cursor2.Previous.OpCode.IsLdarg()) { name = $"{((MemberReference)cursor2.Method).Name}_arg{cursor2.Method.GetParameterIndex(cursor2.Previous)}"; return true; } while (cursor2.Previous.OpCode.IsLdloc() && cursor2.TryGotoPrev((MoveType)0, new Func<Instruction, bool>[1] { (Instruction instr) => instr.IsComplimentaryStOf(cursor2.Previous) })) { if (cursor2.SkipNeutralBackward().Previous.OpCode.IsFieldLoad()) { FieldReference val2 = (FieldReference)cursor2.Previous.Operand; name = ((MemberReference)((MemberReference)val2).DeclaringType).Name + "." + ((MemberReference)val2).Name; return true; } if (cursor2.Previous.OpCode.IsLdarg()) { name = $"{((MemberReference)cursor2.Method).Name}_arg{cursor2.Method.GetParameterIndex(cursor2.Previous)}"; return true; } } } return false; } private bool TryTraceToTarget(Instruction current, Instruction target, ref int stackCount) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (current == null || target == null) { return false; } Instruction obj; for (; current != null; current = obj) { if (current == target) { stackCount -= current.GetStackPopCount(); return true; } stackCount -= current.GetStackPopCount(); stackCount += current.GetStackPushCount(); if (current.OpCode.IsUnconditionalBranch()) { object operand = current.Operand; Instruction val = (Instruction)((operand is Instruction) ? operand : null); if (val != null) { obj = val; continue; } } obj = current.Next; } return false; } } public class WeaverOptions { private readonly HashSet<string> includedFieldNames = new HashSet<string>(); public IReadOnlyCollection<string> IncludedFieldNames => includedFieldNames; public WeaverOptions IncludeField(string fieldName) { includedFieldNames.Add(fieldName); return this; } internal bool IsFieldIncluded(string fieldName) { return includedFieldNames.Contains(fieldName); } } public class WeaverResult { private class Entry { public ResultKind Kind { get; set; } public string Scope { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string Details { get; set; } = string.Empty; } private enum ResultKind { Patched, Skipped } private readonly List<Entry> entries = new List<Entry>(); public int PatchedCount => entries.Count((Entry e) => e.Kind == ResultKind.Patched); public int SkippedCount => entries.Count((Entry e) => e.Kind == ResultKind.Skipped); public void AddPatched(string scope, string name, MethodReference methodReference) { entries.Add(new Entry { Kind = ResultKind.Patched, Scope = scope, Name = name, Details = ((MemberReference)methodReference).FullName }); } public void AddSkipped(string scope, string name, string reason) { entries.Add(new Entry { Kind = ResultKind.Skipped, Scope = scope, Name = name, Details = reason }); } public void Merge(WeaverResult other) { if (other != null) { entries.AddRange(other.entries); } } public string CompileLog() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("=== Weaver Results ==="); foreach (Entry item in entries.Where((Entry e) => e.Kind == ResultKind.Patched)) { stringBuilder.AppendLine(" ✔ [" + item.Scope + "] " + item.Name + " -> " + item.Details); } List<Entry> list = entries.Where((Entry e) => e.Kind == ResultKind.Skipped).ToList(); if (list.Count > 0) { stringBuilder.AppendLine("--- Skipped ---"); foreach (Entry item2 in list) { stringBuilder.AppendLine(" ✘ [" + item2.Scope + "] " + item2.Name + " -> " + item2.Details); } } return stringBuilder.ToString(); } } } namespace CollectionWeaver.Extensions { internal static class ArrayTypeExtensions { internal static bool IsEquivalentTo(this ArrayType source, ArrayType target, GenericInstanceType? genericContext) { if (((TypeSpecification)source).ElementType.IsEquivalentTo(((TypeSpecification)target).ElementType, genericContext)) { return source.Rank == target.Rank; } return false; } } internal static class CursorExtensions { internal static ILCursor SkipNeutralForward(this ILCursor cursor) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) while (cursor.Next != null && cursor.Next.OpCode.IsNeutral()) { cursor.GotoNext(Array.Empty<Func<Instruction, bool>>()); } return cursor; } internal static ILCursor SkipNeutralBackward(this ILCursor cursor) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) while (cursor.Previous != null && cursor.Previous.OpCode.IsNeutral()) { cursor.GotoPrev(Array.Empty<Func<Instruction, bool>>()); } return cursor; } } internal static class GenericInstanceTypeExtensions { internal static bool IsEquivalentTo(this GenericInstanceType source, GenericInstanceType target, GenericInstanceType? genericContext) { if (!((TypeSpecification)source).ElementType.IsEquivalentTo(((TypeSpecification)target).ElementType, genericContext)) { return false; } Collection<TypeReference> genericArguments = source.GenericArguments; Collection<TypeReference> genericArguments2 = target.GenericArguments; if (genericArguments.Count != genericArguments2.Count) { return false; } for (int i = 0; i < genericArguments.Count; i++) { if (!genericArguments[i].IsEquivalentTo(genericArguments2[i], genericContext)) { return false; } } return true; } } internal static class GenericParameterExtensions { internal static bool TryResolveAndMatch(this GenericParameter genericParam, TypeReference target, GenericInstanceType? genericContext) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) GenericParameter val = (GenericParameter)(object)((target is GenericParameter) ? target : null); if (val != null) { if (genericParam.Position == val.Position) { return genericParam.Type == val.Type; } return false; } if (genericContext != null && genericParam.Position < genericContext.GenericArguments.Count) { return ((MemberReference)genericContext.GenericArguments[genericParam.Position]).FullName == ((MemberReference)target).FullName; } return false; } } internal static class InstructionExtensions { internal static bool MatchCollectionLoad(this Instruction instruction, MethodDefinition method, TypeReference[] targetGenericArguments) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected I4, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 if (!instruction.OpCode.IsLoadCode()) { return false; } OpCode opCode = instruction.OpCode; Code code = ((OpCode)(ref opCode)).Code; if ((int)code <= 120) { switch (code - 2) { case 4: goto IL_0099; case 5: goto IL_00ab; case 6: goto IL_00bd; case 7: goto IL_00cf; case 15: goto IL_00e1; case 0: goto IL_00fe; case 1: goto IL_011b; case 2: goto IL_0136; case 3: goto IL_0151; case 13: goto IL_016c; case 8: case 9: case 10: case 11: case 12: case 14: goto IL_01a0; } if ((int)code == 120) { goto IL_0186; } } else { if ((int)code == 123) { goto IL_0186; } if ((int)code == 199) { goto IL_016c; } if ((int)code == 202) { goto IL_00e1; } } goto IL_01a0; IL_0186: object operand = instruction.Operand; object obj = ((operand is FieldReference) ? operand : null); TypeReference val = ((obj != null) ? ((FieldReference)obj).FieldType : null); goto IL_01a2; IL_01a0: val = null; goto IL_01a2; IL_00e1: object operand2 = instruction.Operand; object obj2 = ((operand2 is VariableReference) ? operand2 : null); val = ((obj2 != null) ? ((VariableReference)obj2).VariableType : null); goto IL_01a2; IL_01a2: TypeReference val2 = val; if (val2 == null || !val2.IsSupportedCollectionType()) { return false; } GenericInstanceType genericInstanceType = val2.GetGenericInstanceType(); if (genericInstanceType != null) { return targetGenericArguments.Select((TypeReference x) => ((MemberReference)x).FullName).SequenceEqual(((IEnumerable<TypeReference>)genericInstanceType.GenericArguments).Select((TypeReference x) => ((MemberReference)x).FullName)); } return false; IL_00cf: val = method.Body.GetVariableType(3); goto IL_01a2; IL_00bd: val = method.Body.GetVariableType(2); goto IL_01a2; IL_00ab: val = method.Body.GetVariableType(1); goto IL_01a2; IL_0099: val = method.Body.GetVariableType(0); goto IL_01a2; IL_0151: val = (((MethodReference)method).HasThis ? method.GetParameterType(2) : method.GetParameterType(3)); goto IL_01a2; IL_011b: val = (((MethodReference)method).HasThis ? method.GetParameterType(0) : method.GetParameterType(1)); goto IL_01a2; IL_00fe: val = (TypeReference)(((MethodReference)method).HasThis ? ((object)method.DeclaringType) : ((object)method.GetParameterType(0))); goto IL_01a2; IL_016c: object operand3 = instruction.Operand; object obj3 = ((operand3 is ParameterReference) ? operand3 : null); val = ((obj3 != null) ? ((ParameterReference)obj3).ParameterType : null); goto IL_01a2; IL_0136: val = (((MethodReference)method).HasThis ? method.GetParameterType(1) : method.GetParameterType(2)); goto IL_01a2; } internal static bool IsComplimentaryStOf(this Instruction stInstruction, Instruction ldInstruction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!stInstruction.OpCode.IsStloc() || !ldInstruction.OpCode.IsLdloc()) { return false; } int? localCodeIndex = stInstruction.GetLocalCodeIndex(); int? localCodeIndex2 = ldInstruction.GetLocalCodeIndex(); if (localCodeIndex.HasValue) { return localCodeIndex == localCodeIndex2; } return false; } internal static int? GetLocalCodeIndex(this Instruction instr) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 OpCode opCode = instr.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 6) { default: if ((int)code != 202 && (int)code != 204) { break; } goto case 11; case 0: case 4: return 0; case 1: case 5: return 1; case 2: case 6: return 2; case 3: case 7: return 3; case 11: case 13: { object operand = instr.Operand; VariableReference val = (VariableReference)((operand is VariableReference) ? operand : null); return (val != null) ? new int?(val.Index) : null; } case 8: case 9: case 10: case 12: break; } return null; } internal static int GetStackPopCount(this Instruction inst) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected I4, but got Unknown OpCode opCode = inst.OpCode; StackBehaviour stackBehaviourPop = ((OpCode)(ref opCode)).StackBehaviourPop; return (int)stackBehaviourPop switch { 0 => 0, 1 => 1, 2 => 2, 3 => 1, 4 => 2, 5 => 2, 6 => 2, 7 => 3, 8 => 2, 9 => 2, 10 => 1, 11 => 2, 12 => 2, 13 => 3, 14 => 3, 15 => 3, 16 => 3, 17 => 3, 27 => inst.GetVarPop(), _ => 0, }; } internal static int GetStackPushCount(this Instruction inst) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected I4, but got Unknown OpCode opCode = inst.OpCode; StackBehaviour stackBehaviourPush = ((OpCode)(ref opCode)).StackBehaviourPush; return (stackBehaviourPush - 19) switch { 0 => 0, 1 => 1, 2 => 2, 3 => 1, 4 => 1, 5 => 1, 6 => 1, 7 => 1, 9 => inst.GetVarPush(), _ => 0, }; } internal static int GetVarPop(this Instruction inst) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 OpCode opCode = inst.OpCode; if ((int)((OpCode)(ref opCode)).FlowControl == 2) { object operand = inst.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null) { return val.Parameters.Count + (val.HasThis ? 1 : 0); } } opCode = inst.OpCode; return ((int)((OpCode)(ref opCode)).Code == 68) ? 1 : 0; } internal static int GetVarPush(this Instruction inst) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 OpCode opCode = inst.OpCode; if ((int)((OpCode)(ref opCode)).FlowControl == 2) { object operand = inst.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null) { return ((int)val.ReturnType.MetadataType != 1) ? 1 : 0; } } return 0; } } internal static class MethodBodyExtensions { internal static TypeReference? GetVariableType(this MethodBody body, int index) { if (index < 0 || index >= body.Variables.Count) { return null; } return ((VariableReference)body.Variables[index]).VariableType; } } internal static class MethodDefinitionExtensions { internal static TypeReference? GetParameterType(this MethodDefinition method, int index) { if (index < 0 || index >= ((MethodReference)method).Parameters.Count) { return null; } return ((ParameterReference)((MethodReference)method).Parameters[index]).ParameterType; } internal static int? GetParameterIndex(this MethodDefinition method, Instruction instr) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected I4, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 OpCode opCode = instr.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 2) { default: if ((int)code == 14 || (int)code == 199) { object operand = instr.Operand; ParameterReference val = (ParameterReference)((operand is ParameterReference) ? operand : null); return (val != null) ? new int?(val.Index) : null; } return null; case 0: return (!((MethodReference)method).HasThis) ? 1 : 0; case 1: return ((MethodReference)method).HasThis ? 1 : 2; case 2: return ((MethodReference)method).HasThis ? 2 : 3; case 3: return ((MethodReference)method).HasThis ? 3 : 4; } } } internal static class OpCodeExtensions { internal static bool IsLoadCode(this OpCode opCode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!opCode.IsLdloc() && !opCode.IsLdarg() && !opCode.IsLdc() && !opCode.IsLdelem() && !opCode.IsFieldLoad() && !opCode.IsLdNullOrStr()) { return opCode.IsLdind(); } return true; } internal static bool IsFieldLoad(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 120 || (int)code == 123) { return true; } return false; } internal static bool IsLdloc(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 6 <= 3 || (int)code == 17 || (int)code == 202) { return true; } return false; } internal static bool IsLdarg(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 2 <= 3 || code - 14 <= 1 || code - 199 <= 1) { return true; } return false; } internal static bool IsLdc(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 21 <= 14) { return true; } return false; } internal static bool IsLdelem(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 145 || (int)code == 151 || (int)code == 160) { return true; } return false; } internal static bool IsLdind(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 69 <= 6 || code - 77 <= 2) { return true; } return false; } internal static bool IsLdNullOrStr(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 20 || (int)code == 113) { return true; } return false; } internal static bool IsStloc(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 10 <= 3 || (int)code == 19 || (int)code == 204) { return true; } return false; } internal static bool IsNeutral(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0010: 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_002d: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code <= 209) { if ((int)code == 0 || code - 207 <= 2) { goto IL_002f; } } else if ((int)code == 211 || (int)code == 218) { goto IL_002f; } return false; IL_002f: return true; } internal static bool IsUnconditionalBranch(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 42 || (int)code == 55 || code - 187 <= 1) { return true; } return false; } internal static bool IsConditionalBranch(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 43 <= 1 || code - 56 <= 1) { return true; } return false; } internal static bool IsCompareBranch(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 45 <= 9 || code - 58 <= 9) { return true; } return false; } internal static bool IsSwitchBranch(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 return (int)((OpCode)(ref opCode)).Code == 68; } } internal static class TypeDefinitionExtensions { internal static bool IsClassType(this TypeDefinition typeDef) { if (typeDef.IsClass && !typeDef.IsInterface) { return !((TypeReference)typeDef).IsValueType; } return false; } } internal static class TypeReferenceExtensions { private static readonly Dictionary<string, bool> collectionTypeCache = new Dictionary<string, bool>(); private static readonly Dictionary<string, GenericInstanceType?> genericInstanceCache = new Dictionary<string, GenericInstanceType>(); internal static bool IsSupportedCollectionType(this TypeReference typeRef) { return typeRef.IsListType(); } internal static bool IsListType(this TypeReference typeRef) { if (!collectionTypeCache.TryGetValue(((MemberReference)typeRef).FullName, out var value)) { bool flag = typeRef.Namespace == "System.Collections.Generic"; if (flag) { string name = ((MemberReference)typeRef).Name; bool flag2 = ((name == "List`1" || name == "IList`1") ? true : false); flag = flag2; } if (flag && typeRef is GenericInstanceType) { value = true; } else { TypeDefinition obj = typeRef.Resolve(); value = ((obj == null) ? null : obj.BaseType?.IsListType()).GetValueOrDefault(); } collectionTypeCache[((MemberReference)typeRef).FullName] = value; } return value; } internal static GenericInstanceType? GetGenericInstanceType(this TypeReference typeRef) { if (!genericInstanceCache.TryGetValue(((MemberReference)typeRef).FullName, out GenericInstanceType value)) { try { GenericInstanceType val = (GenericInstanceType)(object)((typeRef is GenericInstanceType) ? typeRef : null); value = (GenericInstanceType)((val == null) ? ((object)typeRef.Resolve().BaseType?.GetGenericInstanceType()) : ((object)val)); genericInstanceCache[((MemberReference)typeRef).FullName] = value; } catch (Exception ex) { Log.Debug("Failed to resolve generic instance type for " + ((MemberReference)typeRef).FullName + ": " + ex.Message); genericInstanceCache[((MemberReference)typeRef).FullName] = null; } } return value; } internal static bool IsEquivalentTo(this TypeReference source, TypeReference target, GenericInstanceType? genericContext = null) { if (source == null || target == null) { return false; } if (((MemberReference)source).FullName == ((MemberReference)target).FullName) { return true; } GenericParameter val = (GenericParameter)(object)((source is GenericParameter) ? source : null); if (val != null) { return val.TryResolveAndMatch(target, genericContext); } GenericParameter val2 = (GenericParameter)(object)((target is GenericParameter) ? target : null); if (val2 != null) { return val2.TryResolveAndMatch(source, genericContext); } GenericInstanceType val3 = (GenericInstanceType)(object)((source is GenericInstanceType) ? source : null); if (val3 != null) { GenericInstanceType val4 = (GenericInstanceType)(object)((target is GenericInstanceType) ? target : null); if (val4 != null) { return val3.IsEquivalentTo(val4, genericContext); } } ArrayType val5 = (ArrayType)(object)((source is ArrayType) ? source : null); if (val5 != null) { ArrayType val6 = (ArrayType)(object)((target is ArrayType) ? target : null); if (val6 != null) { return val5.IsEquivalentTo(val6, genericContext); } } return false; } } } namespace CollectionWeaver.Core { public class ConsoleLogger : ILogger { private readonly object logLock = new object(); public void Log(LogLevel logLevel, string message) { lock (logLock) { ConsoleColor foregroundColor = Console.ForegroundColor; try { Console.ForegroundColor = GetLevelColor(logLevel); Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [{logLevel}] {message}"); } finally { Console.ForegroundColor = foregroundColor; } } } private ConsoleColor GetLevelColor(LogLevel level) { return level switch { LogLevel.Debug => ConsoleColor.DarkGray, LogLevel.Info => ConsoleColor.White, LogLevel.Warning => ConsoleColor.Yellow, LogLevel.Error => ConsoleColor.Red, _ => ConsoleColor.Gray, }; } } public interface ILogger { void Log(LogLevel logLevel, string message); } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class InterceptorHandler : Attribute { } public static class InterceptorRegistry { public static void RegisterFromAssembly(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException("assembly"); } foreach (Type item in assembly.GetTypes().Where(IsInterceptorType)) { TryRegisterHandler(item); } } public static void RegisterFromAllAssemblies() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { RegisterFromAssembly(assembly); } catch (Exception ex) { Log.Debug("Skipping assembly " + assembly.GetName().Name + ": " + ex.Message); } } } private static bool IsInterceptorType(Type type) { if (type.IsClass && !type.IsAbstract) { return type.GetCustomAttribute<InterceptorHandler>() != null; } return false; } private static void TryRegisterHandler(Type handlerType) { Type type = FindInterceptorBase(handlerType); if (type == null) { Log.Warning(handlerType.Name + " has [Interceptor] but does not inherit from a valid InterceptorHandler<T>"); return; } Type type2 = ResolveInterceptorType(type); if (type2 == null) { Log.Warning("No runtime interceptor found for " + type.Name); return; } IList handlersList = GetHandlersList(type2); if (handlersList == null) { Log.Error("Cannot access Handlers property on " + type2.Name); } else { RegisterHandler(handlersList, handlerType, type.GenericTypeArguments); } } private static Type? FindInterceptorBase(Type type) { Type baseType = type.BaseType; while (baseType != null) { if (baseType.IsGenericType && baseType.Name.EndsWith("InterceptorHandler`1")) { return baseType; } baseType = baseType.BaseType; } return null; } private static Type? ResolveInterceptorType(Type interceptorBase) { return ((!(interceptorBase.Name == "ListInterceptorHandler`1")) ? null : typeof(ListInterceptor<>))?.MakeGenericType(interceptorBase.GenericTypeArguments); } private static IList? GetHandlersList(Type interceptorType) { return interceptorType.GetProperty("Handlers", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as IList; } private static void RegisterHandler(IList handlerList, Type handlerType, Type[] genericArgs) { try { object obj = Activator.CreateInstance(handlerType); if (obj == null) { Log.Error("Activator.CreateInstance returned null for " + handlerType.Name); return; } handlerList.Add(obj); Log.Info("Registered " + handlerType.Name + " for " + string.Join(", ", genericArgs.Select((Type a) => a.Name))); } catch (Exception ex) { Log.Error("Failed to register " + handlerType.Name + ": " + ex.Message); } } } public abstract class ListInterceptorHandler<T> { public abstract bool ShouldHandleCall(string fieldName); public virtual T GetItem(List<T> list, int index, string fieldName) { return list[index]; } public virtual void SetItem(List<T> list, int index, T value, string fieldName) { list[index] = value; } public virtual int Count(List<T> list, string fieldName) { return list.Count; } public virtual List<T>.Enumerator GetEnumerator(List<T> list, string fieldName) { return list.GetEnumerator(); } public virtual void Add(List<T> list, T item, string fieldName) { list.Add(item); } public virtual void Insert(List<T> list, int index, T value, string fieldName) { list.Insert(index, value); } public virtual void AddRange(List<T> list, IEnumerable<T> values, string fieldName) { list.AddRange(values); } public virtual bool Remove(List<T> list, T value, string fieldName) { return list.Remove(value); } public virtual void RemoveRange(List<T> list, int index, int count, string fieldName) { list.RemoveRange(index, count); } public virtual void Clear(List<T> list, string fieldName) { list.Clear(); } public virtual bool Contains(List<T> list, T value, string fieldName) { return list.Contains(value); } public virtual int IndexOf(List<T> list, T value, string fieldName) { return list.IndexOf(value); } public virtual void Sort(List<T> list, string fieldName) { list.Sort(); } public virtual void Sort(List<T> list, Comparison<T> comparison, string fieldName) { list.Sort(comparison); } public virtual void Sort(List<T> list, IComparer<T> comparer, string fieldName) { list.Sort(comparer); } public virtual void Reverse(List<T> list, string fieldName) { list.Reverse(); } public virtual void Reverse(List<T> list, int index, int count, string fieldName) { list.Reverse(index, count); } public virtual void CopyTo(List<T> list, T[] array, int arrayIndex, string fieldName) { list.CopyTo(array, arrayIndex); } public virtual void RemoveAt(List<T> list, int index, string fieldName) { list.RemoveAt(index); } public virtual void InsertRange(List<T> list, int index, IEnumerable<T> values, string fieldName) { list.InsertRange(index, values); } public virtual int LastIndexOf(List<T> list, T value, string fieldName) { return list.LastIndexOf(value); } public virtual bool Exists(List<T> list, Predicate<T> predicate, string fieldName) { return list.Exists(predicate); } public virtual T Find(List<T> list, Predicate<T> predicate, string fieldName) { return list.Find(predicate); } public virtual int FindIndex(List<T> list, Predicate<T> predicate, string fieldName) { return list.FindIndex(predicate); } public virtual int FindIndex(List<T> list, int index, Predicate<T> predicate, string fieldName) { return list.FindIndex(index, predicate); } public virtual int FindIndex(List<T> list, int index, int count, Predicate<T> predicate, string fieldName) { return list.FindIndex(index, count, predicate); } public virtual T FindLast(List<T> list, Predicate<T> predicate, string fieldName) { return list.FindLast(predicate); } public virtual int FindLastIndex(List<T> list, Predicate<T> predicate, string fieldName) { return list.FindLastIndex(predicate); } public virtual int FindLastIndex(List<T> list, int index, Predicate<T> predicate, string fieldName) { return list.FindLastIndex(index, predicate); } public virtual int FindLastIndex(List<T> list, int index, int count, Predicate<T> predicate, string fieldName) { return list.FindLastIndex(index, count, predicate); } public virtual bool TrueForAll(List<T> list, Predicate<T> predicate, string fieldName) { return list.TrueForAll(predicate); } public virtual T[] ToArray(List<T> list, string fieldName) { return list.ToArray(); } } public static class Log { public static ILogger Logger { get; set; } = new ConsoleLogger(); public static LogLevel LogLevel { get; set; } = LogLevel.Debug; internal static void Debug(string message) { InternalLog(LogLevel.Debug, message); } internal static void Info(string message) { InternalLog(LogLevel.Info, message); } internal static void Warning(string message) { InternalLog(LogLevel.Warning, message); } internal static void Error(string message) { InternalLog(LogLevel.Error, message); } private static void InternalLog(LogLevel logLevel, string message) { if (logLevel >= LogLevel) { Logger.Log(logLevel, message); } } } public enum LogLevel { Debug, Info, Warning, Error, None } }
BepInEx/patchers/EnhancedPrefabLoader/EnhancedPrefabLoaderPrepatch.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Logging; using CollectionWeaver.Core; using CollectionWeaver.IL; using EnhancedPrefabLoader.Prepatch.Extensions; using EnhancedPrefabLoader.Shared.Extensions; using EnhancedPrefabLoader.Shared.Models; using EnhancedPrefabLoader.Shared.Services; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Newtonsoft.Json; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EnhancedPrefabLoaderPrepatch")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+cd7431ddc1ec5aac5b27bb4a89a6104e570aad10")] [assembly: AssemblyProduct("Enhanced Prefab Loader Prepatch")] [assembly: AssemblyTitle("EnhancedPrefabLoaderPrepatch")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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; } } [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 EnhancedPrefabLoader.Shared.Services { public class BundleDiscoveryService { public List<string> DiscoverBundles(string basePath) { return Directory.EnumerateDirectories(basePath, "*_prefabloader", new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive }).ToList().SelectMany((string d) => Directory.GetFiles(d, "*.json", SearchOption.AllDirectories)) .ToList(); } } } namespace EnhancedPrefabLoader.Shared.Models { public class BundleDescriptor { public string BundleId { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public List<string> Assemblies { get; set; } = new List<string>(); public List<CustomShopInfo> CustomShops { get; set; } = new List<CustomShopInfo>(); public List<ItemInfo> Items { get; set; } = new List<ItemInfo>(); public List<PrefabInfo> Prefabs { get; set; } = new List<PrefabInfo>(); public List<CardExpansionInfo> CardExpansions { get; set; } = new List<CardExpansionInfo>(); public List<PrefabInfo> Furniture => Prefabs.Where((PrefabInfo p) => p.AddItemToFurnitureShop).ToList(); public List<PrefabInfo> Deco => Prefabs.Where((PrefabInfo p) => p.IsDecoObject || p.IsDecoFloorTexture || p.IsDecoCeilingTexture || p.IsDecoWallTexture).ToList(); public HashSet<string> PrefabNames { get { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in (from p in Prefabs?.Where((PrefabInfo p) => !string.IsNullOrWhiteSpace(p.PrefabName)) select p.PrefabName) ?? Array.Empty<string>()) { hashSet.Add(item); } return hashSet; } } public HashSet<string> MeshNames { get { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in (from i in Items?.Where((ItemInfo i) => !string.IsNullOrWhiteSpace(i.Mesh)) select i.Mesh) ?? Array.Empty<string>()) { hashSet.Add(item); } return hashSet; } } public HashSet<string> MaterialNames { get { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in (from i in Items?.Where((ItemInfo i) => !string.IsNullOrWhiteSpace(i.Material)) select i.Material) ?? Array.Empty<string>()) { hashSet.Add(item); } return hashSet; } } } public class CardExpansionInfo { public string Name { get; set; } = string.Empty; public string MenuCategory { get; set; } = string.Empty; public string CardExpansion { get; set; } = string.Empty; [JsonProperty("CardbackSprite")] public string Cardback { get; set; } = string.Empty; public string FoilMask { get; set; } = string.Empty; public bool HasRandomFoils { get; set; } public float FoilChance { get; set; } public List<string> Rarities { get; set; } = new List<string>(); public List<CardInfo> Cards { get; set; } = new List<CardInfo>(); public string CardPriceStrategy { get; set; } = string.Empty; public float DefaultBorderMultiplierBase { get; set; } = 3.15f; public float DefaultFoilMultiplier { get; set; } = 2.9f; public float RarityDrivenFloor { get; set; } = 4f; public float RarityDrivenStepSize { get; set; } = 1026f; public float RarityDrivenBorderMultiplierBase { get; set; } = 1.15f; public float RarityDrivenFoilMultiplier { get; set; } = 1.4f; public int TradeUnlockLevel { get; set; } public List<string> PlayCardMaterials { get; set; } = new List<string>(); public bool IsValid { get; set; } = true; } public class CardExpansionMetadata { public string ExpansionName { get; set; } = string.Empty; public int CardCount { get; set; } } public class CardInfo { public string Name { get; set; } = string.Empty; public string ElementType { get; set; } = string.Empty; public string Rarity { get; set; } = string.Empty; public int CardNumber { get; set; } public string Sprite { get; set; } = string.Empty; public string BorderType { get; set; } = string.Empty; public bool IsFoil { get; set; } public string FoilMask { get; set; } = string.Empty; public string Cardback { get; set; } = string.Empty; } [Serializable] public struct ColorData { public float R { get; set; } public float G { get; set; } public float B { get; set; } public float A { get; set; } } public class CustomShopInfo { public string PhoneAppId { get; set; } = string.Empty; public string AppDisplayName { get; set; } = string.Empty; public string AppIcon { get; set; } = string.Empty; public string AppInnerBGImage { get; set; } = string.Empty; public string AppOuterBGImage { get; set; } = string.Empty; public string SiteLogo { get; set; } = string.Empty; public string SiteHeader { get; set; } = string.Empty; public string SiteBackground { get; set; } = string.Empty; public bool IsValid { get; internal set; } = true; } public class ItemInfo { public string Name { get; set; } = string.Empty; public string ItemCategory { get; set; } = string.Empty; public string SpriteName { get; set; } = string.Empty; public float BaseCost { get; set; } public bool AddItemAsAccessory { get; set; } public bool AddItemAsFigurine { get; set; } public bool AddItemAsBoardGame { get; set; } public string PhoneAppId { get; set; } = string.Empty; public string ItemType { get; set; } = string.Empty; public bool UsesBaseGameMesh { get; set; } public string MeshToUse { get; set; } = string.Empty; public string Mesh { get; set; } = string.Empty; public string MeshSecondary { get; set; } = string.Empty; public string Material { get; set; } = string.Empty; public string MaterialSecondary { get; set; } = string.Empty; public List<string> MaterialList { get; set; } = new List<string>(); [JsonProperty("IsBigBox")] public bool HasBigBox { get; set; } public bool HasSmallBox { get; set; } [JsonProperty("HideTillUnlocked")] public bool BigBoxHideTillUnlocked { get; set; } public bool SmallBoxHideTillUnlocked { get; set; } [JsonProperty("LicensePrice")] public float BigBoxLicensePrice { get; set; } public float SmallBoxLicensePrice { get; set; } [JsonProperty("LicenseLevelRequirement")] public int BigBoxLicenseLevelRequirement { get; set; } public int SmallBoxLicenseLevelRequirement { get; set; } [JsonProperty("IgnoreDoubleImage")] public bool BigBoxIgnoreDoubleImage { get; set; } public bool SmallBoxIgnoreDoubleImage { get; set; } public float MinMarketPricePercent { get; set; } public float MaxMarketPricePercent { get; set; } public string FollowItemPrice { get; set; } = string.Empty; public bool AutoSetBoxPrice { get; set; } public bool IsTallItem { get; set; } public float InBoxOffsetY { get; set; } public float InBoxOffsetScale { get; set; } public Vector3Data ItemDeminsion { get; set; } public Vector3Data CollidorPosOffset { get; set; } public Vector3Data ColliderScale { get; set; } public List<string> PriceAffectedBy { get; set; } = new List<string>(); public bool IsSprayCan { get; set; } public bool IsCardPack { get; set; } public bool IsCardBox { get; set; } public bool IsBulkBox { get; set; } public int MinValue { get; set; } public string CardExpansion { get; set; } = string.Empty; public bool CanHaveDuplicates { get; set; } public bool CanHaveGodPacks { get; set; } public string PackGenerationStrategy { get; set; } = string.Empty; public Dictionary<string, float> NormalWeights { get; set; } = new Dictionary<string, float>(); public Dictionary<string, float> GodWeights { get; set; } = new Dictionary<string, float>(); public Dictionary<string, Dictionary<string, float>> SlotWeights { get; set; } = new Dictionary<string, Dictionary<string, float>>(); [Obsolete("Use NormalWeights, GodWeights, and SlotWeights instead. This field exists for backwards compatibility with older descriptors.")] public List<RarityWeightInfo> GenerationWeights { get; set; } = new List<RarityWeightInfo>(); public string SpawnsPackType { get; set; } = string.Empty; public string PackType { get; set; } = string.Empty; public float GodPackPercentage { get; set; } public bool IsValid { get; set; } = true; } public class ModManifest { public string ModId { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string Directory { get; set; } = string.Empty; public string BundlePath { get; set; } = string.Empty; public string JsonPath { get; set; } = string.Empty; public bool IsValid { get; set; } = true; public bool IsLoaded { get; set; } = true; public List<string> Errors { get; set; } = new List<string>(); public int ItemCount { get; set; } public int FurnitureCount { get; set; } public int CustomShopCount { get; set; } public int DecoCount { get; set; } public List<CardExpansionMetadata> CardExpansions { get; set; } = new List<CardExpansionMetadata>(); } public class PrefabInfo { public string Name { get; set; } = string.Empty; public string PrefabName { get; set; } = string.Empty; public string SpriteName { get; set; } = string.Empty; public float Price { get; set; } public int LevelRequirement { get; set; } public bool AddItemToFurnitureShop { get; set; } public string Description { get; set; } = string.Empty; public string ObjectType { get; set; } public List<VideoClipInfo> VideoClips { get; set; } = new List<VideoClipInfo>(); public float DecoBonus { get; set; } public bool IsDecoWallTexture { get; set; } public bool IsDecoFloorTexture { get; set; } public bool IsDecoCeilingTexture { get; set; } public bool IsDecoObject { get; set; } public string DecoObject { get; set; } = string.Empty; public string DecoType { get; set; } = string.Empty; public string Texture { get; set; } = string.Empty; public string RoughnessMap { get; set; } = string.Empty; public string NormalMap { get; set; } = string.Empty; public float Smoothness { get; set; } public ColorData Color { get; set; } public bool IsValid { get; set; } = true; } public class RarityWeightInfo { public string Rarity { get; set; } = string.Empty; [Obsolete("Use SlotWeights instead. This field exists for backwards compatibility with older descriptors.")] public string GuaranteedSlots { get; set; } = string.Empty; public float NormalWeight { get; set; } public float GodPackWeight { get; set; } } [Serializable] public struct Vector3Data { public float X { get; set; } public float Y { get; set; } public float Z { get; set; } } public class VideoClipInfo { public string Name { get; set; } = string.Empty; public string VideoPlayerName { get; set; } = string.Empty; } } namespace EnhancedPrefabLoader.Shared.Helpers { public static class FileHelper { public static List<string> GetAllJsonFilesIn(string basePath, string folderPattern) { return Directory.EnumerateDirectories(basePath, folderPattern, new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive }).SelectMany((string d) => Directory.GetFiles(d, "*.json", SearchOption.AllDirectories)).ToList(); } } public static class ModIdGenerator { public static string GenerateFromDirectory(string directory) { DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(directory)); string fullName = directoryInfo.FullName; string name = directoryInfo.Name; using SHA1 sHA = SHA1.Create(); string text = BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(fullName.ToLowerInvariant()))).Replace("-", "").Substring(0, 8); return name + "_" + text; } } } namespace EnhancedPrefabLoader.Shared.Extensions { public static class DictionaryExtensions { public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key) { if (!dict.TryGetValue(key, out TValue value)) { return default(TValue); } return value; } public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, Func<TKey, TValue> factory) { if (!dict.TryGetValue(key, out TValue value)) { value = (dict[key] = factory(key)); } return value; } public static void MergeAdd<TKey>(this Dictionary<TKey, int> dict, IEnumerable<(TKey key, int amount)> items) { foreach (var item3 in items) { TKey item = item3.key; int item2 = item3.amount; dict[item] = dict.GetOrAdd(item, (TKey _) => 0) + item2; } } public static void AddRange<TKey, TValue>(this Dictionary<TKey, TValue> dict, IEnumerable<KeyValuePair<TKey, TValue>> items) { foreach (KeyValuePair<TKey, TValue> item in items) { dict[item.Key] = item.Value; } } } public static class ListExtensions { public static List<T> Shuffle<T>(this List<T> list) where T : class { for (int num = list.Count - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); int index = num; int index2 = num2; T value = list[num2]; T value2 = list[num]; list[index] = value; list[index2] = value2; } return list; } public static List<T> SwapAndRemove<T>(this List<T> list, int index) { int num = list.Count - 1; if (index != num) { int index2 = num; T value = list[num]; T value2 = list[index]; list[index] = value; list[index2] = value2; } list.RemoveAt(num); return list; } } } namespace EnhancedPrefabLoader.Shared.Enums { [Flags] public enum ItemFlags : byte { None = 0, BoardGame = 1, Accessory = 2, Figurine = 4, TCG = 8 } } namespace EnhancedPrefabLoader.Prepatch { public class BepInExLogger : ILogger { private readonly ManualLogSource logSource; public BepInExLogger(string sourceName) { logSource = Logger.CreateLogSource(sourceName); } public void Log(LogLevel logLevel, string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown switch ((int)logLevel) { case 0: logSource.LogDebug((object)message); break; case 1: logSource.LogInfo((object)message); break; case 2: logSource.LogWarning((object)message); break; case 3: logSource.LogError((object)message); break; } } } public class EnumPatcher { public void PatchEnums(AssemblyDefinition assembly, int startingValue, Dictionary<string, HashSet<string>> userData, Dictionary<string, Dictionary<string, int>> savedData) { //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Expected O, but got Unknown //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Expected O, but got Unknown foreach (string enumName in userData.Keys) { int i = startingValue; TypeDefinition val = ((IEnumerable<TypeDefinition>)assembly.MainModule.Types).FirstOrDefault((Func<TypeDefinition, bool>)((TypeDefinition t) => ((MemberReference)t).Name == enumName)); if (val == null || !val.IsEnum) { Patcher.Log.LogWarning((object)("Enum type " + enumName + " not found in assembly.")); continue; } FieldDefinition val2 = ((IEnumerable<FieldDefinition>)val.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition f) => f.HasConstant && f.IsStatic && f.IsLiteral)); if (val2 == null) { Patcher.Log.LogWarning((object)("No valid enum fields found in " + enumName + ".")); continue; } HashSet<string> hashSet = new HashSet<string>(from f in (IEnumerable<FieldDefinition>)val.Fields where f.HasConstant && f.IsStatic && f.IsLiteral select ((MemberReference)f).Name); HashSet<int> hashSet2 = new HashSet<int>(from f in (IEnumerable<FieldDefinition>)val.Fields where f.HasConstant && f.IsStatic && f.IsLiteral select (int)f.Constant); SortedDictionary<int, FieldDefinition> sortedDictionary = new SortedDictionary<int, FieldDefinition>(); HashSet<string> hashSet3 = (from f in userData[enumName] select f.Sanitize() into f where !string.IsNullOrWhiteSpace(f) select f).ToHashSet(); if (savedData.TryGetValue(enumName, out Dictionary<string, int> value)) { List<string> list = new List<string>(); foreach (KeyValuePair<string, int> item in value) { string text = item.Key.Sanitize(); if (hashSet.Contains(text)) { Patcher.Log.LogWarning((object)("Field name '" + text + "' already exists in enum " + enumName + ". Skipping.")); list.Add(item.Key); } else if (hashSet2.Contains(item.Value)) { Patcher.Log.LogWarning((object)$"Field value {item.Value} already exists in enum {enumName} for saved field '{text}'. Assigning new value."); list.Add(item.Key); } else { sortedDictionary[item.Value] = new FieldDefinition(text, val2.Attributes, (TypeReference)(object)val) { Constant = item.Value }; hashSet.Add(text); hashSet2.Add(item.Value); } } foreach (string item2 in list) { value.Remove(item2); Patcher.Log.LogDebug((object)("Removed obsolete/conflicting saved field " + item2 + " from enum " + enumName)); } } foreach (string fieldName in hashSet3) { if (sortedDictionary.Values.Any((FieldDefinition f) => ((MemberReference)f).Name == fieldName)) { continue; } if (hashSet.Contains(fieldName)) { Patcher.Log.LogWarning((object)("Field name '" + fieldName + "' already exists in enum " + enumName + ". Skipping.")); continue; } for (; hashSet2.Contains(i) || sortedDictionary.ContainsKey(i); i++) { } sortedDictionary[i] = new FieldDefinition(fieldName, val2.Attributes, (TypeReference)(object)val) { Constant = i }; savedData.GetOrAdd(enumName, (string _) => new Dictionary<string, int>())[fieldName] = i; hashSet.Add(fieldName); hashSet2.Add(i); } foreach (KeyValuePair<int, FieldDefinition> item3 in sortedDictionary) { val.Fields.Add(item3.Value); Patcher.Log.LogDebug((object)$"Added field {((MemberReference)item3.Value).Name} with value {item3.Key} to enum {((MemberReference)val).Name}"); } Patcher.Log.LogInfo((object)$"Patching for enum {enumName} complete. {sortedDictionary.Count} fields added."); } } } public class PatchDataManager { private static readonly string SaveDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low", "OPNeonGames", "Card Shop Simulator", "PrefabLoader"); private readonly BundleDiscoveryService bundleDiscoveryService = new BundleDiscoveryService(); private bool initialized; private readonly Dictionary<string, string> keyMapping = new Dictionary<string, string> { { "FurnitureObjectTypes", "EObjectType" }, { "ItemTypes", "EItemType" }, { "FurnitureTypes", "EObjectType" }, { "DecoTypes", "EDecoObject" }, { "DecoObject", "EDecoObject" }, { "PackType", "ECollectionPackType" }, { "Rarity", "ERarity" }, { "CardExpansions", "ECardExpansionType" } }; public Dictionary<string, Dictionary<string, int>> SavedData { get; private set; } = new Dictionary<string, Dictionary<string, int>>(); public Dictionary<string, HashSet<string>> UserData { get; private set; } = new Dictionary<string, HashSet<string>>(); public void Initialize() { if (!initialized) { LoadSavedEnumValues(); LoadNewEnumEntries(); initialized = true; } } public void SaveEnumValues() { if (!initialized) { Patcher.Log.LogError((object)"Cannot save - not initialized"); return; } try { if (!Directory.Exists(SaveDirectory)) { Directory.CreateDirectory(SaveDirectory); } string contents = JsonConvert.SerializeObject((object)SavedData, (Formatting)1); File.WriteAllText(Path.Combine(SaveDirectory, "enum_values.json"), contents); Patcher.Log.LogInfo((object)$"Saved values for {SavedData.Count} enums"); } catch (Exception ex) { Patcher.Log.LogError((object)("Error saving values: " + ex.Message)); } } private string MapLegacyKey(string key) { if (!keyMapping.TryGetValue(key, out string value)) { return key; } return value; } private void LoadSavedEnumValues() { List<string> obj = new List<string>(3) { Path.Combine(SaveDirectory, "enum_values.json"), Paths.PatcherPluginPath + "/EnhancedPrefabLoader/savedTypes", Paths.PatcherPluginPath + "/EnhancedPrefabLoader/enum_values.json" }; Dictionary<string, Dictionary<string, int>> dictionary = new Dictionary<string, Dictionary<string, int>>(); string text = obj[0]; foreach (string item in obj) { if (!File.Exists(item)) { continue; } try { string text2 = File.ReadAllText(item); dictionary.AddRange(JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(text2) ?? new Dictionary<string, Dictionary<string, int>>()); if (item != text) { File.Delete(item); Patcher.Log.LogInfo((object)("Migrated and removed legacy enum values from " + item)); } } catch (Exception ex) { Patcher.Log.LogError((object)("Failed to load saved enum values from " + item + ": " + ex.Message + ".")); } } foreach (KeyValuePair<string, Dictionary<string, int>> item2 in dictionary) { SavedData[MapLegacyKey(item2.Key)] = item2.Value; } } private void LoadNewEnumEntries() { List<string> list = bundleDiscoveryService.DiscoverBundles(Paths.PluginPath); UserData["EObjectType"] = new HashSet<string>(); UserData["EDecoObject"] = new HashSet<string>(); UserData["EItemType"] = new HashSet<string>(); UserData["ECardExpansionType"] = new HashSet<string>(); UserData["ERarity"] = new HashSet<string>(); UserData["ECollectionPackType"] = new HashSet<string>(); foreach (string item in list) { try { BundleDescriptor bundleDescriptor = JsonConvert.DeserializeObject<BundleDescriptor>(File.ReadAllText(item)); if (bundleDescriptor != null) { UserData["EObjectType"].UnionWith(bundleDescriptor.Furniture.Select((PrefabInfo f) => f.ObjectType)); UserData["EDecoObject"].UnionWith(bundleDescriptor.Deco.Select((PrefabInfo d) => d.DecoObject)); UserData["EItemType"].UnionWith(bundleDescriptor.Items.Select((ItemInfo i) => i.ItemType)); UserData["ECardExpansionType"].UnionWith(bundleDescriptor.CardExpansions.Select((CardExpansionInfo c) => c.CardExpansion)); UserData["ERarity"].UnionWith(bundleDescriptor.CardExpansions.SelectMany((CardExpansionInfo c) => c.Rarities)); UserData["ECollectionPackType"].UnionWith(from i in bundleDescriptor.Items where i.IsCardPack select i.PackType); } } catch (Exception ex) { Patcher.Log.LogError((object)("Failed to load bundle descriptor from " + item + ": " + ex.Message)); } } } } public class Patcher { private static ILWeaver weaver = null; private static EnumPatcher enumPatcher = null; private static PatchDataManager patchDataManager = null; public static ManualLogSource Log { get; private set; } = Logger.CreateLogSource("EnhancedPrefabLoader"); public static IEnumerable<string> TargetDLLs { get; } = new <>z__ReadOnlySingleElementList<string>("Assembly-CSharp.dll"); public static void Initialize() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown Log.Logger = (ILogger)(object)new BepInExLogger("CollectionWeaver"); Log.LogLevel = (LogLevel)3; WeaverOptions val = new WeaverOptions(); val.IncludeField("CPlayerData.m_CurrentTotalItemCountList").IncludeField("CPlayerData.m_GeneratedMarketPriceList").IncludeField("CPlayerData.m_GeneratedCostPriceList") .IncludeField("CPlayerData.m_ItemPricePercentChangeList") .IncludeField("CPlayerData.m_AverageItemCostList") .IncludeField("CPlayerData.m_SetItemPriceList") .IncludeField("CPlayerData.m_ItemPricePercentPastChangeList") .IncludeField("CPlayerData.m_IsItemLicenseUnlocked") .IncludeField("CPlayerData.m_DecorationInventoryList") .IncludeField("CPlayerData.m_CollectionSortingMethodIndexList") .IncludeField("StockItemData_ScriptableObject.m_ItemDataList") .IncludeField("StockItemData_ScriptableObject.m_ItemMeshDataList") .IncludeField("StockItemData_ScriptableObject.m_RestockDataList") .IncludeField("StockItemData_ScriptableObject.m_CardPackItemTypeList") .IncludeField("ShelfData_ScriptableObject.m_DecoDataList") .IncludeField("ShelfData_ScriptableObject.m_DecoPurchaseDataList") .IncludeField("ShelfData_ScriptableObject.m_WallDecoDataList") .IncludeField("ShelfData_ScriptableObject.m_FloorDecoDataList") .IncludeField("ShelfData_ScriptableObject.m_CeilingDecoDataList") .IncludeField("MonsterData_ScriptableObject.m_CardBackImageList") .IncludeField("MonsterData_ScriptableObject.m_CardFoilMaskImageList") .IncludeField("MonsterData_ScriptableObject.m_CardUISettingList") .IncludeField("CardUI.m_CardRaritySpriteList"); if (weaver == null) { weaver = new ILWeaver(val); } if (enumPatcher == null) { enumPatcher = new EnumPatcher(); } if (patchDataManager == null) { patchDataManager = new PatchDataManager(); } patchDataManager.Initialize(); } public static void Patch(AssemblyDefinition assembly) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) BaseAssemblyResolver val = (BaseAssemblyResolver)assembly.MainModule.AssemblyResolver; val.AddSearchDirectory(Path.GetDirectoryName(typeof(Patcher).Assembly.Location)); val.AddSearchDirectory(Paths.PatcherPluginPath); Log.LogInfo((object)"Starting Enhanced Prefab Loader PrePatching"); ILWeaver obj = weaver; WeaverResult val2 = ((obj != null) ? obj.Weave(assembly) : null); Log.LogInfo((object)$"Collection weaving complete. Weaved: {((val2 != null) ? new int?(val2.PatchedCount) : null)}, Skipped: {((val2 != null) ? new int?(val2.SkippedCount) : null)}"); enumPatcher?.PatchEnums(assembly, 200000, patchDataManager.UserData, patchDataManager.SavedData); patchDataManager.SaveEnumValues(); Log.LogInfo((object)"Enhanced Prefab Loader PrePatching complete"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "EnhancedPrefabLoaderPrepatch"; public const string PLUGIN_NAME = "Enhanced Prefab Loader Prepatch"; public const string PLUGIN_VERSION = "6.0.0"; } } namespace EnhancedPrefabLoader.Prepatch.Extensions { public static class CicelExtensions { public static bool IsLoadCode(this OpCode opCode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!opCode.IsLdloc() && !opCode.IsLdarg() && !opCode.IsLdc() && !opCode.IsLdelem() && !opCode.IsFieldLoad() && !opCode.IsLdNullOrStr()) { return opCode.IsLdind(); } return true; } public static bool IsFieldLoad(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 120 || (int)code == 123) { return true; } return false; } public static bool IsLdloc(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 6 <= 3 || (int)code == 17 || (int)code == 202) { return true; } return false; } public static bool IsLdarg(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 2 <= 3 || code - 14 <= 1 || code - 199 <= 1) { return true; } return false; } public static bool IsLdc(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 21 <= 14) { return true; } return false; } public static bool IsLdelem(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 145 || (int)code == 151 || (int)code == 160) { return true; } return false; } public static bool IsLdind(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 69 <= 6 || code - 77 <= 2) { return true; } return false; } public static bool IsLdNullOrStr(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if ((int)code == 20 || (int)code == 113) { return true; } return false; } public static bool IsStloc(this OpCode opCode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 Code code = ((OpCode)(ref opCode)).Code; if (code - 10 <= 3 || (int)code == 19 || (int)code == 204) { return true; } return false; } public static bool IsComplimentaryStOf(this Instruction stInstruction, Instruction ldInstruction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (stInstruction.OpCode.IsStloc() && ldInstruction.OpCode.IsLdloc()) { return stInstruction.GetLocalCodeIndex() == ldInstruction.GetLocalCodeIndex(); } return false; } public static int? GetLocalCodeIndex(this Instruction instr) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 OpCode opCode = instr.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 6) { default: if ((int)code != 202 && (int)code != 204) { break; } goto case 11; case 0: case 4: return 0; case 1: case 5: return 1; case 2: case 6: return 2; case 3: case 7: return 3; case 11: case 13: { object operand = instr.Operand; object obj = ((operand is VariableReference) ? operand : null); return (obj != null) ? new int?(((VariableReference)obj).Index) : null; } case 8: case 9: case 10: case 12: break; } return null; } public static bool IsListType(this TypeReference typeRef) { if (((typeRef != null) ? ((MemberReference)typeRef).Name : null) == "List`1" && ((typeRef != null) ? typeRef.Namespace : null) == "System.Collections.Generic") { if (!(typeRef is GenericInstanceType)) { TypeDefinition obj = typeRef.Resolve(); object obj2; if (obj == null) { obj2 = null; } else { TypeReference baseType = obj.BaseType; obj2 = ((baseType != null) ? ((MemberReference)baseType).Name : null); } return (string?)obj2 == "List`1"; } return true; } return false; } public static bool IsListAccessor(this MethodReference methodRef) { if (methodRef != null) { if (!methodRef.IsListGetItemCall() && !methodRef.IsListSetItemCall()) { return methodRef.IsListGetCountCall(); } return true; } return false; } public static bool IsListGetItemCall(this MethodReference methodRef) { if (methodRef != null && ((MemberReference)methodRef).DeclaringType.IsListType()) { return ((MemberReference)methodRef).Name == "get_Item"; } return false; } public static bool IsListSetItemCall(this MethodReference methodRef) { if (methodRef != null && ((MemberReference)methodRef).DeclaringType.IsListType()) { return ((MemberReference)methodRef).Name == "set_Item"; } return false; } public static bool IsListGetCountCall(this MethodReference methodRef) { if (methodRef != null && ((MemberReference)methodRef).DeclaringType.IsListType()) { return ((MemberReference)methodRef).Name == "get_Count"; } return false; } public static bool MatchListLoad(this Instruction instr, MethodBody methodBody, out TypeReference elementType) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected I4, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Invalid comparison between Unknown and I4 elementType = null; if (instr != null) { _ = instr.OpCode; if (0 == 0 && ((methodBody != null) ? methodBody.Method : null) != null && instr.OpCode.IsLoadCode()) { try { OpCode opCode = instr.OpCode; Code code = ((OpCode)(ref opCode)).Code; if ((int)code <= 120) { switch (code - 2) { case 4: goto IL_00bb; case 5: goto IL_00d2; case 6: goto IL_00e9; case 7: goto IL_0100; case 15: goto IL_0117; case 0: goto IL_0134; case 1: goto IL_0171; case 2: goto IL_019a; case 3: goto IL_01c3; case 12: goto IL_01ec; case 8: case 9: case 10: case 11: case 13: case 14: goto IL_0220; } if ((int)code == 120) { goto IL_0206; } } else { if ((int)code == 123) { goto IL_0206; } if ((int)code == 199) { goto IL_01ec; } if ((int)code == 202) { goto IL_0117; } } goto IL_0220; IL_0220: TypeReference val = null; goto IL_0222; IL_0134: object obj2; if (!((MethodReference)methodBody.Method).HasThis) { ParameterDefinition obj = ((MethodReference)methodBody.Method).Parameters[0]; obj2 = ((obj != null) ? ((ParameterReference)obj).ParameterType : null); } else { obj2 = methodBody.Method.DeclaringType; } val = (TypeReference)obj2; goto IL_0222; IL_0100: val = ((VariableReference)methodBody.Variables[3]).VariableType; goto IL_0222; IL_00e9: val = ((VariableReference)methodBody.Variables[2]).VariableType; goto IL_0222; IL_00d2: val = ((VariableReference)methodBody.Variables[1]).VariableType; goto IL_0222; IL_00bb: val = ((VariableReference)methodBody.Variables[0]).VariableType; goto IL_0222; IL_01c3: val = ((ParameterReference)((MethodReference)methodBody.Method).Parameters[((MethodReference)methodBody.Method).HasThis ? 2 : 3]).ParameterType; goto IL_0222; IL_0117: object operand = instr.Operand; object obj3 = ((operand is VariableReference) ? operand : null); val = ((obj3 != null) ? ((VariableReference)obj3).VariableType : null); goto IL_0222; IL_0206: object operand2 = instr.Operand; object obj4 = ((operand2 is FieldReference) ? operand2 : null); val = ((obj4 != null) ? ((FieldReference)obj4).FieldType : null); goto IL_0222; IL_01ec: object operand3 = instr.Operand; object obj5 = ((operand3 is ParameterReference) ? operand3 : null); val = ((obj5 != null) ? ((ParameterReference)obj5).ParameterType : null); goto IL_0222; IL_019a: val = ((ParameterReference)((MethodReference)methodBody.Method).Parameters[((MethodReference)methodBody.Method).HasThis ? 1 : 2]).ParameterType; goto IL_0222; IL_0222: TypeReference val2 = val; GenericInstanceType val3 = (GenericInstanceType)(object)((val2 is GenericInstanceType) ? val2 : null); if (val3 != null && val2.IsListType() && val3.GenericArguments.Count > 0) { elementType = val3.GenericArguments[0]; return true; } return false; IL_0171: val = ((ParameterReference)((MethodReference)methodBody.Method).Parameters[(!((MethodReference)methodBody.Method).HasThis) ? 1 : 0]).ParameterType; goto IL_0222; } catch (Exception ex) when (((ex is ArgumentOutOfRangeException || ex is NullReferenceException) ? 1 : 0) != 0) { elementType = null; return false; } } } return false; } } internal static class StringExtensions { public static string Sanitize(this string value) { if (string.IsNullOrWhiteSpace(value)) { return "_Invalid"; } string input = Regex.Replace(value, "\\s", ""); input = Regex.Replace(input, "[^\\w]", "_"); if (!string.IsNullOrEmpty(input) && !char.IsDigit(input[0])) { return input; } return "_" + (input ?? "Invalid"); } } }
BepInEx/plugins/EnhancedPrefabLoader/EnhancedPrefabLoader.API.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using EnhancedPrefabLoader.API.Assets; using EnhancedPrefabLoader.API.Behaviors; using EnhancedPrefabLoader.API.Components; using EnhancedPrefabLoader.API.Events; using EnhancedPrefabLoader.API.InternalBridges; using EnhancedPrefabLoader.API.Models; using EnhancedPrefabLoader.API.Registry; using EnhancedPrefabLoader.API.Services; using EnhancedPrefabLoader.Shared.Models; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(false)] [assembly: Guid("d64dc15b-8078-4750-8278-87e0065dc75e")] [assembly: InternalsVisibleTo("EnhancedPrefabLoader")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("EnhancedPrefabLoader.API")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("6.0.1.0")] [assembly: AssemblyInformationalVersion("6.0.1+cd7431ddc1ec5aac5b27bb4a89a6104e570aad10")] [assembly: AssemblyProduct("EnhancedPrefabLoader.API")] [assembly: AssemblyTitle("EnhancedPrefabLoader.API")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.1.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] [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; } } [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 EnhancedPrefabLoader.Shared.Models { public enum DecoFlags { None, FloorTexture, WallTexture, CeilingTexture } } namespace EnhancedPrefabLoader.API { public static class Epl { private static IEplApi? instance; public static IEplApi Api => instance ?? throw new InvalidOperationException("EPL is not loaded"); public static bool IsAvailable => instance != null; internal static void RegisterApi(IEplApi api) { instance = api; } } public interface IEplApi { bool IsBundleLoadingComplete { get; } IEplAssets Assets { get; } IEplServices Services { get; } IEplEvents Events { get; } IBundleRegistry BundleRegistry { get; } } } namespace EnhancedPrefabLoader.API.UI { public interface ICustomShopScreen { } } namespace EnhancedPrefabLoader.API.Services { public interface ICardExpansionService { void SetCardPriceGenerator(ECardExpansionType expansionType, ICardPriceGenerator generator); void SetCardExpGenerator(ECardExpansionType expansionType, ICardExpGenerator generator); float GenerateCardMarketPrice(ECardExpansionType cardExpansionType, EMonsterType monsterType, bool isFoil); float GenerateCardMarketPrice(CardData cardData); float GenerateCardExp(CardData cardData); } public interface ICardUIService { void ApplyEplCardUI(CardUI cardUI, CardData cardData); void RestoreOriginalCardUI(CardUI cardUI, CardData cardData); } public interface IDecoService { void SetLevelRequirement(EDecoObject decoObject, int level); } public interface IEplServices { IItemService ItemService { get; } ICardExpansionService CardExpansionService { get; } ICardUIService CardUIService { get; } IMenuService MenuService { get; } IFurnitureService FurnitureService { get; } IDecoService DecoService { get; } } public interface IFurnitureService { void SetLevelRequirement(EObjectType objectType, int level); } public interface IItemService { void SetPackGenerator(EItemType pack, IPackGenerator generator); List<CardData> GeneratePackContent(EItemType pack); void SetItemPriceGenerator(string bundleId, IItemPriceGenerator generator); float GenerateItemCost(EItemType itemType); float GenerateItemMarketPrice(EItemType itemType, float costPrice, float minMarkup, float maxMarkup); void SetNormalGenerationWeight(EItemType pack, ERarity rarity, float weight); void SetGodGenerationWeight(EItemType pack, ERarity rarity, float weight); void SetSlotWeight(EItemType pack, PackSlot slot, ERarity rarity, float weight); void SetLicensePrice(EItemType itemType, bool isBigBox, float price); void SetLicenseLevel(EItemType itemType, bool isBigBox, int level); void SetAutoBoxPrice(EItemType itemType, EItemType followItemType); void SetMarketPricePercent(EItemType itemType, float min, float max); void SetFollowItemPrice(EItemType itemType, EItemType sourceItemType); void SetCanHaveGodPacks(EItemType pack, bool enabled); void SetGodPackPercentage(EItemType pack, float percentage); void SetGodPack(EItemType pack, bool enabled, float percentage); } public interface IMenuService { void AddGenericExpansionButton(string label, Action onClick); void AddBinderExpansionButton(string label, Action onClick); } } namespace EnhancedPrefabLoader.API.Registry { public interface IBundleRegistry { IReadOnlyDictionary<string, BundleInfo> BundleInfo { get; } string? GetBundleIdFor<TEnum>(TEnum enumValue) where TEnum : Enum; string? GetBundleIdFor(DecoFlags category, string assetName); bool IsEplAsset<TEnum>(TEnum enumValue) where TEnum : Enum; bool IsEplAsset(string category, string assetName); bool HasRegisteredRestockData(EItemType itemType); } } namespace EnhancedPrefabLoader.API.Models { public class BundleInfo { internal readonly List<string> ceilingTextures = new List<string>(); internal readonly List<string> floorTextures = new List<string>(); internal readonly List<string> wallTextures = new List<string>(); internal readonly List<ECardExpansionType> expansionTypes = new List<ECardExpansionType>(); internal readonly List<EObjectType> furnitureTypes = new List<EObjectType>(); internal readonly List<EDecoObject> decoObjects = new List<EDecoObject>(); internal readonly List<EItemType> itemTypes = new List<EItemType>(); internal readonly List<string> errors = new List<string>(); internal readonly List<string> warnings = new List<string>(); public string BundleId { get; internal set; } = string.Empty; public string Name { get; internal set; } = string.Empty; public string JsonPath { get; internal set; } = string.Empty; public string BundlePath { get; internal set; } = string.Empty; public bool IsLoaded { get; internal set; } public bool IsValid { get; internal set; } = true; public IReadOnlyList<ECardExpansionType> ExpansionTypes => expansionTypes; public IReadOnlyList<EObjectType> FurnitureTypes => furnitureTypes; public IReadOnlyList<EDecoObject> DecoObjects => decoObjects; public IReadOnlyList<EItemType> ItemTypes => itemTypes; public IReadOnlyList<string> CeilingTextures => ceilingTextures; public IReadOnlyList<string> FloorTextures => floorTextures; public IReadOnlyList<string> WallTextures => wallTextures; public IReadOnlyList<string> Errors => errors; public IReadOnlyList<string> Warnings => warnings; } public class ItemShopInfo { public string PhoneAppId { get; internal set; } public string AppDisplayName { get; internal set; } public RestockData? SmallBox { get; internal set; } public RestockData? BigBox { get; internal set; } } public class PackGenerationEventArgs { public EItemType Pack { get; internal set; } public bool IsGodPack { get; internal set; } public Dictionary<ERarity, float>? NormalWeights { get; internal set; } public Dictionary<ERarity, float>? GodWeights { get; internal set; } public SortedDictionary<PackSlot, Dictionary<ERarity, float>>? SlotWeights { get; internal set; } } [Flags] public enum PackSlot : byte { None = 0, Slot1 = 1, Slot2 = 2, Slot3 = 4, Slot4 = 8, Slot5 = 0x10, Slot6 = 0x20, Slot7 = 0x40, All = byte.MaxValue } public class PackWeightData { public IReadOnlyDictionary<ERarity, float> NormalWeights { get; internal set; } public IReadOnlyDictionary<ERarity, float> GodWeights { get; internal set; } public IReadOnlyDictionary<PackSlot, IReadOnlyDictionary<ERarity, float>> SlotWeights { get; internal set; } } public class ShopData { public string PhoneAppId { get; internal set; } public string AppDisplayName { get; internal set; } public IReadOnlyList<RestockData> TCG { get; internal set; } public IReadOnlyList<RestockData> Accessories { get; internal set; } public IReadOnlyList<RestockData> Figurines { get; internal set; } } public class StreamingAsset<T> where T : Object { public string BundlePath { get; private set; } public string AssetName { get; private set; } public StreamingAsset(string bundlePath, string assetName) { BundlePath = bundlePath; AssetName = assetName; base..ctor(); } internal void GetAsync(Action<Object?> callback, bool keepAlive = false) { if (callback != null) { StreamingAssetsBridge.AssetLoadBridge?.StartLoadingCoroutine(BundlePath, AssetName, keepAlive, typeof(T), callback); } } } } namespace EnhancedPrefabLoader.API.InternalBridges { internal interface IAssetLoadBridge { void StartLoadingCoroutine(string bundlePath, string assetName, bool keepAlive, Type type, Action<Object?> callback); } internal interface IAssetRefTracker { void IncrementRef(string assetKey); void DecrementRef(string assetKey); } internal static class StreamingAssetsBridge { internal static IAssetLoadBridge? AssetLoadBridge { get; set; } internal static IAssetRefTracker? AssetRefTracker { get; set; } } } namespace EnhancedPrefabLoader.API.Extensions { public static class GameObjectExtensions { public static T GetOrAddComponent<T>(this GameObject obj) where T : Component { T result = default(T); if (!obj.TryGetComponent<T>(ref result)) { return obj.AddComponent<T>(); } return result; } } public static class StreamingAssetExtensions { private class AssetRequest { public string AssetName = string.Empty; public string RequestId = string.Empty; } private static readonly ConditionalWeakTable<Image, AssetRequest> activeSpriteRequests = new ConditionalWeakTable<Image, AssetRequest>(); private static readonly ConditionalWeakTable<Material, Dictionary<string, AssetRequest>> activeTextureRequests = new ConditionalWeakTable<Material, Dictionary<string, AssetRequest>>(); public static void SetSpriteAsync(this Image image, StreamingAsset<Sprite>? asset) { Image image2 = image; StreamingAsset<Sprite> asset2 = asset; if (asset2 == null) { image2.sprite = null; return; } string requestId = Guid.NewGuid().ToString(); AssetRequest orCreateValue = activeSpriteRequests.GetOrCreateValue(image2); orCreateValue.AssetName = asset2.AssetName; orCreateValue.RequestId = requestId; asset2.GetAsync(delegate(Object? obj) { if (image2 != null) { Sprite val = (Sprite)(object)((obj is Sprite) ? obj : null); if (val != null && activeSpriteRequests.TryGetValue(image2, out AssetRequest value) && !(value.RequestId != requestId) && !(value.AssetName != asset2.AssetName)) { ((Component)image2).gameObject.GetOrAddComponent<StreamingAssetTracker>().TrackImage(image2, asset2.BundlePath + "|" + asset2.AssetName); image2.sprite = val; ((Graphic)image2).SetAllDirty(); } } }); } public static void CancelPendingSpriteAsync(this Image image) { if (activeSpriteRequests.TryGetValue(image, out AssetRequest value)) { value.RequestId = Guid.NewGuid().ToString(); value.AssetName = string.Empty; } } public static void CancelPendingTextureAsync(this Material material, string propertyName) { if (activeTextureRequests.TryGetValue(material, out Dictionary<string, AssetRequest> value) && value.TryGetValue(propertyName, out var value2)) { value2.RequestId = Guid.NewGuid().ToString(); value2.AssetName = string.Empty; } } public static void SetTextureAsync(this Material material, string propertyName, StreamingAsset<Texture>? asset) { Material material2 = material; string propertyName2 = propertyName; StreamingAsset<Texture> asset2 = asset; if (asset2 == null) { material2.SetTexture(propertyName2, (Texture)null); return; } string requestId = Guid.NewGuid().ToString(); Dictionary<string, AssetRequest> orCreateValue = activeTextureRequests.GetOrCreateValue(material2); if (!orCreateValue.TryGetValue(propertyName2, out var value)) { value = new AssetRequest(); orCreateValue[propertyName2] = value; } value.AssetName = asset2.AssetName; value.RequestId = requestId; asset2.GetAsync(delegate(Object? obj) { if (material2 != null) { Texture val = (Texture)(object)((obj is Texture) ? obj : null); if (val != null && activeTextureRequests.TryGetValue(material2, out Dictionary<string, AssetRequest> value2) && value2.TryGetValue(propertyName2, out var value3) && !(value3.RequestId != requestId) && !(value3.AssetName != asset2.AssetName)) { material2.SetTexture(propertyName2, val); } } }, keepAlive: true); } } public static class StringExtensions { public static T? TryParseToEnum<T>(this string value) where T : struct, Enum { if (!Enum.TryParse<T>(value, out var result)) { return null; } return result; } public static string Sanitize(this string value) { if (string.IsNullOrWhiteSpace(value)) { return "_Invalid"; } string input = Regex.Replace(value, "\\s", ""); input = Regex.Replace(input, "[^\\w]", "_"); if (!string.IsNullOrEmpty(input) && !char.IsDigit(input[0])) { return input; } return "_" + (input ?? "Invalid"); } public static string Prettierize(this string value) { if (string.IsNullOrWhiteSpace(value)) { return value; } value = value.Replace('_', ' '); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(value[0]); for (int i = 1; i < value.Length; i++) { char c = value[i]; char c2 = value[i - 1]; if (char.IsUpper(c) && !char.IsWhiteSpace(c2) && (char.IsLower(c2) || (i < value.Length - 1 && char.IsLower(value[i + 1])))) { stringBuilder.Append(' '); } if (char.IsDigit(c) && char.IsLetter(c2)) { stringBuilder.Append(' '); } stringBuilder.Append(c); } return Regex.Replace(stringBuilder.ToString(), "\\s+", " ").Trim(); } } } namespace EnhancedPrefabLoader.API.Events { public interface IEplEvents { IShopEvents Shops { get; } IItemEvents Items { get; } event Action OnBundleLoadingComplete; } public interface IItemEvents { event Action<PackGenerationEventArgs> OnBeforePackGenerated; } public interface IShopEvents { event Action OnShopsReady; } } namespace EnhancedPrefabLoader.API.Components { internal class StreamingAssetTracker : MonoBehaviour { private readonly ConditionalWeakTable<Image, string> imageTracker = new ConditionalWeakTable<Image, string>(); private readonly ConditionalWeakTable<Material, Dictionary<string, string>> materialTracker = new ConditionalWeakTable<Material, Dictionary<string, string>>(); internal void TrackImage(Image image, string assetKey) { if (imageTracker.TryGetValue(image, out string value)) { StreamingAssetsBridge.AssetRefTracker?.DecrementRef(value); } imageTracker.AddOrUpdate(image, assetKey); StreamingAssetsBridge.AssetRefTracker?.IncrementRef(assetKey); } internal void TrackMaterial(Material material, string layer, string assetKey) { if (materialTracker.TryGetValue(material, out Dictionary<string, string> value) && value.TryGetValue(layer, out var value2)) { StreamingAssetsBridge.AssetRefTracker?.DecrementRef(value2); } materialTracker.GetOrCreateValue(material)[layer] = assetKey; StreamingAssetsBridge.AssetRefTracker?.IncrementRef(assetKey); } internal bool TryGetTrackedKey(Image image, out string? assetKey) { return imageTracker.TryGetValue(image, out assetKey); } internal bool TryGetTrackedKey(Material material, string layer, out string? assetKey) { if (materialTracker.TryGetValue(material, out Dictionary<string, string> value)) { return value.TryGetValue(layer, out assetKey); } assetKey = null; return false; } private void OnDestroy() { foreach (var (_, assetKey) in (IEnumerable<KeyValuePair<Image, string>>)imageTracker) { StreamingAssetsBridge.AssetRefTracker?.DecrementRef(assetKey); } foreach (KeyValuePair<Material, Dictionary<string, string>> item in (IEnumerable<KeyValuePair<Material, Dictionary<string, string>>>)materialTracker) { item.Deconstruct(out var _, out var value); foreach (string value2 in value.Values) { StreamingAssetsBridge.AssetRefTracker?.DecrementRef(value2); } } } } } namespace EnhancedPrefabLoader.API.Behaviors { public interface ICardExpGenerator { float CalculateExp(CardData cardData); } public interface ICardPriceGenerator { float GenerateCardMarketPrice(ECardExpansionType expansionType, EMonsterType monsterType, ECardBorderType borderType, ERarity rarity, List<ERarity> expansionRarities, bool isFoil); } public interface IItemPriceGenerator { float GenerateItemCost(EItemType itemType, float baseCost); float GenerateItemMarketPrice(EItemType itemType, float baseCost, float minMarkup, float maxMarkup); } public interface IPackGenerator { List<MonsterData> GeneratePack(ECardExpansionType cardExpansion, List<MonsterData> cardPool, bool hasRandomFoils); } } namespace EnhancedPrefabLoader.API.Assets { public interface ICardExpansionLibrary { StreamingAsset<Texture>? GetCardExpansionCardBack(ECardExpansionType cardExpansionType); StreamingAsset<Sprite>? GetCardExpansionFoilMask(ECardExpansionType cardExpansionType); StreamingAsset<Sprite>? GetCardFoilMask(ECardExpansionType cardExpansionType, EMonsterType monsterType); StreamingAsset<Texture>? GetCardBack(ECardExpansionType cardExpansionType, EMonsterType monsterType); StreamingAsset<Sprite>? GetCardSprite(ECardExpansionType cardExpansionType, EMonsterType monsterType); IReadOnlyDictionary<EMonsterType, StreamingAsset<Sprite>> GetCardSprites(ECardExpansionType cardExpansionType); MonsterData GetMonsterData(CardData cardData); MonsterData GetMonsterData(ECardExpansionType expansionType, EMonsterType monsterType); bool IsCardExpansionUnlocked(ECardExpansionType expansionType); bool IsCardFoil(ECardExpansionType expansionType, EMonsterType monsterType); } public interface IDecoLibrary { StreamingAsset<Sprite>? GetIcon(EDecoObject decoObject); IReadOnlyDictionary<EDecoObject, StreamingAsset<Sprite>> GetIcons(); InteractableObject? GetPrefab(EDecoObject decoObject); IReadOnlyDictionary<EDecoObject, InteractableObject> GetPrefabs(); int GetLevelRequirement(EDecoObject decoObject); } public interface IEplAssets { ICardExpansionLibrary CardExpansions { get; } IFurnitureLibrary Furniture { get; } IItemLibrary Items { get; } IDecoLibrary Deco { get; } IShopLibrary Shops { get; } } public interface IFurnitureLibrary { StreamingAsset<Sprite>? GetIcon(EObjectType objectType); IReadOnlyDictionary<EObjectType, StreamingAsset<Sprite>> GetIcons(); InteractableObject? GetPrefab(EObjectType objectType); IReadOnlyDictionary<EObjectType, InteractableObject> GetPrefabs(); int GetLevelRequirement(EObjectType objectType); } public interface IItemLibrary { StreamingAsset<Sprite>? GetIcon(EItemType itemType); IReadOnlyDictionary<EItemType, StreamingAsset<Sprite>> GetIcons(); ItemMeshData? GetItemMeshData(EItemType itemType); IReadOnlyDictionary<EItemType, ItemMeshData> GetAllItemMeshData(); EItemType GetBulkBox(ECardExpansionType expansionType, int priceCutoff); IReadOnlyDictionary<ECardExpansionType, List<(int MinPrice, EItemType ItemType)>> GetBulkBoxes(); PackWeightData GetPackWeights(EItemType pack); } public interface IShopLibrary { List<string> GetPhoneAppIds(); ShopData? GetShopDataFor(string appId); ItemShopInfo? GetShopInfoFor(EItemType itemType); } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }
BepInEx/plugins/EnhancedPrefabLoader/EnhancedPrefabLoader.dll
Decompiled 3 weeks 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.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CollectionWeaver.Core; using EnhancedPrefabLoader.API; using EnhancedPrefabLoader.API.Assets; using EnhancedPrefabLoader.API.Behaviors; using EnhancedPrefabLoader.API.Events; using EnhancedPrefabLoader.API.Extensions; using EnhancedPrefabLoader.API.InternalBridges; using EnhancedPrefabLoader.API.Models; using EnhancedPrefabLoader.API.Registry; using EnhancedPrefabLoader.API.Services; using EnhancedPrefabLoader.API.UI; using EnhancedPrefabLoader.Core; using EnhancedPrefabLoader.Core.Assets; using EnhancedPrefabLoader.Core.Cards; using EnhancedPrefabLoader.Core.Cards.ExpGenerators; using EnhancedPrefabLoader.Core.Cards.PriceGenerators; using EnhancedPrefabLoader.Core.Components; using EnhancedPrefabLoader.Core.Events; using EnhancedPrefabLoader.Core.Extensions; using EnhancedPrefabLoader.Core.ExternalBridges; using EnhancedPrefabLoader.Core.LoadingPipeline; using EnhancedPrefabLoader.Core.LoadingPipeline.Processors; using EnhancedPrefabLoader.Core.LoadingPipeline.Validators; using EnhancedPrefabLoader.Core.Models.Runtime; using EnhancedPrefabLoader.Core.Models.SaveData; using EnhancedPrefabLoader.Core.Packs.PackGenerators; using EnhancedPrefabLoader.Core.Properties; using EnhancedPrefabLoader.Core.Registry; using EnhancedPrefabLoader.Core.Saves; using EnhancedPrefabLoader.Core.Services; using EnhancedPrefabLoader.Core.Services.Internal; using EnhancedPrefabLoader.Core.Shops; using EnhancedPrefabLoader.Core.Trading; using EnhancedPrefabLoader.Core.Uninstall; using EnhancedPrefabLoader.Core.Utils; using EnhancedPrefabLoader.Shared.Enums; using EnhancedPrefabLoader.Shared.Extensions; using EnhancedPrefabLoader.Shared.Helpers; using EnhancedPrefabLoader.Shared.Models; using HarmonyLib; using I2.Loc; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("EnhancedPrefabLoader")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("6.0.1.0")] [assembly: AssemblyInformationalVersion("6.0.1+cd7431ddc1ec5aac5b27bb4a89a6104e570aad10")] [assembly: AssemblyProduct("Enhanced Prefab Loader")] [assembly: AssemblyTitle("EnhancedPrefabLoader")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Count; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Count; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Count; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyList(List<T> items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return _items.Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { _items.CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return _items.IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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; } } [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; } } } public sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } namespace EnhancedPrefabLoader { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("EnhancedPrefabLoader", "Enhanced Prefab Loader", "6.0.1")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("EnhancedPrefabLoader"); private readonly BundleMaintenanceService maintenanceService = new BundleMaintenanceService(); internal static Plugin Instance { get; private set; } public Plugin() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown Instance = this; } private void Awake() { EplRuntimeData.Config.Initialize(((BaseUnityPlugin)this).Config); ModLogger.Initialize(((BaseUnityPlugin)this).Logger); Epl.RegisterApi((IEplApi)(object)new EplApi()); InterceptorRegistry.RegisterFromAssembly(Assembly.GetExecutingAssembly()); StreamingAssetsBridge.AssetLoadBridge = (IAssetLoadBridge)(object)EplRuntimeData.Services.StreamingAssetService; StreamingAssetsBridge.AssetRefTracker = (IAssetRefTracker)(object)EplRuntimeData.Services.StreamingAssetService; EplRuntimeData.Events.OnInventoryBaseAwake += delegate { EplRuntimeData.Services.ShopInventoryManager.PopulateAllShopInventories(); }; SceneManager.sceneLoaded += OnSceneLoad; harmony.PatchAll(); ModLogger.Info("Plugin Enhanced Prefab Loader v:6.0.1 by GhostNarwhal is loaded!", "Awake", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Plugin.cs"); } private void Update() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!EplRuntimeData.IsBundleLoadingComplete) { return; } KeyboardShortcut value = EplRuntimeData.Config.PriceResetHotkey.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { return; } ModLogger.Info("Force price reset triggered for all bundles", "Update", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Plugin.cs"); foreach (string key in EplRuntimeData.Assets.BundleRegistry.BundleInfo.Keys) { maintenanceService.ResetPricesFor(key); } ModLogger.Info("Price reset complete", "Update", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Plugin.cs"); } private void OnDestroy() { harmony.UnpatchSelf(); ModLogger.Info("Plugin Enhanced Prefab Loader is unloaded!", "OnDestroy", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Plugin.cs"); } private void OnSceneLoad(Scene scene, LoadSceneMode _) { if (((Scene)(ref scene)).name == "Title") { EplRuntimeData.Services.SaveDataManager.ResetAllSaveData(); EplRuntimeData.Services.ShopService.ResetUIState(); EplRuntimeData.Services.WorkerPackOpenerScreenService.IsLoaded = false; EplRuntimeData.Services.CardExpansionSelectService.IsLoaded = false; EplRuntimeData.Services.CardRaritySelectService.IsLoaded = false; EplRuntimeData.Services.CollectionBinderService.IsLoaded = false; return; } EplRuntimeData.Services.ShopService.CreateAndRegisterCustomShops(); EplRuntimeData.Services.StreamingAssetService.StartCleanupCoroutine(); if (!(((Scene)(ref scene)).name == "Start")) { return; } CardFanRandomizer[] array = Resources.FindObjectsOfTypeAll<CardFanRandomizer>(); foreach (CardFanRandomizer val in array) { string text = ((Object)((Component)val).transform).name; for (Transform parent = ((Component)val).transform.parent; parent != null; parent = parent.parent) { text = ((Object)parent).name + "/" + text; } ModLogger.Info($"CardFanRandomizer on: {text} (active: {((Component)val).gameObject.activeInHierarchy})", "OnSceneLoad", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Plugin.cs"); } } } } namespace EnhancedPrefabLoader.Shared.Services { public class BundleDiscoveryService { public List<string> DiscoverBundles(string basePath) { return Directory.EnumerateDirectories(basePath, "*_prefabloader", new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive }).ToList().SelectMany((string d) => Directory.GetFiles(d, "*.json", SearchOption.AllDirectories)) .ToList(); } } } namespace EnhancedPrefabLoader.Shared.Models { public class BundleDescriptor { public string BundleId { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public List<string> Assemblies { get; set; } = new List<string>(); public List<CustomShopInfo> CustomShops { get; set; } = new List<CustomShopInfo>(); public List<ItemInfo> Items { get; set; } = new List<ItemInfo>(); public List<PrefabInfo> Prefabs { get; set; } = new List<PrefabInfo>(); public List<CardExpansionInfo> CardExpansions { get; set; } = new List<CardExpansionInfo>(); public List<PrefabInfo> Furniture => Prefabs.Where((PrefabInfo p) => p.AddItemToFurnitureShop).ToList(); public List<PrefabInfo> Deco => Prefabs.Where((PrefabInfo p) => p.IsDecoObject || p.IsDecoFloorTexture || p.IsDecoCeilingTexture || p.IsDecoWallTexture).ToList(); public HashSet<string> PrefabNames { get { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in (from p in Prefabs?.Where((PrefabInfo p) => !string.IsNullOrWhiteSpace(p.PrefabName)) select p.PrefabName) ?? Array.Empty<string>()) { hashSet.Add(item); } return hashSet; } } public HashSet<string> MeshNames { get { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in (from i in Items?.Where((ItemInfo i) => !string.IsNullOrWhiteSpace(i.Mesh)) select i.Mesh) ?? Array.Empty<string>()) { hashSet.Add(item); } return hashSet; } } public HashSet<string> MaterialNames { get { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in (from i in Items?.Where((ItemInfo i) => !string.IsNullOrWhiteSpace(i.Material)) select i.Material) ?? Array.Empty<string>()) { hashSet.Add(item); } return hashSet; } } } public class CardExpansionInfo { public string Name { get; set; } = string.Empty; public string MenuCategory { get; set; } = string.Empty; public string CardExpansion { get; set; } = string.Empty; [JsonProperty("CardbackSprite")] public string Cardback { get; set; } = string.Empty; public string FoilMask { get; set; } = string.Empty; public bool HasRandomFoils { get; set; } public float FoilChance { get; set; } public List<string> Rarities { get; set; } = new List<string>(); public List<CardInfo> Cards { get; set; } = new List<CardInfo>(); public string CardPriceStrategy { get; set; } = string.Empty; public float DefaultBorderMultiplierBase { get; set; } = 3.15f; public float DefaultFoilMultiplier { get; set; } = 2.9f; public float RarityDrivenFloor { get; set; } = 4f; public float RarityDrivenStepSize { get; set; } = 1026f; public float RarityDrivenBorderMultiplierBase { get; set; } = 1.15f; public float RarityDrivenFoilMultiplier { get; set; } = 1.4f; public int TradeUnlockLevel { get; set; } public List<string> PlayCardMaterials { get; set; } = new List<string>(); public bool IsValid { get; set; } = true; } public class CardExpansionMetadata { public string ExpansionName { get; set; } = string.Empty; public int CardCount { get; set; } } public class CardInfo { public string Name { get; set; } = string.Empty; public string ElementType { get; set; } = string.Empty; public string Rarity { get; set; } = string.Empty; public int CardNumber { get; set; } public string Sprite { get; set; } = string.Empty; public string BorderType { get; set; } = string.Empty; public bool IsFoil { get; set; } public string FoilMask { get; set; } = string.Empty; public string Cardback { get; set; } = string.Empty; } [Serializable] public struct ColorData { public float R { get; set; } public float G { get; set; } public float B { get; set; } public float A { get; set; } } public class CustomShopInfo { public string PhoneAppId { get; set; } = string.Empty; public string AppDisplayName { get; set; } = string.Empty; public string AppIcon { get; set; } = string.Empty; public string AppInnerBGImage { get; set; } = string.Empty; public string AppOuterBGImage { get; set; } = string.Empty; public string SiteLogo { get; set; } = string.Empty; public string SiteHeader { get; set; } = string.Empty; public string SiteBackground { get; set; } = string.Empty; public bool IsValid { get; internal set; } = true; } public class ItemInfo { public string Name { get; set; } = string.Empty; public string ItemCategory { get; set; } = string.Empty; public string SpriteName { get; set; } = string.Empty; public float BaseCost { get; set; } public bool AddItemAsAccessory { get; set; } public bool AddItemAsFigurine { get; set; } public bool AddItemAsBoardGame { get; set; } public string PhoneAppId { get; set; } = string.Empty; public string ItemType { get; set; } = string.Empty; public bool UsesBaseGameMesh { get; set; } public string MeshToUse { get; set; } = string.Empty; public string Mesh { get; set; } = string.Empty; public string MeshSecondary { get; set; } = string.Empty; public string Material { get; set; } = string.Empty; public string MaterialSecondary { get; set; } = string.Empty; public List<string> MaterialList { get; set; } = new List<string>(); [JsonProperty("IsBigBox")] public bool HasBigBox { get; set; } public bool HasSmallBox { get; set; } [JsonProperty("HideTillUnlocked")] public bool BigBoxHideTillUnlocked { get; set; } public bool SmallBoxHideTillUnlocked { get; set; } [JsonProperty("LicensePrice")] public float BigBoxLicensePrice { get; set; } public float SmallBoxLicensePrice { get; set; } [JsonProperty("LicenseLevelRequirement")] public int BigBoxLicenseLevelRequirement { get; set; } public int SmallBoxLicenseLevelRequirement { get; set; } [JsonProperty("IgnoreDoubleImage")] public bool BigBoxIgnoreDoubleImage { get; set; } public bool SmallBoxIgnoreDoubleImage { get; set; } public float MinMarketPricePercent { get; set; } public float MaxMarketPricePercent { get; set; } public string FollowItemPrice { get; set; } = string.Empty; public bool AutoSetBoxPrice { get; set; } public bool IsTallItem { get; set; } public float InBoxOffsetY { get; set; } public float InBoxOffsetScale { get; set; } public Vector3Data ItemDeminsion { get; set; } public Vector3Data CollidorPosOffset { get; set; } public Vector3Data ColliderScale { get; set; } public List<string> PriceAffectedBy { get; set; } = new List<string>(); public bool IsSprayCan { get; set; } public bool IsCardPack { get; set; } public bool IsCardBox { get; set; } public bool IsBulkBox { get; set; } public int MinValue { get; set; } public string CardExpansion { get; set; } = string.Empty; public bool CanHaveDuplicates { get; set; } public bool CanHaveGodPacks { get; set; } public string PackGenerationStrategy { get; set; } = string.Empty; public Dictionary<string, float> NormalWeights { get; set; } = new Dictionary<string, float>(); public Dictionary<string, float> GodWeights { get; set; } = new Dictionary<string, float>(); public Dictionary<string, Dictionary<string, float>> SlotWeights { get; set; } = new Dictionary<string, Dictionary<string, float>>(); [Obsolete("Use NormalWeights, GodWeights, and SlotWeights instead. This field exists for backwards compatibility with older descriptors.")] public List<RarityWeightInfo> GenerationWeights { get; set; } = new List<RarityWeightInfo>(); public string SpawnsPackType { get; set; } = string.Empty; public string PackType { get; set; } = string.Empty; public float GodPackPercentage { get; set; } public bool IsValid { get; set; } = true; } public class ModManifest { public string ModId { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string Directory { get; set; } = string.Empty; public string BundlePath { get; set; } = string.Empty; public string JsonPath { get; set; } = string.Empty; public bool IsValid { get; set; } = true; public bool IsLoaded { get; set; } = true; public List<string> Errors { get; set; } = new List<string>(); public int ItemCount { get; set; } public int FurnitureCount { get; set; } public int CustomShopCount { get; set; } public int DecoCount { get; set; } public List<CardExpansionMetadata> CardExpansions { get; set; } = new List<CardExpansionMetadata>(); } public class PrefabInfo { public string Name { get; set; } = string.Empty; public string PrefabName { get; set; } = string.Empty; public string SpriteName { get; set; } = string.Empty; public float Price { get; set; } public int LevelRequirement { get; set; } public bool AddItemToFurnitureShop { get; set; } public string Description { get; set; } = string.Empty; public string ObjectType { get; set; } public List<VideoClipInfo> VideoClips { get; set; } = new List<VideoClipInfo>(); public float DecoBonus { get; set; } public bool IsDecoWallTexture { get; set; } public bool IsDecoFloorTexture { get; set; } public bool IsDecoCeilingTexture { get; set; } public bool IsDecoObject { get; set; } public string DecoObject { get; set; } = string.Empty; public string DecoType { get; set; } = string.Empty; public string Texture { get; set; } = string.Empty; public string RoughnessMap { get; set; } = string.Empty; public string NormalMap { get; set; } = string.Empty; public float Smoothness { get; set; } public ColorData Color { get; set; } public bool IsValid { get; set; } = true; } public class RarityWeightInfo { public string Rarity { get; set; } = string.Empty; [Obsolete("Use SlotWeights instead. This field exists for backwards compatibility with older descriptors.")] public string GuaranteedSlots { get; set; } = string.Empty; public float NormalWeight { get; set; } public float GodPackWeight { get; set; } } [Serializable] public struct Vector3Data { public float X { get; set; } public float Y { get; set; } public float Z { get; set; } } public class VideoClipInfo { public string Name { get; set; } = string.Empty; public string VideoPlayerName { get; set; } = string.Empty; } } namespace EnhancedPrefabLoader.Shared.Helpers { public static class FileHelper { public static List<string> GetAllJsonFilesIn(string basePath, string folderPattern) { return Directory.EnumerateDirectories(basePath, folderPattern, new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive }).SelectMany((string d) => Directory.GetFiles(d, "*.json", SearchOption.AllDirectories)).ToList(); } } public static class ModIdGenerator { public static string GenerateFromDirectory(string directory) { DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(directory)); string fullName = directoryInfo.FullName; string name = directoryInfo.Name; using SHA1 sHA = SHA1.Create(); string text = BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(fullName.ToLowerInvariant()))).Replace("-", "").Substring(0, 8); return name + "_" + text; } } } namespace EnhancedPrefabLoader.Shared.Extensions { public static class DictionaryExtensions { public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key) { if (!dict.TryGetValue(key, out TValue value)) { return default(TValue); } return value; } public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, Func<TKey, TValue> factory) { if (!dict.TryGetValue(key, out TValue value)) { value = (dict[key] = factory(key)); } return value; } public static void MergeAdd<TKey>(this Dictionary<TKey, int> dict, IEnumerable<(TKey key, int amount)> items) { foreach (var item3 in items) { TKey item = item3.key; int item2 = item3.amount; dict[item] = dict.GetOrAdd(item, (TKey _) => 0) + item2; } } public static void AddRange<TKey, TValue>(this Dictionary<TKey, TValue> dict, IEnumerable<KeyValuePair<TKey, TValue>> items) { foreach (KeyValuePair<TKey, TValue> item in items) { dict[item.Key] = item.Value; } } } public static class ListExtensions { public static List<T> Shuffle<T>(this List<T> list) where T : class { for (int num = list.Count - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); int index = num; int index2 = num2; T value = list[num2]; T value2 = list[num]; list[index] = value; list[index2] = value2; } return list; } public static List<T> SwapAndRemove<T>(this List<T> list, int index) { int num = list.Count - 1; if (index != num) { int index2 = num; T value = list[num]; T value2 = list[index]; list[index] = value; list[index2] = value2; } list.RemoveAt(num); return list; } } } namespace EnhancedPrefabLoader.Shared.Enums { [Flags] public enum ItemFlags : byte { None = 0, BoardGame = 1, Accessory = 2, Figurine = 4, TCG = 8 } } namespace EnhancedPrefabLoader.Core { internal class BundleManager { internal class BundleHandle { [CompilerGenerated] private sealed class <WaitForLoadAsync>d__12 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public BundleHandle <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForLoadAsync>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; BundleHandle bundleHandle = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (bundleHandle.IsLoaded) { return false; } if (bundleHandle.isLoading) { break; } bundleHandle.isLoading = true; if (bundleHandle.loadRequest != null) { <>2__current = bundleHandle.loadRequest; <>1__state = 1; return true; } goto IL_00a2; case 1: <>1__state = -1; bundleHandle.assetBundle = bundleHandle.loadRequest.assetBundle; bundleHandle.loadRequest = null; bundleHandle.IsLoaded = bundleHandle.assetBundle != null; bundleHandle.HasError = bundleHandle.assetBundle == null; goto IL_00a2; case 2: { <>1__state = -1; break; } IL_00a2: bundleHandle.isLoading = false; break; } if (bundleHandle.isLoading) { ModLogger.Debug("Waiting for another coroutine to finish loading bundle.", "WaitForLoadAsync", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\BundleManager.cs"); <>2__current = null; <>1__state = 2; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private AssetBundle? assetBundle; private AssetBundleCreateRequest? loadRequest; private bool isLoading; public bool HasError { get; private set; } public bool IsLoaded { get; private set; } public static BundleHandle Create(string bundlePath) { string bundleName = Path.GetFileNameWithoutExtension(bundlePath); AssetBundle val = AssetBundle.GetAllLoadedAssetBundles().FirstOrDefault((Func<AssetBundle, bool>)((AssetBundle b) => ((Object)b).name == bundleName)); if (val != null) { ModLogger.Debug("Bundle '" + bundleName + "' already loaded externally, reusing.", "Create", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\BundleManager.cs"); return new BundleHandle { assetBundle = val, IsLoaded = true }; } return new BundleHandle { loadRequest = AssetBundle.LoadFromFileAsync(bundlePath) }; } [IteratorStateMachine(typeof(<WaitForLoadAsync>d__12))] internal IEnumerator WaitForLoadAsync() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForLoadAsync>d__12(0) { <>4__this = this }; } internal AssetBundleRequest? LoadAssetAsync<T>(string assetName) where T : Object { if (!string.IsNullOrEmpty(assetName)) { AssetBundle? obj = assetBundle; if (obj == null) { return null; } return obj.LoadAssetAsync<T>(assetName); } return null; } internal AssetBundleRequest? LoadAssetAsync(string assetName, Type type) { if (!string.IsNullOrEmpty(assetName)) { AssetBundle? obj = assetBundle; if (obj == null) { return null; } return obj.LoadAssetAsync(assetName, type); } return null; } internal AssetBundleRequest? LoadAllAsync<T>() where T : Object { AssetBundle? obj = assetBundle; if (obj == null) { return null; } return obj.LoadAllAssetsAsync<T>(); } } private readonly Dictionary<string, BundleHandle> bundleHandles = new Dictionary<string, BundleHandle>(); internal BundleHandle GetOrOpen(string bundlePath) { if (bundleHandles.TryGetValue(bundlePath, out BundleHandle value)) { if (!value.HasError) { return value; } bundleHandles.Remove(bundlePath); } value = BundleHandle.Create(bundlePath); bundleHandles[bundlePath] = value; return value; } } internal class EplApi : IEplApi { public bool IsBundleLoadingComplete => EplRuntimeData.IsBundleLoadingComplete; public IBundleRegistry BundleRegistry => (IBundleRegistry)(object)EplRuntimeData.Assets.BundleRegistry; public IEplAssets Assets => (IEplAssets)(object)EplRuntimeData.Assets; public IEplServices Services => (IEplServices)(object)EplRuntimeData.Services; public IEplEvents Events => (IEplEvents)(object)EplRuntimeData.Events; } internal class EplCaches { internal Dictionary<string, Material> CardBackMaterials { get; } = new Dictionary<string, Material>(); internal Material? OriginalCardBackMaterial { get; set; } internal Dictionary<InteractablePlayTable, List<Material>> PlayTableExpansionCache { get; } = new Dictionary<InteractablePlayTable, List<Material>>(); } internal class EplConfig { internal bool ExcludeBaseGameCardsFromTrade { get; private set; } internal bool SparkleFoilEnabled { get; private set; } internal bool UseCustomExpForBase { get; private set; } internal bool DisableBaseGamePlayCards { get; private set; } internal ConfigEntry<KeyboardShortcut> PriceResetHotkey { get; private set; } internal ConfigEntry<LogLevel> MinimumLogLevelEntry { get; private set; } internal ConfigEntry<float> CollectionBinderSpacingXEntry { get; private set; } internal ConfigEntry<float> CollectionBinderSpacingYEntry { get; private set; } internal ConfigEntry<Vector2> CollectionBinderButtonSizeEntry { get; private set; } internal ConfigEntry<float> CardExpansionSelectSpacingXEntry { get; private set; } internal ConfigEntry<float> CardExpansionSelectSpacingYEntry { get; private set; } internal ConfigEntry<Vector2> CardExpansionSelectButtonSizeEntry { get; private set; } internal ConfigEntry<float> RaritySelectSpacingXEntry { get; private set; } internal ConfigEntry<float> RaritySelectSpacingYEntry { get; private set; } internal ConfigEntry<Vector2> RaritySelectButtonSizeEntry { get; private set; } internal void Initialize(ConfigFile config) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<bool> excludeBaseGame = config.Bind<bool>("Trading", "ExcludeBaseGameCardsFromTrade", false, "When enabled, base-game expansions (Tetramon, Destiny, Ghost) will not appear in customer card trade/sell selection."); ExcludeBaseGameCardsFromTrade = excludeBaseGame.Value; excludeBaseGame.SettingChanged += delegate { ExcludeBaseGameCardsFromTrade = excludeBaseGame.Value; }; ConfigEntry<bool> sparkleFoil = config.Bind<bool>("CardUI", "Sparkle Foil Enabled", true, "When enabled, foil cards display the sparkle glitter effect."); SparkleFoilEnabled = sparkleFoil.Value; sparkleFoil.SettingChanged += delegate { SparkleFoilEnabled = sparkleFoil.Value; }; CollectionBinderSpacingXEntry = config.Bind<float>("CollectionBinderUI", "ExpansionSpacingX", 30f, (ConfigDescription)null); CollectionBinderSpacingYEntry = config.Bind<float>("CollectionBinderUI", "ExpansionSpacingY", -45f, (ConfigDescription)null); CollectionBinderButtonSizeEntry = config.Bind<Vector2>("CollectionBinderUI", "ExpansionButtonSize", new Vector2(325f, 184.5f), (ConfigDescription)null); CardExpansionSelectSpacingXEntry = config.Bind<float>("UI", "ExpansionSpacingX", 30f, (ConfigDescription)null); CardExpansionSelectSpacingYEntry = config.Bind<float>("UI", "ExpansionSpacingY", -45f, (ConfigDescription)null); CardExpansionSelectButtonSizeEntry = config.Bind<Vector2>("UI", "ExpansionButtonSize", new Vector2(325f, 184.5f), (ConfigDescription)null); RaritySelectSpacingXEntry = config.Bind<float>("UI", "RaritySpacingX", 30f, (ConfigDescription)null); RaritySelectSpacingYEntry = config.Bind<float>("UI", "RaritySpacingY", -45f, (ConfigDescription)null); RaritySelectButtonSizeEntry = config.Bind<Vector2>("UI", "RarityButtonSize", new Vector2(325f, 184.5f), (ConfigDescription)null); ConfigEntry<bool> useCustomExp = config.Bind<bool>("GamePlay", "UseCustomExpForBase", false, "When enabled, base-game card expansions will use the EPL experience formula instead of the vanilla formula."); UseCustomExpForBase = useCustomExp.Value; useCustomExp.SettingChanged += delegate { UseCustomExpForBase = useCustomExp.Value; }; PriceResetHotkey = config.Bind<KeyboardShortcut>("Hotkeys", "Force Price Reset", new KeyboardShortcut((KeyCode)114, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Press to reset all item and card prices for every loaded bundle."); MinimumLogLevelEntry = config.Bind<LogLevel>("Logging", "Minimum log level to log", LogLevel.None, (ConfigDescription)null); ConfigEntry<bool> disableBaseCards = config.Bind<bool>("PlayTable", "DisableBaseGamePlayCards", false, "When enabled, base game card textures will not appear on play tables. If no mod expansion textures are available, this setting is ignored."); DisableBaseGamePlayCards = disableBaseCards.Value; disableBaseCards.SettingChanged += delegate { DisableBaseGamePlayCards = disableBaseCards.Value; }; } } internal static class EplRuntimeData { internal static bool IsBundleLoadingComplete { get; set; } internal static BundleAssetTracker BundleAssetTracker { get; set; } = new BundleAssetTracker(); internal static List<Assembly> Assemblies { get; private set; } = new List<Assembly>(); internal static EplCaches Caches { get; private set; } = new EplCaches(); internal static EplConfig Config { get; private set; } = new EplConfig(); internal static EplEvents Events { get; private set; } = new EplEvents(); internal static EplAssets Assets { get; private set; } = new EplAssets(new BundleRegistry(BundleAssetTracker)); internal static EplServices Services { get; private set; } = new EplServices(new SaveDataService(BundleAssetTracker)); } public enum LogLevel { Debug, Info, Warning, Error, None } public static class ModLogger { private static ManualLogSource logger; private static LogLevel logLevel; public static void Initialize(ManualLogSource logger) { ModLogger.logger = logger; logLevel = EplRuntimeData.Config.MinimumLogLevelEntry.Value; EplRuntimeData.Config.MinimumLogLevelEntry.SettingChanged += delegate { logLevel = EplRuntimeData.Config.MinimumLogLevelEntry.Value; }; } public static void Debug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "") { if (logLevel <= LogLevel.Debug) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); logger.LogDebug((object)("[" + fileNameWithoutExtension + "." + memberName + "]: " + message)); } } public static void Info(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "") { if (logLevel <= LogLevel.Info) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); logger.LogInfo((object)("[" + fileNameWithoutExtension + "." + memberName + "]: " + message)); } } public static void Warning(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "") { if (logLevel <= LogLevel.Warning) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); logger.LogWarning((object)("[" + fileNameWithoutExtension + "." + memberName + "]: " + message)); } } public static void Error(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "") { if (logLevel <= LogLevel.Error) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); logger.LogError((object)("[" + fileNameWithoutExtension + "." + memberName + "]: " + message)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "EnhancedPrefabLoader"; public const string PLUGIN_NAME = "Enhanced Prefab Loader"; public const string PLUGIN_VERSION = "6.0.1"; } } namespace EnhancedPrefabLoader.Core.Utils { public static class EplConstants { public const string EplDirectoryDescriptor = "*_prefabloader"; } internal static class ItemTypeResolver { private static EItemType[]? sortedModKeys; internal static EItemType Resolve(int index) { if (index >= 129) { if (index < 200000) { return GetSortedModKeys()[index - 129]; } return (EItemType)index; } return (EItemType)index; } internal static EItemType[] GetSortedModKeys() { return sortedModKeys ?? (sortedModKeys = EplRuntimeData.Assets.ItemLibrary.ItemData.Keys.OrderBy((EItemType k) => (int)k).ToArray()); } internal static void InvalidateCache() { sortedModKeys = null; } } public static class RandomUtils { public static T Weighted<T>(Dictionary<T, float> weights) { float num = 0f; foreach (KeyValuePair<T, float> weight in weights) { num += weight.Value; } float num2 = Random.value * num; foreach (KeyValuePair<T, float> weight2 in weights) { num2 -= weight2.Value; if (num2 <= 0f) { return weight2.Key; } } return weights.Last().Key; } } } namespace EnhancedPrefabLoader.Core.Uninstall { internal class CardRemovalStrategy : IAssetRemovalStrategy { [CompilerGenerated] private HashSet<ECardExpansionType> <cardExpansions>P; private Dictionary<CardData, int> removedCards; public CardRemovalStrategy(HashSet<ECardExpansionType> cardExpansions) { <cardExpansions>P = cardExpansions; removedCards = new Dictionary<CardData, int>(); base..ctor(); } public RemovalResult RemoveAssets() { removedCards = new Dictionary<CardData, int>(); RemoveFromCardShelves(); RemoveFromBinder(); RemoveFromBulkDonationBoxes(); RemoveFromCardStorageShelves(); RemoveFromCardPackageBoxes(); return RemovalResult.Success(removedCards.Values.Sum(), removedCards.Sum<KeyValuePair<CardData, int>>((KeyValuePair<CardData, int> kvp) => CPlayerData.GetCardMarketPrice(kvp.Key) * (float)kvp.Value)); } private void RemoveFromCardShelves() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) foreach (InteractableCardCompartment item in CSingleton<ShelfManager>.Instance.m_CardShelfList.SelectMany((CardShelf cs) => cs.m_CardCompartmentList)) { if (item.m_StoredCardList.Count == 0) { continue; } CardData cardData = item.m_StoredCardList[0].m_Card3dUI.m_CardUI.m_CardData; if (!<cardExpansions>P.Contains(cardData.expansionType)) { continue; } foreach (InteractableCardPriceTag interactablePriceTag in item.m_InteractablePriceTagList) { interactablePriceTag.SetPriceChecked(false); } item.m_StoredCardList[0].SetIsDisplayedOnShelf(false); item.m_StoredCardList[0].SetTargetRotation(Quaternion.identity); item.m_StoredCardList.RemoveAt(0); item.SetPriceTagCardData((CardData)null); item.SetPriceTagVisibility(false); if (item.m_CardShelf?.m_ElectronicCardListener != null) { item.m_CardShelf.m_ElectronicCardListener.UpdateCardUI((CardData)null); } removedCards[cardData] = removedCards.GetValueOrDefault(cardData) + 1; } } private void RemoveFromBinder() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) foreach (CardData item in CPlayerData.m_GradedCardInventoryList.Where((CompactCardDataAmount c) => <cardExpansions>P.Contains(c.expansionType)).Select((Func<CompactCardDataAmount, CardData>)CPlayerData.GetGradedCardData).ToList()) { CPlayerData.RemoveGradedCard(item, false); removedCards[item] = removedCards.GetValueOrDefault(item) + 1; } CardExpansionLibrary cardExpansionLibrary = EplRuntimeData.Assets.CardExpansionLibrary; foreach (ECardExpansionType item2 in <cardExpansions>P) { if (!cardExpansionLibrary.CardExpansionData.TryGetValue(item2, out ModCardExpansionData value)) { continue; } foreach (KeyValuePair<EMonsterType, ModCardData> card in value.Cards) { card.Deconstruct(out var _, out var value2); CardData val = value2; int cardAmount = CPlayerData.GetCardAmount(val); if (cardAmount > 0) { CPlayerData.ReduceCard(val, cardAmount); removedCards[val] = removedCards.GetValueOrDefault(val) + cardAmount; } } } } private void RemoveFromBulkDonationBoxes() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) foreach (List<CompactCardDataAmount> item in CSingleton<ShelfManager>.Instance.m_BulkDonationBoxList.Select((InteractableBulkDonationBox b) => b.m_CompactCardDataAmountList)) { foreach (CompactCardDataAmount item2 in item.Where((CompactCardDataAmount c) => <cardExpansions>P.Contains(c.expansionType))) { CardData cardData = CPlayerData.GetCardData(item2.cardSaveIndex, item2.expansionType, item2.isDestiny); removedCards[cardData] = removedCards.GetValueOrDefault(cardData) + item2.amount; } item.RemoveAll((CompactCardDataAmount c) => <cardExpansions>P.Contains(c.expansionType)); } } private void RemoveFromCardStorageShelves() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) foreach (List<CompactCardDataAmount> item in CSingleton<ShelfManager>.Instance.m_CardStorageShelfList.Select((InteractableCardStorageShelf b) => b.m_CompactCardDataAmountList)) { foreach (CompactCardDataAmount item2 in item.Where((CompactCardDataAmount c) => <cardExpansions>P.Contains(c.expansionType))) { CardData cardData = CPlayerData.GetCardData(item2.cardSaveIndex, item2.expansionType, item2.isDestiny); removedCards[cardData] = removedCards.GetValueOrDefault(cardData) + item2.amount; } item.RemoveAll((CompactCardDataAmount c) => <cardExpansions>P.Contains(c.expansionType)); } } private void RemoveFromCardPackageBoxes() { List<InteractablePackagingBox_Card> list = new List<InteractablePackagingBox_Card>(); foreach (InteractablePackagingBox_Card spawnedPackageBox in CSingleton<ShelfManager>.Instance.m_SpawnedPackageBoxCardList) { spawnedPackageBox.m_StoredCardList.RemoveAll(delegate(InteractableCard3d i) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) CardData cardData = i.m_Card3dUI.m_CardUI.m_CardData; if (<cardExpansions>P.Contains(cardData.expansionType)) { removedCards[cardData] = removedCards.GetValueOrDefault(cardData) + 1; spawnedPackageBox.m_StoredCardDataList.Remove(cardData); ((InteractableObject)i).OnDestroyed(); return true; } return false; }); if (spawnedPackageBox.m_StoredCardList.Count == 0) { list.Add(spawnedPackageBox); } } foreach (InteractablePackagingBox_Card item in list) { CSingleton<ShelfManager>.Instance.m_SpawnedPackageBoxCardList.Remove(item); ((InteractableObject)item).OnDestroyed(); } } } internal class DecoRemovalStrategy : IAssetRemovalStrategy { [CompilerGenerated] private HashSet<EDecoObject> <decoTypes>P; [CompilerGenerated] private string <bundleId>P; public DecoRemovalStrategy(HashSet<EDecoObject> decoTypes, string bundleId) { <decoTypes>P = decoTypes; <bundleId>P = bundleId; base..ctor(); } public RemovalResult RemoveAssets() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) float totalValue = 0f; int totalDecoCount = 0; foreach (EDecoObject item in <decoTypes>P) { if (EplRuntimeData.Services.SaveDataManager.TryGetSaveData<EDecoObject, DecoSaveData>(item, out DecoSaveData data)) { totalDecoCount += data.ItemCount; totalValue += InventoryBase.GetItemDecoPurchaseData(item).price * (float)data.ItemCount; data.Reset(); } } ResetTextureSaveData((DecoFlags)3, EplRuntimeData.Assets.DecoLibrary.firstInsertedCeilingTexture, CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_CeilingDecoDataList, ref totalDecoCount, ref totalValue); ResetTextureSaveData((DecoFlags)1, EplRuntimeData.Assets.DecoLibrary.firstInsertedFloorTexture, CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_FloorDecoDataList, ref totalDecoCount, ref totalValue); ResetTextureSaveData((DecoFlags)2, EplRuntimeData.Assets.DecoLibrary.firstInsertedWallTexture, CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_WallDecoDataList, ref totalDecoCount, ref totalValue); return RemovalResult.Success(totalDecoCount, totalValue); } private void ResetTextureSaveData(DecoFlags category, int? firstInsertedIndex, List<ShopDecoData> decoDataList, ref int totalDecoCount, ref float totalValue) { if (!firstInsertedIndex.HasValue) { return; } string category2 = ((object)(DecoFlags)(ref category)).ToString(); BundleAssetTracker bundleAssetTracker = EplRuntimeData.BundleAssetTracker; SaveDataService saveDataManager = EplRuntimeData.Services.SaveDataManager; for (int i = firstInsertedIndex.Value; i < decoDataList.Count; i++) { string name = decoDataList[i].name; if (!(bundleAssetTracker.GetBundleIdFor(category2, name) != <bundleId>P) && saveDataManager.TryGetSaveData<DecoSaveData>(category2, name, out DecoSaveData data)) { totalDecoCount += data.ItemCount; totalValue += decoDataList[i].price * (float)data.ItemCount; data.Reset(); } } } } internal interface IAssetRemovalStrategy { RemovalResult RemoveAssets(); } internal class InteractableObjectRemovalStrategy : IAssetRemovalStrategy { [CompilerGenerated] private HashSet<EObjectType> <furnitures>P; [CompilerGenerated] private HashSet<EDecoObject> <decos>P; private readonly Dictionary<EItemType, int> itemsToRestock; public InteractableObjectRemovalStrategy(HashSet<EObjectType> furnitures, HashSet<EDecoObject> decos) { <furnitures>P = furnitures; <decos>P = decos; itemsToRestock = new Dictionary<EItemType, int>(); base..ctor(); } public RemovalResult RemoveAssets() { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) itemsToRestock.Clear(); int num = 0; float num2 = 0f; List<InteractableObject> list = (from Transform t in (IEnumerable)CSingleton<ShelfManager>.Instance.m_ShelfParentGrp select ((Component)t).GetComponent<InteractableObject>() into i where i != null && (<furnitures>P.Contains(i.m_ObjectType) || <decos>P.Contains(i.m_DecoObjectType)) select i).ToList(); FurnitureLibrary furnitureLibrary = EplRuntimeData.Assets.FurnitureLibrary; foreach (InteractableObject item in list) { InteractableDecoration val = (InteractableDecoration)(object)((item is InteractableDecoration) ? item : null); if (val == null) { InteractableBulkDonationBox val2 = (InteractableBulkDonationBox)(object)((item is InteractableBulkDonationBox) ? item : null); if (val2 == null) { InteractableCardStorageShelf val3 = (InteractableCardStorageShelf)(object)((item is InteractableCardStorageShelf) ? item : null); if (val3 == null) { CardShelf val4 = (CardShelf)(object)((item is CardShelf) ? item : null); if (val4 == null) { InteractableWorkbench val5 = (InteractableWorkbench)(object)((item is InteractableWorkbench) ? item : null); if (val5 == null) { Shelf val6 = (Shelf)(object)((item is Shelf) ? item : null); if (val6 == null) { WarehouseShelf val7 = (WarehouseShelf)(object)((item is WarehouseShelf) ? item : null); if (val7 != null) { EmptyWarehouseShelf(val7); num2 += furnitureLibrary.FurnitureData[((InteractableObject)val7).m_ObjectType].BaseFurniturePurchaseData.price; } else { num2 += furnitureLibrary.FurnitureData[item.m_ObjectType].BaseFurniturePurchaseData.price; } } else { EmptyShelf(val6); num2 += furnitureLibrary.FurnitureData[((InteractableObject)val6).m_ObjectType].BaseFurniturePurchaseData.price; } } else { EmptyWorkbench(val5); num2 += furnitureLibrary.FurnitureData[((InteractableObject)val5).m_ObjectType].BaseFurniturePurchaseData.price; } } else { EmptyCardShelf(val4); num2 += furnitureLibrary.FurnitureData[((InteractableObject)val4).m_ObjectType].BaseFurniturePurchaseData.price; } } else { EmptyCardStorageShelf(val3); num2 += furnitureLibrary.FurnitureData[((InteractableObject)val3).m_ObjectType].BaseFurniturePurchaseData.price; } } else { EmptyBulkDonationBox(val2); num2 += furnitureLibrary.FurnitureData[((InteractableObject)val2).m_ObjectType].BaseFurniturePurchaseData.price; } } else { num2 += InventoryBase.GetItemDecoPurchaseData(((InteractableObject)val).m_DecoObjectType).price; } if (item.m_IsBoxedUp) { ((InteractableObject)item.m_InteractablePackagingBox_Shelf).OnDestroyed(); } else { item.OnDestroyed(); } num++; } RestockItems(); return RemovalResult.Success(num, num2); } private void EmptyWarehouseShelf(WarehouseShelf warehouseShelf) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) foreach (ShelfCompartment item in from p in warehouseShelf.m_StorageCompartmentList.SelectMany((InteractableStorageCompartment s) => s.m_ShelfCompartment.m_InteractablePackagingBoxList) select p.m_ItemCompartment) { itemsToRestock[item.m_ItemType] = itemsToRestock.GetValueOrDefault(item.m_ItemType) + item.m_StoredItemList.Count; } } private void EmptyShelf(Shelf shelf) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) foreach (ShelfCompartment itemCompartment in ((InteractableObject)shelf).m_ItemCompartmentList) { itemsToRestock[itemCompartment.m_ItemType] = itemsToRestock.GetValueOrDefault(itemCompartment.m_ItemType) + itemCompartment.m_StoredItemList.Count; } } private void EmptyWorkbench(InteractableWorkbench interactableWorkbench) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) foreach (Item storedItem in interactableWorkbench.m_StoredItemList) { itemsToRestock[storedItem.m_ItemType] = itemsToRestock.GetValueOrDefault(storedItem.m_ItemType) + 1; } } private static void EmptyCardShelf(CardShelf cardShelf) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) foreach (InteractableCardCompartment item in cardShelf.m_CardCompartmentList.Where((InteractableCardCompartment c) => c.m_StoredCardList.Count > 0)) { foreach (InteractableCardPriceTag interactablePriceTag in item.m_InteractablePriceTagList) { interactablePriceTag.SetPriceChecked(false); } CardData cardData = item.m_StoredCardList[0].m_Card3dUI.m_CardUI.m_CardData; item.m_StoredCardList[0].SetIsDisplayedOnShelf(false); item.m_StoredCardList[0].SetTargetRotation(Quaternion.identity); item.m_StoredCardList.RemoveAt(0); item.SetPriceTagCardData((CardData)null); item.SetPriceTagVisibility(false); if (item.m_CardShelf?.m_ElectronicCardListener != null) { item.m_CardShelf.m_ElectronicCardListener.UpdateCardUI((CardData)null); } CPlayerData.AddCard(cardData, 1); } } private static void EmptyCardStorageShelf(InteractableCardStorageShelf interactableCardStorageShelf) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) foreach (CompactCardDataAmount compactCardDataAmount in interactableCardStorageShelf.m_CompactCardDataAmountList) { CPlayerData.AddCard(CPlayerData.GetCardData(compactCardDataAmount.cardSaveIndex, compactCardDataAmount.expansionType, compactCardDataAmount.isDestiny), compactCardDataAmount.amount); } interactableCardStorageShelf.m_CompactCardDataAmountList.Clear(); } private static void EmptyBulkDonationBox(InteractableBulkDonationBox interactableBulkDonationBox) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) foreach (CompactCardDataAmount compactCardDataAmount in interactableBulkDonationBox.m_CompactCardDataAmountList) { CPlayerData.AddCard(CPlayerData.GetCardData(compactCardDataAmount.cardSaveIndex, compactCardDataAmount.expansionType, compactCardDataAmount.isDestiny), compactCardDataAmount.amount); } interactableBulkDonationBox.m_CompactCardDataAmountList.Clear(); } private void RestockItems() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<EItemType, int> item in itemsToRestock) { item.Deconstruct(out var key, out var value); EItemType val = key; int num; int num2 = (num = value); int maxItemCountInBox = RestockManager.GetMaxItemCountInBox(val, true); int num3 = Mathf.CeilToInt((float)num2 / (float)maxItemCountInBox); for (int i = 0; i < num3; i++) { int num4 = ((num >= maxItemCountInBox) ? maxItemCountInBox : num); RestockManager.SpawnPackageBoxItem(val, num4, true); num -= num4; } } } } internal class ItemRemovalStrategy : IAssetRemovalStrategy { [CompilerGenerated] private HashSet<EItemType> <items>P; private List<Item> removedItems; public ItemRemovalStrategy(HashSet<EItemType> items) { <items>P = items; removedItems = new List<Item>(); base..ctor(); } public RemovalResult RemoveAssets() { removedItems = new List<Item>(); RemoveFromShelves(); RemoveFromPackagingBoxes(); float totalValue = removedItems.Select((Item i) => RestockManager.GetItemMarketPrice(i.m_ItemType)).Sum(); foreach (Item removedItem in removedItems) { CSingleton<ItemSpawnManager>.Instance.m_ItemList.Remove(removedItem); Object.Destroy((Object)(object)removedItem); } return RemovalResult.Success(removedItems.Count, totalValue); } private void RemoveFromPackagingBoxes() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) foreach (InteractablePackagingBox_Item item in RestockManager.GetItemPackagingBoxList().ToList()) { if (!<items>P.Contains(item.m_ItemType) && !<items>P.Contains(item.m_ItemCompartment.m_ItemType)) { continue; } if (item.m_IsStored) { item.m_BoxStoredCompartment.RemoveBox(item); if (item.m_BoxStoredCompartment.m_ItemAmount == 0) { item.m_BoxStoredCompartment.RemoveLabel(false); } } removedItems.AddRange(item.m_ItemCompartment.m_StoredItemList); EmptyItemCompartment(item.m_ItemCompartment); ((InteractableObject)item).OnDestroyed(); } } private void RemoveFromShelves() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) foreach (ShelfCompartment item in CSingleton<ShelfManager>.Instance.m_ShelfList.SelectMany((Shelf s) => ((InteractableObject)s).m_ItemCompartmentList)) { if (<items>P.Contains(item.m_ItemType) && item.m_ItemAmount != 0) { removedItems.AddRange(item.m_StoredItemList); EmptyItemCompartment(item); } } } private static void EmptyItemCompartment(ShelfCompartment itemCompartment) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) itemCompartment.m_StoredItemList.Clear(); itemCompartment.m_ItemAmount = 0; itemCompartment.m_ItemType = (EItemType)(-1); itemCompartment.RemoveLabel(false); } } internal class RemovalResult { internal bool IsSuccess { get; private set; } internal int AssetsRemoved { get; private set; } internal float TotalValue { get; private set; } internal string ErrorMessage { get; private set; } = string.Empty; private RemovalResult() { } internal static RemovalResult Success(int assetsRemoved, float totalValue) { return new RemovalResult { IsSuccess = true, AssetsRemoved = assetsRemoved, TotalValue = totalValue }; } internal static RemovalResult Failure(string msg) { return new RemovalResult { IsSuccess = false, ErrorMessage = msg }; } internal static RemovalResult Empty() { return new RemovalResult { IsSuccess = true }; } internal void Merge(RemovalResult other) { IsSuccess = IsSuccess && other.IsSuccess; AssetsRemoved += other.AssetsRemoved; TotalValue += other.TotalValue; } } } namespace EnhancedPrefabLoader.Core.Trading { public class CardTradeManager { private readonly CardSelectionService cardSelectionService = new CardSelectionService(); private readonly CardTradePricingService cardTradePricingService = new CardTradePricingService(); private readonly CardTradeUIManager cardTradeUIManager = new CardTradeUIManager(); public void SetCustomer(CustomerTradeCardScreen screen, Customer customer, CustomerTradeData customerTradeData) { CSingleton<CustomerManager>.Instance.m_IsPlayerTrading = true; screen.m_CurrentCustomer = customer; screen.m_HasAccepted = false; screen.m_IsTrading = customerTradeData?.m_IsTrading ?? (Random.Range(0, 100) < Math.Min(40, CPlayerData.m_ShopLevel)); screen.m_CardData_L = (CardData)((customerTradeData != null) ? ((object)customerTradeData.m_CardData_L) : ((object)cardSelectionService.SelectRandomCard())); if (screen.m_IsTrading) { SetupTradeMode(screen, customerTradeData); } else { SetupSellMode(screen, customerTradeData); } cardTradeUIManager.UpdateUI(screen); } private void SetupTradeMode(CustomerTradeCardScreen screen, CustomerTradeData customerTradeData) { screen.m_CardData_R = (CardData)((customerTradeData != null) ? ((object)customerTradeData.m_CardData_R) : ((object)cardSelectionService.SelectPlayerCard(screen.m_CardData_L, customerTradeData))); if (screen.m_CardData_R == null) { screen.m_IsTrading = false; SetupSellMode(screen, customerTradeData); } } private void SetupSellMode(CustomerTradeCardScreen screen, CustomerTradeData customerTradeData) { cardTradePricingService.CalculateAskingPrice(screen, screen.m_CardData_L, customerTradeData); if (customerTradeData != null) { screen.m_PriceSet = customerTradeData.m_PriceSet; screen.m_LastPriceSet = customerTradeData.m_LastPriceSet; } else { screen.OnInputTextUpdated("0"); } } } public class CardTradePricingService { private static readonly (float threshold, float minBonus, float maxBonus)[] PriceTiers = new(float, float, float)[9] { (10f, 0f, 0.03f), (20f, 0f, 0.04f), (100f, 0.01f, 0.05f), (300f, 0.01f, 0.06f), (500f, 0.01f, 0.08f), (1000f, 0.01f, 0.1f), (2000f, 0.02f, 0.11f), (5000f, 0.03f, 0.12f), (8000f, 0.03f, 0.12f) }; public void CalculateAskingPrice(CustomerTradeCardScreen screen, CardData customerCard, CustomerTradeData customerTradeData) { screen.m_SellCardMarketPrice = CPlayerData.GetCardMarketPrice(customerCard); if (customerTradeData != null) { screen.m_SellCardAskPrice = customerTradeData.m_SellCardAskPrice; screen.m_MaxDeclineCount = customerTradeData.m_MaxDeclineCount; screen.m_DeclineCount = customerTradeData.m_DeclineCount; } else { screen.m_SellCardAskPrice = CalculateInitialAskingPrice(screen.m_SellCardMarketPrice); screen.m_MaxDeclineCount = Random.Range(0, 5); screen.m_DeclineCount = 0; } } private float CalculateInitialAskingPrice(float marketPrice) { float num = Random.Range(0.7f, 1.2f); (float, float, float)[] priceTiers = PriceTiers; for (int i = 0; i < priceTiers.Length; i++) { (float, float, float) tuple = priceTiers[i]; if (marketPrice > tuple.Item1) { num += Random.Range(tuple.Item2, tuple.Item3); } } return num * marketPrice; } } public class CardTradeUIManager { public void UpdateUI(CustomerTradeCardScreen screen) { SetTradingScreenText(screen); UpdateScreenGrpVisibility(screen); SetPriceTexts(screen); UpdateCardDisplays(screen); UpdateButtonVisibility(screen); } private void SetTradingScreenText(CustomerTradeCardScreen screen) { List<string> list = (screen.m_IsTrading ? screen.m_CustomerTradeCardTextList : screen.m_CustomerSellCardTextList); ((TMP_Text)screen.m_CustomerTopText).text = LocalizationManager.GetTranslation("CustomerTrade/" + list[Random.Range(0, list.Count)], true, 0, true, false, (GameObject)null, (string)null, true); screen.m_CustomerTopTextAnim.Rewind(); screen.m_CustomerTopTextAnim.Play(); } private void UpdateScreenGrpVisibility(CustomerTradeCardScreen screen) { screen.m_CustomerTradingText.SetActive(screen.m_IsTrading); screen.m_CustomerSellingText.SetActive(!screen.m_IsTrading); screen.m_TradeGrp_R.SetActive(screen.m_IsTrading); screen.m_SellGrp_R.SetActive(!screen.m_IsTrading); } private void SetPriceTexts(CustomerTradeCardScreen screen) { string translation = LocalizationManager.GetTranslation("Market Price", true, 0, true, false, (GameObject)null, (string)null, true); string priceString = GameInstance.GetPriceString(CPlayerData.GetCardMarketPrice(screen.m_CardData_L), false, true, false, "F2"); string translation2 = LocalizationManager.GetTranslation("Ask Price", true, 0, true, false, (GameObject)null, (string)null, true); string priceString2 = GameInstance.GetPriceString(screen.m_SellCardAskPrice, false, true, false, "F2"); if (screen.m_IsTrading) { ((TMP_Text)screen.m_MarketPrice_L).text = translation + " : " + priceString; return; } ((TMP_Text)screen.m_MarketPrice_L).text = translation2 + " : " + priceString2 + "\n" + translation + " : " + priceString; screen.m_CardUI_Buying.SetCardUI(screen.m_CardData_L); } private void UpdateButtonVisibility(CustomerTradeCardScreen screen) { screen.m_AcceptBtn.SetActive(true); screen.m_CancelBtn.SetActive(true); screen.m_LetMeThinkBtn.SetActive(true); screen.m_DoneBtn.SetActive(false); } private void UpdateCardDisplays(CustomerTradeCardScreen screen) { screen.m_IsNewUI.SetActive(CPlayerData.GetCardAmount(screen.m_CardData_L) == 0); screen.m_CardUI_L.SetCardUI(screen.m_CardData_L); screen.m_CardUI_Album_L.SetCardUI(screen.m_CardData_L); ((TMP_Text)screen.m_AlbumCardCount_L).text = GetCardCountText(screen.m_CardData_L); if (screen.m_IsTrading && screen.m_CardData_R != null) { screen.m_CardUI_R.SetCardUI(screen.m_CardData_R); screen.m_CardUI_Album.SetCardUI(screen.m_CardData_R); ((TMP_Text)screen.m_AlbumCardCount).text = GetCardCountText(screen.m_CardData_R); float cardMarketPrice = CPlayerData.GetCardMarketPrice(screen.m_CardData_R); string translation = LocalizationManager.GetTranslation("Market Price", true, 0, true, false, (GameObject)null, (string)null, true); ((TMP_Text)screen.m_MarketPrice_R).text = translation + " : " + GameInstance.GetPriceString(cardMarketPrice, false, true, false, "F2"); } } private string GetCardCountText(CardData card) { if (card.cardGrade <= 0) { return "X" + CPlayerData.GetCardAmount(card); } if (!CPlayerData.HasGradedCardInAlbum(card)) { return "X0"; } return "X1"; } } } namespace EnhancedPrefabLoader.Core.TODO { public static class Globals { public static class CardUI { public static readonly HashSet<string> TransformsToCache = new HashSet<string> { "MonsterMask", "CenterFrameMask", "Image", "CardBG", "DescriptionText", "PlayEffectText", "PlayEffectBG", "EvoText", "EvoPreviousStageIcon", "EvoNameText", "EvoBasicIcon", "EvoBorder", "CompanyText", "ArtistText", "StatGrp", "EvoBG", "StatText_1", "StatText_2", "StatText_3", "StatText_4", "NameTextGrp", "NumberTextGrp", "FirstEditionTextGrp", "CardBorder", "FoilGrp", "GlowMask", "CameraFoilShine (1)", "CameraFoilShine_Glitter", "RarityImage", "RarityText", "FirstEditionText", "NumberText", "NameText", "EvoBasicText", "CardFront" }; public const string CardMask = "CardMask"; } public static class Config { public static class UI { public static class CollectionBinder { public const string Category = "CollectionBinderUI"; } public const string Category = "UI"; public const string ExpansionSpacingX = "ExpansionSpacingX"; public const string ExpansionSpacingY = "ExpansionSpacingY"; public const string ExpansionButtonSize = "ExpansionButtonSize"; public const string RarityButtonSize = "RarityButtonSize"; public const string RaritySpacingX = "RaritySpacingX"; public const string RaritySpacingY = "RaritySpacingY"; } public static class GamePlay { public const string Category = "GamePlay"; public const string UseCustomExpForBase = "UseCustomExpForBase"; } } public static class CacheKeys { public const string ModID = "ModID"; public const string ModdedCardUI = "ModdedCardUI"; public const string CardBacks = "CardBacks"; public const string OriginalCardBack = "OriginalCardBack"; public const string TransformStateCache = "TransformStateCache"; } public static class DirectoryPatterns { public static readonly string SaveDirectory = Application.persistentDataPath + "/PrefabLoader"; public const string PrefabLoader = "*_prefabloader"; public const string FilePrefix = "file:///"; } public static class Materials { public const string ColorProperty = "_Color"; public static readonly Color DefaultColor = new Color(0.885f, 0.885f, 0.885f, 1f); } } } namespace EnhancedPrefabLoader.Core.Shops { internal class CustomShopScreen : RestockItemScreen, ICustomShopScreen { private TextMeshProUGUI? pageUrl; private Image? pageLogo; private Image? pageHeader; private Image? pageBackground; private Color originalHeaderColor; private Color originalBackgroundColor; private string displayName = string.Empty; private readonly List<string> pageUrls = new List<string>(3) { "cards", "accessories", "figurines" }; private List<List<RestockData>> pageItems = new List<List<RestockData>>(); private int currentPageIndex; public override void Awake() { //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Expected O, but got Unknown //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Expected O, but got Unknown //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Expected O, but got Unknown //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Expected O, but got Unknown //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Expected O, but got Unknown //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Expected O, but got Unknown //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Expected O, but got Unknown //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Expected O, but got Unknown //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Expected O, but got Unknown //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Expected O, but got Unknown //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Expected O, but got Unknown ((UIScreenBase)this).m_ScreenGroup = ((Component)((Component)this).transform.Find("ScreenGrp")).gameObject; ref RectTransform animGrp = ref ((GenericSliderScreen)this).m_AnimGrp; Transform obj = ((UIScreenBase)this).m_ScreenGroup.transform.Find("AnimGrp"); animGrp = (RectTransform)(object)((obj is RectTransform) ? obj : null); ((GenericSliderScreen)this).m_VerticalLayoutGrp = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteContent_Grp/ScrollerGrp"); ((GenericSliderScreen)this).m_VerticalLayout = ((Component)((GenericSliderScreen)this).m_VerticalLayoutGrp).GetComponent<VerticalLayoutGroup>(); ((GenericSliderScreen)this).m_SliderGrp = ((Component)((GenericSliderScreen)this).m_VerticalLayoutGrp).gameObject; ((GenericSliderScreen)this).m_ScrollEndComparer = ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("ScrollEndComparer")).gameObject; ((GenericSliderScreen)this).m_ScrollEndPos = ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("ScrollEnd")).gameObject; Transform obj2 = ((Component)this).transform.parent.Find("RestockItemAddToCartScreen"); base.m_RestockItemAddToCartScreen = ((obj2 != null) ? ((Component)obj2).GetComponent<RestockItemAddToCartScreen>() : null); Transform obj3 = ((Component)this).transform.parent.Find("RestockItemCheckoutScreen"); base.m_RestockItemCheckoutScreen = ((obj3 != null) ? ((Component)obj3).GetComponent<RestockItemCheckoutScreen>() : null); base.m_SortUIScreen = ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("SortingUIScreen")).GetComponent<UIScreenBase>(); base.m_RestockItemPanelUIList = new List<RestockItemPanelUI>(); base.m_PageButtonHighlightList = new List<GameObject>(4) { ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/PackBtn/AnimGrp/BGBarGrp/BGBlack")).gameObject, ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/AccessoriesBtn/AnimGrp/BGBarGrp/BGBlack")).gameObject, ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/FigurineBtn/AnimGrp/BGBarGrp/BGBlack")).gameObject, ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/AllBtn/AnimGrp/BGBarGrp/BGBlack")).gameObject }; base.m_SortBtnList = (from Transform t in (IEnumerable)((Component)base.m_SortUIScreen).transform.Find("Screen_Grp/AnimGrp/Mask/UIGroup") select ((Component)t).GetComponent<ControllerButton>()).ToList(); Transform val = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar"); Transform obj4 = val.Find("TotalPriceBG/TotalPrice"); base.m_TotalCostText = ((obj4 != null) ? ((Component)obj4).GetComponent<TextMeshProUGUI>() : null); base.m_CartNotification = ((Component)val.Find("NotificationGrp")).gameObject; Transform obj5 = base.m_CartNotification.transform.Find("NotificationText"); base.m_TotalCartItemCountText = ((obj5 != null) ? ((Component)obj5).GetComponent<TextMeshProUGUI>() : null); Button component = ((Component)val.Find("CheckoutBtn/BtnRaycast")).GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener(new UnityAction(base.OnPressCheckoutButton)); Button component2 = ((Component)val.Find("PackBtn/AnimGrp/BGBarGrp/BtnRaycast")).GetComponent<Button>(); component2.onClick = new ButtonClickedEvent(); ((UnityEvent)component2.onClick).AddListener((UnityAction)delegate { OnScreenSelection(0); }); Button component3 = ((Component)val.Find("AccessoriesBtn/AnimGrp/BGBarGrp/BtnRaycast")).GetComponent<Button>(); component3.onClick = new ButtonClickedEvent(); ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { OnScreenSelection(1); }); Button component4 = ((Component)val.Find("FigurineBtn/AnimGrp/BGBarGrp/BtnRaycast")).GetComponent<Button>(); component4.onClick = new ButtonClickedEvent(); ((UnityEvent)component4.onClick).AddListener((UnityAction)delegate { OnScreenSelection(2); }); Button component5 = ((Component)((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("TopWebBar/AddressBar/CloseBtn")).GetComponent<Button>(); component5.onClick = new ButtonClickedEvent(); ((UnityEvent)component5.onClick).AddListener(new UnityAction(((UIScreenBase)this).CloseScreen)); Button component6 = ((Component)val.Find("SortBtn/AnimGrp/BGBarGrp/BtnRaycast")).GetComponent<Button>(); component6.onClick = new ButtonClickedEvent(); ((UnityEvent)component6.onClick).AddListener(new UnityAction(base.OpenSortScreen)); Button component7 = ((Component)((Component)base.m_SortUIScreen).transform.Find("Screen_Grp/AnimGrp/CloseButton/ButtonArea")).GetComponent<Button>(); component7.onClick = new ButtonClickedEvent(); ((UnityEvent)component7.onClick).AddListener(new UnityAction(base.CloseSortScreen)); foreach (var item in ((IEnumerable)((Component)base.m_SortUIScreen).transform.Find("Screen_Grp/AnimGrp/Mask/UIGroup")).Cast<Transform>().Select((Transform t, int index) => (((Component)t.Find("AnimGrp/BGBarGrp/BtnRaycast")).GetComponent<Button>(), index))) { var (val2, index2) = item; val2.onClick = new ButtonClickedEvent(); ((UnityEvent)val2.onClick).AddListener((UnityAction)delegate { OnPressSortButton(index2); }); } for (int i = 1; i < ((GenericSliderScreen)this).m_VerticalLayoutGrp.childCount; i++) { Object.Destroy((Object)(object)((Component)((GenericSliderScreen)this).m_VerticalLayoutGrp.GetChild(i)).gameObject); } base.m_RestockItemPanelUIList.AddRange(from Transform t in (IEnumerable)((GenericSliderScreen)this).m_VerticalLayoutGrp.GetChild(0) select ((Component)t).GetComponent<RestockItemPanelUI>()); ((GenericSliderScreen)this).m_ScrollEndPosOffsetYAmount = 0f; ((GenericSliderScreen)this).m_MaximizePosY = -100f; ((GenericSliderScreen)this).m_ScrollSpeedMultiplier = 1f; ((GenericSliderScreen)this).m_GamepadJoystickSpeedMultiplier = 1f; ((GenericSliderScreen)this).m_MaxPosXClamp = 100000f; ((GenericSliderScreen)this).m_EvalSliderMaxOnOpen = true; ((GenericSliderScreen)this).m_ResetScrollPosOnOpen = true; ((UIScreenBase)this).m_CloseIfScreenOpened = true; ((RestockItemScreen)this).Awake(); } internal void SwapTo(CustomShopData shopData) { //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) displayName = shopData.AppDisplayName; pageItems = new List<List<RestockData>>(3) { shopData.TCG, shopData.Accessories, shopData.Figurines }; currentPageIndex = 0; Transform val = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar"); if (val != null) { if (pageLogo == null) { Transform obj = val.Find("Logo"); pageLogo = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); } Image? obj2 = pageLogo; if (obj2 != null) { StreamingAssetExtensions.SetSpriteAsync(obj2, shopData.SiteLogo); } if (pageHeader == null) { pageHeader = ((Component)val).GetComponent<Image>(); if ((Object)(object)pageHeader != (Object)null) { originalHeaderColor = ((Graphic)pageHeader).color; } } Image? obj3 = pageHeader; if (obj3 != null) { StreamingAssetExtensions.SetSpriteAsync(obj3, shopData.SiteHeader); } if ((Object)(object)pageHeader != (Object)null) { ((Graphic)pageHeader).color = ((shopData.SiteHeader != null) ? Color.white : originalHeaderColor); } } if (pageBackground == null) { Transform obj4 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("BG"); pageBackground = ((obj4 != null) ? ((Component)obj4).GetComponent<Image>() : null); if ((Object)(object)pageBackground != (Object)null) { originalBackgroundColor = ((Graphic)pageBackground).color; } } Image? obj5 = pageBackground; if (obj5 != null) { StreamingAssetExtensions.SetSpriteAsync(obj5, shopData.SiteBackground); } if ((Object)(object)pageBackground != (Object)null) { ((Graphic)pageBackground).color = ((shopData.SiteBackground != null) ? Color.white : originalBackgroundColor); } if (pageUrl == null) { Transform obj6 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("TopWebBar/AddressBar/AddressBarWhite/Text"); pageUrl = ((obj6 != null) ? ((Component)obj6).GetComponent<TextMeshProUGUI>() : null); } TextMeshProUGUI? obj7 = pageUrl; if (obj7 != null) { ((TMP_Text)obj7).text = "www." + displayName.ToLower().Replace(" ", "-") + ".com/shop/" + pageUrls[0]; } ((RestockItemScreen)this).EvaluateRestockItemPanelUI(0); ((GenericSliderScreen)this).m_PosX = 0f; ((GenericSliderScreen)this).m_LerpPosX = 0f; } public override void EvaluateRestockItemPanelUI(int _) { if (pageItems.Count == 0) { return; } List<int> sortedItems = GetSortedItems(); for (int i = 0; i < base.m_RestockItemPanelUIList.Count; i++) { if (i < sortedItems.Count) { base.m_RestockItemPanelUIList[i].Init((RestockItemScreen)(object)this, sortedItems[i]); ((UIElementBase)base.m_RestockItemPanelUIList[i]).SetActive(true); ((GenericSliderScreen)this).m_ScrollEndPosParent = ((Component)base.m_RestockItemPanelUIList[i]).gameObject; } else { ((UIElementBase)base.m_RestockItemPanelUIList[i]).SetActive(false); } } } internal void InitializeControllerExtension() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) ControllerScreenUIExtension component = ((Component)this).GetComponent<ControllerScreenUIExtension>(); if (component == null) { ModLogger.Warning("Unable to find the Controller script on custom shop. Likely broken due to a base game update.", "InitializeControllerExtension", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Shops\\CustomShopScreen.cs"); return; } component.m_ControllerBtnColumnList.Clear(); component.m_CtrlBtnXChangeMethodList.Clear(); List<ControllerBtnList> controllerBtnColumnList = component.m_ControllerBtnColumnList; ControllerBtnList item = default(ControllerBtnList); List<ControllerButton> list = new List<ControllerButton>(1); Transform obj = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("TopWebBar"); list.Add((obj != null) ? ((Component)obj).GetComponent<ControllerButton>() : null); item.rowList = list; controllerBtnColumnList.Add(item); component.m_CtrlBtnXChangeMethodList.Add((ECtrlBtnXChangeMethod)0); List<ControllerBtnList> controllerBtnColumnList2 = component.m_ControllerBtnColumnList; item = default(ControllerBtnList); List<ControllerButton> list2 = new List<ControllerButton>(5); Transform obj2 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/SortBtn"); list2.Add((obj2 != null) ? ((Component)obj2).GetComponent<ControllerButton>() : null); Transform obj3 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/PackBtn"); list2.Add((obj3 != null) ? ((Component)obj3).GetComponent<ControllerButton>() : null); Transform obj4 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/AccessoriesBtn"); list2.Add((obj4 != null) ? ((Component)obj4).GetComponent<ControllerButton>() : null); Transform obj5 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/FigurineBtn"); list2.Add((obj5 != null) ? ((Component)obj5).GetComponent<ControllerButton>() : null); Transform obj6 = ((Transform)((GenericSliderScreen)this).m_AnimGrp).Find("WebsiteTopBar/CheckoutBtn"); list2.Add((obj6 != null) ? ((Component)obj6).GetComponent<ControllerButton>() : null); item.rowList = list2; controllerBtnColumnList2.Add(item); component.m_CtrlBtnXChangeMethodList.Add((ECtrlBtnXChangeMethod)0); for (int i = 0; i < base.m_RestockItemPanelUIList.Count; i += 4) { item = default(ControllerBtnList); item.rowList = new List<ControllerButton>(); ControllerBtnList val = item; int num = Mathf.Min(4, base.m_RestockItemPanelUIList.Count - i); for (int j = 0; j < num; j++) { val.rowList.Add(((Component)base.m_RestockItemPanelUIList[i + j]).GetComponent<ControllerButton>()); } component.m_ControllerBtnColumnList.Add(val); component.m_CtrlBtnXChangeMethodList.Add((ECtrlBtnXChangeMethod)0); } } private void OnScreenSelection(int pageIndex) { if (pageIndex != currentPageIndex) { currentPageIndex = pageIndex; TextMeshProUGUI? obj = pageUrl; if (obj != null) { ((TMP_Text)obj).text = "www." + displayName.ToLower().Replace(" ", "-") + ".com/shop/" + pageUrls[pageIndex]; } ((RestockItemScreen)this).EvaluateRestockItemPanelUI(pageIndex); ((MonoBehaviour)this).StartCoroutine(((GenericSliderScreen)this).EvaluateActiveRestockUIScroller()); ((GenericSliderScreen)this).m_PosX = 0f; ((GenericSliderScreen)this).m_LerpPosX = 0f; } } private void OnPressSortButton(int index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) CPlayerData.m_RestockSortingType = (ERestockSortingType)index; ((RestockItemScreen)this).EvaluateRestockItemPanelUI(index); ((MonoBehaviour)this).StartCoroutine(((GenericSliderScreen)this).EvaluateActiveRestockUIScroller()); ((GenericSliderScreen)this).m_PosX = 0f; ((GenericSliderScreen)this).m_LerpPosX = 0f; ((RestockItemScreen)this).CloseSortScreen(); } private List<int> GetSortedItems() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected I4, but got Unknown int baseItemsCount = CSingleton<InventoryBase>.Instance.m_StockItemData_SO.m_RestockDataList.Count; List<RestockData> currentPageItems = pageItems[currentPageIndex]; IEnumerable<(ModRestockData, int)> source = from x in EplRuntimeData.Assets.ItemLibrary.RestockEntries.Select((ModRestockData entry, int index) => (entry, index + baseItemsCount)) where currentPageItems.Contains(x.entry.RestockData) select x; ERestockSortingType restockSortingType = CPlayerData.m_RestockSortingType; return (restockSortingType - 1) switch { 1 => (from x in source orderby x.entry.RestockData.licenseShopLevelRequired descending, x.entry.RestockData.name select x.index).ToList(), 0 => (from x in source orderby x.entry.RestockData.licenseShopLevelRequired, x.entry.RestockData.name select x.index).ToList(), 3 => (from x in source orderby GetItemCost(x.entry, x.index) descending, x.entry.RestockData.name select x.index).ToList(), 2 => (from x in source orderby GetItemCost(x.entry, x.index), x.entry.RestockData.name select x.index).ToList(), _ => (from x in source orderby x.entry.RestockData.licenseShopLevelRequired, x.entry.RestockData.name select x.index).ToList(), }; } private float GetItemCost(ModRestockData entry, int index) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!CPlayerData.GetIsItemLicenseUnlocked(index)) { return entry.RestockData.licensePrice; } return CPlayerData.GetItemCost(entry.RestockData.itemType) * (float)RestockManager.GetMaxItemCountInBox(entry.RestockData.itemType, entry.RestockData.isBigBox); } } internal class ShopInventoryManager { private bool IsFurnitureLoaded { get; set; } private bool IsItemsLoaded { get; set; } private bool IsDecoLoaded { get; set; } internal List<EItemType> CustomShopTcgItems { get; } = new List<EItemType>(); internal List<EItemType> CustomShopAccessoryItems { get; } = new List<EItemType>(); internal List<EItemType> CustomShopFigurineItems { get; } = new List<EItemType>(); internal List<EItemType> CustomShopBoardGameItems { get; } = new List<EItemType>(); internal void PopulateAllShopInventories() { AddFurnitureToInventory(); AddItemsToInventory(); AddDecoToInventory(); } private void AddFurnitureToInventory() { if (IsFurnitureLoaded) { return; } if (EplRuntimeData.Assets.FurnitureLibrary.FurnitureData.Count == 0) { ModLogger.Debug("No furniture to add to shop", "AddFurnitureToInventory", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Shops\\ShopInventoryManager.cs"); IsFurnitureLoaded = true; return; } foreach (ModFurniturePurchaseData value in EplRuntimeData.Assets.FurnitureLibrary.FurnitureData.Values) { for (int i = 0; i < CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_FurniturePurchaseDataList.Count; i++) { if (CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_FurniturePurchaseDataList[i].levelRequirement > value.BaseFurniturePurchaseData.levelRequirement) { CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_FurniturePurchaseDataList.Insert(i, value.BaseFurniturePurchaseData); CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_ObjectDataList.Insert(i, value.BaseObjectData); break; } } } IsFurnitureLoaded = true; } internal void AddItemsToInventory() { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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) if (IsItemsLoaded) { return; } if (EplRuntimeData.Assets.ItemLibrary.ItemData.Count == 0) { ModLogger.Debug("No items to add to shop", "AddItemsToInventory", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Shops\\ShopInventoryManager.cs"); IsItemsLoaded = true; return; } foreach (ModRestockData restockEntry in EplRuntimeData.Assets.ItemLibrary.RestockEntries) { if (!string.IsNullOrWhiteSpace(restockEntry.PhoneAppId) && EplRuntimeData.Assets.ShopLibrary.CustomShops.ContainsKey(restockEntry.PhoneAppId)) { if ((restockEntry.ItemFlags & ItemFlags.Accessory) != 0) { CustomShopAccessoryItems.Add(restockEntry.RestockData.itemType); } if ((restockEntry.ItemFlags & ItemFlags.BoardGame) != 0) { CustomShopBoardGameItems.Add(restockEntry.RestockData.itemType); } if ((restockEntry.ItemFlags & ItemFlags.Figurine) != 0) { CustomShopFigurineItems.Add(restockEntry.RestockData.itemType); } if ((restockEntry.ItemFlags & ItemFlags.TCG) != 0) { CustomShopTcgItems.Add(restockEntry.RestockData.itemType); } } else { if ((restockEntry.ItemFlags & ItemFlags.Accessory) != 0) { CSingleton<InventoryBase>.Instance.m_StockItemData_SO.m_ShownAccessoryItemType.Add(restockEntry.RestockData.itemType); } if ((restockEntry.ItemFlags & ItemFlags.BoardGame) != 0) { CSingleton<InventoryBase>.Instance.m_StockItemData_SO.m_ShownBoardGameItemType.Add(restockEntry.RestockData.itemType); } if ((restockEntry.ItemFlags & ItemFlags.Figurine) != 0) { CSingleton<InventoryBase>.Instance.m_StockItemData_SO.m_ShownFigurineItemType.Add(restockEntry.RestockData.itemType); } if ((restockEntry.ItemFlags & ItemFlags.TCG) != 0) { CSingleton<InventoryBase>.Instance.m_StockItemData_SO.m_ShownItemType.Add(restockEntry.RestockData.itemType); } } } IsItemsLoaded = true; } private void AddDecoToInventory() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Invalid comparison between Unknown and I4 //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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) if (IsDecoLoaded) { return; } if (EplRuntimeData.Assets.DecoLibrary.DecoObjectData.Count == 0) { ModLogger.Debug("No deco objects to add to shop", "AddDecoToInventory", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Shops\\ShopInventoryManager.cs"); } else { foreach (KeyValuePair<EDecoObject, ModDecoData> decoObjectDatum in EplRuntimeData.Assets.DecoLibrary.DecoObjectData) { CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_DecoPurchaseDataList.Add(decoObjectDatum.Value.BasePurchaseData); CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_DecoDataList.Add(decoObjectDatum.Value.BaseDecoData); EDecoType decoType = decoObjectDatum.Value.BaseDecoData.decoType; if ((int)decoType != 1 && (int)decoType != 0) { CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_OtherDecoList.Add(decoObjectDatum.Key); } if ((int)decoObjectDatum.Value.BaseDecoData.decoType == 1) { CSingleton<InventoryBase>.Instance.m_ObjectData_SO.m_PosterDecoList.Add(decoObjectDatum.Key); } } } if (EplRuntimeData.Assets.DecoLibrary.DecoWallTextureData.Count == 0) { ModLogger.Debug("No wall textures to add to shop", "AddDecoToInventory", "D:\\Projects\\EnhancedPrefabLoader\\EnhancedPrefabLoader.Core\\Shops\\ShopInventoryManager.cs"); } else { foreach (ModShopDecoData decoWallTextureDatum in EplRuntimeData.Assets.DecoLibrary.DecoWallTextureData) { DecoLibrary decoLibrary = EplRuntimeData.Assets.DecoLibr
BepInEx/plugins/EnhancedPrefabLoader/Scripts.dll
Decompiled 3 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Scripts")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0+cd7431ddc1ec5aac5b27bb4a89a6104e570aad10")] [assembly: AssemblyProduct("Scripts")] [assembly: AssemblyTitle("Scripts")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.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] [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; } } [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; } } } public class CeilingHangingInteractableObject : InteractableObject { public override void Update() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (!base.m_IsMovingObject) { return; } ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, base.m_TargetMoveObjectPosition, Time.deltaTime * 7.5f); bool flag = false; int mask = LayerMask.GetMask(new string[2] { "MoveStateBlockedArea", "Customer" }); if (Physics.OverlapBox(base.m_MoveStateValidArea.position, base.m_MoveStateValidArea.lossyScale / 2f, base.m_MoveStateValidArea.rotation, mask).Length == 0) { if (base.m_PlaceObjectInShopOnly) { if (Physics.OverlapBox(base.m_MoveStateValidArea.position, base.m_MoveStateValidArea.lossyScale / 2f, base.m_MoveStateValidArea.rotation, LayerMask.GetMask(new string[1] { "MoveStateValidArea" })).Length != 0) { flag = true; } } else if (base.m_PlaceObjectInShopOnly && Physics.OverlapBox(base.m_MoveStateValidArea.position, base.m_MoveStateValidArea.lossyScale / 2f, base.m_MoveStateValidArea.rotation, LayerMask.GetMask(new string[1] { "MoveStateValidWarehouseArea" })).Length != 0) { flag = true; } } base.m_IsMovingObjectValidState = flag; ShelfManager.SetMoveObjectPreviewModelValidState(flag); } public override void OnPlacedMovedObject() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) CSingleton<InteractionPlayerController>.Instance.OnExitMoveObjectMode(); base.m_IsMovingObject = false; ((Component)this).gameObject.layer = base.m_OriginalLayer; ((Collider)base.m_BoxCollider).enabled = true; for (int i = 0; i < base.m_BoxColliderList.Count; i++) { ((Collider)base.m_BoxColliderList[i]).enabled = true; } int mask = LayerMask.GetMask(new string[1] { "ShopModel" }); Vector3 position = ((Component)base.m_PickupObjectMesh).transform.position; position.y += 0.2f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(position, Vector3.up, ref val, 50f, mask)) { ((Component)this).transform.position = ((RaycastHit)(ref val)).point; } ((Component)base.m_MoveStateValidArea).gameObject.SetActive(true); ShelfManager.DisableMoveObjectPreviewMode(); if (Object.op_Implicit((Object)(object)base.m_BoxCollider)) { ((Component)CSingleton<ShelfManager>.Instance.m_MoveObjectCustomerBlocker).gameObject.SetActive(false); } if (!base.m_IsBoxedUp && Object.op_Implicit((Object)(object)base.m_InteractablePackagingBox_Shelf)) { if (Object.op_Implicit((Object)(object)base.m_Shelf_WorldUIGrp)) { ((Component)base.m_Shelf_WorldUIGrp).transform.position = ((Component)this).transform.position; } base.m_InteractablePackagingBox_Shelf.EmptyBoxShelf(); ((InteractableObject)base.m_InteractablePackagingBox_Shelf).OnDestroyed(); } if (Object.op_Implicit((Object)(object)base.m_Shelf_WorldUIGrp) && !base.m_IsBoxedUp) { ((Component)base.m_Shelf_WorldUIGrp).transform.position = ((Component)this).transform.position; ((Component)base.m_Shelf_WorldUIGrp).transform.rotation = ((Component)this).transform.rotation; } if (Object.op_Implicit((Object)(object)base.m_NavMeshCut)) { base.m_NavMeshCut.SetActive(false); base.m_NavMeshCut.SetActive(true); } } } namespace Scripts { public class CustomInteractableDeco : InteractableDecoration { public bool m_CanBePlacedOnFurniture; public bool m_IsDecorationCeiling; public override void Update() { if (((InteractableObject)this).m_IsMovingObject) { UpdatePosition(); bool isMovingObjectValidState = (((InteractableObject)this).m_IsDecorationVertical ? IsValidWallPlacement() : (m_IsDecorationCeiling ? IsValidCeilingPlacement() : IsValidFloorOrFurniturePlacement())); ((InteractableObject)this).m_IsMovingObjectValidState = isMovingObjectValidState; ShelfManager.SetMoveObjectPreviewModelValidState(((InteractableObject)this).m_IsMovingObjectValidState); } } public override void OnPlacedMovedObject() { //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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) CSingleton<InteractionPlayerController>.Instance.OnExitMoveObjectMode(); ((Component)((InteractableObject)this).m_MoveStateValidArea).gameObject.SetActive(true); ((Component)this).gameObject.layer = ((InteractableObject)this).m_OriginalLayer; ((InteractableObject)this).m_IsMovingObject = false; if (((InteractableObject)this).m_BoxCollider != null) { ((Component)CSingleton<ShelfManager>.Instance.m_MoveObjectCustomerBlocker).gameObject.SetActive(false); ((Collider)((InteractableObject)this).m_BoxCollider).enabled = true; } foreach (BoxCollider boxCollider in ((InteractableObject)this).m_BoxColliderList) { ((Collider)boxCollider).enabled = true; } if (!m_CanBePlacedOnFurniture && !m_IsDecorationCeiling && !((InteractableObject)this).m_IsDecorationVertical) { Vector3 position = ((Component)this).transform.position; position.y = 0f; ((Component)this).transform.position = position; } else if (m_IsDecorationCeiling) { Vector3 position2 = ((Component)this).transform.position; Bounds bounds = ((Collider)((InteractableObject)this).m_BoxCollider).bounds; position2.y = 3f - (((Bounds)(ref bounds)).max.y - ((Component)this).transform.position.y); ((Component)this).transform.position = position2; } else if (((InteractableObject)this).m_IsDecorationVertical && ((InteractableObject)this).m_LastHitTransform != null) { ((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker = null; DecoBlocker component = ((Component)((InteractableObject)this).m_LastHitTransform).GetComponent<DecoBlocker>(); if (component != null) { ((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker = component.m_LockedRoomBlocker; ((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker.AddToVerticalDecoObjectList((InteractableObject)(object)this); if (((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker.m_MainRoomIndex != -1) { ((InteractableObject)this).m_IsVerticalSnapToWarehouseWall = false; ((InteractableObject)this).m_VerticalSnapWallIndex = ((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker.m_MainRoomIndex; } else if (((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker.m_StoreRoomIndex != -1) { ((InteractableObject)this).m_IsVerticalSnapToWarehouseWall = true; ((InteractableObject)this).m_VerticalSnapWallIndex = ((InteractableObject)this).m_DecoPlaccedLockedRoomBlocker.m_StoreRoomIndex; } } } ShelfManager.DisableMoveObjectPreviewMode(); if (!((InteractableObject)this).m_IsBoxedUp && ((InteractableObject)this).m_InteractablePackagingBox_Shelf != null) { if (((InteractableObject)this).m_Shelf_WorldUIGrp != null) { ((Component)((InteractableObject)this).m_Shelf_WorldUIGrp).transform.position = ((Component)this).transform.position; } ((InteractableObject)this).m_InteractablePackagingBox_Shelf.EmptyBoxShelf(); ((InteractableObject)((InteractableObject)this).m_InteractablePackagingBox_Shelf).OnDestroyed(); } if (((InteractableObject)this).m_Shelf_WorldUIGrp != null && !((InteractableObject)this).m_IsBoxedUp) { ((Component)((InteractableObject)this).m_Shelf_WorldUIGrp).transform.position = ((Component)this).transform.position; ((Component)((InteractableObject)this).m_Shelf_WorldUIGrp).transform.rotation = ((Component)this).transform.rotation; } if (((InteractableObject)this).m_NavMeshCut != null) { ((InteractableObject)this).m_NavMeshCut.SetActive(false); ((InteractableObject)this).m_NavMeshCut.SetActive(true); } } private void UpdatePosition() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, ((InteractableObject)this).m_TargetMoveObjectPosition, Time.deltaTime * 7.5f); if (m_IsDecorationCeiling) { float y = ((Component)this).transform.position.y; Bounds bounds = ((Collider)((InteractableObject)this).m_BoxCollider).bounds; if (y + (((Bounds)(ref bounds)).max.y - ((Component)this).transform.position.y) > 3f) { Vector3 position = ((Component)this).transform.position; bounds = ((Collider)((InteractableObject)this).m_BoxCollider).bounds; position.y = 3f - (((Bounds)(ref bounds)).max.y - ((Component)this).transform.position.y); ((Component)this).transform.position = position; } } else if (((InteractableObject)this).m_IsDecorationVertical && ((InteractableObject)this).m_LastHitTransform != null) { Quaternion rotation = Quaternion.FromToRotation(Vector3.forward, ((InteractableObject)this).m_HitNormal); Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; eulerAngles.x = 0f; Quaternion rotation2 = ((Component)this).transform.rotation; eulerAngles.z = ((Quaternion)(ref rotation2)).eulerAngles.z; if (((InteractableObject)this).m_IsFlipped) { eulerAngles.y += 180f; } ((Quaternion)(ref rotation)).eulerAngles = eulerAngles; ((Component)this).transform.rotation = rotation; } } private bool IsValidFloorOrFurniturePlacement() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (GetCollisions("MoveStateBlockedArea", "Customer").Length != 0) { return false; } if (((InteractableObject)this).m_PlaceObjectInShopOnly && GetCollisions("MoveStateValidArea").Length == 0) { return false; } if (((InteractableObject)this).m_PlaceObjectInWarehouseOnly && GetCollisions("MoveStateValidWarehouseArea").Length == 0) { return false; } if (m_CanBePlacedOnFurniture) { Bounds bounds = ((Collider)((InteractableObject)this).m_BoxCollider).bounds; Vector3 center = ((Bounds)(ref bounds)).center; bounds = ((Collider)((InteractableObject)this).m_BoxCollider).bounds; center.y = ((Bounds)(ref bounds)).min.y; RaycastHit val = default(RaycastHit); if (Physics.Raycast(center, Vector3.down, ref val, 0.1f) && ((RaycastHit)(ref val)).normal.y > 0.9f) { return true; } } return ((Component)this).transform.position.y <= 0.1f; } private bool IsValidCeilingPlacement() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = ((Collider)((InteractableObject)this).m_BoxCollider).bounds; float num = ((Bounds)(ref bounds)).max.y - ((Component)this).transform.position.y; float num2 = 3.1f - num; if (((Component)this).transform.position.y < num2 && ((Component)this).transform.position.y > num2 - 0.2f) { return GetCollisions("MoveStateValidArea", "MoveStateValidWarehouseArea").Length != 0; } return false; } private bool IsValidWallPlacement() { //IL_0001: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((InteractableObject)this).m_TargetMoveObjectPosition - ((Component)this).transform.position; if (((Vector3)(ref val)).magnitude <= 0.02f && ((Component)this).transform.position.y >= 0.1f) { Collider[] collisions = GetCollisions("DecorationBlocker"); if (collisions.Length != 0 && GetCollisions("DecorationMoveStateBlockedArea").Length == 0) { ((InteractableObject)this).m_LastHitTransform = ((Component)collisions[0]).transform; return true; } } ((InteractableObject)this).m_LastHitTransform = null; return false; } private Collider[] GetCollisions(params string[] layers) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) int mask = LayerMask.GetMask(layers); return Physics.OverlapBox(((InteractableObject)this).m_MoveStateValidArea.position, ((InteractableObject)this).m_MoveStateValidArea.lossyScale / 2f, ((InteractableObject)this).m_MoveStateValidArea.rotation, mask); } } public class CustomInteractableObject : InteractableObject { public override void Awake() { } public override void Update() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (!base.m_IsMovingObject) { return; } ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, base.m_TargetMoveObjectPosition, Time.deltaTime * 7.5f); bool flag = false; int mask = LayerMask.GetMask(new string[2] { "MoveStateBlockedArea", "Customer" }); if (Physics.OverlapBox(base.m_MoveStateValidArea.position, base.m_MoveStateValidArea.lossyScale / 2f, base.m_MoveStateValidArea.rotation, mask).Length == 0) { if (base.m_PlaceObjectInShopOnly) { if (Physics.OverlapBox(base.m_MoveStateValidArea.position, base.m_MoveStateValidArea.lossyScale / 2f, base.m_MoveStateValidArea.rotation, LayerMask.GetMask(new string[1] { "MoveStateValidArea" })).Length != 0) { flag = true; } } else if (base.m_PlaceObjectInWarehouseOnly && Physics.OverlapBox(base.m_MoveStateValidArea.position, base.m_MoveStateValidArea.lossyScale / 2f, base.m_MoveStateValidArea.rotation, LayerMask.GetMask(new string[1] { "MoveStateValidWarehouseArea" })).Length != 0) { flag = true; } } base.m_IsMovingObjectValidState = flag; ShelfManager.SetMoveObjectPreviewModelValidState(flag); } public override void OnPlacedMovedObject() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) CSingleton<InteractionPlayerController>.Instance.OnExitMoveObjectMode(); base.m_IsMovingObject = false; ((Component)this).gameObject.layer = base.m_OriginalLayer; ((Collider)base.m_BoxCollider).enabled = true; for (int i = 0; i < base.m_BoxColliderList.Count; i++) { ((Collider)base.m_BoxColliderList[i]).enabled = true; } int mask = LayerMask.GetMask(new string[1] { "ShopModel" }); Vector3 position = ((Component)base.m_PickupObjectMesh).transform.position; position.y += 0.2f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(position, Vector3.down, ref val, 100f, mask)) { ((Component)this).transform.position = ((RaycastHit)(ref val)).point; } ((Component)base.m_MoveStateValidArea).gameObject.SetActive(true); ShelfManager.DisableMoveObjectPreviewMode(); if (Object.op_Implicit((Object)(object)base.m_BoxCollider)) { ((Component)CSingleton<ShelfManager>.Instance.m_MoveObjectCustomerBlocker).gameObject.SetActive(false); } if (!base.m_IsBoxedUp && Object.op_Implicit((Object)(object)base.m_InteractablePackagingBox_Shelf)) { if (Object.op_Implicit((Object)(object)base.m_Shelf_WorldUIGrp)) { ((Component)base.m_Shelf_WorldUIGrp).transform.position = ((Component)this).transform.position; } base.m_InteractablePackagingBox_Shelf.EmptyBoxShelf(); ((InteractableObject)base.m_InteractablePackagingBox_Shelf).OnDestroyed(); } if (Object.op_Implicit((Object)(object)base.m_Shelf_WorldUIGrp) && !base.m_IsBoxedUp) { ((Component)base.m_Shelf_WorldUIGrp).transform.position = ((Component)this).transform.position; ((Component)base.m_Shelf_WorldUIGrp).transform.rotation = ((Component)this).transform.rotation; } if (Object.op_Implicit((Object)(object)base.m_NavMeshCut)) { base.m_NavMeshCut.SetActive(false); base.m_NavMeshCut.SetActive(true); } } } public class VideoPlayerController : MonoBehaviour { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ErrorEventHandler <>9__9_1; internal void <Start>b__9_1(VideoPlayer source, string error) { Debug.Log((object)error); } } public bool m_StopOnPickupObject; public AudioSource m_AudioSource; public VideoPlayer m_VideoPlayer; public InteractableObject m_InteractableObject; private bool isPrepared; private InteractableObject InteractableObject { get { if (m_InteractableObject == null) { m_InteractableObject = ((Component)this).GetComponentInParent<InteractableObject>(); } return m_InteractableObject; } } private VideoPlayer VideoPlayer { get { if (m_VideoPlayer == null) { m_VideoPlayer = ((Component)this).gameObject.GetComponent<VideoPlayer>(); } return m_VideoPlayer; } } public void Start() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //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) //IL_0050: Expected O, but got Unknown if (m_AudioSource != null) { VideoPlayer.audioOutputMode = (VideoAudioOutputMode)1; } VideoPlayer.prepareCompleted += (EventHandler)delegate(VideoPlayer player) { if (player.audioTrackCount > 0) { player.SetTargetAudioSource((ushort)0, m_AudioSource); } else { Debug.LogWarning((object)"Video has no audio tracks!"); } isPrepared = true; }; VideoPlayer videoPlayer = VideoPlayer; object obj = <>c.<>9__9_1; if (obj == null) { ErrorEventHandler val = delegate(VideoPlayer source, string error) { Debug.Log((object)error); }; <>c.<>9__9_1 = val; obj = (object)val; } videoPlayer.errorReceived += (ErrorEventHandler)obj; VideoPlayer.Prepare(); } public void Update() { if (isPrepared) { if (InteractableObject.GetIsBoxedUp() && VideoPlayer.isPlaying) { VideoPlayer.Stop(); } if (InteractableObject.GetIsMovingObject() && m_StopOnPickupObject && VideoPlayer.isPlaying) { VideoPlayer.Stop(); } if (!InteractableObject.GetIsMovingObject() && !InteractableObject.GetIsBoxedUp() && !VideoPlayer.isPlaying) { VideoPlayer.Play(); } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Scripts"; public const string PLUGIN_NAME = "Scripts"; public const string PLUGIN_VERSION = "6.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }