Decompiled source of ServersideQoL v0.2.13
Valheim.ServersideQoL.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using Valheim.ServersideQoL.Processors; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Valheim.ServersideQoL")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.13.0")] [assembly: AssemblyInformationalVersion("0.2.13+dd2f7a3e5d90ab7229c4f1667cc74aab9317228b")] [assembly: AssemblyProduct("Valheim.ServersideQoL")] [assembly: AssemblyTitle("Valheim.ServersideQoL")] [assembly: AssemblyVersion("0.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] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } [EditorBrowsable(EditorBrowsableState.Never)] internal static class IsExternalInit { } } namespace Valheim.ServersideQoL { internal sealed class ConcurrentHashSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyCollection<T> where T : notnull { private readonly ConcurrentDictionary<T, object?> _dict = new ConcurrentDictionary<T, object>(); public int Count => _dict.Count; bool ICollection<T>.IsReadOnly => false; public bool Add(T value) { return _dict.TryAdd(value, null); } public bool Remove(T value) { object value2; return _dict.TryRemove(value, out value2); } void ICollection<T>.Add(T item) { if (!Add(item)) { throw new InvalidOperationException(); } } public void Clear() { _dict.Clear(); } public bool Contains(T item) { return _dict.ContainsKey(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { throw new NotImplementedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return _dict.Keys.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _dict.Keys.GetEnumerator(); } } internal static class EnumUtils { private static class Generic<T> where T : unmanaged, Enum { public static bool IsBitSet { get; } = OfType(typeof(T)).IsBitSet; public static Func<T, ulong> EnumToUInt64 { get; } public static Func<ulong, T> UInt64ToEnum { get; } public static Func<T, long> EnumToInt64 { get; } public static Func<long, T> Int64ToEnum { get; } static Generic() { ParameterExpression parameterExpression = Expression.Parameter(typeof(T)); EnumToUInt64 = Expression.Lambda<Func<T, ulong>>(Expression.ConvertChecked(parameterExpression, typeof(ulong)), new ParameterExpression[1] { parameterExpression }).Compile(); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ulong)); UInt64ToEnum = Expression.Lambda<Func<ulong, T>>(Expression.ConvertChecked(parameterExpression2, typeof(T)), new ParameterExpression[1] { parameterExpression2 }).Compile(); ParameterExpression parameterExpression3 = Expression.Parameter(typeof(T)); EnumToInt64 = Expression.Lambda<Func<T, long>>(Expression.ConvertChecked(parameterExpression3, typeof(long)), new ParameterExpression[1] { parameterExpression3 }).Compile(); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(long)); Int64ToEnum = Expression.Lambda<Func<long, T>>(Expression.ConvertChecked(parameterExpression4, typeof(T)), new ParameterExpression[1] { parameterExpression4 }).Compile(); } } public sealed class ObjectEnumUtils { public bool IsBitSet { get; } = enumType.GetCustomAttribute<FlagsAttribute>() != null; public Func<object, ulong> EnumToUInt64 { get; } public Func<ulong, object> UInt64ToEnum { get; } public Func<object, long> EnumToInt64 { get; } public Func<long, object> Int64ToEnum { get; } public ObjectEnumUtils(Type enumType) { ParameterExpression parameterExpression = Expression.Parameter(typeof(object)); EnumToUInt64 = Expression.Lambda<Func<object, ulong>>(Expression.ConvertChecked(Expression.Convert(parameterExpression, enumType), typeof(ulong)), new ParameterExpression[1] { parameterExpression }).Compile(); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ulong)); UInt64ToEnum = Expression.Lambda<Func<ulong, object>>(Expression.Convert(Expression.ConvertChecked(parameterExpression2, enumType), typeof(object)), new ParameterExpression[1] { parameterExpression2 }).Compile(); ParameterExpression parameterExpression3 = Expression.Parameter(typeof(object)); EnumToInt64 = Expression.Lambda<Func<object, long>>(Expression.ConvertChecked(Expression.Convert(parameterExpression3, enumType), typeof(long)), new ParameterExpression[1] { parameterExpression3 }).Compile(); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(long)); Int64ToEnum = Expression.Lambda<Func<long, object>>(Expression.Convert(Expression.ConvertChecked(parameterExpression4, enumType), typeof(object)), new ParameterExpression[1] { parameterExpression4 }).Compile(); base..ctor(); } } private static readonly ConcurrentDictionary<Type, ObjectEnumUtils> __isBitSet = new ConcurrentDictionary<Type, ObjectEnumUtils>(); public static ObjectEnumUtils OfType(Type type) { return __isBitSet.GetOrAdd(type, (Type t) => new ObjectEnumUtils(t)); } public static bool IsBitSet<T>() where T : unmanaged, Enum { return Generic<T>.IsBitSet; } public static ulong ToUInt64<T>(this T value) where T : unmanaged, Enum { return Generic<T>.EnumToUInt64(value); } public static T ToEnum<T>(ulong value) where T : unmanaged, Enum { return Generic<T>.UInt64ToEnum(value); } public static long ToInt64<T>(this T value) where T : unmanaged, Enum { return Generic<T>.EnumToInt64(value); } public static T ToEnum<T>(long value) where T : unmanaged, Enum { return Generic<T>.Int64ToEnum(value); } } internal interface IZDOInventory { Inventory Inventory { get; } IList<ItemData> Items { get; } void Save(); } internal sealed class ExtendedZDO : ZDO { public readonly struct ZDOVars_ { private readonly ExtendedZDO _zdo; public ZDOVars_(ExtendedZDO zdo) { _zdo = zdo; } public int GetState(int defaultValue = 0) { return ((ZDO)_zdo).GetInt(ZDOVars.s_state, defaultValue); } public void SetState(int value) { ((ZDO)_zdo).Set(ZDOVars.s_state, value, false); } public long GetCreator(long defaultValue = 0L) { return ((ZDO)_zdo).GetLong(ZDOVars.s_creator, defaultValue); } public void SetCreator(long value) { ((ZDO)_zdo).Set(ZDOVars.s_creator, value); } public bool GetInUse(bool defaultValue = false) { return ((ZDO)_zdo).GetBool(ZDOVars.s_inUse, defaultValue); } public void SetInUse(bool value) { ((ZDO)_zdo).Set(ZDOVars.s_inUse, value); } public float GetFuel(float defaultValue = 0f) { return ((ZDO)_zdo).GetFloat(ZDOVars.s_fuel, defaultValue); } public void SetFuel(float value) { ((ZDO)_zdo).Set(ZDOVars.s_fuel, value); } public bool GetPiece(bool defaultValue = false) { return ((ZDO)_zdo).GetBool(ZDOVars.s_piece, defaultValue); } public void SetPiece(bool value) { ((ZDO)_zdo).Set(ZDOVars.s_piece, value); } public string GetItems(string defaultValue = "") { return ((ZDO)_zdo).GetString(ZDOVars.s_items, defaultValue); } public void SetItems(string value) { ((ZDO)_zdo).Set(ZDOVars.s_items, value); } public string GetTag(string defaultValue = "") { return ((ZDO)_zdo).GetString(ZDOVars.s_tag, defaultValue); } public void SetTag(string value) { ((ZDO)_zdo).Set(ZDOVars.s_tag, value); } public byte[]? GetData(byte[]? defaultValue = null) { return ((ZDO)_zdo).GetByteArray(ZDOVars.s_data, defaultValue); } public void SetData(byte[]? value) { ((ZDO)_zdo).Set(ZDOVars.s_data, value); } public float GetStamina(float defaultValue = 0f) { return ((ZDO)_zdo).GetFloat(ZDOVars.s_stamina, defaultValue); } public void SetStamina(float value) { ((ZDO)_zdo).Set(ZDOVars.s_stamina, value); } public long GetPlayerID(long defaultValue = 0L) { return ((ZDO)_zdo).GetLong(ZDOVars.s_playerID, defaultValue); } public void SetPlayerID(long value) { ((ZDO)_zdo).Set(ZDOVars.s_playerID, value); } public string GetPlayerName(string defaultValue = "") { return ((ZDO)_zdo).GetString(ZDOVars.s_playerName, defaultValue); } public void SetPlayerName(string value) { ((ZDO)_zdo).Set(ZDOVars.s_playerName, value); } public string GetFollow(string defaultValue = "") { return ((ZDO)_zdo).GetString(ZDOVars.s_follow, defaultValue); } public void SetFollow(string value) { ((ZDO)_zdo).Set(ZDOVars.s_follow, value); } public int GetRightItem(int defaultValue = 0) { return ((ZDO)_zdo).GetInt(ZDOVars.s_rightItem, defaultValue); } public void SetRightItem(int value) { ((ZDO)_zdo).Set(ZDOVars.s_rightItem, value, false); } public string GetText(string defaultValue = "") { return ((ZDO)_zdo).GetString(ZDOVars.s_text, defaultValue); } public void SetText(string value) { ((ZDO)_zdo).Set(ZDOVars.s_text, value); } public string GetItem(int idx, string defaultValue = "") { return ((ZDO)_zdo).GetString(FormattableString.Invariant($"item{idx}"), defaultValue); } public void SetItem(int idx, string value) { ((ZDO)_zdo).Set(FormattableString.Invariant($"item{idx}"), value); } public int GetQueued(int defaultValue = 0) { return ((ZDO)_zdo).GetInt(ZDOVars.s_queued, defaultValue); } public void SetQueued(int value) { ((ZDO)_zdo).Set(ZDOVars.s_queued, value, false); } public bool GetTamed(bool defaultValue = false) { return ((ZDO)_zdo).GetBool(ZDOVars.s_tamed, defaultValue); } public void SetTamed(bool value) { ((ZDO)_zdo).Set(ZDOVars.s_tamed, value); } public float GetTameTimeLeft(float defaultValue = 0f) { return ((ZDO)_zdo).GetFloat(ZDOVars.s_tameTimeLeft, defaultValue); } public void SetTameTimeLeft(float value) { ((ZDO)_zdo).Set(ZDOVars.s_tameTimeLeft, value); } public int GetAmmo(int defaultValue = 0) { return ((ZDO)_zdo).GetInt(ZDOVars.s_ammo, defaultValue); } public void SetAmmo(int value) { ((ZDO)_zdo).Set(ZDOVars.s_ammo, value, false); } public string GetAmmoType(string defaultValue = "") { return ((ZDO)_zdo).GetString(ZDOVars.s_ammoType, defaultValue); } public void SetAmmoType(string value) { ((ZDO)_zdo).Set(ZDOVars.s_ammoType, value); } public float GetGrowStart(float defaultValue = 0f) { return ((ZDO)_zdo).GetFloat(ZDOVars.s_growStart, defaultValue); } public void SetGrowStart(float value) { ((ZDO)_zdo).Set(ZDOVars.s_growStart, value); } public DateTime GetSpawnTime(DateTime defaultValue = default(DateTime)) { return new DateTime(((ZDO)_zdo).GetLong(ZDOVars.s_spawnTime, defaultValue.Ticks)); } public void SetSpawnTime(DateTime value) { ((ZDO)_zdo).Set(ZDOVars.s_spawnTime, value.Ticks); } public float GetHealth(float defaultValue = 0f) { return ((ZDO)_zdo).GetFloat(ZDOVars.s_health, defaultValue); } public void SetHealth(float value) { ((ZDO)_zdo).Set(ZDOVars.s_health, value); } public int GetPermitted(int defaultValue = 0) { return ((ZDO)_zdo).GetInt(ZDOVars.s_permitted, defaultValue); } public void SetPermitted(int value) { ((ZDO)_zdo).Set(ZDOVars.s_permitted, value, false); } } private sealed class AdditionalData_ { private static ConcurrentDictionary<int, IReadOnlyList<Processor>> _processors = new ConcurrentDictionary<int, IReadOnlyList<Processor>>(); public IReadOnlyList<Processor> Processors { get; private set; } = Processor.DefaultProcessors; public PrefabInfo PrefabInfo { get; } public ConcurrentDictionary<Type, object>? ComponentFieldAccessors { get; set; } public Dictionary<Processor, uint>? ProcessorDataRevisions { get; set; } public ZDOInventory? Inventory { get; set; } public bool? HasFields { get; set; } public static AdditionalData_ Dummy { get; } = new AdditionalData_(Valheim.ServersideQoL.PrefabInfo.Dummy); public AdditionalData_(PrefabInfo prefabInfo) { PrefabInfo = prefabInfo; base..ctor(); } public void Ungregister(IEnumerable<Processor> processors) { IEnumerable<Processor> processors2 = processors; int num = 0; foreach (Processor processor in Processors) { if (!processors2.Any((Processor x) => x == processor)) { num = (num, processor.GetType()).GetHashCode(); } } Processors = _processors.GetOrAdd(num, (int _) => Processors.Where((Processor x) => !processors2.Any((Processor y) => x == y)).ToList()); foreach (Processor item in processors2) { ProcessorDataRevisions?.Remove(item); } } public void ReregisterAll() { Processors = Processor.DefaultProcessors; } } public sealed class ComponentFieldAccessor<TComponent> { private readonly ExtendedZDO _zdo; private readonly TComponent _component; private bool? _hasComponentFields; private static readonly int __hasComponentFieldsHash = StringExtensionMethods.GetStableHashCode(FormattableString.Invariant(FormattableStringFactory.Create("{0}{1}", "HasFields", typeof(TComponent).Name))); private bool HasFields { get { if (_zdo.HasFields) { bool valueOrDefault = _hasComponentFields.GetValueOrDefault(); if (!_hasComponentFields.HasValue) { valueOrDefault = ((ZDO)_zdo).GetBool(__hasComponentFieldsHash, false); _hasComponentFields = valueOrDefault; return valueOrDefault; } return valueOrDefault; } return false; } } public ComponentFieldAccessor(ExtendedZDO zdo, TComponent component) { _zdo = zdo; _component = component; base..ctor(); } private void SetHasFields(bool value) { if (value && !_zdo.HasFields) { _zdo.SetHasFields(); } if (_hasComponentFields != value) { ExtendedZDO zdo = _zdo; int _hasComponentFieldsHash = __hasComponentFieldsHash; bool? flag = (_hasComponentFields = value); ((ZDO)zdo).Set(_hasComponentFieldsHash, flag.Value); } } private static int GetHash<T>(Expression<Func<TComponent, T>> fieldExpression, out FieldInfo field) { MemberExpression memberExpression = (MemberExpression)fieldExpression.Body; field = (FieldInfo)memberExpression.Member; return StringExtensionMethods.GetStableHashCode(FormattableString.Invariant($"{typeof(TComponent).Name}.{field.Name}")); } private T Get<T>(Expression<Func<TComponent, T>> fieldExpression, Func<ZDO, int, T?, T> getter) { MemberExpression memberExpression = (MemberExpression)fieldExpression.Body; FieldInfo fieldInfo = (FieldInfo)memberExpression.Member; if (!HasFields) { return (T)fieldInfo.GetValue(_component); } int stableHashCode = StringExtensionMethods.GetStableHashCode(FormattableString.Invariant($"{typeof(TComponent).Name}.{fieldInfo.Name}")); return getter((ZDO)(object)_zdo, stableHashCode, (T)fieldInfo.GetValue(_component)); } public bool GetBool(Expression<Func<TComponent, bool>> fieldExpression) { return Get(fieldExpression, (ZDO zdo, int hash, bool defaultValue) => zdo.GetBool(hash, defaultValue)); } public float GetFloat(Expression<Func<TComponent, float>> fieldExpression) { return Get(fieldExpression, (ZDO zdo, int hash, float defaultValue) => zdo.GetFloat(hash, defaultValue)); } public int GetInt(Expression<Func<TComponent, int>> fieldExpression) { return Get(fieldExpression, (ZDO zdo, int hash, int defaultValue) => zdo.GetInt(hash, defaultValue)); } public string GetString(Expression<Func<TComponent, string>> fieldExpression) { return Get(fieldExpression, (ZDO zdo, int hash, string? defaultValue) => zdo.GetString(hash, defaultValue)); } private ComponentFieldAccessor<TComponent> SetCore<T>(Expression<Func<TComponent, T>> fieldExpression, T value, Action<ZDO, int>? remover, Action<ZDO, int, T> setter) where T : notnull { FieldInfo field; int hash = GetHash(fieldExpression, out field); if (remover != null) { ref T reference = ref value; T val = default(T); if (val == null) { val = reference; reference = ref val; } if (reference.Equals(field.GetValue(_component))) { remover((ZDO)(object)_zdo, hash); goto IL_0071; } } if (!HasFields) { SetHasFields(value: true); } setter((ZDO)(object)_zdo, hash, value); goto IL_0071; IL_0071: return this; } public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, bool>> fieldExpression, bool value) { return SetCore(fieldExpression, value, delegate(ZDO zdo, int hash) { zdo.RemoveInt(hash); }, delegate(ZDO zdo, int hash, bool value) { zdo.Set(hash, value); }); } public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, float>> fieldExpression, float value) { return SetCore(fieldExpression, value, delegate(ZDO zdo, int hash) { zdo.RemoveFloat(hash); }, delegate(ZDO zdo, int hash, float value) { zdo.Set(hash, value); }); } public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, int>> fieldExpression, int value) { return SetCore(fieldExpression, value, delegate(ZDO zdo, int hash) { zdo.RemoveInt(hash); }, delegate(ZDO zdo, int hash, int value) { zdo.Set(hash, value, false); }); } public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, string>> fieldExpression, string value) { return SetCore(fieldExpression, value, null, delegate(ZDO zdo, int hash, string value) { zdo.Set(hash, value); }); } private bool SetIfChangedCore<T>(Expression<Func<TComponent, T>> fieldExpression, T value, Action<ZDO, int>? remover, Action<ZDO, int, T> setter, Func<ZDO, int, T?, T> getter) where T : notnull { FieldInfo field; int hash = GetHash(fieldExpression, out field); T val = (T)field.GetValue(_component); ref T reference = ref value; T val2 = default(T); if (val2 == null) { val2 = reference; reference = ref val2; } if (reference.Equals(getter((ZDO)(object)_zdo, hash, val))) { return false; } if (remover != null && value.Equals(val)) { remover((ZDO)(object)_zdo, hash); } else { if (!HasFields) { SetHasFields(value: true); } setter((ZDO)(object)_zdo, hash, value); } return true; } public bool SetIfChanged(Expression<Func<TComponent, bool>> fieldExpression, bool value) { return SetIfChangedCore(fieldExpression, value, delegate(ZDO zdo, int hash) { zdo.RemoveInt(hash); }, delegate(ZDO zdo, int hash, bool value) { zdo.Set(hash, value); }, (ZDO zdo, int hash, bool defaultValue) => zdo.GetBool(hash, defaultValue)); } public bool SetIfChanged(Expression<Func<TComponent, float>> fieldExpression, float value) { return SetIfChangedCore(fieldExpression, value, delegate(ZDO zdo, int hash) { zdo.RemoveFloat(hash); }, delegate(ZDO zdo, int hash, float value) { zdo.Set(hash, value); }, (ZDO zdo, int hash, float defaultValue) => zdo.GetFloat(hash, defaultValue)); } public bool SetIfChanged(Expression<Func<TComponent, int>> fieldExpression, int value) { return SetIfChangedCore(fieldExpression, value, delegate(ZDO zdo, int hash) { zdo.RemoveInt(hash); }, delegate(ZDO zdo, int hash, int value) { zdo.Set(hash, value, false); }, (ZDO zdo, int hash, int defaultValue) => zdo.GetInt(hash, defaultValue)); } public bool SetIfChanged(Expression<Func<TComponent, string>> fieldExpression, string value) { return SetIfChangedCore(fieldExpression, value, null, delegate(ZDO zdo, int hash, string value) { zdo.Set(hash, value); }, (ZDO zdo, int hash, string? defaultValue) => zdo.GetString(hash, defaultValue)); } private ComponentFieldAccessor<TComponent> ResetCore<T>(Expression<Func<TComponent, T>> fieldExpression, Action<ZDO, int> remover) { FieldInfo field; int hash = GetHash(fieldExpression, out field); remover((ZDO)(object)_zdo, hash); return this; } public ComponentFieldAccessor<TComponent> Reset(Expression<Func<TComponent, bool>> fieldExpression) { return ResetCore(fieldExpression, delegate(ZDO zdo, int hash) { zdo.RemoveInt(hash); }); } public ComponentFieldAccessor<TComponent> Reset(Expression<Func<TComponent, float>> fieldExpression) { return ResetCore(fieldExpression, delegate(ZDO zdo, int hash) { zdo.RemoveFloat(hash); }); } public ComponentFieldAccessor<TComponent> Reset(Expression<Func<TComponent, int>> fieldExpression) { return ResetCore(fieldExpression, delegate(ZDO zdo, int hash) { zdo.RemoveInt(hash); }); } private bool ResetIfChangedCore<T>(Expression<Func<TComponent, T>> fieldExpression, Func<ZDO, int, bool> remover) { FieldInfo field; int hash = GetHash(fieldExpression, out field); return remover((ZDO)(object)_zdo, hash); } public bool ResetIfChanged(Expression<Func<TComponent, bool>> fieldExpression) { return ResetIfChangedCore(fieldExpression, (ZDO zdo, int hash) => zdo.RemoveInt(hash)); } public bool ResetIfChanged(Expression<Func<TComponent, float>> fieldExpression) { return ResetIfChangedCore(fieldExpression, (ZDO zdo, int hash) => zdo.RemoveFloat(hash)); } public bool ResetIfChanged(Expression<Func<TComponent, int>> fieldExpression) { return ResetIfChangedCore(fieldExpression, (ZDO zdo, int hash) => zdo.RemoveInt(hash)); } } private sealed class ZDOInventory : IZDOInventory { private IList<ItemData>? _items; private uint _dataRevision; private string? _lastData; public Inventory Inventory { get; private set; } public ExtendedZDO ZDO { get; private set; } public IList<ItemData> Items { get { if (_items == null) { _items = Inventory.GetAllItems(); } else if (_items != Inventory.GetAllItems()) { throw new Exception("Assumption violated"); } return _items; } } public ZDOInventory(ExtendedZDO zdo) { ZDO = zdo; _dataRevision = uint.MaxValue; base..ctor(); } public ZDOInventory Update() { //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown if (_dataRevision == ((ZDO)ZDO).DataRevision) { return this; } string items = ZDO.Vars.GetItems(); if (_lastData == items) { return this; } ComponentFieldAccessor<Container> componentFieldAccessor = ZDO.Fields<Container>(getUnknownComponent: false); int @int = componentFieldAccessor.GetInt((Expression<Func<Container, int>>)((Container x) => x.m_width)); int int2 = componentFieldAccessor.GetInt((Expression<Func<Container, int>>)((Container x) => x.m_height)); if (Inventory == null || Inventory.GetWidth() != @int || Inventory.GetHeight() != int2) { Inventory = new Inventory(ZDO.PrefabInfo.Container.Value.Container.m_name, ZDO.PrefabInfo.Container.Value.Container.m_bkg, @int, int2); } if (string.IsNullOrEmpty(items)) { Items.Clear(); } else { Inventory.Load(new ZPackage(items)); } _dataRevision = ((ZDO)ZDO).DataRevision; _lastData = items; return this; } public void UpdateZDO(ExtendedZDO zdo) { ZDO = zdo; _items = null; _dataRevision = 0u; _lastData = null; Update(); } public void Save() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); Inventory.Save(val); uint dataRevision = ((ZDO)ZDO).DataRevision; string @base = val.GetBase64(); ZDO.Vars.SetItems(@base); if (dataRevision != ((ZDO)ZDO).DataRevision) { (Container, Piece, PieceTable, PrefabInfo.Optional<ZSyncTransform>)? container = ZDO.PrefabInfo.Container; if (container.HasValue) { PrefabInfo.Optional<ZSyncTransform> item = container.GetValueOrDefault().Item4; if (item.Value != null) { ExtendedZDO zDO = ZDO; ((ZDO)zDO).DataRevision = ((ZDO)zDO).DataRevision + 120; } } } _dataRevision = ((ZDO)ZDO).DataRevision; _lastData = @base; } } private ZDOID _lastId = ZDOID.None; private AdditionalData_? _addData; private static readonly int __hasFieldsHash = StringExtensionMethods.GetStableHashCode("HasFields"); private AdditionalData_ AddData { get { //IL_0001: 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_001d: 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) if (_lastId != base.m_uid || _addData == null) { _lastId = base.m_uid; PrefabInfo prefabInfo = SharedProcessorState.GetPrefabInfo(((ZDO)this).GetPrefab()); if (prefabInfo != null) { _addData = new AdditionalData_(prefabInfo); } else { _addData = AdditionalData_.Dummy; } } return _addData; } } public PrefabInfo PrefabInfo => AddData.PrefabInfo; public IZDOInventory Inventory { get { AdditionalData_ addData = AddData; ZDOInventory zDOInventory = addData.Inventory; if (zDOInventory == null) { if (!PrefabInfo.Container.HasValue) { throw new InvalidOperationException(); } ZDOInventory zDOInventory3 = (addData.Inventory = new ZDOInventory(this)); zDOInventory = zDOInventory3; } return zDOInventory.Update(); } } public bool HasFields { get { AdditionalData_ addData = AddData; bool? hasFields = addData.HasFields; bool valueOrDefault = hasFields.GetValueOrDefault(); if (!hasFields.HasValue) { valueOrDefault = ((ZDO)this).GetBool(__hasFieldsHash, false); bool? hasFields2 = valueOrDefault; addData.HasFields = hasFields2; return valueOrDefault; } return valueOrDefault; } } public ZDOVars_ Vars => new ZDOVars_(this); public IReadOnlyList<Processor> Processors => AddData.Processors; private void SetHasFields() { if ((!AddData.HasFields) ?? true) { ((ZDO)this).Set(__hasFieldsHash, true); AddData.HasFields = true; } } public void UnregisterProcessors(IEnumerable<Processor> processors) { AddData.Ungregister(processors); } public void ReregisterAllProcessors() { _addData?.ReregisterAll(); } public void UpdateProcessorDataRevision(Processor processor) { AdditionalData_ addData = AddData; (addData.ProcessorDataRevisions ?? (addData.ProcessorDataRevisions = new Dictionary<Processor, uint>()))[processor] = ((ZDO)this).DataRevision; } public bool CheckProcessorDataRevisionChanged(Processor processor) { if (AddData.ProcessorDataRevisions == null || !AddData.ProcessorDataRevisions.TryGetValue(processor, out var value) || value != ((ZDO)this).DataRevision) { return true; } return false; } public void Destroy() { ClaimOwnershipInternal(); ZDOMan.instance.DestroyZDO((ZDO)(object)this); _addData = null; } public ExtendedZDO Recreate() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_001b: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown int prefab = ((ZDO)this).GetPrefab(); Vector3 position = ((ZDO)this).GetPosition(); long owner = ((ZDO)this).GetOwner(); ZPackage val = new ZPackage(); ((ZDO)this).Serialize(val); Destroy(); ExtendedZDO extendedZDO = (ExtendedZDO)(object)ZDOMan.instance.CreateNewZDO(position, prefab); ((ZDO)extendedZDO).Deserialize(new ZPackage(val.GetArray())); ((ZDO)extendedZDO).SetOwnerInternal(owner); return extendedZDO; } public void ClaimOwnership() { ((ZDO)this).SetOwner(ZDOMan.GetSessionID()); } public void ClaimOwnershipInternal() { ((ZDO)this).SetOwnerInternal(ZDOMan.GetSessionID()); } public ComponentFieldAccessor<TComponent> Fields<TComponent>(bool getUnknownComponent = false) where TComponent : MonoBehaviour { AdditionalData_ addData = AddData; return (ComponentFieldAccessor<TComponent>)(addData.ComponentFieldAccessors ?? (addData.ComponentFieldAccessors = new ConcurrentDictionary<Type, object>())).GetOrAdd(typeof(TComponent), delegate(Type key) { if (!PrefabInfo.Components.TryGetValue(key, out MonoBehaviour value) && getUnknownComponent) { value = (MonoBehaviour)(object)PrefabInfo.Prefab.GetComponentInChildren<TComponent>(); } if (value == null) { throw new KeyNotFoundException(); } return new ComponentFieldAccessor<TComponent>(this, (TComponent)(object)value); }); } } internal static class ExtensionMethods { public static ExtendedZDO? GetExtendedZDO(this ZDOMan instance, ZDOID id) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return (ExtendedZDO)(object)instance.GetZDO(id); } } [BepInPlugin("argusmagnus.ServersideQoL", "ServersideQoL", "0.2.13")] public sealed class Main : BaseUnityPlugin { private record SectorInfo(List<ZNetPeer> Peers, List<ZDO> ZDOs) { public int InverseWeight { get; set; } } private sealed class MyTerminal : Terminal { private sealed class MyConsoleEventArgs : ConsoleEventArgs { public MyConsoleEventArgs(string command, params string[] args) : base("", (Terminal)null) { int num = 0; string[] array = new string[1 + args.Length]; array[num] = command; num++; foreach (string text in args) { array[num] = text; num++; } base.Args = array; } } protected override Terminal m_terminalInstance { get { throw new NotImplementedException(); } } public static void ExecuteCommand(string command, params string[] args) { ConsoleCommand command2 = Terminal.commands[command]; ConsoleEvent action = command2.GetAction(); if (action != null) { action.Invoke((ConsoleEventArgs)(object)new MyConsoleEventArgs(command, args)); return; } ConsoleEventFailable actionFailable = command2.GetActionFailable(); if (actionFailable != null) { object obj = actionFailable.Invoke((ConsoleEventArgs)(object)new MyConsoleEventArgs(command, args)); if (obj is bool && (bool)obj) { return; } throw new Exception(obj.ToString()); } throw new ArgumentException("command"); } } [CompilerGenerated] private sealed class <<Start>g__CallExecute|34_0>d : IEnumerator<YieldInstruction>, IDisposable, IEnumerator { private int <>1__state; private YieldInstruction <>2__current; public Main <>4__this; YieldInstruction IEnumerator<YieldInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <<Start>g__CallExecute|34_0>d(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown int num = <>1__state; Main main = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; goto IL_004f; case 1: <>1__state = -1; goto IL_004f; case 2: <>1__state = -1; goto IL_0094; case 3: { <>1__state = -1; try { main.Execute(); } catch (OperationCanceledException) { return false; } catch (Exception ex2) { main.Logger.LogError((object)ex2); return false; } break; } IL_004f: if (ZNet.instance == null) { <>2__current = (YieldInstruction)new WaitForSeconds(0.2f); <>1__state = 1; return true; } if (!ZNet.instance.IsServer()) { main.Logger.LogWarning((object)"Mod should only be installed on the host"); return false; } goto IL_0094; IL_0094: if (ZDOMan.instance == null || ZNetScene.instance == null) { <>2__current = (YieldInstruction)new WaitForSeconds(0.2f); <>1__state = 2; return true; } if (!main.Initialize()) { return false; } break; } <>2__current = (YieldInstruction)new WaitForSeconds(1f / main.Config.General.Frequency.Value); <>1__state = 3; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal const string PluginName = "ServersideQoL"; internal const string PluginGuid = "argusmagnus.ServersideQoL"; private ModConfig? _config; private readonly Stopwatch _watch = new Stopwatch(); private ulong _executeCounter; private uint _unfinishedProcessingInRow; private ConcurrentDictionary<Vector2i, SectorInfo> _playerSectors = new ConcurrentDictionary<Vector2i, SectorInfo>(); private ConcurrentDictionary<Vector2i, SectorInfo> _playerSectorsOld = new ConcurrentDictionary<Vector2i, SectorInfo>(); private readonly HashSet<ZDOID> _ignore = new HashSet<ZDOID>(); private readonly List<Processor> _unregister = new List<Processor>(); private bool _configChanged = true; private readonly GameVersion ExpectedGameVersion = GameVersion.ParseGameVersion("0.220.5"); private const uint ExpectedNetworkVersion = 34u; private const uint ExpectedItemDataVersion = 106u; private const uint ExpectedWorldVersion = 35u; internal const string DummyConfigSection = "Z - Dummy"; private const string PluginVersion = "0.2.13"; internal const string PluginInformationalVersion = "0.2.13"; internal static int PluginGuidHash { get; } = StringExtensionMethods.GetStableHashCode("argusmagnus.ServersideQoL"); internal static Main Instance { get; private set; } = null; private static Harmony HarmonyInstance { get; } = new Harmony("argusmagnus.ServersideQoL"); internal ManualLogSource Logger { get; } = Logger.CreateLogSource("ServersideQoL"); internal ModConfig Config => _config ?? (_config = new ModConfig(((BaseUnityPlugin)this).Config)); public Main() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) Instance = this; } private void Awake() { HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); } private void Start() { ((MonoBehaviour)this).StartCoroutine((IEnumerator)CallExecute()); [IteratorStateMachine(typeof(<<Start>g__CallExecute|34_0>d))] IEnumerator<YieldInstruction> CallExecute() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <<Start>g__CallExecute|34_0>d(0) { <>4__this = this }; } } private bool Initialize() { //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_004c: 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) if (!Config.General.Enabled.Value) { return false; } bool flag = false; bool flag2 = false; if (RuntimeInformation.Instance.GameVersion != ExpectedGameVersion) { Logger.LogWarning((object)FormattableString.Invariant($"Unsupported game version: {RuntimeInformation.Instance.GameVersion}, expected: {ExpectedGameVersion}")); flag = true; flag2 |= !Config.General.IgnoreGameVersionCheck.Value; } if (RuntimeInformation.Instance.NetworkVersion != 34) { Logger.LogWarning((object)FormattableString.Invariant($"Unsupported network version: {RuntimeInformation.Instance.NetworkVersion}, expected: {34u}")); flag = true; flag2 |= !Config.General.IgnoreNetworkVersionCheck.Value; } if ((long)RuntimeInformation.Instance.ItemDataVersion != 106) { Logger.LogWarning((object)FormattableString.Invariant($"Unsupported item data version: {RuntimeInformation.Instance.ItemDataVersion}, expected: {106u}")); flag = true; flag2 |= !Config.General.IgnoreItemDataVersionCheck.Value; } if ((long)RuntimeInformation.Instance.WorldVersion != 35) { Logger.LogWarning((object)FormattableString.Invariant($"Unsupported world version: {RuntimeInformation.Instance.WorldVersion}, expected: {35u}")); flag = true; flag2 |= !Config.General.IgnoreWorldVersionCheck.Value; } if (flag) { if (flag2) { Logger.LogError((object)"Version checks failed. Mod execution is stopped"); return false; } Logger.LogError((object)"Version checks failed, but you chose to ignore the checks (config). Continuing..."); } return true; } private void Execute() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_0659: Unknown result type (might be due to invalid IL or missing references) //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_06a0: Unknown result type (might be due to invalid IL or missing references) //IL_06a5: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_06b5: Unknown result type (might be due to invalid IL or missing references) //IL_06bf: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_07d0: Unknown result type (might be due to invalid IL or missing references) //IL_07d5: Unknown result type (might be due to invalid IL or missing references) //IL_0829: Unknown result type (might be due to invalid IL or missing references) //IL_0b54: Unknown result type (might be due to invalid IL or missing references) //IL_0b5c: Unknown result type (might be due to invalid IL or missing references) //IL_0bd5: Unknown result type (might be due to invalid IL or missing references) //IL_08b2: Unknown result type (might be due to invalid IL or missing references) //IL_0949: Unknown result type (might be due to invalid IL or missing references) _executeCounter++; if (_configChanged) { _configChanged = false; if (Config.WorldModifiers.SetPresetFromConfig.Value) { try { MyTerminal.ExecuteCommand("setworldpreset", FormattableString.Invariant($"{Config.WorldModifiers.Preset.Value}")); } catch (Exception ex) { Logger.LogError((object)ex); } } if (Config.WorldModifiers.SetModifiersFromConfig.Value) { foreach (var (val, val2) in Config.WorldModifiers.Modifiers.Select<KeyValuePair<WorldModifiers, ConfigEntry<WorldModifierOption>>, (WorldModifiers, WorldModifierOption)>((KeyValuePair<WorldModifiers, ConfigEntry<WorldModifierOption>> x) => (x.Key, x.Value.Value))) { try { MyTerminal.ExecuteCommand("setworldmodifier", FormattableString.Invariant($"{val}"), FormattableString.Invariant($"{val2}")); } catch (Exception ex2) { Logger.LogError((object)ex2); } } } if (Config.GlobalsKeys.SetGlobalKeysFromConfig.Value) { foreach (var item5 in Config.GlobalsKeys.KeyConfigs.Select<KeyValuePair<GlobalKeys, ConfigEntryBase>, (GlobalKeys, ConfigEntryBase)>((KeyValuePair<GlobalKeys, ConfigEntryBase> x) => (x.Key, x.Value))) { GlobalKeys item = item5.Item1; ConfigEntryBase item2 = item5.Item2; object boxedValue = item2.BoxedValue; if (boxedValue is bool) { if ((bool)boxedValue) { ZoneSystem.instance.SetGlobalKey(item); } else { ZoneSystem.instance.RemoveGlobalKey(item); } continue; } float num; try { num = (float)Convert.ChangeType(item2.BoxedValue, typeof(float)); } catch (Exception ex3) { Logger.LogError((object)ex3); continue; } ZoneSystem.instance.SetGlobalKey(item, num); } } foreach (Processor defaultProcessor in Processor.DefaultProcessors) { defaultProcessor.Initialize(); } if (_executeCounter == 1) { ((BaseUnityPlugin)this).Config.Bind<string>("Z - Dummy", "Dummy", "", FormattableString.Invariant($"Dummy entry which does nothing, it's abused to include runtime information in the config file:{Environment.NewLine}{RuntimeInformation.Instance}")); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { _configChanged = true; }; return; } Logger.LogInfo((object)"Configuration changed"); { foreach (ExtendedZDO value3 in ZDOMan.instance.GetObjectsByID().Values) { value3.ReregisterAllProcessors(); } return; } } List<ZNetPeer> peers = ZNet.instance.GetPeers(); if (peers == null || peers.Count <= 0) { return; } _watch.Restart(); if (_executeCounter % (ulong)(60f * Config.General.Frequency.Value) == 0L) { foreach (var (key, concurrentHashSet) in SharedProcessorState.FollowingTamesByPlayerName.Select<KeyValuePair<string, ConcurrentHashSet<ZDOID>>, (string, ConcurrentHashSet<ZDOID>)>((KeyValuePair<string, ConcurrentHashSet<ZDOID>> x) => (x.Key, x.Value))) { foreach (ZDOID item6 in (IEnumerable<ZDOID>)concurrentHashSet) { ZDO zDO = ZDOMan.instance.GetZDO(item6); if (zDO == null || !zDO.IsValid()) { concurrentHashSet.Remove(item6); } } if (concurrentHashSet != null && concurrentHashSet.Count == 0) { SharedProcessorState.FollowingTamesByPlayerName.TryRemove(key, out ConcurrentHashSet<ZDOID> _); } } } ConcurrentDictionary<Vector2i, SectorInfo> playerSectorsOld = _playerSectorsOld; ConcurrentDictionary<Vector2i, SectorInfo> playerSectors = _playerSectors; _playerSectors = playerSectorsOld; _playerSectorsOld = playerSectors; _playerSectors.Clear(); Vector2i key2 = default(Vector2i); foreach (ZNetPeer item7 in peers) { Vector2i zone = ZoneSystem.GetZone(item7.m_refPos); for (int i = zone.x - Config.General.ZonesAroundPlayers.Value; i <= zone.x + Config.General.ZonesAroundPlayers.Value; i++) { for (int j = zone.y - Config.General.ZonesAroundPlayers.Value; j <= zone.y + Config.General.ZonesAroundPlayers.Value; j++) { ((Vector2i)(ref key2))..ctor(i, j); if (_playerSectorsOld.TryRemove(key2, out SectorInfo value2)) { _playerSectors.TryAdd(key2, value2); value2.InverseWeight = 0; value2.Peers.Clear(); value2.Peers.Add(item7); } else if (_playerSectors.TryGetValue(key2, out value2)) { value2.InverseWeight = 0; value2.Peers.Add(item7); } else { value2 = new SectorInfo(new List<ZNetPeer>(1) { item7 }, new List<ZDO>()); _playerSectors.TryAdd(key2, value2); } } } } if (_unfinishedProcessingInRow > 10) { foreach (ZNetPeer item8 in peers) { Vector2i zone2 = ZoneSystem.GetZone(item8.m_refPos); foreach (var item9 in _playerSectors.Select<KeyValuePair<Vector2i, SectorInfo>, (Vector2i, SectorInfo)>((KeyValuePair<Vector2i, SectorInfo> x) => (x.Key, x.Value))) { Vector2i item3 = item9.Item1; SectorInfo item4 = item9.Item2; int num2 = item3.x - zone2.x; int num3 = item3.y - zone2.y; item4.InverseWeight += num2 * num2 + num3 * num3; } } } int num4 = 0; int num5 = 0; int num6 = 0; IEnumerable<KeyValuePair<Vector2i, SectorInfo>> source = _playerSectors.AsEnumerable(); if (_unfinishedProcessingInRow > 10) { source = source.OrderBy((KeyValuePair<Vector2i, SectorInfo> x) => x.Value.InverseWeight); } foreach (Processor defaultProcessor2 in Processor.DefaultProcessors) { defaultProcessor2.PreProcess(); } foreach (var (val3, sectorInfo) in source.Select((KeyValuePair<Vector2i, SectorInfo> x) => (x.Key, x.Value))) { if (_watch.ElapsedMilliseconds > Config.General.MaxProcessingTime.Value) { break; } num4++; if ((object)sectorInfo != null) { List<ZDO> zDOs = sectorInfo.ZDOs; if (zDOs != null && zDOs.Count == 0) { ZDOMan.instance.FindSectorObjects(val3, 1, 0, sectorInfo.ZDOs, (List<ZDO>)null); } } num6 += sectorInfo.ZDOs.Count; while ((object)sectorInfo != null) { List<ZDO> zDOs = sectorInfo.ZDOs; if (zDOs == null || zDOs.Count <= 0 || _watch.ElapsedMilliseconds >= Config.General.MaxProcessingTime.Value) { break; } num5++; ExtendedZDO extendedZDO2 = (ExtendedZDO)(object)sectorInfo.ZDOs[sectorInfo.ZDOs.Count - 1]; sectorInfo.ZDOs.RemoveAt(sectorInfo.ZDOs.Count - 1); if (!((ZDO)extendedZDO2).IsValid() || extendedZDO2.PrefabInfo == PrefabInfo.Dummy || _ignore.Contains(((ZDO)extendedZDO2).m_uid)) { continue; } if (extendedZDO2.Processors.Count > 1) { Processor claimedExclusiveBy = null; foreach (Processor processor in extendedZDO2.Processors) { if (processor.ClaimExclusive(extendedZDO2)) { if (claimedExclusiveBy == null) { claimedExclusiveBy = processor; } else if (Config.General.DiagnosticLogs.Value) { Logger.LogError((object)FormattableString.Invariant($"ZDO {((ZDO)extendedZDO2).m_uid} claimed exclusive by {processor.GetType().Name} while already claimed by {claimedExclusiveBy.GetType().Name}")); } } } if (claimedExclusiveBy != null) { extendedZDO2.UnregisterProcessors(extendedZDO2.Processors.Where((Processor x) => x != claimedExclusiveBy)); } } bool flag = false; bool flag2 = false; _unregister.Clear(); foreach (Processor processor2 in extendedZDO2.Processors) { processor2.Process(extendedZDO2, sectorInfo.Peers); if (processor2.UnregisterZdoProcessor) { _unregister.Add(processor2); } if (flag = processor2.DestroyZdo) { extendedZDO2.Destroy(); break; } flag2 = flag2 || processor2.RecreateZdo; } if (!flag && flag2) { extendedZDO2.Recreate(); } else if (_unregister.Count > 0) { extendedZDO2.UnregisterProcessors(_unregister); } } } if (num4 < _playerSectors.Count || num5 < num6) { _unfinishedProcessingInRow++; } else { _unfinishedProcessingInRow = 0u; } _watch.Stop(); if (Config.General.DiagnosticLogs.Value) { LogLevel val4 = (LogLevel)((_watch.ElapsedMilliseconds > Config.General.MaxProcessingTime.Value) ? 16 : 32); Logger.Log(val4, (object)FormattableString.Invariant(FormattableStringFactory.Create("{0} took {1} ms to process {2} of {3} ZDOs in {4} of {5} zones. Uncomplete runs in row: {6}", "Execute", _watch.ElapsedMilliseconds, num5, num6, num4, _playerSectors.Count, _unfinishedProcessingInRow))); Logger.Log(val4, (object)FormattableString.Invariant(FormattableStringFactory.Create("Processing Time: {0}", string.Join(", ", from x in Processor.DefaultProcessors where x.ProcessingTime.Ticks > 0 orderby x.ProcessingTime.Ticks descending select FormattableString.Invariant($"{x.GetType().Name}: {x.ProcessingTime.TotalMilliseconds}ms"))))); } } } internal sealed class ModConfig { public sealed class GeneralConfig { public ConfigEntry<bool> Enabled { get; } = cfg.Bind<bool>(section, "Enabled", true, "Enables/disables the entire mode"); public ConfigEntry<bool> InWorldConfigRoom { get; } = cfg.Bind<bool>(section, "InWorldConfigRoom", false, "True to generate an in-world room which admins can enter to configure this mod by editing signs. A portal is placed at the start location"); public ConfigEntry<bool> DiagnosticLogs { get; } = cfg.Bind<bool>(section, "DiagnosticLogs", false, "Enables/disables diagnostic logs"); public ConfigEntry<float> Frequency { get; } = cfg.Bind<float>(section, "Frequency", 5f, new ConfigDescription("How many times per second the mod processes the world", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public ConfigEntry<int> MaxProcessingTime { get; } = cfg.Bind<int>(section, "MaxProcessingTime", 20, "Max processing time (in ms) per update"); public ConfigEntry<int> ZonesAroundPlayers { get; } = cfg.Bind<int>(section, "ZonesAroundPlayers", 1, "Zones to process around each player"); public ConfigEntry<float> MinPlayerDistance { get; } = cfg.Bind<float>(section, "MinPlayerDistance", 4f, "Min distance all players must have to a ZDO for it to be modified"); public ConfigEntry<bool> IgnoreGameVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreGameVersionCheck", true, "True to ignore the game version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption"); public ConfigEntry<bool> IgnoreNetworkVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreNetworkVersionCheck", false, "True to ignore the network version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption"); public ConfigEntry<bool> IgnoreItemDataVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreItemDataVersionCheck", false, "True to ignore the item data version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption"); public ConfigEntry<bool> IgnoreWorldVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreWorldVersionCheck", false, "True to ignore the world version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption"); public GeneralConfig(ConfigFile cfg, string section) { }//IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown } public sealed class SignsConfig { public ConfigEntry<bool> TimeSigns { get; } = cfg.Bind<bool>(section, "TimeSigns", false, FormattableString.Invariant($"True to update sign texts which contain time emojis (any of {string.Concat(SignProcessor.ClockEmojis)}) with the in-game time")); public SignsConfig(ConfigFile cfg, string section) { } } public sealed class MapTableConfig { public ConfigEntry<bool> AutoUpdatePortals { get; } = cfg.Bind<bool>(section, "AutoUpdatePortals", false, "True to update map tables with portal pins"); public ConfigEntry<string> AutoUpdatePortalsExclude { get; } = cfg.Bind<string>(section, "AutoUpdatePortalsExclude", "", "Portals with a tag that matches this filter are not added to map tables"); public ConfigEntry<string> AutoUpdatePortalsInclude { get; } = cfg.Bind<string>(section, "AutoUpdatePortalsInclude", "*", "Only portals with a tag that matches this filter are added to map tables"); public ConfigEntry<bool> AutoUpdateShips { get; } = cfg.Bind<bool>(section, "AutoUpdateShips", false, "True to update map tables with ship pins"); public MapTableConfig(ConfigFile cfg, string section) { } } public sealed class TamesConfig { public ConfigEntry<bool> MakeCommandable { get; } = cfg.Bind<bool>(section, "MakeCommandable", false, "True to make all tames commandable (like wolves)"); public ConfigEntry<bool> ShowTamingProgress { get; } = cfg.Bind<bool>(section, "ShowTamingProgress", false, "True to show taming progress to nearby players"); public ConfigEntry<bool> ShowGrowingProgress { get; } = cfg.Bind<bool>(section, "ShowGrowingProgress", false, "True to show growing progress to nearby players"); public ConfigEntry<bool> AlwaysFed { get; } = cfg.Bind<bool>(section, "AlwaysFed", false, "True to make tames always fed (not hungry)"); public ConfigEntry<bool> TeleportFollow { get; } = cfg.Bind<bool>(section, "TeleportFollow", false, "True to teleport following tames to the players location if the player gets too far away from them"); public TamesConfig(ConfigFile cfg, string section) { } } public sealed class FireplacesConfig { public enum IgnoreRainOptions { Never, Always, InsideShield } public ConfigEntry<bool> MakeToggleable { get; } = cfg.Bind<bool>(section, "MakeToggleable", false, "True to make all fireplaces (including torches, braziers, etc.) toggleable"); public ConfigEntry<bool> InfiniteFuel { get; } = cfg.Bind<bool>(section, "InfiniteFuel", false, "True to make all fireplaces have infinite fuel"); public ConfigEntry<IgnoreRainOptions> IgnoreRain { get; } = cfg.Bind<IgnoreRainOptions>(section, "IgnoreRain", IgnoreRainOptions.Never, new ConfigDescription("Options to make all fireplaces ignore rain", (AcceptableValueBase)(object)new AcceptableEnum<IgnoreRainOptions>(), Array.Empty<object>())); public FireplacesConfig(ConfigFile cfg, string section) { }//IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown } public sealed class ContainersConfig { public ConfigEntry<bool> AutoSort { get; } public ConfigEntry<bool> AutoPickup { get; } public ConfigEntry<float> AutoPickupRange { get; } public ConfigEntry<float> AutoPickupMinPlayerDistance { get; } public IReadOnlyDictionary<int, ConfigEntry<string>> ContainerSizes { get; } public ContainersConfig(ConfigFile cfg, string section) { ConfigFile cfg2 = cfg; string section2 = section; AutoSort = cfg2.Bind<bool>(section2, "AutoSort", false, "True to auto sort container inventories"); AutoPickup = cfg2.Bind<bool>(section2, "AutoPickup", false, "True to automatically put dropped items into containers if they already contain said item"); AutoPickupRange = cfg2.Bind<float>(section2, "AutoPickupRange", 64f, "Required proximity of a container to a dropped item to be considered as auto pickup target"); AutoPickupMinPlayerDistance = cfg2.Bind<float>(section2, "AutoPickupMinPlayerDistance", 8f, "Min distance all player must have to a dropped item for it to be picked up"); ContainerSizes = (from x in ZNetScene.instance.m_prefabs where SharedProcessorState.PieceTablesByPiece.ContainsKey(((Object)x).name) select (((Object)x).name, x.GetComponent<Container>() ?? x.GetComponentInChildren<Container>(), x.GetComponent<Piece>()) into x where x.Container != null && x.Piece != null select x).ToDictionary<(string, Container, Piece), int, ConfigEntry<string>>(((string Name, Container Container, Piece Piece) x) => StringExtensionMethods.GetStableHashCode(x.Name), ((string Name, Container Container, Piece Piece) x) => cfg2.Bind<string>(section2, FormattableString.Invariant($"InventorySize_{x.Name}"), FormattableString.Invariant($"{x.Container.m_width}x{x.Container.m_height}"), FormattableString.Invariant($"Inventory size for '{Localization.instance.Localize(x.Piece.m_name)}'"))); base..ctor(); } } public sealed class SmeltersConfig { public ConfigEntry<bool> FeedFromContainers { get; } = cfg.Bind<bool>(section, "FeedFromContainers", false, "True to automatically feed smelters from nearby containers"); public ConfigEntry<float> FeedFromContainersRange { get; } = cfg.Bind<float>(section, "FeedFromContainersRange", 4f, "Required proxmity of a container to a smelter to be used as feeding source"); public ConfigEntry<int> FeedFromContainersLeaveAtLeastFuel { get; } = cfg.Bind<int>(section, "FeedFromContainersLeaveAtLeastFuel", 1, "Minimum amout of fuel to leave in a container"); public ConfigEntry<int> FeedFromContainersLeaveAtLeastOre { get; } = cfg.Bind<int>(section, "FeedFromContainersLeaveAtLeastOre", 1, "Minimum amout of ore to leave in a container"); public SmeltersConfig(ConfigFile cfg, string section) { } } public sealed class WindmillsConfig { public ConfigEntry<bool> IgnoreWind { get; } = cfg.Bind<bool>(section, "IgnoreWind", false, "True to make windmills ignore wind (Cover still decreases operating efficiency though)"); public WindmillsConfig(ConfigFile cfg, string section) { } } public sealed class CartsConfig { public ConfigEntry<float> ContentMassMultiplier { get; } = cfg.Bind<float>(section, "ContentMassMultiplier", 1f, new ConfigDescription("Multiplier for a carts content weight. E.g. set to 0 to ignore a cart's content weight", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public CartsConfig(ConfigFile cfg, string section) { }//IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown } public sealed class DoorsConfig { public ConfigEntry<float> AutoCloseMinPlayerDistance { get; } = cfg.Bind<float>(section, "AutoCloseMinPlayerDistance", float.NaN, FormattableString.Invariant($"Min distance all players must have to the door before it is closed. {float.NaN} to disable this feature")); public DoorsConfig(ConfigFile cfg, string section) { } } public sealed class PlayersConfig { public ConfigEntry<bool> InfiniteBuildingStamina { get; } = cfg.Bind<bool>(section, "InfiniteBuildingStamina", false, FormattableString.Invariant(FormattableStringFactory.Create("True to give players infinite stamina when building. If you want infinite stamina in general, set the global key '{0}' to 0", "StaminaRate"))); public ConfigEntry<bool> InfiniteFarmingStamina { get; } = cfg.Bind<bool>(section, "InfiniteFarmingStamina", false, FormattableString.Invariant(FormattableStringFactory.Create("True to give players infinite stamina when farming. If you want infinite stamina in general, set the global key '{0}' to 0", "StaminaRate"))); public PlayersConfig(ConfigFile cfg, string section) { } } public sealed class TurretsConfig { public ConfigEntry<bool> DontTargetPlayers { get; } = cfg.Bind<bool>(section, "DontTargetPlayers", false, "True to stop ballistas from targeting players"); public ConfigEntry<bool> DontTargetTames { get; } = cfg.Bind<bool>(section, "DontTargetTames", false, "True to stop ballistas from targeting tames"); public ConfigEntry<bool> LoadFromContainers { get; } = cfg.Bind<bool>(section, "LoadFromContainers", false, "True to automatically load ballistas from containers"); public ConfigEntry<float> LoadFromContainersRange { get; } = cfg.Bind<float>(section, "LoadFromContainersRange", 4f, "Required proxmity of a container to a ballista to be used as ammo source"); public TurretsConfig(ConfigFile cfg, string section) { } } public sealed class WearNTearConfig { [Flags] public enum DisableSupportRequirementsOptions { None = 0, PlayerBuilt = 1, World = 2 } public ConfigEntry<bool> DisableRainDamage { get; } = cfg.Bind<bool>(section, "DisableRainDamage", false, "True to prevent rain from damaging build pieces"); public ConfigEntry<DisableSupportRequirementsOptions> DisableSupportRequirements { get; } = cfg.Bind<DisableSupportRequirementsOptions>(section, "DisableSupportRequirements", DisableSupportRequirementsOptions.None, new ConfigDescription("Ignore support requirements on build pieces", (AcceptableValueBase)(object)new AcceptableEnum<DisableSupportRequirementsOptions>(), Array.Empty<object>())); public WearNTearConfig(ConfigFile cfg, string section) { }//IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown } public sealed class PortalHubConfig { public ConfigEntry<bool> Enable { get; } = cfg.Bind<bool>(section, "Enable", false, "True to automatically generate a portal hub"); public ConfigEntry<string> Exclude { get; } = cfg.Bind<string>(section, "Exclude", "", "Portals with a tag that matches this filter are not added to the portal hub"); public ConfigEntry<string> Include { get; } = cfg.Bind<string>(section, "Include", "*", "Only portals with a tag that matches this filter are added to the portal hub"); public PortalHubConfig(ConfigFile cfg, string section) { } } public sealed class WorldModifiersConfig { public ConfigEntry<bool> SetPresetFromConfig { get; } = cfg.Bind<bool>(section, "SetPresetFromConfig", false, FormattableString.Invariant(FormattableStringFactory.Create("True to set the world preset according to the '{0}' config entry", "Preset"))); public ConfigEntry<WorldPresets> Preset { get; } = GetPreset(cfg, section); public ConfigEntry<bool> SetModifiersFromConfig { get; } = cfg.Bind<bool>(section, "SetModifiersFromConfig", false, "True to set world modifiers according to the following configuration entries"); public IReadOnlyDictionary<WorldModifiers, ConfigEntry<WorldModifierOption>> Modifiers { get; } = GetModifiers(cfg, section); public WorldModifiersConfig(ConfigFile cfg, string section) { } private static ConfigEntry<WorldPresets> GetPreset(ConfigFile cfg, string section) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown IReadOnlyList<KeyButton> source = PrivateAccessor.GetServerOptionsGUIPresets(); return cfg.Bind<WorldPresets>(section, "Preset", (WorldPresets)0, new ConfigDescription(FormattableString.Invariant(FormattableStringFactory.Create("World preset. Enable '{0}' for this to have an effect", "SetPresetFromConfig")), (AcceptableValueBase)(object)new AcceptableEnum<WorldPresets>(source.Select((KeyButton x) => x.m_preset)), Array.Empty<object>())); } private static IReadOnlyDictionary<WorldModifiers, ConfigEntry<WorldModifierOption>> GetModifiers(ConfigFile cfg, string section) { ConfigFile cfg2 = cfg; string section2 = section; return (from keySlider in PrivateAccessor.GetServerOptionsGUIModifiers().OfType<KeySlider>() select (keySlider.m_modifier, cfg2.Bind<WorldModifierOption>(section2, FormattableString.Invariant($"{keySlider.m_modifier}"), (WorldModifierOption)0, new ConfigDescription(FormattableString.Invariant(FormattableStringFactory.Create("World modifier '{0}'. Enable '{1}' for this to have an effect", keySlider.m_modifier, "SetModifiersFromConfig")), (AcceptableValueBase)(object)new AcceptableEnum<WorldModifierOption>(keySlider.m_settings.Select((SliderSetting x) => x.m_modifierValue)), Array.Empty<object>())))).ToDictionary<(WorldModifiers, ConfigEntry<WorldModifierOption>), WorldModifiers, ConfigEntry<WorldModifierOption>>(((WorldModifiers Key, ConfigEntry<WorldModifierOption> Cfg) x) => x.Key, ((WorldModifiers Key, ConfigEntry<WorldModifierOption> Cfg) x) => x.Cfg); } } public sealed class GlobalsKeysConfig { public ConfigEntry<bool> SetGlobalKeysFromConfig { get; } = cfg.Bind<bool>(section, "SetGlobalKeysFromConfig", false, "True to set global keys according to the following configuration entries"); public IReadOnlyDictionary<GlobalKeys, ConfigEntryBase> KeyConfigs { get; } = ((GlobalKeyConfigFinder)(tmp ?? (tmp = new GlobalKeyConfigFinder()))).Get<GlobalKeys>((GlobalKeys?)(GlobalKeys)30, cfg, section, FormattableString.Invariant(FormattableStringFactory.Create("Sets the value for the '{{0}}' global key. Enable '{0}' for this to have an effect", "SetGlobalKeysFromConfig"))); public ConfigEntry<bool> NoPortalsPreventsContruction { get; } = cfg.Bind<bool>(section, "NoPortalsPreventsContruction", true, FormattableString.Invariant($"True to change the effect of the '{(object)(GlobalKeys)26}' global key, to prevent the construction of new portals but leave existing portals functional")); public GlobalsKeysConfig(ConfigFile cfg, string section, object? tmp = null) { } } private sealed class GlobalKeyConfigFinder { private sealed record FieldInfoEx(FieldInfo Field, object? OriginalValueObject, double OriginalValue); private readonly List<FieldInfoEx> fields = (from x in typeof(Game).GetFields(BindingFlags.Static | BindingFlags.Public) select new FieldInfoEx(x, x.GetValue(null), TryGetAsDouble(x)) into x where !double.IsNaN(x.OriginalValue) select x).ToList(); private readonly List<(double TestValue, double Value)> _testResults = new List<(double, double)>(); private readonly IEnumerable<double> _testValues; private readonly Dictionary<string, string> _keyTestValues; private MethodInfo? _bindDefinition; public IReadOnlyDictionary<TKey, ConfigEntryBase> Get<TKey>(TKey? maxEclusive, ConfigFile cfg, string section, string descriptionFormat) where TKey : unmanaged, Enum { //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Expected O, but got Unknown //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Expected O, but got Unknown Dictionary<TKey, ConfigEntryBase> dictionary = new Dictionary<TKey, ConfigEntryBase>(); foreach (TKey value3 in Enum.GetValues(typeof(TKey))) { if (maxEclusive.HasValue && value3.ToInt64() >= maxEclusive.Value.ToInt64()) { continue; } string text = value3.ToString(); string key = text.ToLower(); FieldInfo fieldInfo = null; object value = null; double num = double.NaN; _testResults.Clear(); foreach (double testValue in _testValues) { _keyTestValues.Clear(); _keyTestValues.Add(key, FormattableString.Invariant($"{testValue}")); try { Game.UpdateWorldRates(new HashSet<string>(), _keyTestValues); } catch (NullReferenceException) { } double num2 = double.NaN; if ((object)fieldInfo == null) { int index; (fieldInfo, value, num, num2, index) = fields.Select((FieldInfoEx x, int i) => (x.Field, x.OriginalValueObject, x.OriginalValue, TryGetAsDouble(x.Field), i)).FirstOrDefault<(FieldInfo, object, double, double, int)>(((FieldInfo Field, object OriginalValueObject, double OriginalValue, double Value, int i) x) => x.OriginalValue != x.Value); if ((object)fieldInfo != null) { fields.RemoveAt(index); } } else { num2 = TryGetAsDouble(fieldInfo); if (num2 == num) { num2 = double.NaN; } } if (!double.IsNaN(num2)) { _testResults.Add((testValue, num2)); } } List<(double, double)> testResults = _testResults; if (testResults != null && testResults.Count > 0 && (object)fieldInfo != null) { double min = _testResults.Min(((double TestValue, double Value) x) => x.Value); double max = _testResults.Max(((double TestValue, double Value) x) => x.Value); IEnumerable<(double, double)> source = _testResults.Where(((double TestValue, double Value) x) => x.Value != 0.0 && x.Value > min && x.Value < max); double num3 = (source.Any() ? source.Average<(double, double)>(((double TestValue, double Value) x) => x.TestValue / x.Value) : 1.0); min *= num3; max *= num3; num *= num3; AcceptableValueBase val2 = null; if (min > -3.4028234663852886E+38 && max < 3.4028234663852886E+38 && min < max) { val2 = (AcceptableValueBase)Activator.CreateInstance(typeof(AcceptableValueRange<>).MakeGenericType(fieldInfo.FieldType), Convert.ChangeType(min, fieldInfo.FieldType), Convert.ChangeType(max, fieldInfo.FieldType)); } ConfigDescription val3 = new ConfigDescription(string.Format(descriptionFormat, text), val2, Array.Empty<object>()); if ((object)_bindDefinition == null) { _bindDefinition = new Func<string, string, bool, ConfigDescription, ConfigEntry<bool>>(cfg.Bind<bool>).Method.GetGenericMethodDefinition(); } ConfigEntryBase value2 = (ConfigEntryBase)_bindDefinition.MakeGenericMethod(fieldInfo.FieldType).Invoke(cfg, new object[4] { section, text, Convert.ChangeType(num, fieldInfo.FieldType), val3 }); dictionary.Add(value3, value2); } else { dictionary.Add(value3, (ConfigEntryBase)(object)cfg.Bind<bool>(section, text, false, string.Format(descriptionFormat, text))); } fieldInfo?.SetValue(null, value); } return dictionary; } private static double TryGetAsDouble(FieldInfo field) { object value = field.GetValue(null); try { return (double)Convert.ChangeType(value, typeof(double)); } catch { return double.NaN; } } public GlobalKeyConfigFinder() { List<double> list = new List<double>(); list.Add(-3.4028234663852886E+38); list.Add(-2147483648.0); list.AddRange(Enumerable.Range(-100, 100).Select((Func<int, double>)((int x) => x))); list.Add(2147483647.0); list.Add(3.4028234663852886E+38); _testValues = new <>z__ReadOnlyList<double>(list); _keyTestValues = new Dictionary<string, string>(); base..ctor(); } } public sealed class TradersConfig { public IReadOnlyDictionary<Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)>> AlwaysUnlock { get; } = GetAlwaysUnlock(cfg, section); public TradersConfig(ConfigFile cfg, string section) { } private static IReadOnlyDictionary<Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)>> GetAlwaysUnlock(ConfigFile cfg, string section) { ConfigFile cfg2 = cfg; string section2 = section; if (!ZNet.instance.IsServer() || !ZNet.instance.IsDedicated()) { return new Dictionary<Trader, IReadOnlyList<(string, ConfigEntry<bool>)>>(); } return (from x in (from x in ZNetScene.instance.m_prefabs select x.GetComponent<Trader>() into x where x != null select x).Select((Func<Trader, (Trader, IReadOnlyList<(string, ConfigEntry<bool>)>)>)((Trader trader) => (trader, (from x in trader.m_items where !string.IsNullOrEmpty(x.m_requiredGlobalKey) select x into item select (item.m_requiredGlobalKey, cfg2.Bind<bool>(section2, FormattableString.Invariant(FormattableStringFactory.Create("{0}{1}{2}", "AlwaysUnlock", ((Object)trader).name, ((Object)item.m_prefab).name)), false, FormattableString.Invariant($"Remove the progression requirements for buying {Localization.instance.Localize(item.m_prefab.m_itemData.m_shared.m_name)} from {Localization.instance.Localize(trader.m_name)}")))).ToList()))) where x.Entries.Any() select x).ToDictionary<(Trader, IReadOnlyList<(string, ConfigEntry<bool>)>), Trader, IReadOnlyList<(string, ConfigEntry<bool>)>>(((Trader Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)> Entries) x) => x.Trader, ((Trader Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)> Entries) x) => x.Entries); } } public sealed class PlantsConfig { public ConfigEntry<float> GrowTimeMultiplier { get; } = cfg.Bind<float>(section, "GrowTimeMultiplier", 1f, new ConfigDescription("Multiply plant grow time by this factor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public ConfigEntry<float> SpaceRequirementMultiplier { get; } = cfg.Bind<float>(section, "SpaceRequirementMultiplier", 1f, new ConfigDescription("Multiply plant grow time by this factor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public ConfigEntry<bool> DontDestroyIfCantGrow { get; } = cfg.Bind<bool>(section, "DontDestroyIfCantGrow", false, "True to keep plants which can't grow alive"); public PlantsConfig(ConfigFile cfg, string section) { }//IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown } public sealed class SummonsConfig { public ConfigEntry<float> UnsummonDistanceMultiplier { get; } = cfg.Bind<float>(section, "UnsummonDistanceMultiplier", 1f, new ConfigDescription("Multiply unsummon distance by this factor. 0 to disable distance-based unsummoning", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public ConfigEntry<float> UnsummonLogoutTimeMultiplier { get; } = cfg.Bind<float>(section, "UnsummonLogoutTimeMultiplier", 1f, new ConfigDescription("Multiply the time after which summons are unsummoned when the player logs out. 0 to disable logout-based unsummoning", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public SummonsConfig(ConfigFile cfg, string section) { }//IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown } public sealed class TrapsConfig { public ConfigEntry<bool> DisableTriggeredByPlayers { get; } = cfg.Bind<bool>(section, "DisableTriggeredByPlayers", false, "True to stop traps from being triggered by players"); public ConfigEntry<bool> DisableFriendlyFire { get; } = cfg.Bind<bool>(section, "DisableFriendlyFire", false, "True to stop traps from damaging players and tames"); public ConfigEntry<float> SelfDamageMultiplier { get; } = cfg.Bind<float>(section, "SelfDamageMultiplier", 1f, new ConfigDescription("Multiply the damage the trap takes when it is triggered by this factor. 0 to make the trap take no damage", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>())); public TrapsConfig(ConfigFile cfg, string section) { }//IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown } internal sealed class AcceptableEnum<T> : AcceptableValueBase where T : unmanaged, Enum { private readonly T _default; public IReadOnlyList<T> AcceptableValues { get; } public AcceptableEnum() : this((IEnumerable<T>)(T[])Enum.GetValues(typeof(T))) { } public AcceptableEnum(IEnumerable<T> values) : base(typeof(T)) { if (EnumUtils.IsBitSet<T>()) { List<T> list = new List<T>(); list.AddRange(values.Where((T x) => !x.Equals(default(T)))); AcceptableValues = new <>z__ReadOnlyList<T>(list); _default = default(T); return; } object obj = values as IReadOnlyList<T>; if (obj == null) { List<T> list2 = new List<T>(); list2.AddRange(values); obj = new <>z__ReadOnlyList<T>(list2); } AcceptableValues = (IReadOnlyList<T>)obj; _default = AcceptableValues.FirstOrDefault(); } public override object Clamp(object value) { if (value is T) { T e = (T)value; if (EnumUtils.IsBitSet<T>()) { ulong val = e.ToUInt64(); ulong num = 0uL; foreach (ulong item in from x in AcceptableValues select x.ToUInt64() into x where (val & x) == x select x) { num |= item; } return EnumUtils.ToEnum<T>(num); } if (!AcceptableValues.Any((T x) => x.Equals(e))) { return _default; } return e; } return _default; } public override bool IsValid(object value) { return object.Equals(value, ((AcceptableValueBase)this).Clamp(value)); } public override string ToDescriptionString() { if (EnumUtils.IsBitSet<T>()) { return FormattableString.Invariant(FormattableStringFactory.Create("# Acceptable values: {0} or combination of {1}", _default, string.Join(", ", AcceptableValues.Where((T x) => !x.Equals(_default))))); } return FormattableString.Invariant(FormattableStringFactory.Create("# Acceptable values: {0}", string.Join(", ", AcceptableValues))); } } public ConfigFile ConfigFile { get; } public GeneralConfig General { get; } public SignsConfig Signs { get; } public MapTableConfig MapTables { get; } public TamesConfig Tames { get; } public SummonsConfig Summons { get; } public FireplacesConfig Fireplaces { get; } public ContainersConfig Containers { get; } public SmeltersConfig Smelters { get; } public WindmillsConfig Windmills { get; } public CartsConfig Carts { get; } public DoorsConfig Doors { get; } public PlayersConfig Players { get; } public TurretsConfig Turrets { get; } public WearNTearConfig WearNTear { get; } public TradersConfig Traders { get; } public PlantsConfig Plants { get; } public TrapsConfig Traps { get; } public PortalHubConfig PortalHub { get; } public WorldModifiersConfig WorldModifiers { get; } public GlobalsKeysConfig GlobalsKeys { get; } public ModConfig(ConfigFile cfg) { ConfigFile = cfg; General = new GeneralConfig(cfg, "A - General"); Signs = new SignsConfig(cfg, "B - Signs"); MapTables = new MapTableConfig(cfg, "B - Map Tables"); Tames = new TamesConfig(cfg, "B - Tames"); Summons = new SummonsConfig(cfg, "B - Summons"); Fireplaces = new FireplacesConfig(cfg, "B - Fireplaces"); Containers = new ContainersConfig(cfg, "B - Containers"); Smelters = new SmeltersConfig(cfg, "B - Smelters"); Windmills = new WindmillsConfig(cfg, "B - Windmills"); Carts = new CartsConfig(cfg, "B - Carts"); Doors = new DoorsConfig(cfg, "B - Doors"); Players = new PlayersConfig(cfg, "B - Players"); Turrets = new TurretsConfig(cfg, "B - Turrets"); WearNTear = new WearNTearConfig(cfg, "B - Build Pieces"); Traders = new TradersConfig(cfg, "B - Traders"); Plants = new PlantsConfig(cfg, "B - Plants"); Traps = new TrapsConfig(cfg, "B - Traps"); PortalHub = new PortalHubConfig(cfg, "B - Portal Hub"); WorldModifiers = new WorldModifiersConfig(cfg, "C - World Modifiers"); GlobalsKeys = new GlobalsKeysConfig(cfg, "D - Global Keys"); base..ctor(); } } internal sealed class PrefabInfo { public record struct Optional<T>(T? Value) where T : MonoBehaviour { public static implicit operator T(in Optional<T> value) { return value.Value ?? throw new ArgumentNullException(); } } public GameObject Prefab { get; } public string PrefabName { get { GameObject prefab = Prefab; return ((prefab != null) ? ((Object)prefab).name : null) ?? ""; } } public IReadOnlyDictionary<Type, MonoBehaviour> Components { get; } public Sign? Sign { get; } public MapTable? MapTable { get; } public Tameable? Tameable { get; } public Fireplace? Fireplace { get; } public (Container Container, Piece Piece, PieceTable PieceTable, Optional<ZSyncTransform> ZSyncTransform)? Container { get; } public (Ship Ship, Piece Piece)? Ship { get; } public (ItemDrop ItemDrop, Optional<Piece> Piece)? ItemDrop { get; } public Smelter? Smelter { get; } public ShieldGenerator? ShieldGenerator { get; } public Windmill? Windmill { get; } public Vagon? Vagon { get; } public Player? Player { get; } public TeleportWorld? TeleportWorld { get; } public Door? Door { get; } public (Turret Turret, Piece Piece, PieceTable PieceTable)? Turret { get; } public (WearNTear WearNTear, Optional<Piece> Piece, Optional<PieceTable> PieceTable)? WearNTear { get; } public Trader? Trader { get; } public Plant? Plant { get; } public EggGrow? EggGrow { get; } public Growup? Growup { get; } public (Aoe Aoe, Piece Piece, PieceTable PieceTable, Optional<Trap> Trap)? Trap { get; } public static PrefabInfo Dummy { get; } = new PrefabInfo(null, new Dictionary<Type, MonoBehaviour>(0)); public PrefabInfo(GameObject prefab, IReadOnlyDictionary<Type, MonoBehaviour> components) { Prefab = prefab; Components = components; Sign = Get<Sign>(components); MapTable = Get<MapTable>(components); Tameable = Get<Tameable>(components); Fireplace = Get<Fireplace>(components); (Container, Optional<Piece>, Optional<PieceTable>, Optional<ZSyncTransform>)? tuple = Get<Container, Piece, PieceTable, ZSyncTransform>(components); (Container, Piece, PieceTable, Optional<ZSyncTransform>)? obj; if (!tuple.HasValue) { obj = null; } else { (Container, Optional<Piece>, Optional<PieceTable>, Optional<ZSyncTransform>) valueOrDefault = tuple.GetValueOrDefault(); obj = (valueOrDefault.Item1, valueOrDefault.Item2, valueOrDefault.Item3, valueOrDefault.Item4); } Container = obj; (Ship, Optional<Piece>)? tuple2 = Get<Ship, Piece>(components); (Ship, Piece)? obj2; if (!tuple2.HasValue) { obj2 = null; } else { (Ship, Optional<Piece>) valueOrDefault2 = tuple2.GetValueOrDefault(); obj2 = (valueOrDefault2.Item1, valueOrDefault2.Item2); } Ship = obj2; ItemDrop = Get<ItemDrop, Piece>(components); Smelter = Get<Smelter>(components); ShieldGenerator = Get<ShieldGenerator>(components); Windmill = Get<Windmill>(components); Vagon = Get<Vagon>(components); Player = Get<Player>(components); TeleportWorld = Get<TeleportWorld>(components); Door = Get<Door>(components); (Turret, Optional<Piece>, Optional<PieceTable>)? tuple3 = Get<Turret, Piece, PieceTable>(components); (Turret, Piece, PieceTable)? obj3; if (!tuple3.HasValue) { obj3 = null; } else { (Turret, Optional<Piece>, Optional<PieceTable>) valueOrDefault3 = tuple3.GetValueOrDefault(); obj3 = (valueOrDefault3.Item1, valueOrDefault3.Item2, valueOrDefault3.Item3); } Turret = obj3; WearNTear = Get<WearNTear, Piece, PieceTable>(components); Trader = Get<Trader>(components); Plant = Get<Plant>(components); EggGrow = Get<EggGrow>(components); Growup = Get<Growup>(components); (Aoe, Optional<Piece>, Optional<PieceTable>, Optional<Trap>)? tuple4 = Get<Aoe, Piece, PieceTable, Trap>(components); (Aoe, Piece, PieceTable, Optional<Trap>)? obj4; if (!tuple4.HasValue) { obj4 = null; } else { (Aoe, Optional<Piece>, Optional<PieceTable>, Optional<Trap>) valueOrDefault4 = tuple4.GetValueOrDefault(); obj4 = (valueOrDefault4.Item1, valueOrDefault4.Item2, valueOrDefault4.Item3, valueOrDefault4.Item4); } Trap = obj4; base..ctor(); } private static T? Get<T>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T : MonoBehaviour { if (!prefabs.TryGetValue(typeof(T), out MonoBehaviour value)) { return default(T); } return (T)(object)value; } private static (T1 F1, Optional<T2> F2)? Get<T1, T2>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T1 : MonoBehaviour where T2 : MonoBehaviour { if (!prefabs.TryGetValue(typeof(T1), out MonoBehaviour value)) { return null; } MonoBehaviour value2; return ((T1)(object)value, new Optional<T2>(prefabs.TryGetValue(typeof(T2), out value2) ? ((T2)(object)value2) : default(T2))); } private static (T1 F1, Optional<T2> F2, Optional<T3> F3)? Get<T1, T2, T3>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T1 : MonoBehaviour where T2 : MonoBehaviour where T3 : MonoBehaviour { if (!prefabs.TryGetValue(typeof(T1), out MonoBehaviour value)) { return null; } MonoBehaviour value2; MonoBehaviour value3; return ((T1)(object)value, new Optional<T2>(prefabs.TryGetValue(typeof(T2), out value2) ? ((T2)(object)value2) : default(T2)), new Optional<T3>(prefabs.TryGetValue(typeof(T3), out value3) ? ((T3)(object)value3) : default(T3))); } private static (T1 F1, Optional<T2> F2, Optional<T3> F3, Optional<T4> F4)? Get<T1, T2, T3, T4>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T1 : MonoBehaviour where T2 : MonoBehaviour where T3 : MonoBehaviour where T4 : MonoBehaviour { if (!prefabs.TryGetValue(typeof(T1), out MonoBehaviour value)) { return null; } MonoBehaviour value2; MonoBehaviour value3; MonoBehaviour value4; return ((T1)(object)value, new Optional<T2>(prefabs.TryGetValue(typeof(T2), out value2) ? ((T2)(object)value2) : default(T2)), new Optional<T3>(prefabs.TryGetValue(typeof(T3), out value3) ? ((T3)(object)value3) : default(T3)), new Optional<T4>(prefabs.TryGetValue(typeof(T4), out value4) ? ((T4)(object)value4) : default(T4))); } } internal static class PrivateAccessor { private static Action<ItemData, ZDO>? __loadFromZDO; private static Func<ConsoleCommand, ConsoleEvent?>? __getCommandAction; private static Func<ConsoleCommand, ConsoleEventFailable?>? __getCommandActionFailable; private static Func<IReadOnlyList<KeyButton>>? __getServerOptionsGUIPresets; private static Func<IReadOnlyList<KeyUI>>? __getServerOptionsGUIModifiers; private static Func<ZDOMan, IReadOnlyDictionary<ZDOID, ZDO>>? __getZDOManObjectsByID; private static Func<Localization, IReadOnlyDictionary<string, string>>? __getLocalizationStrings; private static Action<ZDOMan>? __convertPortals; public static Action<ItemData, ZDO> LoadFromZDO { get { Action<ItemData, ZDO>? action = __loadFromZDO; if (action == null) { MethodInfo? method = typeof(ItemDrop).GetMethod("LoadFromZDO", BindingFlags.Static | BindingFlags.NonPublic); ParameterExpression parameterExpression = Expression.Parameter(typeof(ItemData)); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ZDO)); action = (__loadFromZDO = Expression.Lambda<Action<ItemData, ZDO>>(Expression.Call(method, parameterExpression, parameterExpression2), new ParameterExpression[2] { parameterExpression, parameterExpression2 }).Compile()); } return action; } } public static Func<IReadOnlyList<KeyButton>> GetServerOptionsGUIPresets => __getServerOptionsGUIPresets ?? (__getServerOptionsGUIPresets = Expression.Lambda<Func<IReadOnlyList<KeyButton>>>(Expression.Field(null, typeof(ServerOptionsGUI).GetField("m_presets", BindingFlags.Static | BindingFlags.NonPublic)), Array.Empty<ParameterExpression>()).Compile()); public static Func<IReadOnlyList<KeyUI>> GetServerOptionsGUIModifiers => __getServerOptionsGUIModifiers ?? (__getServerOptionsGUIModifiers = Expression.Lambda<Func<IReadOnlyList<KeyUI>>>(Expression.Field(null, typeof(ServerOptionsGUI).GetField("m_modifiers", BindingFlags.Static | BindingFlags.NonPublic)), Array.Empty<ParameterExpression>()).Compile()); public static ConsoleEvent? GetAction(this ConsoleCommand command) { Func<ConsoleCommand, ConsoleEvent?>? func = __getCommandAction; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ConsoleCommand)); func = (__getCommandAction = Expression.Lambda<Func<ConsoleCommand, ConsoleEvent>>(Expression.Field(parameterExpression, typeof(ConsoleCommand).GetField("action", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func(command); } public static ConsoleEventFailable? GetActionFailable(this ConsoleCommand command) { Func<ConsoleCommand, ConsoleEventFailable?>? func = __getCommandActionFailable; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ConsoleCommand)); func = (__getCommandActionFailable = Expression.Lambda<Func<ConsoleCommand, ConsoleEventFailable>>(Expression.Field(parameterExpression, typeof(ConsoleCommand).GetField("actionFailable", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func(command); } public static IReadOnlyDictionary<ZDOID, ZDO> GetObjectsByID(this ZDOMan instance) { Func<ZDOMan, IReadOnlyDictionary<ZDOID, ZDO>>? func = __getZDOManObjectsByID; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ZDOMan)); func = (__getZDOManObjectsByID = Expression.Lambda<Func<ZDOMan, IReadOnlyDictionary<ZDOID, ZDO>>>(Expression.Field(parameterExpression, typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func(instance); } public static IReadOnlyDictionary<string, string> GetStrings(this Localization instance) { Func<Localization, IReadOnlyDictionary<string, string>>? func = __getLocalizationStrings; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(Localization)); func = (__getLocalizationStrings = Expression.Lambda<Func<Localization, IReadOnlyDictionary<string, string>>>(Expression.Field(parameterExpression, typeof(Localization).GetField("m_translations", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func(instance); } public static void ConvertPortals(this ZDOMan instance) { Action<ZDOMan>? action = __convertPortals; if (action == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ZDOMan)); action = (__convertPortals = Expression.Lambda<Action<ZDOMan>>(Expression.Call(parameterExpression, typeof(ZDOMan).GetMethod("ConvertPortals", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } action(instance); } } internal sealed record RuntimeInformation(string ModVersion, GameVersion GameVersion, uint NetworkVersion, int ItemDataVersion, int WorldVersion, string LoadedMods) { private sealed record Mod(string GUID, string Name, string? Version); public static RuntimeInformation Instance { get; } = Initialize(); private static RuntimeInformation Initialize() { //IL_004a: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) Type type = typeof(Game).Assembly.GetType("Version", throwOnError: true); object obj = type.GetProperty("CurrentVersion")?.GetValue(null); GameVersion gameVersion = ((!(obj is GameVersion)) ? default(GameVersion) : ((GameVersion)obj)); obj = type.GetField("m_networkVersion")?.GetValue(null); uint networkVersion = ((obj is uint) ? ((uint)obj) : 0u); obj = type.GetField("m_itemDataVersion")?.GetValue(null); int itemDataVersion = ((obj is int) ? ((int)obj) : 0); obj = type.GetField("m_worldVersion")?.GetValue(null); int worldVersion = ((obj is int) ? ((int)obj) : 0); IEnumerable<Mod> values = from x in Chainloader.PluginInfos.Values where x.Instance != Main.Instance select new Mod(x.Metadata.GUID, x.Metadata.Name, FormattableString.Invariant($"{x.Metadata.Version}")); string loadedMods = FormattableString.Invariant(FormattableStringFactory.Create("{{ {0} }}", string.Join(", ", values))); return new RuntimeInformation("0.2.13", gameVersion, networkVersion, itemDataVersion, worldVersion, loadedMods); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("ModVersion = "); builder.Append((object?)ModVersion); builder.Append(", GameVersion = "); GameVersion gameVersion = GameVersion; builder.Append(((object)(GameVersion)(ref gameVersion)).ToString()); builder.Append(", NetworkVersion = "); builder.Append(NetworkVersion.ToString()); builder.Append(", ItemDataVersion = "); builder.Append(ItemDataVersion.ToString()); builder.Append(", WorldVersion = "); builder.Append(WorldVersion.ToString()); builder.Append(", LoadedMods = "); builder.Append((object?)LoadedMods); return true; } [CompilerGenerated] private RuntimeInformation(RuntimeInformation original) { //IL_0014: 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) ModVersion = original.ModVersion; GameVersion = original.GameVersion; NetworkVersion = original.NetworkVersion; ItemDataVersion = original.ItemDataVersion; WorldVersion = original.WorldVersion; LoadedMods = original.LoadedMods; } } } namespace Valheim.ServersideQoL.Processors { internal sealed class ContainerProcessor : Processor { private readonly Dictionary<ItemKey, int> _stackPerItem = new Dictionary<ItemKey, int>(); public ContainerProcessor(ManualLogSource logger, ModConfig cfg) : base(logger, cfg) { } protected override bool ProcessCore(ExtendedZDO zdo, IEnumerable<ZNetPeer> peers) { //IL_0419: Unknown result type (might be due to invalid IL or missing references) if (!zdo.PrefabInfo.Container.HasValue || zdo.Vars.GetCreator(0L) == 0L) { base.UnregisterZdoProcessor = true; return false; } ExtendedZDO.ComponentFieldAccessor<Container> componentFieldAccessor = zdo.Fields<Container>(getUnknownComponent: false); IZDOInventory inventory = zdo.Inventory; int width = inventory.Inventory.GetWidth(); int height = inventory.Inventory.GetHeight(); int result; int result2; int num2; int num3; int num4; if (base.Config.Containers.ContainerSizes.TryGetValue(((ZDO)zdo).GetPrefab(), out ConfigEntry<string> value)) { string[] array = value.Value.Split(new char[1] { 'x' }, 2); if (array != null && array.Length == 2 && int.TryParse(array[0], out result) && int.TryParse(array[1], out result2)) { int num = width; num2 = height; num3 = result; num4 = result2; if (num != num3 || num2 != num4) { IZDOInventory inventory2 = zdo.Inventory; if (inventory2 != null) { IList<ItemData> items = inventory2.Items; if (items != null && items.Count == 0) { componentFieldAccessor.Set((Expression<Func<Container, int>>)((Container x) => x.m_width), width = result); componentFieldAccessor.Set((Expression<Func<Container, int>>)((Container x) => x.m_height), height = result2); base.RecreateZdo = true; return false; } } goto IL_01d2; } } } result = width; result2 = height; goto IL_01d2; IL_0368: bool flag = false; ItemData val = null; _stackPerItem.Clear(); foreach (ItemData item in from x in inventory.Items orderby (!x.IsEquipable()) ? 1 : 0, x.m_shared.m_name, x.m_stack descending select x) { if ((int)zdo.PrefabInfo.Container.Value.Container.m_privacy != 0) { ConcurrentHashSet<ExtendedZDO> orAdd = SharedProcessorState.ContainersByItemName.GetOrAdd(item.m_shared, (SharedItemDataKey _) => new ConcurrentHashSet<ExtendedZDO>()); orAdd.Add(zdo); } if (!base.Config.Containers.AutoSort.Value && !base.RecreateZdo) { continue; } if (val != null && new ItemKey(item) == val) { int num5 = Math.Min(item.m_stack, val.m_shared.m_maxStackSize - val.m_stack); ItemData obj = val; obj.m_stack += num5; item.m_stack -= num5; flag = true; } if (item.m_stack != 0) { if (!_stackPerItem.TryGetValue(item, out var value2)) { value2 = 0; } _stackPerItem[item] = value2 + 1;