using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; 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.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.Cil; using MonoMod.Utils; using ServersideQoL.CodeAnalysis; using SoftReferenceableAssets; using UnityEngine; using YamlDotNet.Serialization; using YamlDotNet.Serialization.TypeInspectors; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ArgusMagnus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("ArgusMagnus")] [assembly: AssemblyDescription("Serverside-only QoL mod, compatible with vanilla (e.g. XBox) clients. Stack from player inventories into nearby chests, generated portal hub, auto-sort chests, refuel smelters from containers, disable rain damage, infinite building/farming stamina and more")] [assembly: AssemblyFileVersion("1.99.8.0")] [assembly: AssemblyInformationalVersion("1.99.8-beta+328851184cc278c858ffbc70e717af9f9d7b6973")] [assembly: AssemblyProduct("ServersideQoL")] [assembly: AssemblyTitle("ServersideQoL")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")] [assembly: AssemblyVersion("1.99.8.0")] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlyList : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { int ICollection.Count => _items.Count; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => _items.Count; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Count; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyList(List items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return _items.Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { _items.CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return _items.IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator { object IEnumerator.Current => _item; T IEnumerator.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => 1; T IReadOnlyList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection.Count => 1; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return EqualityComparer.Default.Equals(_item, item); } void ICollection.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { if (!EqualityComparer.Default.Equals(_item, item)) { return -1; } return 0; } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [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] [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] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { private readonly string k__BackingField; public string Name => k__BackingField; public ExtensionMarkerAttribute(string name) { k__BackingField = name; } } } namespace ServersideQoL { public sealed class Config : ConfigBase { public sealed class AdvancedConfig { public sealed class ProcessingDelaysConfig { public float WhenNoNearbyPlayers { get; init; } = 2f; public float AfterContainerOwnershipRequest { get; init; } = 0.1f; } public sealed class ContainersConfig { public float MinOwnershipRequestInterval { get; init; } = 1f; } public sealed class PlayersConfig { public float UpdateStaminaInterval { get; init; } = 0.2f; } public ProcessingDelaysConfig ProcessingDelays { get; init; } = new ProcessingDelaysConfig(); public ContainersConfig Containers { get; init; } = new ContainersConfig(); public PlayersConfig Players { get; init; } = new PlayersConfig(); } private const string Section = "General"; public override ConfigEntry Enabled { get; } = ConfigBase.BindEx(cfg, "General", defaultValue: true, "Enables/disables the entire mod", null, null, "Enabled"); public ConfigEntry DiagnosticLogs { get; } = ConfigBase.BindEx(cfg, "General", defaultValue: false, "Enables/disables diagnostic logs", null, null, "DiagnosticLogs"); public ConfigEntry IgnoreGameVersionCheck { get; } = ConfigBase.BindEx(cfg, "General", defaultValue: 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", null, null, "IgnoreGameVersionCheck"); public ConfigEntry IgnoreNetworkVersionCheck { get; } = ConfigBase.BindEx(cfg, "General", defaultValue: 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", null, null, "IgnoreNetworkVersionCheck"); public ConfigEntry IgnoreItemDataVersionCheck { get; } = ConfigBase.BindEx(cfg, "General", defaultValue: 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", null, null, "IgnoreItemDataVersionCheck"); public ConfigEntry IgnoreWorldVersionCheck { get; } = ConfigBase.BindEx(cfg, "General", defaultValue: 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", null, null, "IgnoreWorldVersionCheck"); public ConfigEntry FarMessageRange { get; } = ConfigBase.BindEx(cfg, "General", 64f, $"Max distance a player can have to a modified object to receive messages of type {MessageTypes.TopLeftFar} or {MessageTypes.CenterFar}", null, null, "FarMessageRange"); public YamlConfigEntry Advanced { get; } = ConfigBase.BindYaml(cfg, "Advanced"); public Config(ConfigFile cfg, Logger logger) : base(cfg, logger) { } } internal interface IConfig { IServersideQoLPlugin Plugin { get; set; } ConfigEntry Enabled { get; } ConfigFile ConfigFile { get; } event EventHandler? ConfigChanged; void RaiseInitialized(); } public abstract class ConfigBase { protected static class Shared { [CompilerGenerated] private static ConfigEntry? k__BackingField; [CompilerGenerated] private static ConfigEntry? k__BackingField; [CompilerGenerated] private static ConfigEntry? k__BackingField; [CompilerGenerated] private static ConfigEntry? k__BackingField; public static ConfigEntry? AutoPickup { [CompilerGenerated] get { return k__BackingField; } set { Set(ref k__BackingField, value, "AutoPickup"); } } public static ConfigEntry? AutoPickupMaxRange { [CompilerGenerated] get { return k__BackingField; } set { Set(ref k__BackingField, value, "AutoPickupMaxRange"); } } public static ConfigEntry? FeedFromContainers { [CompilerGenerated] get { return k__BackingField; } set { Set(ref k__BackingField, value, "FeedFromContainers"); } } public static ConfigEntry? FeedFromContainersMaxRange { [CompilerGenerated] get { return k__BackingField; } set { Set(ref k__BackingField, value, "FeedFromContainersMaxRange"); } } private static void Set(ref T? field, T? value, [CallerMemberName] string configName = null) where T : class { if (field != null) { throw new Exception("Shared config " + configName + " already set"); } field = value; } } private protected interface IYamlConfigEntry { object Value { get; set; } } public sealed class YamlConfigEntry(T value) : IYamlConfigEntry where T : notnull { public T Value { [CompilerGenerated] get { return k__BackingField; } private set { IsDefault = value.Equals(k__BackingField); k__BackingField = value; } } public bool IsDefault { get; private set; } = true; object IYamlConfigEntry.Value { get { return Value; } set { Value = (T)value; } } } private protected sealed class MyTypeInspector(ITypeInspector inner) : TypeInspectorSkeleton() { private readonly ITypeInspector _inner = inner; public override string GetEnumName(Type enumType, string name) { return inner.GetEnumName(enumType, name); } public override string GetEnumValue(object enumValue) { return inner.GetEnumValue(enumValue); } public override IEnumerable GetProperties(Type type, object? container) { foreach (IPropertyDescriptor property in inner.GetProperties(type, container)) { if (!(property.Type == typeof(Type)) || !(property.Name == "EqualityContract")) { yield return property; } } } } public sealed class AcceptableEnum : AcceptableValueBase where T : unmanaged, Enum { private readonly T _default; public static AcceptableEnum Default { get; } = new AcceptableEnum(GetDefaultValues()); public IReadOnlyList AcceptableValues { get; } private static IEnumerable GetDefaultValues() { HashSet added = new HashSet(); T[] array = (T[])Enum.GetValues(typeof(T)); foreach (T val in array) { if (added.Add(val)) { yield return val; } } } public AcceptableEnum(IEnumerable values) : base(typeof(T)) { if (EnumUtils.IsBitSet()) { List list = new List(); list.AddRange(values.Where((T x) => x.ExactlyOneBitSet())); AcceptableValues = new <>z__ReadOnlyList(list); _default = default(T); return; } object obj = values as IReadOnlyList; if (obj == null) { List list2 = new List(); list2.AddRange(values); obj = new <>z__ReadOnlyList(list2); } AcceptableValues = (IReadOnlyList)obj; _default = AcceptableValues.FirstOrDefault(); } public override object Clamp(object value) { if (value is T) { T e = (T)value; if (EnumUtils.IsBitSet()) { 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(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()) { return "# Acceptable values: " + string.Join(", ", AcceptableValues); } return FormattableString.Invariant(FormattableStringFactory.Create("# Acceptable values: {0}\r\n# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)", string.Join(", ", AcceptableValues))); } } protected sealed class AcceptableFormatString(object[] testArgs) : AcceptableValueBase(typeof(string)) { public override bool IsValid(object value) { if (!(value is string format)) { return false; } try { string.Format(format, testArgs); } catch (FormatException) { return false; } return true; } public override object Clamp(object value) { return value; } public override string ToDescriptionString() { return FormattableString.Invariant(FormattableStringFactory.Create("# Acceptable value formats: .NET Format strings for {0} arguments ({1}): https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-string-format#get-started-with-the-stringformat-method", testArgs.Length, string.Join(", ", testArgs.Select((object x) => x.GetType().Name)))); } } public const Emotes DisabledEmote = (Emotes)(-1); public const Emotes AnyEmote = (Emotes)(-2); protected static IReadOnlyDictionary PieceTablesByPieceName => ServersideQoLPluginBase.Instance.PieceTablesByPieceName; private protected ConfigBase() { } } public abstract class ConfigBase(ConfigFile configFile, Logger logger) : ConfigBase(), IConfig where TSelf : ConfigBase { public sealed record Deprecated(string Reason, Action AdjustConfig); private static readonly HashSet __deprecatedEntries = new HashSet(); private static Dictionary? __yaml = new Dictionary(); private EventHandler? _configChanged; IServersideQoLPlugin IConfig.Plugin { get { return k__BackingField; } set { k__BackingField = value; } } public static TSelf Instance { get { return k__BackingField ?? throw new InvalidOperationException("Config has not been initialized yet"); } [CompilerGenerated] private set { k__BackingField = value; } } protected static IReadOnlyDictionary BossesByBiome => Processor.BossesByBiome; public ConfigFile ConfigFile { get; } = configFile; protected Logger Logger { get; } = logger; public abstract ConfigEntry Enabled { get; } private static event Action? Initialized; public event EventHandler? ConfigChanged { add { if (_configChanged == null) { ConfigFile.SettingChanged += OnSettingsChanged; } _configChanged = (EventHandler)Delegate.Combine(_configChanged, value); } remove { _configChanged = (EventHandler)Delegate.Remove(_configChanged, value); if (_configChanged == null) { ConfigFile.SettingChanged -= OnSettingsChanged; } } } private void OnSettingsChanged(object? sender, SettingChangedEventArgs args) { _configChanged?.Invoke(this, args); } void IConfig.RaiseInitialized() { Instance = (TSelf)this; foreach (var (configPath, entry) in __yaml) { BindYaml(configPath, entry); } __yaml = null; ConfigBase.Initialized?.Invoke(ConfigFile, (TSelf)this); } public static bool IsDeprecated(ConfigEntryBase entry) { return __deprecatedEntries.Contains(entry); } protected static ConfigEntry BindEx(ConfigFile config, string section, T defaultValue, string description, AcceptableValueBase? acceptableValues = null, Deprecated? deprecated = null, [CallerMemberName] string key = null) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown if ((object)deprecated != null) { description = string.Join(Environment.NewLine, "DEPRECATED: " + deprecated.Reason, description); } ConfigEntry cfg = config.Bind(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty())); if ((object)deprecated != null) { __deprecatedEntries.Add((ConfigEntryBase)(object)cfg); Initialized += OnInitialized; } return cfg; void OnInitialized(ConfigFile cfgFile, TSelf modConfig) { if (cfgFile == ((ConfigEntryBase)cfg).ConfigFile) { Initialized -= OnInitialized; cfg.SettingChanged += delegate { OnSettingChanged(deprecated, cfg, modConfig); }; OnSettingChanged(deprecated, cfg, modConfig); } } static void OnSettingChanged(Deprecated deprecated2, ConfigEntry val, TSelf modCfg) { if (!EqualityComparer.Default.Equals(val.Value, (T)((ConfigEntryBase)val).DefaultValue)) { deprecated2.AdjustConfig(modCfg); modCfg.Logger.LogWarning("[" + ((ConfigEntryBase)val).Definition.Section + "].[" + ((ConfigEntryBase)val).Definition.Key + "] is deprecated: " + deprecated2.Reason); } } } protected static YamlConfigEntry BindYaml(ConfigFile cfg, [CallerMemberName] string fileName = null) where T : notnull, new() { if (__yaml == null) { throw new InvalidOperationException("Config alredy initialized"); } string path = Path.Combine(Path.GetDirectoryName(cfg.ConfigFilePath), "ArgusMagnus.ServersideQoL"); string key = Path.Combine(path, Path.GetFileNameWithoutExtension(cfg.ConfigFilePath) + "." + fileName + ".yml"); YamlConfigEntry yamlConfigEntry = new YamlConfigEntry(new T()); __yaml.Add(key, yamlConfigEntry); return yamlConfigEntry; } private static void BindYaml(string configPath, IYamlConfigEntry entry) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown string directoryName = Path.GetDirectoryName(configPath); ISerializer val = ((BuilderSkeleton)(object)((BuilderSkeleton)new SerializerBuilder()).IncludeNonPublicProperties()).WithTypeInspector((Func)((ITypeInspector x) => new MyTypeInspector(x))).Build(); Directory.CreateDirectory(directoryName); string path = Path.ChangeExtension(configPath, "default.yml"); using (StreamWriter streamWriter = new StreamWriter(path, append: false)) { streamWriter.WriteLine("# " + Path.GetFileName(path) + " contains the default values and is overwritten regularly.\r\n# Rename it to " + Path.GetFileName(configPath) + " if you want to change values."); streamWriter.WriteLine(); WriteYamlHeader(streamWriter); val.Serialize((TextWriter)streamWriter, entry.Value); } if (!File.Exists(configPath)) { return; } try { IDeserializer val2 = ((BuilderSkeleton)(object)((BuilderSkeleton)(object)((BuilderSkeleton)new DeserializerBuilder()).IncludeNonPublicProperties()).EnablePrivateConstructors()).WithTypeInspector((Func)((ITypeInspector x) => new MyTypeInspector(x))).Build(); using (StreamReader streamReader = new StreamReader(configPath)) { entry.Value = val2.Deserialize((TextReader)streamReader, entry.Value.GetType()) ?? entry.Value; } ServersideQoLPluginBase.Logger.LogInfo("Advanced config loaded from " + Path.GetFileName(configPath)); } catch (Exception arg) { ServersideQoLPluginBase.Logger.LogWarning($"{Path.GetFileName(configPath)}: {arg}"); } } private static void WriteYamlHeader(StreamWriter writer) { writer.WriteLine("# IMPORTANT:\r\n# This file is for advanced tweaks.\r\n# You are expected to be familiar with YAML and its pitfalls if you decide to edit it.\r\n# Check the log for warnings related to this file.\r\n"); } } [Processor("fe73690f-6790-4cfa-9795-f93136d57286", OnlyWhenDependedOn = true)] public sealed class ContainerRegistryProcessor : Processor { public sealed record PrefabInfo(Container Container, Piece Piece, PieceTable PieceTable) : ProcessorPrefabInfo(); private sealed class ContainerStateImpl(ServersideQoLZDO zdo, Container container) : ContainerState(), ContainerState.IInventory { private Inventory? _inventory; private readonly ServersideQoLZDO _zdo = zdo; private readonly Container _container = container; private List? _items; private uint _dataRevision = uint.MaxValue; private byte[]? _data; private static readonly ZPackage _pkg = new ZPackage(); public DateTimeOffset NextOwnershipRequest { get; set; } public bool WaitingForResponse { get; set; } public long PreviousOwner { get; set; } public bool AddedToContainers { get; set; } public override Container Container => container; public override ServersideQoLZDO ZDO => zdo; Inventory IInventory.Inventory => _inventory; List IInventory.Items { get { if (_items == null) { _items = _inventory.GetAllItems(); } else if (_items != _inventory.GetAllItems()) { throw new Exception("Assumption violated"); } return _items; } } [MemberNotNull("_inventory")] public override IInventory GetInventory() { //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown if (_inventory != null && _dataRevision == zdo.ZDO.DataRevision) { return this; } byte[] items = zdo.Vars.GetItems(); if (_inventory != null) { if (items == _data) { return this; } if (items != null && _data != null && ((ReadOnlySpan)items).SequenceEqual((ReadOnlySpan)_data)) { return this; } } ServersideQoLZDO.ComponentFieldAccessor componentFieldAccessor = zdo.Fields(); int num = componentFieldAccessor.GetInt(() => (Container x) => x.m_width, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\ContainerRegistryProcessor.cs", 227); int num2 = componentFieldAccessor.GetInt(() => (Container x) => x.m_height, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\ContainerRegistryProcessor.cs", 228); if (_inventory == null || _inventory.GetWidth() != num || _inventory.GetHeight() != num2) { _inventory = new Inventory(container.m_name, container.m_bkg, num, num2); _items = null; } if (items == null || items.Length <= 0) { ((IInventory)this).Items.Clear(); } else { _pkg.Load(items); _inventory.Load(_pkg); } _dataRevision = zdo.ZDO.DataRevision; _data = items; return this; } void IInventory.Save() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) _pkg.Clear(); _inventory.Save(_pkg); uint dataRevision = zdo.ZDO.DataRevision; byte[] array = _pkg.GetArray(); zdo.Vars.SetItems(array, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\ContainerRegistryProcessor.cs", 268); if (dataRevision != zdo.ZDO.DataRevision) { if (zdo.PrefabInfo?.HasComponent() ?? false) { ZDO zDO = zdo.ZDO; zDO.DataRevision += 120; } ZDOMan.instance.ForceSendZDO(zdo.ZDO.m_uid); } _dataRevision = zdo.ZDO.DataRevision; _data = array; } } private readonly Dictionary _states = new Dictionary(); private readonly Dictionary>>> _containersByItemName = new Dictionary>>>(); private readonly Dictionary>>> _containers = new Dictionary>>>(); private bool _openResponseRegistered; private static int __returnContentToCreatorHash = ServersideQoLPluginBase.RegisterServerVar("ReturnContentToCreator"); public event Action? ContainerChanged; public SectorDictionary> GetContainersByItemName(float sectorWidth) { SectorDictionary> target; if (!_containersByItemName.TryGetValue(sectorWidth, out WeakReference>> value)) { _containersByItemName.Add(sectorWidth, new WeakReference>>(target = new SectorDictionary>(sectorWidth))); } else if (!value.TryGetTarget(out target)) { value.SetTarget(target = new SectorDictionary>(sectorWidth)); } return target; } public SectorDictionary> GetContainers(float sectorWidth) { SectorDictionary> target; if (!_containers.TryGetValue(sectorWidth, out WeakReference>> value)) { _containers.Add(sectorWidth, new WeakReference>>(target = new SectorDictionary>(sectorWidth))); } else if (!value.TryGetTarget(out target)) { value.SetTarget(target = new SectorDictionary>(sectorWidth)); } return target; } public ContainerState? GetState(ServersideQoLZDO zdo) { Container val = zdo.PrefabInfo?.GetComponent(); if (val == null) { return null; } return GetStateCore(zdo, val); } public ContainerState GetState(ServersideQoLZDO zdo, Container container) { return GetStateCore(zdo, container); } public void SetReturnContentToCreator(ServersideQoLZDO zdo, bool value) { zdo.ZDO.Set(__returnContentToCreatorHash, value); } public bool GetReturnContentToCreator(ServersideQoLZDO zdo, bool defaultValue = false) { return zdo.ZDO.GetBool(__returnContentToCreatorHash, defaultValue); } private ContainerStateImpl GetStateCore(ServersideQoLZDO zdo, Container container) { if (!_states.TryGetValue(zdo, out ContainerStateImpl value)) { _states.Add(zdo, value = new ContainerStateImpl(zdo, container)); zdo.Destroyed += delegate(ServersideQoLZDO x) { _states.Remove(x); }; } return value; } public float RequestOwnership(ServersideQoLZDO zdo, long playerID, [CallerFilePath] string caller = null, [CallerLineNumber] int callerLineNo = 0) { return RequestOwnership(zdo, playerID, _states[zdo], caller, callerLineNo); } public float RequestOwnership(ServersideQoLZDO zdo, long playerID, ContainerState state, [CallerFilePath] string caller = null, [CallerLineNumber] int callerLineNo = 0) { if (zdo.IsOwnerOrUnassigned() || !(state is ContainerStateImpl containerStateImpl) || DateTimeOffset.UtcNow < containerStateImpl.NextOwnershipRequest) { return ConfigBase.Instance.Advanced.Value.ProcessingDelays.AfterContainerOwnershipRequest; } if (!_openResponseRegistered && Player.m_localPlayer != null) { RPC.Intercept.UpdateInterception("OpenRespons", new Func(RPC_OpenResponse), _openResponseRegistered = true); } containerStateImpl.NextOwnershipRequest = DateTimeOffset.UtcNow.AddSeconds(ConfigBase.Instance.Advanced.Value.Containers.MinOwnershipRequestInterval); containerStateImpl.WaitingForResponse = true; containerStateImpl.PreviousOwner = zdo.ZDO.GetOwner(); RPC.RequestOpen(zdo, playerID); return ConfigBase.Instance.Advanced.Value.ProcessingDelays.AfterContainerOwnershipRequest; } protected internal override void Initialize() { _states.Clear(); RPC.Intercept.UpdateInterception("OpenRespons", new Func(RPC_OpenResponse), _openResponseRegistered = false); } protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList peers, PrefabInfo prefabInfo) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) long num = 0L; if ((int)prefabInfo.Container.m_privacy == 0 || (num = zdo.Vars.GetCreator(0L)) == 0L) { return ProcessResult.UnregisterProcessor; } ContainerStateImpl containerStateImpl = null; if (GetReturnContentToCreator(zdo)) { PlayerState stateForPlayerID = Processor.Instance().GetStateForPlayerID(num); if (stateForPlayerID != null) { containerStateImpl = GetStateCore(zdo, prefabInfo.Container); if (containerStateImpl.GetInventory().Items.Count == 0) { return ProcessResult.DestroyZDO; } if (zdo.ZDO.GetOwner() != stateForPlayerID.Owner) { zdo.ZDO.SetOwner(stateForPlayerID.Owner); } else { RPC.TakeAllResponse(zdo, granted: true); } } return ProcessResult.ScheduleReprocessing; } if (zdo.Vars.GetInUse()) { return ProcessResult.Default; } if (containerStateImpl == null) { containerStateImpl = GetStateCore(zdo, prefabInfo.Container); } List list = null; float key; if (_containers.Count != 0 && !containerStateImpl.AddedToContainers) { containerStateImpl.AddedToContainers = true; foreach (KeyValuePair>>> container in _containers) { container.Deconstruct(out key, out var value); float item = key; WeakReference>> weakReference = value; if (!weakReference.TryGetTarget(out var target)) { (list ?? (list = new List())).Add(item); } else { target.Add(zdo); } } if (list != null) { foreach (float item3 in list) { _containers.Remove(item3); } } } if (_containersByItemName.Count != 0) { ContainerState.IInventory inventory = null; list?.Clear(); foreach (KeyValuePair>>> item4 in _containersByItemName) { item4.Deconstruct(out key, out var value2); float item2 = key; WeakReference>> weakReference2 = value2; if (!weakReference2.TryGetTarget(out var target2)) { (list ?? (list = new List())).Add(item2); continue; } if (inventory == null) { inventory = containerStateImpl.GetInventory(); } foreach (ItemData item5 in inventory.Items) { target2.TryAdd(item5.m_shared, zdo); } } if (list != null) { foreach (float item6 in list) { _containersByItemName.Remove(item6); } } } this.ContainerChanged?.Invoke(zdo, containerStateImpl); return ProcessResult.Default; } private bool RPC_OpenResponse(ServersideQoLZDO? zdo, bool granted) { if (zdo == null || !_states.TryGetValue(zdo, out ContainerStateImpl value) || !value.WaitingForResponse) { return true; } value.WaitingForResponse = false; return false; } } public abstract class ContainerState { public interface IInventory { Inventory Inventory { get; } List Items { get; } void Save(); } public abstract Container Container { get; } public abstract ServersideQoLZDO ZDO { get; } public float? PickupRange { get; set; } public float? FeedRange { get; set; } private protected ContainerState() { } public abstract IInventory GetInventory(); } internal sealed class DummySocket : ISocket { public ISocket Accept() { throw new NotImplementedException(); } public void Close() { } public void Dispose() { } public bool Flush() { throw new NotImplementedException(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { throw new NotImplementedException(); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { throw new NotImplementedException(); } public int GetCurrentSendRate() { throw new NotImplementedException(); } public string GetEndPointString() { throw new NotImplementedException(); } public string GetHostName() { return ""; } public int GetHostPort() { throw new NotImplementedException(); } public int GetSendQueueSize() { throw new NotImplementedException(); } public bool GotNewData() { throw new NotImplementedException(); } public bool IsConnected() { return true; } public bool IsHost() { throw new NotImplementedException(); } public ZPackage Recv() { throw new NotImplementedException(); } public void Send(ZPackage pkg) { throw new NotImplementedException(); } public void VersionMatch() { throw new NotImplementedException(); } } public static class EmptyReadOnlyCollections { public static IReadOnlyDictionary Dictionary { get; } = new ReadOnlyDictionary(new Dictionary(0)); } public static class EnumUtils { private static class Generic where T : unmanaged, Enum { public static bool IsBitSet { get; } = OfType(typeof(T)).IsBitSet; public static Func EnumToUInt64 { get; } public static Func UInt64ToEnum { get; } public static Func EnumToInt64 { get; } public static Func Int64ToEnum { get; } static Generic() { ParameterExpression parameterExpression = Expression.Parameter(typeof(T)); EnumToUInt64 = Expression.Lambda>(Expression.ConvertChecked(parameterExpression, typeof(ulong)), new ParameterExpression[1] { parameterExpression }).Compile(); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ulong)); UInt64ToEnum = Expression.Lambda>(Expression.ConvertChecked(parameterExpression2, typeof(T)), new ParameterExpression[1] { parameterExpression2 }).Compile(); ParameterExpression parameterExpression3 = Expression.Parameter(typeof(T)); EnumToInt64 = Expression.Lambda>(Expression.ConvertChecked(parameterExpression3, typeof(long)), new ParameterExpression[1] { parameterExpression3 }).Compile(); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(long)); Int64ToEnum = Expression.Lambda>(Expression.ConvertChecked(parameterExpression4, typeof(T)), new ParameterExpression[1] { parameterExpression4 }).Compile(); } } public sealed class ObjectEnumUtils { public bool IsBitSet { get; } = enumType.GetCustomAttribute() != null; public Func EnumToUInt64 { get; } public Func UInt64ToEnum { get; } public Func EnumToInt64 { get; } public Func Int64ToEnum { get; } public ObjectEnumUtils(Type enumType) { ParameterExpression parameterExpression = Expression.Parameter(typeof(object)); EnumToUInt64 = Expression.Lambda>(Expression.ConvertChecked(Expression.Convert(parameterExpression, enumType), typeof(ulong)), new ParameterExpression[1] { parameterExpression }).Compile(); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ulong)); UInt64ToEnum = Expression.Lambda>(Expression.Convert(Expression.ConvertChecked(parameterExpression2, enumType), typeof(object)), new ParameterExpression[1] { parameterExpression2 }).Compile(); ParameterExpression parameterExpression3 = Expression.Parameter(typeof(object)); EnumToInt64 = Expression.Lambda>(Expression.ConvertChecked(Expression.Convert(parameterExpression3, enumType), typeof(long)), new ParameterExpression[1] { parameterExpression3 }).Compile(); ParameterExpression parameterExpression4 = Expression.Parameter(typeof(long)); Int64ToEnum = Expression.Lambda>(Expression.Convert(Expression.ConvertChecked(parameterExpression4, enumType), typeof(object)), new ParameterExpression[1] { parameterExpression4 }).Compile(); base..ctor(); } } private static readonly ConcurrentDictionary __isBitSet = new ConcurrentDictionary(); public static ObjectEnumUtils OfType(Type type) { return __isBitSet.GetOrAdd(type, (Type t) => new ObjectEnumUtils(t)); } public static bool IsBitSet() where T : unmanaged, Enum { return Generic.IsBitSet; } public static ulong ToUInt64(this T value) where T : unmanaged, Enum { return Generic.EnumToUInt64(value); } public static T ToEnum(ulong value) where T : unmanaged, Enum { return Generic.UInt64ToEnum(value); } public static long ToInt64(this T value) where T : unmanaged, Enum { return Generic.EnumToInt64(value); } public static T ToEnum(long value) where T : unmanaged, Enum { return Generic.Int64ToEnum(value); } public static bool ExactlyOneBitSet(this T value) where T : unmanaged, Enum { bool flag = false; for (ulong num = value.ToUInt64(); num != 0L; num &= num - 1) { if (flag) { return false; } flag = true; } return flag; } } public static class Extensions { [SpecialName] public sealed class $C4EAF3E49419DCB8F1AA1FAC028204B4 { [SpecialName] public static class $FF334B291A5568FFD90BBDD3AE876A53 { } [ExtensionMarker("$FF334B291A5568FFD90BBDD3AE876A53")] public int ActiveArea { [ExtensionMarker("$FF334B291A5568FFD90BBDD3AE876A53")] get { throw new NotSupportedException(); } } [ExtensionMarker("$FF334B291A5568FFD90BBDD3AE876A53")] public int LoadedArea { [ExtensionMarker("$FF334B291A5568FFD90BBDD3AE876A53")] get { throw new NotSupportedException(); } } } public static float GetHeight(this Heightmap hmap, Vector3 pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) int num = default(int); int num2 = default(int); hmap.WorldToVertex(pos, ref num, ref num2); return hmap.GetHeight(num, num2); } public static int get_ActiveArea(ZoneSystem zoneSystem) { return zoneSystem.m_activeArea - 1; } public static int get_LoadedArea(ZoneSystem zoneSystem) { return zoneSystem.m_activeArea; } } public readonly record struct GlobalKey(string Key) { public GlobalKey(string Key) { this.Key = Key; } public unsafe GlobalKey(GlobalKeys key) : this(((object)(*(GlobalKeys*)(&key))/*cast due to .constrained prefix*/).ToString().ToLower()) { } public static implicit operator string(in GlobalKey key) { return key.Key; } } public readonly record struct ItemDataKey(string Name, int Quality, int Variant) { public ItemDataKey(string Name, int Quality, int Variant) { this.Name = Name; this.Quality = Quality; this.Variant = Variant; } public static implicit operator ItemDataKey(ItemData data) { return new ItemDataKey(data); } public ItemDataKey(ItemData data) : this(data.m_shared.m_name, data.m_quality, data.m_variant) { } } public readonly record struct SharedItemDataKey(string Name) { public static implicit operator SharedItemDataKey(SharedData data) { return new SharedItemDataKey(data.m_name); } public static implicit operator SharedItemDataKey(ItemData data) { return new SharedItemDataKey(data.m_shared.m_name); } } public sealed class ItemDataKeyComparer : EqualityComparer { public static ItemDataKeyComparer Instance { get; } = new ItemDataKeyComparer(); public override bool Equals(ItemData x, ItemData y) { return new ItemDataKey(x) == y; } public override int GetHashCode(ItemData obj) { return new ItemDataKey(obj).GetHashCode(); } } public sealed class SharedItemDataKeyComparer : EqualityComparer { public static SharedItemDataKeyComparer Instance { get; } = new SharedItemDataKeyComparer(); public override bool Equals(ItemData x, ItemData y) { return (SharedItemDataKey)x == (SharedItemDataKey)y; } public override int GetHashCode(ItemData obj) { return ((SharedItemDataKey)obj/*cast due to .constrained prefix*/).GetHashCode(); } } public static class ListExtensions { public readonly struct ListEnumerable { public struct Enumerator : IEnumerator, IEnumerator, IDisposable { private readonly IReadOnlyList _list; private readonly int _count; private int _index; public T Current { get; private set; } readonly object? IEnumerator.Current => Current; public Enumerator(IReadOnlyList list) { _list = list; _count = list.Count; _index = -1; Current = default(T); } public void Dispose() { Current = default(T); } public bool MoveNext() { if (++_index < _count) { Current = _list[_index]; return true; } Current = default(T); return false; } public void Reset() { _index = -1; } } private readonly IReadOnlyList _list; public ListEnumerable(IReadOnlyList list) { _list = list; } public Enumerator GetEnumerator() { return new Enumerator(_list); } } public static ListEnumerable Enumerate(this IReadOnlyList list) { return new ListEnumerable(list); } public static void InsertSorted(this List list, T item) where T : IComparable { int num = list.BinarySearch(item); if (num < 0) { num = ~num; } list.Insert(num, item); } } public sealed class Logger : ILogSource, IDisposable { private readonly ManualLogSource _logger = Logger.CreateLogSource(sourceName); public string SourceName => _logger.SourceName; public event EventHandler LogEvent { add { _logger.LogEvent += value; } remove { _logger.LogEvent -= value; } } public Logger(string sourceName) { } public void Dispose() { _logger.Dispose(); } public void Log(LogLevel level, object data) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; TimeSpan timeSpan = TimeSpan.FromSeconds(realtimeSinceStartupAsDouble); if (realtimeSinceStartupAsDouble < 86400.0) { _logger.Log(level, (object)$"[{timeSpan:hh\\:mm\\:ss\\.fff}] {data}"); } else { _logger.Log(level, (object)$"[{timeSpan:d\\.hh\\:mm\\:ss\\.fff}] {data}"); } } public void LogFatal(object data) { Log((LogLevel)1, data); } public void LogError(object data) { Log((LogLevel)2, data); } public void LogWarning(object data) { Log((LogLevel)4, data); } public void LogMessage(object data) { Log((LogLevel)8, data); } public void LogInfo(object data) { Log((LogLevel)16, data); } public void LogDebug(object data) { Log((LogLevel)32, data); } [Conditional("DEBUG")] public void DevLog(string text, LogLevel logLevel = (LogLevel)4) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Log(logLevel, text); } [Conditional("DEBUG")] public void DevLogIf(bool condition, string text, LogLevel logLevel = (LogLevel)4) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (condition) { Log(logLevel, text); } } } public enum MessageTypes { None, TopLeftNear, TopLeftFar, CenterNear, CenterFar, InWorld } public sealed class Peer(ZNetPeer peer) { [CompilerGenerated] private PlayerState? k__BackingField; public ZNetPeer ZNetPeer { get; } = peer; public Vector3 RefPos { get { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) PlayerState? playerState = PlayerState; if (playerState == null) { return ZNetPeer.m_refPos; } return playerState.ZDO.ZDO.GetPosition(); } } public IReadOnlyDictionary ServerSyncedPlayerData { get { ZNetPeer zNetPeer = ZNetPeer; if (zNetPeer == null || zNetPeer.m_server) { return ZNet.instance.m_serverSyncedPlayerData; } return ZNetPeer.m_serverSyncedPlayerData; } } public PlayerState? PlayerState { get { if (k__BackingField == null) { k__BackingField = Processor.Instance().GetStateForPeerID(ZNetPeer.m_uid); PlayerState? playerState = k__BackingField; if (playerState != null) { playerState.ZDO.Destroyed += delegate { k__BackingField = null; }; } } return k__BackingField; } } public Vector2s GetSector() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ZoneSystem.GetZone(RefPos); } public string GetHostName() { return ZNetPeer.m_socket.GetHostName() ?? ""; } public override bool Equals(object obj) { return object.Equals(ZNetPeer, obj); } public override int GetHashCode() { return ((object)ZNetPeer).GetHashCode(); } } public sealed class PeersEnumerable(ZNetPeer? localPeer) : IEnumerable, IEnumerable { public struct Enumerator : IEnumerator, IEnumerator, IDisposable { private readonly PeersEnumerable _enumerable; private int _index; public Peer Current { get; private set; } readonly object IEnumerator.Current => Current; public Enumerator(PeersEnumerable enumerable) { _enumerable = enumerable; _index = -2; Current = null; } public void Dispose() { Current = null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { if (++_index < 0) { if (_enumerable.localPeer != null) { Current = _enumerable.localPeer.ServersideQoLPeer; return true; } _index++; } if (_index < _enumerable._peers.Count) { Current = _enumerable._peers[_index].ServersideQoLPeer; return true; } Current = null; return false; } public void Reset() { _index = -2; } } private readonly ZNetPeer? _localPeer = localPeer; private List _peers = new List(); public int Count => _peers.Count + ((localPeer != null) ? 1 : 0); internal void Update() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (localPeer != null) { localPeer.m_refPos = ZNet.instance.GetReferencePosition(); } _peers = ZNet.instance.GetPeers(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator GetEnumerator() { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [Processor("b5107f88-1c1f-4323-bfce-9205ae4dfcd9", OnlyWhenDependedOn = true)] public sealed class PlayerRegistryProcessor : Processor> { public delegate void ItemUsedHandler(PlayerState state, string animationTriggerName); private sealed class PlayerStateImpl(ServersideQoLZDO zdo, ProcessorPrefabInfo prefabInfo, PlayerRegistryProcessor processor) : PlayerState() { private readonly ServersideQoLZDO _zdo = zdo; private readonly ProcessorPrefabInfo _prefabInfo = prefabInfo; private readonly PlayerRegistryProcessor _processor = processor; private readonly ZNetPeer? _peer = ZNet.instance.GetPeer(zdo.ZDO.GetOwner()); private string? _playerName; private bool? _isAdmin; private int _stamina; private Timestamp _staminaTimestamp; private int _eitr; private Timestamp _eitrTimestamp; private ItemDrop? _lastUsedItem; [CompilerGenerated] private Dictionary k__BackingField; [CompilerGenerated] private Dictionary Queue, List List)> k__BackingField; private bool _hasChangedGlobalKeyModifications; private Dictionary? _globalKeyModifications; public override ServersideQoLZDO ZDO => zdo; public override ProcessorPrefabInfo PrefabInfo => prefabInfo; public override long Owner { get; } = zdo.ZDO.GetOwner(); public override long PlayerID { get; } = zdo.Vars.GetPlayerID(0L); public override string PlayerName => _playerName ?? (_playerName = ZDO.Vars.GetPlayerName()); public override bool IsAdmin { get { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) bool valueOrDefault = _isAdmin == true; if (!_isAdmin.HasValue) { Player localPlayer = Player.m_localPlayer; ZDOID? val = ((localPlayer != null) ? new ZDOID?(((Character)localPlayer).GetZDOID()) : ((ZDOID?)null)); ZDOID uid = ZDO.ZDO.m_uid; int num; if (!val.HasValue || !(val.GetValueOrDefault() == uid)) { ZNet instance = ZNet.instance; ZNetPeer? peer = _peer; num = (instance.IsAdmin(((peer != null) ? peer.m_socket.GetHostName() : null) ?? "") ? 1 : 0); } else { num = 1; } valueOrDefault = (byte)num != 0; _isAdmin = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } public int LastEmoteId { get; set; } public Timestamp NextStaminaCheck { get; set; } public override int Stamina => _stamina; public Timestamp StaminaTimestamp => _staminaTimestamp; public override int Eitr => _eitr; public Timestamp EitrTimestamp => _eitrTimestamp; public override ItemDrop? LastUsedItem => _lastUsedItem; public ItemDrop? CheckSkillItem { get; set; } public float CheckSkillStaminaEitr { get; set; } public Dictionary EstimatedSkillLevels => k__BackingField ?? (k__BackingField = new Dictionary()); public Dictionary Queue, List List)> EstimatedSkillLevelHistories => k__BackingField ?? (k__BackingField = new Dictionary, List)>()); public override IReadOnlyDictionary GlobalKeyModifications { get { IReadOnlyDictionary globalKeyModifications = _globalKeyModifications; return globalKeyModifications ?? EmptyReadOnlyCollections.Dictionary; } } public bool UpdateStamina(int value, Timestamp timestamp) { if (_stamina == value) { return false; } _stamina = value; _staminaTimestamp = timestamp; return true; } public bool UpdateEitr(int value, Timestamp timestamp) { if (_eitr == value) { return false; } _eitr = value; _eitrTimestamp = timestamp; return true; } public void SetLastUsedItem(ItemDrop item) { _lastUsedItem = item; } public override float GetEstimatedSkillLevel(SkillType skillType) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!processor._estimateSkillLevels) { throw new InvalidOperationException("EnableSkillLevelEstimation(true) must be called before calling GetEstimatedSkillLevel"); } if (!EstimatedSkillLevels.TryGetValue(skillType, out var value)) { EstimatedSkillLevels.Add(skillType, value = PlayerRegistryProcessor.GetEstimatedSkillLevel(PlayerID, skillType, float.NaN)); } return value; } public override void AddGlobalKeyModification(GlobalKey key, bool add) { if (_globalKeyModifications == null) { _globalKeyModifications = new Dictionary(); } if (_globalKeyModifications.TryAdd(key, add)) { _hasChangedGlobalKeyModifications = true; } } public override void RemoveGlobalKeyModification(GlobalKey key) { if (_globalKeyModifications?.Remove(key) ?? false) { _hasChangedGlobalKeyModifications = true; } } public void SendGlobalKeyModifications() { if (_hasChangedGlobalKeyModifications) { ZoneSystem.instance.SendGlobalKeys(ZDO.ZDO.GetOwner()); _hasChangedGlobalKeyModifications = false; } } } private readonly Dictionary _statesByPeerID = new Dictionary(); private readonly Dictionary _statesByPlayerID = new Dictionary(); private readonly Dictionary _statesByCharacterID = new Dictionary(); private readonly HashSet<(string, int)> _estimateSkillLevelsFor = new HashSet<(string, int)>(); private bool _estimateSkillLevels; private ItemUsedHandler? _itemUsed; public IReadOnlyCollection PlayerStates => _statesByPeerID.Values; public event Action? EmoteDetected; public event Action? StaminaUpdated; public event ItemUsedHandler? ItemUsed { add { if (_itemUsed == null && value != null && !_estimateSkillLevels) { RPC.Intercept.UpdateInterception("SetTrigger", new Action(OnZSyncAnimationSetTrigger), enable: true); } _itemUsed = (ItemUsedHandler)Delegate.Combine(_itemUsed, value); } remove { bool flag = _itemUsed != null; _itemUsed = (ItemUsedHandler)Delegate.Remove(_itemUsed, value); if (_itemUsed == null && flag && !_estimateSkillLevels) { RPC.Intercept.UpdateInterception("SetTrigger", new Action(OnZSyncAnimationSetTrigger), enable: false); } } } public PlayerState? GetStateForPeerID(long peerID) { if (!_statesByPeerID.TryGetValue(peerID, out PlayerStateImpl value)) { return null; } return value; } public PlayerState? GetStateForPlayerID(long playerID) { if (!_statesByPlayerID.TryGetValue(playerID, out PlayerStateImpl value)) { return null; } return value; } public PlayerState? GetStateForCharacterID(ZDOID characterID) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!_statesByCharacterID.TryGetValue(characterID, out PlayerStateImpl value)) { return null; } return value; } public PlayerState GetState(ServersideQoLZDO playerZdo) { ProcessorPrefabInfo processorPrefabInfo = Processor>.GetProcessorPrefabInfo(playerZdo); return GetStateCore(playerZdo, processorPrefabInfo); } public void EnableSkillLevelEstimation(bool enable, [CallerMemberName] string filename = null, [CallerLineNumber] int lineNo = 0) { if ((enable ? _estimateSkillLevelsFor.Add((filename, lineNo)) : _estimateSkillLevelsFor.Remove((filename, lineNo))) && _estimateSkillLevels != (_estimateSkillLevelsFor.Count != 0)) { _estimateSkillLevels = !_estimateSkillLevels; if (_estimateSkillLevels && _itemUsed == null) { RPC.Intercept.UpdateInterception("SetTrigger", new Action(OnZSyncAnimationSetTrigger), enable: true); } else if (!_estimateSkillLevels && _itemUsed == null) { RPC.Intercept.UpdateInterception("SetTrigger", new Action(OnZSyncAnimationSetTrigger), enable: false); } } } protected internal override void Initialize() { _statesByPeerID.Clear(); _statesByPlayerID.Clear(); _statesByCharacterID.Clear(); } protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList peers, ProcessorPrefabInfo prefabInfo) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) PlayerStateImpl stateCore = GetStateCore(zdo, prefabInfo); if (this.EmoteDetected != null) { int emoteID = zdo.Vars.GetEmoteID(); if (emoteID != stateCore.LastEmoteId) { stateCore.LastEmoteId = emoteID; Emotes emote = zdo.Vars.GetEmote((Emotes)(-1)); if ((int)emote != -1) { this.EmoteDetected(stateCore, emote); } } } if (this.StaminaUpdated != null || _estimateSkillLevels) { Timestamp now = Timestamp.Now; if (stateCore.NextStaminaCheck < now) { stateCore.NextStaminaCheck = now.AddSeconds(ConfigBase.Instance.Advanced.Value.Players.UpdateStaminaInterval); int value = Mathf.FloorToInt(zdo.Vars.GetStamina()); if (stateCore.UpdateStamina(value, now)) { this.StaminaUpdated?.Invoke(stateCore); } stateCore.UpdateEitr(Mathf.FloorToInt(zdo.Vars.GetEitr()), now); } } if (_estimateSkillLevels && stateCore.CheckSkillItem != null) { bool flag = stateCore.CheckSkillItem.m_itemData.m_shared.m_attack.m_attackEitr > 0f; float num = (flag ? zdo.Vars.GetEitr() : zdo.Vars.GetStamina()); if (num < stateCore.CheckSkillStaminaEitr) { SharedData shared = stateCore.CheckSkillItem.m_itemData.m_shared; float num2 = (flag ? shared.m_attack.m_attackEitr : shared.m_attack.m_attackStamina); float num3 = stateCore.CheckSkillStaminaEitr - num; float num4 = num2 - num3; float num5 = num4 / (num2 * 0.33f); if (num5 >= 0f && num5 <= 1f) { float estimatedSkillLevel = stateCore.GetEstimatedSkillLevel(shared.m_skillType); if (!stateCore.EstimatedSkillLevelHistories.TryGetValue(shared.m_skillType, out (Queue, List) value2)) { Dictionary Queue, List List)> estimatedSkillLevelHistories = stateCore.EstimatedSkillLevelHistories; SkillType skillType = shared.m_skillType; value2 = (new Queue(7), new List(7)); estimatedSkillLevelHistories.Add(skillType, value2); if (!float.IsNaN(estimatedSkillLevel)) { for (int i = 0; i < 7; i++) { value2.Item1.Enqueue(estimatedSkillLevel); value2.Item2.Add(estimatedSkillLevel); } } } while (value2.Item1.Count >= 7) { value2.Item2.Remove(value2.Item1.Dequeue()); } value2.Item1.Enqueue(num5); value2.Item2.InsertSorted(num5); num5 = value2.Item2[value2.Item2.Count / 2]; stateCore.EstimatedSkillLevels[shared.m_skillType] = num5; SetEstimatedSkillLevel(stateCore.PlayerID, shared.m_skillType, num5); float num6 = Mathf.Floor(num5 * 100f); float num7 = Mathf.Floor(estimatedSkillLevel * 100f); if (num6 != num7) { base.Logger.Log((LogLevel)((num6 - num7 > 1f) ? 4 : 16), $"Player {stateCore.PlayerName}: Estimated {shared.m_skillType} skill level: {num6}, Previous estimate: {num7} (Item: {((Object)stateCore.CheckSkillItem).name}, max stamina: {num2}, used stamina: {num3})"); } } stateCore.CheckSkillItem = null; } } stateCore.SendGlobalKeyModifications(); return ProcessResult.Default; } private PlayerStateImpl GetStateCore(ServersideQoLZDO zdo, ProcessorPrefabInfo prefabInfo) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) long owner = zdo.ZDO.GetOwner(); if (!_statesByPeerID.TryGetValue(owner, out PlayerStateImpl value)) { _statesByPeerID.Add(owner, value = new PlayerStateImpl(zdo, prefabInfo, this)); _statesByPlayerID[value.PlayerID] = value; _statesByCharacterID[zdo.ZDO.m_uid] = value; zdo.Destroyed += OnPlayerDestroyed; } return value; } private void OnPlayerDestroyed(ServersideQoLZDO zdo) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (_statesByPeerID.Remove(((ZDOID)(ref zdo.ZDO.m_uid)).UserID, out PlayerStateImpl value)) { _statesByCharacterID.Remove(zdo.ZDO.m_uid); if (_statesByPlayerID.Remove(value.PlayerID, out PlayerStateImpl value2) && value2 != value) { _statesByPlayerID.Add(value.PlayerID, value2); } } } private void OnZSyncAnimationSetTrigger(RoutedRPCData data, string name) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (!(Processor.Instance().GetStateForCharacterID(data.m_targetZDO) is PlayerStateImpl playerStateImpl)) { return; } ItemDrop val = GetItem(playerStateImpl.ZDO.Vars.GetRightItem(), playerStateImpl, name) ?? GetItem(playerStateImpl.ZDO.Vars.GetLeftItem(), playerStateImpl, name); if (val == null) { return; } playerStateImpl.SetLastUsedItem(val); _itemUsed?.Invoke(playerStateImpl, name); if (!_estimateSkillLevels) { return; } playerStateImpl.CheckSkillItem = null; Timestamp now = Timestamp.Now; SharedData shared = val.m_itemData.m_shared; bool flag; if (shared != null) { Attack attack = shared.m_attack; if (attack != null) { float attackStamina = attack.m_attackStamina; if (attackStamina > 0f) { SkillType skillType = shared.m_skillType; if ((int)skillType == 1) { DamageTypes damages = shared.m_damages; float slash = damages.m_slash; if (!(slash > 0f)) { goto IL_00eb; } } flag = true; goto IL_00ee; } } } goto IL_00eb; IL_00ee: if (flag) { if (playerStateImpl.StaminaTimestamp < now.AddSeconds(-1.5f * playerStateImpl.PrefabInfo.Component.m_staminaRegenDelay)) { float stamina = playerStateImpl.ZDO.Vars.GetStamina(); int value = Mathf.FloorToInt(stamina); if (playerStateImpl.UpdateStamina(value, now)) { this.StaminaUpdated?.Invoke(playerStateImpl); } else if (stamina >= 2f * val.m_itemData.m_shared.m_attack.m_attackStamina) { playerStateImpl.CheckSkillStaminaEitr = stamina; playerStateImpl.CheckSkillItem = val; } } } else if (val.m_itemData.m_shared.m_attack.m_attackEitr > 0f && playerStateImpl.EitrTimestamp < now.AddSeconds(-1.5f * playerStateImpl.PrefabInfo.Component.m_eitrRegenDelay)) { float eitr = playerStateImpl.ZDO.Vars.GetEitr(); int value2 = Mathf.FloorToInt(eitr); if (!playerStateImpl.UpdateEitr(value2, now)) { playerStateImpl.CheckSkillStaminaEitr = eitr; playerStateImpl.CheckSkillItem = val; } } return; IL_00eb: flag = false; goto IL_00ee; } private ItemDrop? GetItem(int prefab, PlayerStateImpl state, string triggerName) { if (prefab == 0) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if (val == null) { base.Logger.LogWarning($"Player {state.PlayerName}: SetTrigger({triggerName}): Item prefab '{prefab}' not found"); return null; } Attack val2 = val?.m_itemData.m_shared.m_attack; if (val2 == null) { return null; } if (val2.m_attackChainLevels > 1 || val2.m_attackRandomAnimations >= 2) { if (Regex.IsMatch(triggerName, "^" + Regex.Escape(val2.m_attackAnimation) + "\\d+$")) { return val; } } else if (triggerName == val2.m_attackAnimation) { return val; } return null; } private static float GetEstimatedSkillLevel(long playerID, SkillType skill, float defaultValue = 0f) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) return Processor.DataZDO.ZDO.GetFloat($"player{playerID}_EstimatedSkillLevel_{skill}", defaultValue); } private static void SetEstimatedSkillLevel(long playerID, SkillType skill, float value) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Processor.DataZDO.ZDO.Set($"player{playerID}_EstimatedSkillLevel_{skill}", value); } } public abstract class PlayerState { public abstract ServersideQoLZDO ZDO { get; } public abstract ProcessorPrefabInfo PrefabInfo { get; } public abstract long Owner { get; } public abstract long PlayerID { get; } public abstract string PlayerName { get; } public abstract bool IsAdmin { get; } public abstract int Stamina { get; } public abstract int Eitr { get; } public abstract ItemDrop? LastUsedItem { get; } public abstract IReadOnlyDictionary GlobalKeyModifications { get; } private protected PlayerState() { } public abstract float GetEstimatedSkillLevel(SkillType skillType); public abstract void AddGlobalKeyModification(GlobalKey key, bool add); public abstract void RemoveGlobalKeyModification(GlobalKey key); } public interface IPrefabInfo { int PrefabHash { get; } string PrefabName { get; } IReadOnlyDictionary> Components { get; } } [DebuggerDisplay("{PrefabName}: Processors: {EnabledProcessors.Count}")] public abstract class PrefabInfo : IPrefabInfo { public GameObject? Prefab { get; private set; } public int PrefabHash { get; private set; } public string PrefabName { get; private set; } public IReadOnlyDictionary> Components { get; private set; } public bool ReleaseOwnershipOnRecreate { get; private set; } internal List AvailableProcessors { get; } = new List(); internal List EnabledProcessors { get; } = new List(); internal void Init(GameObject prefab, int prefabHash, string prefabName, IReadOnlyDictionary>? components) { Prefab = prefab; PrefabHash = prefabHash; PrefabName = prefabName; Components = (IReadOnlyDictionary>)((components != null && components.Count > 0) ? ((IEnumerable)components) : ((IEnumerable)EmptyReadOnlyCollections>.Dictionary)); ReleaseOwnershipOnRecreate = Components.TryGetValue(typeof(ZSyncTransform), out IReadOnlyList value) && value.Cast().Any((ZSyncTransform x) => x.m_syncPosition || x.m_syncRotation || x.m_syncBodyVelocity); } public bool HasComponent() where T : MonoBehaviour { return Components.ContainsKey(typeof(T)); } public T? GetComponent() where T : MonoBehaviour { if (!Components.TryGetValue(typeof(T), out IReadOnlyList value)) { return default(T); } return (T)(object)value[0]; } public T GetRequiredComponent() where T : MonoBehaviour { return (T)(object)Components[typeof(T)][0]; } } public abstract record ProcessorPrefabInfo { public virtual bool IsValid => true; public PrefabInfo PrefabInfo { get; internal set; } } public sealed record ProcessorPrefabInfo(T Component) : ProcessorPrefabInfo(); internal interface IProcessorPrefabInfo : IPrefabInfo where TPrefabInfo : ProcessorPrefabInfo { TPrefabInfo? PrefabInfo { get; set; } } internal static class PrefabInfoExtensions { public static T GetExtension(this IPrefabInfo prefabInfo) where T : class, IPrefabInfo { return (T)prefabInfo; } } public static class PrefabNames { public const string Megingjord = "BeltStrength"; public const string CryptKey = "CryptKey"; public const string Wishbone = "Wishbone"; public const string TornSpirit = "YagluthDrop"; public const string BlackmetalChest = "piece_chest_blackmetal"; public const string ReinforcedChest = "piece_chest"; public const string WoodChest = "piece_chest_wood"; public const string Barrel = "piece_chest_barrel"; public const string Incinerator = "incinerator"; public const string GiantBrain = "giant_brain"; public const string Hoe = "Hoe"; } public static class Prefabs { public static int Hammer { get; } = StringExtensionMethods.GetStableHashCode("Hammer", true); public static int Hoe { get; } = StringExtensionMethods.GetStableHashCode("Hoe", true); public static int GraustenFloor4x4 { get; } = StringExtensionMethods.GetStableHashCode("Piece_grausten_floor_4x4", true); public static int GraustenWall4x2 { get; } = StringExtensionMethods.GetStableHashCode("Piece_grausten_wall_4x2", true); public static int PortalWood { get; } = StringExtensionMethods.GetStableHashCode("portal_wood", true); public static int Portal { get; } = StringExtensionMethods.GetStableHashCode("portal", true); public static int Sconce { get; } = StringExtensionMethods.GetStableHashCode("piece_walltorch", true); public static int DvergerGuardstone { get; } = StringExtensionMethods.GetStableHashCode("dverger_guardstone", true); public static int Sign { get; } = StringExtensionMethods.GetStableHashCode("sign", true); public static int Candle { get; } = StringExtensionMethods.GetStableHashCode("Candle_resin", true); public static int BlackmetalChest { get; } = StringExtensionMethods.GetStableHashCode("piece_chest_blackmetal", true); public static int ReinforcedChest { get; } = StringExtensionMethods.GetStableHashCode("piece_chest", true); public static int Barrel { get; } = StringExtensionMethods.GetStableHashCode("piece_chest_barrel", true); public static int WoodChest { get; } = StringExtensionMethods.GetStableHashCode("piece_chest_wood", true); public static int Incinerator { get; } = StringExtensionMethods.GetStableHashCode("incinerator", true); public static int CargoCrate { get; } = StringExtensionMethods.GetStableHashCode("CargoCrate", true); public static int PrivateChest { get; } = StringExtensionMethods.GetStableHashCode("piece_chest_private", true); public static int StandingIronTorch { get; } = StringExtensionMethods.GetStableHashCode("piece_groundtorch", true); public static int StandingIronTorchGreen { get; } = StringExtensionMethods.GetStableHashCode("piece_groundtorch_green", true); public static int StandingIronTorchBlue { get; } = StringExtensionMethods.GetStableHashCode("piece_groundtorch_blue", true); public static int MountainRemainsBuried { get; } = StringExtensionMethods.GetStableHashCode("Pickable_MountainRemains01_buried", true); } public static class PrivateAccessor { private const BindingFlags AccessFlags = BindingFlags.Public | BindingFlags.NonPublic; [CompilerGenerated] private static Func k__BackingField; [CompilerGenerated] private static Func k__BackingField; [CompilerGenerated] private static Func> k__BackingField; [CompilerGenerated] private static Func> k__BackingField; [CompilerGenerated] private static Func> k__BackingField; [CompilerGenerated] private static Func> k__BackingField; [CompilerGenerated] private static Func k__BackingField; [CompilerGenerated] private static Func> k__BackingField; [CompilerGenerated] private static Func, GameObject> k__BackingField; [CompilerGenerated] private static Action k__BackingField; private static Func GetCommandAction { get { Func func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ConsoleCommand)); func = (k__BackingField = Expression.Lambda>(Expression.Field(parameterExpression, typeof(ConsoleCommand).GetField("action", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func; } } private static Func GetCommandActionFailable { get { Func func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ConsoleCommand)); func = (k__BackingField = Expression.Lambda>(Expression.Field(parameterExpression, typeof(ConsoleCommand).GetField("actionFailable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func; } } public static Func> GetServerOptionsGUIPresets => k__BackingField ?? (k__BackingField = Expression.Lambda>>(Expression.Field(null, typeof(ServerOptionsGUI).GetField("m_presets", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)), Array.Empty()).Compile()); public static Func> GetServerOptionsGUIModifiers => k__BackingField ?? (k__BackingField = Expression.Lambda>>(Expression.Field(null, typeof(ServerOptionsGUI).GetField("m_modifiers", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)), Array.Empty()).Compile()); private static Func> GetZDOManObjectsByID { get { Func> func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ZDOMan)); func = (k__BackingField = Expression.Lambda>>(Expression.Field(parameterExpression, typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func; } } private static Func> GetLocalizationStrings { get { Func> func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(Localization)); func = (k__BackingField = Expression.Lambda>>(Expression.Field(parameterExpression, typeof(Localization).GetField("m_translations", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func; } } private static Func GetCurrentEventFunc { get { Func func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(RandEventSystem)); func = (k__BackingField = Expression.Lambda>(Expression.Field(parameterExpression, typeof(RandEventSystem).GetField("m_randomEvent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func; } } private static Func> GetLocationsByHashFunc { get { Func> func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ZoneSystem)); func = (k__BackingField = Expression.Lambda>>(Expression.Field(parameterExpression, typeof(ZoneSystem).GetField("m_locationsByHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile()); } return func; } } private static Func, GameObject> SpawnLocationFunc { get { Func, GameObject> func = k__BackingField; if (func == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ZoneSystem)); MethodInfo? method = typeof(ZoneSystem).GetMethod("SpawnLocation", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Expression[] array = new Expression[6]; ParameterExpression parameterExpression2 = (ParameterExpression)(array[0] = Expression.Parameter(typeof(ZoneLocation))); ParameterExpression parameterExpression3 = (ParameterExpression)(array[1] = Expression.Parameter(typeof(int))); ParameterExpression parameterExpression4 = (ParameterExpression)(array[2] = Expression.Parameter(typeof(Vector3))); ParameterExpression parameterExpression5 = (ParameterExpression)(array[3] = Expression.Parameter(typeof(Quaternion))); ParameterExpression parameterExpression6 = (ParameterExpression)(array[4] = Expression.Parameter(typeof(SpawnMode))); ParameterExpression parameterExpression7 = (ParameterExpression)(array[5] = Expression.Parameter(typeof(List))); func = (k__BackingField = Expression.Lambda, GameObject>>(Expression.Call(parameterExpression, method, array), new ParameterExpression[7] { parameterExpression, parameterExpression2, parameterExpression3, parameterExpression4, parameterExpression5, parameterExpression6, parameterExpression7 }).Compile()); } return func; } } private static Action SendGlobalKeysAction { get { Action action = k__BackingField; if (action == null) { ParameterExpression parameterExpression = Expression.Parameter(typeof(ZoneSystem)); MethodInfo? method = typeof(ZoneSystem).GetMethod("SendGlobalKeys", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Expression[] array = new Expression[1]; ParameterExpression parameterExpression2 = (ParameterExpression)(array[0] = Expression.Parameter(typeof(long))); action = (k__BackingField = Expression.Lambda>(Expression.Call(parameterExpression, method, array), new ParameterExpression[2] { parameterExpression, parameterExpression2 }).Compile()); } return action; } } public static int ZSyncAnimationZDOSalt { get; } = (int)typeof(ZSyncAnimation).GetField("c_ZDOSalt", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetRawConstantValue(); public static int CharacterAnimationHashEncumbered { get; } = (int)typeof(Character).GetField("s_encumbered", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); public static int CharacterAnimationHashInWater { get; } = (int)typeof(Character).GetField("s_inWater", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); public static int PlayerAnimationHashCrouching { get; } = (int)typeof(Player).GetField("s_crouching", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); public static ConsoleEvent? GetAction(this ConsoleCommand command) { return GetCommandAction(command); } public static ConsoleEventFailable? GetActionFailable(this ConsoleCommand command) { return GetCommandActionFailable(command); } private static Dictionary GetObjectsByIDCore(this ZDOMan instance) { return GetZDOManObjectsByID(instance); } public static Dictionary.ValueCollection GetObjects(this ZDOMan instance) { return instance.GetObjectsByIDCore().Values; } public static IReadOnlyDictionary GetStrings(this Localization instance) { return GetLocalizationStrings(instance); } public static RandomEvent? GetCurrentEvent(this RandEventSystem instance) { return GetCurrentEventFunc(instance); } public static IReadOnlyDictionary GetLocationsByHash(this ZoneSystem instance) { return GetLocationsByHashFunc(instance); } public static GameObject SpawnLocation(this ZoneSystem instance, ZoneLocation location, int seed, Vector3 pos, Quaternion rot, SpawnMode mode, List? spawnedGhostObjects = null) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return SpawnLocationFunc(instance, location, seed, pos, rot, mode, spawnedGhostObjects ?? new List()); } public static void SendGlobalKeys(this ZoneSystem instance, long peerID) { SendGlobalKeysAction(instance, peerID); } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class ProcessorAttribute : Attribute { public Guid Id { get; } = new Guid(id); public bool OnlyWhenDependedOn { get; init; } public int Priority { get; init; } public ProcessorAttribute(string id) { } } public abstract class ProcessorDependencyAttribute : Attribute { public Guid ProcessorId { get; } public bool Required { get; init; } public bool? RunBefore { get; } private ProcessorDependencyAttribute(Guid processorId, bool required, bool? runBefore) { ProcessorId = processorId; Required = required; RunBefore = runBefore; } private protected ProcessorDependencyAttribute(string processorId, bool? runBefore) : this(new Guid(processorId), required: false, runBefore) { } private protected ProcessorDependencyAttribute(Type processorType, bool? runBefore) : this(processorType.GetCustomAttribute()?.Id ?? default(Guid), required: true, runBefore) { } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class DependsOnAttribute : ProcessorDependencyAttribute { public DependsOnAttribute(string processorId) : base(processorId, null) { } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class DependsOnAttribute : ProcessorDependencyAttribute where T : Processor, new() { public DependsOnAttribute() : base(typeof(T), null) { } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class RunBeforeAttribute : ProcessorDependencyAttribute { public RunBeforeAttribute(string processorId) : base(processorId, true) { } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class RunBeforeAttribute : ProcessorDependencyAttribute where T : Processor, new() { public RunBeforeAttribute() : base(typeof(T), true) { } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class RunAfterAttribute : ProcessorDependencyAttribute { public RunAfterAttribute(string processorId) : base(processorId, false) { } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class RunAfterAttribute : ProcessorDependencyAttribute where T : Processor, new() { public RunAfterAttribute() : base(typeof(T), false) { } } public abstract class Processor { private static class InstanceCache where T : Processor, new() { public static readonly T Instance = new T(); } [Flags] protected internal enum ProcessResult { Default = 0, UnregisterProcessor = 2, DestroyZDO = 4, RecreateZDO = 8, SkipOtherProcessors = 0x10, ScheduleReprocessing = 0x20 } [Flags] public enum CreatorMarkers : uint { None = 0u, DataZDO = 1u, ProcessorOwned = 2u } private static class HeightmapUtils { private static readonly List<(Vector2s ZoneId, GameObject Root)> _zoneRoots = new List<(Vector2s, GameObject)>(); private static DateTimeOffset __nextCleanup; public static Heightmap CreateHeightmap(Vector2s zoneId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Vector3 zonePos = ZoneSystem.GetZonePos(zoneId); GameObject val = Object.Instantiate(ZoneSystem.instance.m_zonePrefab, zonePos, Quaternion.identity); _zoneRoots.Add((zoneId, val)); return val.GetComponentInChildren(); } public static Heightmap CreateHeightmap(Vector3 refPos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CreateHeightmap(ZoneSystem.GetZone(refPos)); } public static void CleanUp(PeersEnumerable peers) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (__nextCleanup > DateTimeOffset.UtcNow) { return; } for (int num = _zoneRoots.Count - 1; num >= 0; num--) { var (zone, val) = _zoneRoots[num]; if (!peers.Any((Peer x) => ZNetScene.InActiveArea(zone, x.RefPos))) { _zoneRoots.RemoveAt(num); Object.Destroy((Object)(object)val); } } __nextCleanup = DateTimeOffset.UtcNow.AddSeconds(2.0); } } private static ServersideQoLZDO? __dataZDO; private static bool __enableProcessingTimeMonitoring; private static int __processorId = ServersideQoLPluginBase.RegisterServerVar("ProcessorId"); [CompilerGenerated] private static IReadOnlyDictionary k__BackingField; internal ProcessorAttribute Attribute { get; } internal IServersideQoLPlugin Plugin { get; private set; } protected Logger Logger { get; private set; } protected HashSet PlacedObjects { get; } = new HashSet(); public double ProcessingTimeSeconds { get; private set; } public double TotalProcessingTimeSeconds { get; private set; } protected static IReadOnlyDictionary PieceTablesByPieceName => ServersideQoLPluginBase.Instance.PieceTablesByPieceName; protected internal static IReadOnlyDictionary BossesByBiome => k__BackingField ?? (k__BackingField = ((Func>)delegate { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); foreach (bool item in (IEnumerable)new <>z__ReadOnlyArray(new bool[2] { false, true })) { foreach (ZoneLocation location in ZoneSystem.instance.m_locations) { bool flag = !location.m_enable || !location.m_prioritized; bool flag2 = flag; if (!flag2) { Biome biome = location.m_biome; bool flag3 = (((int)biome == 0 || (int)biome == 256 || (int)biome == 895) ? true : false); flag2 = flag3; } if (!flag2 && !dictionary.ContainsKey(location.m_biome)) { try { location.m_prefab.Load(); } catch (Exception arg) { ServersideQoLPluginBase.Logger.LogWarning($"Loading location asset {location.m_prefabName} failed: {arg}"); continue; } GameObject asset = location.m_prefab.Asset; if (asset == null) { ServersideQoLPluginBase.Logger.LogWarning("Loading location asset " + location.m_prefabName + " failed"); } else { OfferingBowl componentInChildren = asset.GetComponentInChildren(); if (item && componentInChildren == null) { DungeonGenerator componentInChildren2 = asset.GetComponentInChildren(); if (componentInChildren2 != null) { SoftReference[] availableRoomPrefabs = componentInChildren2.GetAvailableRoomPrefabs(); for (int i = 0; i < availableRoomPrefabs.Length; i++) { SoftReference val = availableRoomPrefabs[i]; val.Load(); Room component = val.Asset.GetComponent(); componentInChildren = ((Component)component).GetComponentInChildren(); if (componentInChildren != null) { break; } } } } if (componentInChildren != null) { dictionary.Add(location.m_biome, componentInChildren.m_bossPrefab.GetComponent()); } } } } } return dictionary; })()); protected static ServersideQoLZDO DataZDO { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (__dataZDO == null) { __dataZDO = ZDOMan.instance.CreateNewZDO(new Vector3(105000f, -1000f, 105000f), Prefabs.Sconce).ServersideQoLZDO; __dataZDO.ZDO.SetPrefab(Prefabs.Sconce); __dataZDO.ZDO.Persistent = true; __dataZDO.ZDO.Distant = false; __dataZDO.ZDO.Type = (ObjectType)0; __dataZDO.SetModAsCreator(CreatorMarkers.DataZDO); __dataZDO.Vars.SetHealth(-1f, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 230); __dataZDO.Fields().Set(() => (Piece x) => x.m_canBeRemoved, value: false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 231); __dataZDO.Fields().Set(() => (WearNTear x) => x.m_noRoofWear, value: false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 232).Set(() => (WearNTear x) => x.m_noSupportWear, value: false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 232) .Set(() => (WearNTear x) => x.m_health, -1f, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 232); __dataZDO.UnregisterAll(); } return __dataZDO; } } private protected Processor() { Attribute = GetType().GetCustomAttribute() ?? throw new Exception("Required ProcessorAttribute missing on type " + GetType().FullName); } internal void Init(IServersideQoLPlugin plugin, Logger logger) { Plugin = plugin; Logger = logger; ValidateProcessor(); } private protected abstract void ValidateProcessor(); private protected abstract bool InitializePrefabInfo(PrefabInfo prefabInfo); internal bool InitializePrefabInfoInternal(PrefabInfo prefabInfo) { return InitializePrefabInfo(prefabInfo); } private protected abstract void AddPrefabInfoInterface(TypeExtensionBuilder prefabInfoBuilder); internal void AddPrefabInfoInterfaceInternal(TypeExtensionBuilder prefabInfoBuilder) { AddPrefabInfoInterface(prefabInfoBuilder); } public static T Instance() where T : Processor, new() { return InstanceCache.Instance; } internal static void StaticInitialize() { __enableProcessingTimeMonitoring = ConfigBase.Instance.DiagnosticLogs.Value; __dataZDO = null; foreach (ServersideQoLZDO item in from x in ZDOMan.instance.GetObjects() select x.ServersideQoLZDO) { if (!item.IsModCreator(out var marker)) { continue; } if (marker == CreatorMarkers.None) { item.Destroy(); continue; } if ((marker & CreatorMarkers.DataZDO) != CreatorMarkers.None) { if (__dataZDO == null) { __dataZDO = item; } else { ServersideQoLPluginBase.Logger.LogError("More then one DataZDO found, destroying the second one"); item.Destroy(); } } if ((marker & CreatorMarkers.ProcessorOwned) != CreatorMarkers.None && ServersideQoLPluginBase.Instance.Processors.TryGetValue(GetProcessorId(item), out Processor value)) { value.PlacedObjects.Add(item); item.Destroyed += value.OnPlacedObjectDestroyed; } } } internal static void StaticPreProcess(PeersEnumerable peers) { HeightmapUtils.CleanUp(peers); } protected internal virtual void Initialize() { } public static Guid GetProcessorId(ServersideQoLZDO zdo, Guid defaultValue = default(Guid)) { byte[] byteArray = zdo.ZDO.GetByteArray(__processorId, Array.Empty()); if (byteArray == null || byteArray.Length <= 0) { return defaultValue; } return new Guid(byteArray); } public static void SetProcessorId(ServersideQoLZDO zdo, Guid value) { zdo.ZDO.Set(__processorId, (value == default(Guid)) ? Array.Empty() : value.ToByteArray()); } protected void ScheduleReprocessing(ServersideQoLZDO zdo) { ServersideQoLPluginBase.Instance.ScheduleReprocessing(zdo); } protected void ScheduleReprocessing(ServersideQoLZDO zdo, float delayInSeconds) { ServersideQoLPluginBase.Instance.ScheduleReprocessing(zdo, delayInSeconds); } private protected abstract ProcessResult Process(IReadOnlyList peers, ServersideQoLZDO zdo); protected virtual void PreProcess(PeersEnumerable peers) { } internal ProcessResult ProcessInternal(IReadOnlyList peers, ServersideQoLZDO zdo) { if (!__enableProcessingTimeMonitoring) { return Process(peers, zdo); } double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; ProcessResult result = Process(peers, zdo); ProcessingTimeSeconds += Time.realtimeSinceStartupAsDouble - realtimeSinceStartupAsDouble; return result; } internal void PreProcessInternal(PeersEnumerable peers) { if (!__enableProcessingTimeMonitoring) { PreProcess(peers); return; } TotalProcessingTimeSeconds += ProcessingTimeSeconds; double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; PreProcess(peers); ProcessingTimeSeconds = Time.realtimeSinceStartupAsDouble - realtimeSinceStartupAsDouble; } protected internal bool ClaimExclusive(ServersideQoLZDO zdo) { return PlacedObjects.Contains(zdo); } protected static bool CheckMinDistance(IReadOnlyList peers, ServersideQoLZDO zdo, float minDistance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) minDistance *= minDistance; foreach (Peer item in peers.Enumerate()) { if (Utils.DistanceSqr(item.RefPos, zdo.ZDO.GetPosition()) < minDistance) { return false; } } return true; } protected static PrefabInfo GetPrefabInfo(int prefab) { return ServersideQoLPluginBase.Instance.GetPrefabInfo(prefab); } protected static PrefabInfo GetPrefabInfo(ServersideQoLZDO zdo) { return zdo.PrefabInfo ?? (zdo.PrefabInfo = ServersideQoLPluginBase.Instance.GetPrefabInfo(zdo.ZDO.GetPrefab())); } protected static ServersideQoLZDO Spawn(int prefab, Vector3 pos, Quaternion rot, long owner = 0L) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) ZDO val = ZDOMan.instance.CreateNewZDO(pos, prefab); val.SetPrefab(prefab); val.Persistent = true; val.Distant = false; val.Type = (ObjectType)0; val.SetRotation(rot); val.SetOwnerInternal(owner); val.ServersideQoLZDO.PrefabInfo = ServersideQoLPluginBase.Instance.GetPrefabInfo(prefab); return val.ServersideQoLZDO; } private void OnPlacedObjectDestroyed(ServersideQoLZDO zdo) { PlacedObjects.Remove(zdo); } protected ServersideQoLZDO PlaceObject(Vector3 pos, int prefab, float rot, CreatorMarkers marker = CreatorMarkers.None, long owner = 0L) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return PlaceObject(pos, prefab, Quaternion.Euler(0f, rot, 0f), marker, owner); } protected ServersideQoLZDO PlaceObject(Vector3 pos, int prefab, Quaternion rot, CreatorMarkers marker = CreatorMarkers.None, long owner = 0L) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) ServersideQoLZDO serversideQoLZDO = ZDOMan.instance.CreateNewZDO(pos, prefab).ServersideQoLZDO; serversideQoLZDO.ZDO.SetPrefab(prefab); serversideQoLZDO.ZDO.Persistent = true; serversideQoLZDO.ZDO.Distant = false; serversideQoLZDO.ZDO.Type = (ObjectType)0; serversideQoLZDO.ZDO.SetRotation(rot); serversideQoLZDO.SetModAsCreator(marker); serversideQoLZDO.Vars.SetHealth(-1f, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 320); if (marker.HasFlag(CreatorMarkers.ProcessorOwned)) { SetProcessorId(serversideQoLZDO, Attribute.Id); } serversideQoLZDO.ZDO.SetOwnerInternal(owner); serversideQoLZDO.PrefabInfo = ServersideQoLPluginBase.Instance.GetPrefabInfo(prefab); PlacedObjects.Add(serversideQoLZDO); serversideQoLZDO.Destroyed += OnPlacedObjectDestroyed; return serversideQoLZDO; } protected ServersideQoLZDO PlacePiece(Vector3 pos, int prefab, float rot, CreatorMarkers marker = CreatorMarkers.None) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return PlacePiece(pos, prefab, Quaternion.Euler(0f, rot, 0f), marker); } protected ServersideQoLZDO PlacePiece(Vector3 pos, int prefab, Quaternion rot, CreatorMarkers marker = CreatorMarkers.None) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) ServersideQoLZDO serversideQoLZDO = PlaceObject(pos, prefab, rot, marker, 0L); serversideQoLZDO.Fields().Set(() => (Piece x) => x.m_canBeRemoved, value: false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 338); serversideQoLZDO.Fields().Set(() => (WearNTear x) => x.m_noRoofWear, value: false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 340).Set(() => (WearNTear x) => x.m_noSupportWear, value: false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 341) .Set(() => (WearNTear x) => x.m_health, -1f, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\Processor.cs", 342); return serversideQoLZDO; } protected ServersideQoLZDO RecreatePiece(ServersideQoLZDO zdo) { if (!PlacedObjects.Remove(zdo)) { throw new ArgumentException(); } zdo.Destroyed -= OnPlacedObjectDestroyed; PlacedObjects.Add(zdo = zdo.Recreate()); zdo.Destroyed += OnPlacedObjectDestroyed; return zdo; } protected void DestroyObject(ServersideQoLZDO zdo) { if (!PlacedObjects.Remove(zdo)) { throw new ArgumentException(); } zdo.Destroy(); } protected static Heightmap GetHeightmap(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return Heightmap.FindHeightmap(pos) ?? HeightmapUtils.CreateHeightmap(pos); } protected static Biome GetBiome(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) return GetHeightmap(pos).GetBiome(pos, 0.02f, false); } protected static float GetHeight(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return GetHeightmap(pos).GetHeight(pos); } protected static string ConvertToRegexPattern(string searchPattern) { searchPattern = Regex.Escape(searchPattern); searchPattern = searchPattern.Replace("\\*", ".*").Replace("\\?", ".?"); return "(?i)^" + searchPattern + "$"; } protected static void ShowMessage(IEnumerable peers, Vector3 pos, string message, MessageTypes type, TextType inWorldTextType = (TextType)0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) switch (type) { default: return; case MessageTypes.TopLeftNear: case MessageTypes.CenterNear: case MessageTypes.InWorld: peers = peers.Where((Peer x) => Vector3.Distance(x.RefPos, pos) <= DamageText.instance.m_maxTextDistance); break; case MessageTypes.TopLeftFar: case MessageTypes.CenterFar: peers = peers.Where((Peer x) => Vector3.Distance(x.RefPos, pos) <= ConfigBase.Instance.FarMessageRange.Value); break; } bool flag; switch (type) { case MessageTypes.InWorld: RPC.ShowInWorldText(peers.Select((Peer x) => x.ZNetPeer.m_uid), inWorldTextType, pos, StringExtensionMethods.RemoveRichTextTags(message)); return; case MessageTypes.TopLeftNear: case MessageTypes.TopLeftFar: flag = true; break; default: flag = false; break; } MessageType type2 = (MessageType)(flag ? 1 : 2); foreach (Peer peer in peers) { RPC.ShowMessage(peer.ZNetPeer.m_uid, type2, message); } } protected static void ShowMessage(IEnumerable peers, ServersideQoLZDO zdo, string message, MessageTypes type, TextType inWorldTextType = (TextType)0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) ShowMessage(peers, zdo.ZDO.GetPosition(), message, type, inWorldTextType); } [Conditional("DEBUG")] protected static void DevShowMessage(ServersideQoLZDO zdo, string message, TextType type = (TextType)0, [CallerFilePath] string callerFile = null, [CallerLineNumber] int callerLineNo = 0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) RPC.ShowInWorldText(new <>z__ReadOnlySingleElementList(0L), type, zdo.ZDO.GetPosition(), $"{Path.GetFileNameWithoutExtension(callerFile)} L{callerLineNo}: {message}"); } protected internal static (int Width, int Height) GetBackpackSize(int slots) { int num = ((slots < 16) ? ((slots < 4) ? 1 : ((slots >= 9) ? 3 : 2)) : ((slots <= 32) ? 4 : 0)); int num2 = num; int num3 = 0; if (num2 > 0) { num3 = (slots + num2 - 1) / num2; } else { num3 = 8; num2 = (slots + num3 - 1) / num3; } return (Width: num3, Height: num2); } } public abstract class Processor : Processor where TPrefabInfo : notnull, ProcessorPrefabInfo { private readonly ConstructorInfo? _prefabInfoCtor; private readonly ParameterInfo[]? _prefabInfoCtorParameters; private readonly bool?[]? _prefabInfoCtorParametersNullable; protected Processor() { ConstructorInfo[] constructors = typeof(TPrefabInfo).GetConstructors(); if (constructors != null && constructors.Length == 1) { _prefabInfoCtor = constructors[0]; _prefabInfoCtorParameters = _prefabInfoCtor.GetParameters(); _prefabInfoCtorParametersNullable = new bool?[_prefabInfoCtorParameters.Length]; } } private protected override void AddPrefabInfoInterface(TypeExtensionBuilder prefabInfoBuilder) { prefabInfoBuilder.AddInterface>(); } private protected override bool InitializePrefabInfo(PrefabInfo prefabInfo) { IProcessorPrefabInfo extension = prefabInfo.GetExtension>(); if ((object)extension.PrefabInfo == null) { extension.PrefabInfo = GetProcessorPrefabInfo(prefabInfo); TPrefabInfo? prefabInfo2 = extension.PrefabInfo; if ((object)prefabInfo2 != null) { prefabInfo2.PrefabInfo = prefabInfo; } } return extension.PrefabInfo?.IsValid ?? false; } protected static TPrefabInfo? GetProcessorPrefabInfo(ServersideQoLZDO zdo) { return zdo.GetProcessorPrefabInfo(); } [Conditional("DEBUG")] public static void AssertHasProcessorPrefabInfo(ServersideQoLZDO zdo) { } private TPrefabInfo? GetProcessorPrefabInfo(PrefabInfo prefabInfo) { if ((object)_prefabInfoCtor == null || _prefabInfoCtorParameters == null || _prefabInfoCtorParametersNullable == null) { throw new InvalidOperationException(); } if (_prefabInfoCtorParameters.Length == 0) { return (TPrefabInfo)_prefabInfoCtor.Invoke(Array.Empty()); } GameObject prefab = prefabInfo.Prefab; IReadOnlyDictionary> components = prefabInfo.Components; object[] array = new object[_prefabInfoCtorParameters.Length]; bool flag = false; MethodInfo methodInfo = null; List list = null; bool? defaultNullable = null; for (int i = 0; i < _prefabInfoCtorParameters.Length; i++) { ParameterInfo parameterInfo = _prefabInfoCtorParameters[i]; Type type = parameterInfo.ParameterType; bool flag2 = false; if (type.IsGenericType) { Type[] genericArguments = type.GetGenericArguments(); if (genericArguments != null && genericArguments.Length == 1 && type.IsAssignableFrom(typeof(IReadOnlyList<>).MakeGenericType(genericArguments))) { type = genericArguments[0]; flag2 = true; } } if (!components.TryGetValue(type, out var value)) { bool? flag3 = _prefabInfoCtorParametersNullable[i]; bool flag4; if (flag3.HasValue) { flag4 = flag3 == true; } else { _prefabInfoCtorParametersNullable[i] = (flag4 = IsNullable(parameterInfo, ref defaultNullable)); } if (!flag4) { return null; } continue; } if (flag2) { array[i] = (methodInfo ?? (methodInfo = new Func, IReadOnlyList>(CreateList).Method.GetGenericMethodDefinition())).MakeGenericMethod(type).Invoke(null, new object[1] { value }); } else { array[i] = value[0]; if (value.Count != 1) { (list ?? (list = new List())).Add(type); } } flag = true; } if (!flag) { return null; } if (list != null) { base.Logger.LogWarning(typeof(TPrefabInfo).FullName + " has the following property types which are not lists but have multiple components in the prefab: " + string.Join(", ", list.Select((Type x) => x.FullName)) + ". Only the first component will be used."); } return (TPrefabInfo)_prefabInfoCtor.Invoke(array); static IReadOnlyList CreateList(IReadOnlyList source) where T : notnull, MonoBehaviour { List list2 = new List(); list2.AddRange(source.Cast()); return new <>z__ReadOnlyList(list2); } } private bool IsNullable(ParameterInfo par, ref bool? defaultNullable) { CustomAttributeData customAttributeData = par.CustomAttributes.FirstOrDefault((CustomAttributeData x) => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); if (customAttributeData != null) { return (byte)customAttributeData.ConstructorArguments[0].Value == 2; } bool? flag = defaultNullable; if (!flag.HasValue) { CustomAttributeData customAttributeData2 = _prefabInfoCtor.CustomAttributes.FirstOrDefault((CustomAttributeData x) => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute") ?? _prefabInfoCtor.DeclaringType.CustomAttributes.FirstOrDefault((CustomAttributeData x) => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute") ?? _prefabInfoCtor.DeclaringType.Assembly.CustomAttributes.FirstOrDefault((CustomAttributeData x) => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute"); if (customAttributeData2 == null) { defaultNullable = false; } else { defaultNullable = (byte)customAttributeData2.ConstructorArguments[0].Value == 2; } } return defaultNullable.Value; } private protected override void ValidateProcessor() { if ((object)_prefabInfoCtor == null) { throw new ArgumentException("Cannot use " + GetType().FullName + " with " + typeof(TPrefabInfo).FullName + ": type must have exactly one constructor."); } ParameterInfo[] prefabInfoCtorParameters = _prefabInfoCtorParameters; foreach (ParameterInfo parameterInfo in prefabInfoCtorParameters) { if (!parameterInfo.ParameterType.IsSubclassOf(typeof(MonoBehaviour))) { throw new ArgumentException("Cannot use " + GetType().FullName + " with " + typeof(TPrefabInfo).FullName + ": constructor parameter '" + parameterInfo.Name + "' is not a MonoBehaviour."); } } } private protected sealed override ProcessResult Process(IReadOnlyList peers, ServersideQoLZDO zdo) { ProcessResult processResult = ProcessResult.Default; PrefabInfo? prefabInfo = zdo.PrefabInfo; TPrefabInfo val = ((prefabInfo != null) ? prefabInfo.GetExtension>().PrefabInfo : null); if ((object)val == null) { return processResult | ProcessResult.UnregisterProcessor; } return processResult | Process(zdo, peers, val); } protected abstract ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList peers, TPrefabInfo prefabInfo); } public static class RPC { public static class Intercept { private sealed class RpcDelegate { public Delegate Delegate { get; } public ParameterInfo[] Parameters { get; } public int DataParameterIndex { get; } public int ZdoParameterIndex { get; } public RpcDelegate(Delegate del) { Delegate = del; Parameters = del.Method.GetParameters(); List list = Parameters.Select((ParameterInfo x) => x.ParameterType).ToList(); DataParameterIndex = list.IndexOf(typeof(RoutedRPCData)); ZdoParameterIndex = list.IndexOf(typeof(ServersideQoLZDO)); } } private sealed record RpcMethod(string Name, List Delegates); private static List __args = new List(); private static readonly Dictionary __argArrays = new Dictionary(); private static int __loopCounter; private static readonly Dictionary __methods = new Dictionary(); private static readonly MethodInfo __handleRoutedRPCMethod = typeof(ZRoutedRpc).GetMethod("HandleRoutedRPC", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo __handleRoutedRPCPrefix = new Func(HandleRoutedRPCPrefix).Method; private static bool HandleRoutedRPCPrefix(RoutedRPCData data) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (__methods.TryGetValue(data.m_methodHash, out RpcMethod value)) { ServersideQoLZDO serversideQoLZDO = null; for (int i = 0; i < value.Delegates.Count; i++) { RpcDelegate rpcDelegate = value.Delegates[i]; try { __args.Clear(); ZRpc.Deserialize(rpcDelegate.Parameters, data.m_parameters, ref __args); data.m_parameters.SetPos(0); if (rpcDelegate.DataParameterIndex < rpcDelegate.ZdoParameterIndex) { if (rpcDelegate.DataParameterIndex > -1) { __args.Insert(rpcDelegate.DataParameterIndex, data); } if (rpcDelegate.ZdoParameterIndex > -1) { __args.Insert(rpcDelegate.ZdoParameterIndex, serversideQoLZDO ?? (serversideQoLZDO = ZDOMan.instance.GetZDO(data.m_targetZDO).ServersideQoLZDO)); } } else { if (rpcDelegate.ZdoParameterIndex > -1) { __args.Insert(rpcDelegate.ZdoParameterIndex, serversideQoLZDO ?? (serversideQoLZDO = ZDOMan.instance.GetZDO(data.m_targetZDO).ServersideQoLZDO)); } if (rpcDelegate.DataParameterIndex > -1) { __args.Insert(rpcDelegate.DataParameterIndex, data); } } if (!__argArrays.TryGetValue(__args.Count, out object[] value2)) { __argArrays.Add(__args.Count, value2 = __args.ToArray()); } else { __args.CopyTo(value2); } __loopCounter++; _ = __loopCounter; _ = 1; object obj = rpcDelegate.Delegate.DynamicInvoke(value2); __loopCounter--; if (obj is bool && !(bool)obj) { return false; } } catch (Exception ex) { ServersideQoLPluginBase.Logger.LogError($"{value.Name}: {rpcDelegate.Delegate.Method.DeclaringType.Name}.{rpcDelegate.Delegate.Method.Name}: {ex}"); ServersideQoLPluginBase.Logger.LogError("Arguments: " + string.Join(", ", __args.Select((object x, int num) => $"{num}: {x?.GetType().Name}"))); value.Delegates.RemoveAt(i--); if (value.Delegates.Count == 0 && __methods.Remove(data.m_methodHash) && __methods.Count == 0) { ServersideQoLPlugin.HarmonyInstance.Unpatch((MethodBase)__handleRoutedRPCMethod, __handleRoutedRPCPrefix); } } } } else if (__methods.Count == 0) { ServersideQoLPlugin.HarmonyInstance.Unpatch((MethodBase)__handleRoutedRPCMethod, __handleRoutedRPCPrefix); } return true; } public static void UpdateInterception(string methodName, Delegate interceptor, bool enable) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown bool flag = __methods.Count != 0; int stableHashCode = StringExtensionMethods.GetStableHashCode(methodName, true); if (!__methods.TryGetValue(stableHashCode, out RpcMethod value) && enable) { __methods.Add(stableHashCode, value = new RpcMethod(methodName, new List())); } if (enable) { if (!value.Delegates.Any((RpcDelegate x) => x.Delegate == interceptor)) { value.Delegates.Add(new RpcDelegate(interceptor)); } } else if ((object)value != null) { int num = value.Delegates.FindIndex((RpcDelegate x) => x.Delegate == interceptor); if (num > -1) { value.Delegates.RemoveAt(num); if (value.Delegates.Count == 0) { __methods.Remove(stableHashCode); } } } if (!flag && __methods.Count > 0) { ServersideQoLPlugin.HarmonyInstance.Patch((MethodBase)__handleRoutedRPCMethod, new HarmonyMethod(__handleRoutedRPCPrefix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static readonly Dictionary __invokeCounters = new Dictionary(); private static readonly Dictionary __invokeAsSenderCounters = new Dictionary(); private static int __invokeTotalCounter; private static Action? __invokeRouteRPCAsSender; public static void ShowMessage(long targetPeerId, MessageType type, string message) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown InvokeRoutedRPC(targetPeerId, "ShowMessage", new object[2] { (int)type, message }); } public static void ShowMessage(Peer peer, MessageType type, string message) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) ShowMessage(peer.ZNetPeer.m_uid, type, message); } public static void ShowMessage(IEnumerable peers, MessageType type, string message) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) foreach (Peer peer in peers) { ShowMessage(peer, type, message); } } public static void UseStamina(ServersideQoLZDO playerZdo, float value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(playerZdo.ZDO.GetOwner(), playerZdo.ZDO.m_uid, "UseStamina", new object[1] { value }); } public static void SendGlobalKeys(Peer peer, List keys) { InvokeRoutedRPC(peer.ZNetPeer.m_uid, "GlobalKeys", new object[1] { keys }); } public static void ShowInWorldText(IEnumerable targetPeerIds, TextType type, Vector3 pos, string text) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write((int)type); val.Write(pos); val.Write(text); val.Write(false); foreach (long targetPeerId in targetPeerIds) { InvokeRoutedRPC(targetPeerId, "RPC_DamageText", new object[1] { val }); } } private static void TeleportPlayer(long targetPeerID, Vector3 pos, Quaternion rot, bool distantTeleport) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(targetPeerID, "RPC_TeleportPlayer", new object[3] { pos, rot, distantTeleport }); } public static void TeleportPlayer(Peer peer, Vector3 pos, Quaternion rot, bool distantTeleport) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) TeleportPlayer(peer.ZNetPeer.m_uid, pos, rot, distantTeleport); } public static void TeleportPlayer(ServersideQoLZDO player, Vector3 pos, Quaternion rot, bool distantTeleport) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(player.ZDO.GetOwner(), player.ZDO.m_uid, "RPC_TeleportTo", new object[3] { pos, rot, distantTeleport }); } public static void Remove(ServersideQoLZDO piece, bool blockDrop = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(piece.ZDO.GetOwner(), piece.ZDO.m_uid, "RPC_Remove", new object[1] { false }); } public static void AddStatusEffect(ServersideQoLZDO character, int nameHash, bool resetTime = false, int itemLevel = 0, float skillLevel = 0f) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(character.ZDO.GetOwner(), character.ZDO.m_uid, "RPC_AddStatusEffect", new object[4] { nameHash, resetTime, itemLevel, skillLevel }); } public static void RequestStack(ServersideQoLZDO container, ServersideQoLZDO player, long playerID = 0L) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (playerID == 0L) { playerID = player.Vars.GetPlayerID(0L); } InvokeRoutedRPCAsSender(player.ZDO.GetOwner(), container.ZDO.GetOwner(), container.ZDO.m_uid, "RPC_RequestStack", new object[1] { playerID }); } public static void StackResponse(ServersideQoLZDO container, bool granted) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(container.ZDO.GetOwner(), container.ZDO.m_uid, "RPC_StackResponse", new object[1] { granted }); } public static void TakeAllResponse(ServersideQoLZDO container, bool granted) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(container.ZDO.GetOwner(), container.ZDO.m_uid, "TakeAllRespons", new object[1] { granted }); } public static void RequestStateChange(ServersideQoLZDO trap, int state) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(trap.ZDO.GetOwner(), trap.ZDO.m_uid, "RPC_RequestStateChange", new object[1] { state }); } public static void SetTamed(ServersideQoLZDO character, bool tamed) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(character.ZDO.GetOwner(), character.ZDO.m_uid, "RPC_SetTamed", new object[1] { tamed }); } public static void Damage(ServersideQoLZDO character, HitData hitData) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(character.ZDO.GetOwner(), character.ZDO.m_uid, "RPC_Damage", new object[1] { hitData }); } public static void RequestOwn(ServersideQoLZDO itemDrop, [CallerFilePath] string callerFile = null, [CallerLineNumber] int callerLineNo = 0) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(itemDrop.ZDO.GetOwner(), itemDrop.ZDO.m_uid, "RPC_RequestOwn"); } public static void RequestOpen(ServersideQoLZDO container, long playerID) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(container.ZDO.GetOwner(), container.ZDO.m_uid, "RequestOpen", new object[1] { playerID }); } public static void RequestOpenFor(ServersideQoLZDO player, ServersideQoLZDO container) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPCAsSender(player.ZDO.GetOwner(), container.ZDO.GetOwner(), container.ZDO.m_uid, "RequestOpen", new object[1] { player.Vars.GetPlayerID(0L) }); } public static void OpenResponse(ServersideQoLZDO container, bool granted) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(container.ZDO.GetOwner(), container.ZDO.m_uid, "OpenRespons", new object[1] { granted }); } public static void DamageMineRock5(ServersideQoLZDO minerock5, HitData hit, int hitAreaIndex) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) InvokeRoutedRPC(minerock5.ZDO.GetOwner(), minerock5.ZDO.m_uid, "RPC_Damage", new object[2] { hit, hitAreaIndex }); } private static void InvokeRoutedRPC(long targetPeerId, string methodName, object[]? parameters = null) { if (ConfigBase.Instance.DiagnosticLogs.Value) { __invokeCounters.TryGetValue(methodName, out var value); value = (__invokeCounters[methodName] = value + 1); __invokeTotalCounter++; if (value % 10 == 0) { ServersideQoLPluginBase.Logger.LogInfo(string.Format("{0}: {1}: {2} of {3} ({4:P0})", "InvokeRoutedRPC", methodName, value, __invokeTotalCounter, (float)value / (float)__invokeTotalCounter)); } } ZRoutedRpc.instance.InvokeRoutedRPC(targetPeerId, methodName, parameters ?? Array.Empty()); } private static void InvokeRoutedRPC(long targetPeerId, ZDOID targetZDO, string methodName, object[]? parameters = null) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (ConfigBase.Instance.DiagnosticLogs.Value) { __invokeCounters.TryGetValue(methodName, out var value); value = (__invokeCounters[methodName] = value + 1); __invokeTotalCounter++; if (value % 10 == 0) { ServersideQoLPluginBase.Logger.LogInfo(string.Format("{0}: {1}: {2} of {3} ({4:P0})", "InvokeRoutedRPC", methodName, value, __invokeTotalCounter, (float)value / (float)__invokeTotalCounter)); } } ZRoutedRpc.instance.InvokeRoutedRPC(targetPeerId, targetZDO, methodName, parameters ?? Array.Empty()); } private static void InvokeRoutedRPCAsSender(long senderPeerId, long targetPeerID, ZDOID targetZDO, string methodName, object[] parameters) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (ConfigBase.Instance.DiagnosticLogs.Value) { __invokeAsSenderCounters.TryGetValue(methodName, out var value); value = (__invokeAsSenderCounters[methodName] = value + 1); __invokeTotalCounter++; if (value % 10 == 0) { ServersideQoLPluginBase.Logger.LogInfo(string.Format("{0}: {1}: {2} of {3} ({4:P0})", "InvokeRoutedRPCAsSender", methodName, value, __invokeTotalCounter, (float)value / (float)__invokeTotalCounter)); } } if (__invokeRouteRPCAsSender == null) { __invokeRouteRPCAsSender = GetDelegate(); } __invokeRouteRPCAsSender(ZRoutedRpc.instance, targetPeerID, targetZDO, methodName, parameters, senderPeerId); static Action GetDelegate() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) FieldInfo fieldInfo = GetField((RoutedRPCData x) => x.m_senderPeerID); FieldInfo field = typeof(ZRoutedRpc).GetField("m_id", BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo method = new Action(ZRoutedRpc.instance.InvokeRoutedRPC).Method; DynamicMethodDefinition val = new DynamicMethodDefinition((MethodBase)method) { Name = "InvokeRoutedRPC_InjectSender" }; typeof(DynamicMethodDefinition).GetProperty("OriginalMethod").SetValue(val, null); ((MethodReference)val.Definition).Parameters.Add(new ParameterDefinition("senderPeerID", (ParameterAttributes)0, val.Module.ImportReference(typeof(long)))); Collection instructions = val.Definition.Body.Instructions; bool flag = false; for (int num2 = 2; num2 < instructions.Count; num2++) { if (ILPatternMatchingExt.MatchStfld(instructions[num2], fieldInfo) && ILPatternMatchingExt.MatchLdfld(instructions[num2 - 1], field) && instructions[num2 - 2].OpCode == OpCodes.Ldarg_0) { instructions[num2 - 1] = val.GetILProcessor().Create(OpCodes.Ldarg, ((MethodReference)val.Definition).Parameters.Count - 1); instructions.RemoveAt(num2 - 2); flag = true; break; } } if (!flag) { throw new Exception("Failed"); } MethodInfo methodInfo = val.Generate(); return Extensions.CreateDelegate>((MethodBase)methodInfo); } static FieldInfo GetField(Expression> expression) { if (expression.Body is MemberExpression memberExpression) { return (FieldInfo)memberExpression.Member; } throw new ArgumentException(); } } } internal sealed record RuntimeInformation(string ModVersion, GameVersion GameVersion, uint NetworkVersion, int ItemDataVersion, int WorldVersion) { 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_00e4: 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); return new RuntimeInformation("1.99.8-beta", gameVersion, networkVersion, itemDataVersion, worldVersion); } [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; } } public sealed class SectorDictionary(float sectorWidth) : IDictionary, ICollection>, IEnumerable>, IEnumerable, IReadOnlyDictionary, IReadOnlyCollection> { public readonly record struct Key(int X, int Z); public struct AdjacentEnumerator : IEnumerator, IEnumerator, IDisposable { private readonly int _x; private readonly int _z; private int _idx; public TValue Current { get; private set; } readonly object IEnumerator.Current => Current; public AdjacentEnumerator(Dictionary dict, Key key) { P = dict; _x = key.X; _z = key.Z; _idx = -1; Current = default(TValue); } public readonly AdjacentEnumerator GetEnumerator() { return this; } public readonly void Dispose() { } public bool MoveNext() { TValue value; while (true) { switch (++_idx) { case 0: if (!P.TryGetValue(new Key(_x, _z), out value)) { continue; } break; case 1: if (!P.TryGetValue(new Key(_x - 1, _z - 1), out value)) { continue; } break; case 2: if (!P.TryGetValue(new Key(_x, _z - 1), out value)) { continue; } break; case 3: if (!P.TryGetValue(new Key(_x + 1, _z - 1), out value)) { continue; } break; case 4: if (!P.TryGetValue(new Key(_x - 1, _z), out value)) { continue; } break; case 5: if (!P.TryGetValue(new Key(_x + 1, _z), out value)) { continue; } break; case 6: if (!P.TryGetValue(new Key(_x - 1, _z + 1), out value)) { continue; } break; case 7: if (!P.TryGetValue(new Key(_x, _z + 1), out value)) { continue; } break; case 8: if (!P.TryGetValue(new Key(_x + 1, _z + 1), out value)) { continue; } break; default: Current = default(TValue); return false; } break; } Current = value; return true; } public void Reset() { _idx = -1; } } private readonly float _scale; private readonly Dictionary _sections; public float SectorWidth { get; } = sectorWidth; ICollection IDictionary.Keys { get { throw new NotSupportedException(); } } IEnumerable IReadOnlyDictionary.Keys { get { throw new NotSupportedException(); } } public Dictionary.ValueCollection Values => _sections.Values; ICollection IDictionary.Values => _sections.Values; IEnumerable IReadOnlyDictionary.Values => _sections.Values; public int Count => _sections.Count; bool ICollection>.IsReadOnly => false; public TValue this[Vector3 key] { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return _sections[GetKey(key)]; } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _sections[GetKey(key)] = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private Key GetKey(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Key(Mathf.RoundToInt(pos.x * _scale), Mathf.RoundToInt(pos.z * _scale)); } public void Add(Vector3 key, TValue value) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _sections.Add(GetKey(key), value); } bool IDictionary.ContainsKey(Vector3 key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return _sections.ContainsKey(GetKey(key)); } bool IReadOnlyDictionary.ContainsKey(Vector3 key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return _sections.ContainsKey(GetKey(key)); } bool IDictionary.Remove(Vector3 key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return _sections.Remove(GetKey(key)); } public bool TryGetValue(Vector3 key, out TValue value) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return _sections.TryGetValue(GetKey(key), out value); } public void Clear() { _sections.Clear(); } public bool TryGetValue(Vector3 key, bool includeAdjacent, out TValue value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) var (num3, num4) = (Key)(ref GetKey(key)); if (_sections.TryGetValue(new Key(num3, num4), out value)) { return true; } if (!includeAdjacent) { return false; } if (_sections.TryGetValue(new Key(num3 - 1, num4 - 1), out value)) { return true; } if (_sections.TryGetValue(new Key(num3, num4 - 1), out value)) { return true; } if (_sections.TryGetValue(new Key(num3 + 1, num4 - 1), out value)) { return true; } if (_sections.TryGetValue(new Key(num3 - 1, num4), out value)) { return true; } if (_sections.TryGetValue(new Key(num3 + 1, num4), out value)) { return true; } if (_sections.TryGetValue(new Key(num3 - 1, num4 + 1), out value)) { return true; } if (_sections.TryGetValue(new Key(num3, num4 + 1), out value)) { return true; } if (_sections.TryGetValue(new Key(num3 + 1, num4 + 1), out value)) { return true; } return false; } void ICollection>.Add(KeyValuePair item) { throw new NotSupportedException(); } bool ICollection>.Contains(KeyValuePair item) { throw new NotSupportedException(); } void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { throw new NotSupportedException(); } bool ICollection>.Remove(KeyValuePair item) { throw new NotSupportedException(); } IEnumerator> IEnumerable>.GetEnumerator() { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { throw new NotSupportedException(); } public AdjacentEnumerator EnumerateAdjacent(Vector3 key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return new AdjacentEnumerator(_sections, GetKey(key)); } } public sealed class SectorDictionary(float sectorWidth) : IDictionary<(Vector3, TKey), TValue>, ICollection>, IEnumerable>, IEnumerable, IReadOnlyDictionary<(Vector3, TKey), TValue>, IReadOnlyCollection> where TKey : notnull { public struct AdjacentEnumerator : IEnumerator, IEnumerator, IDisposable { private readonly int _x; private readonly int _y; private readonly TKey _k; private int _idx; public TValue Current { get; private set; } readonly object IEnumerator.Current => Current; public AdjacentEnumerator(Dictionary<(int, int, TKey), TValue> dict, (int x, int y, TKey k) key) { P = dict; _x = key.x; _y = key.y; _k = key.k; _idx = -1; Current = default(TValue); } public readonly AdjacentEnumerator GetEnumerator() { return this; } public readonly void Dispose() { } public bool MoveNext() { TValue value; while (true) { switch (++_idx) { case 0: if (!P.TryGetValue((_x, _y, _k), out value)) { continue; } break; case 1: if (!P.TryGetValue((_x - 1, _y - 1, _k), out value)) { continue; } break; case 2: if (!P.TryGetValue((_x, _y - 1, _k), out value)) { continue; } break; case 3: if (!P.TryGetValue((_x + 1, _y - 1, _k), out value)) { continue; } break; case 4: if (!P.TryGetValue((_x - 1, _y, _k), out value)) { continue; } break; case 5: if (!P.TryGetValue((_x + 1, _y, _k), out value)) { continue; } break; case 6: if (!P.TryGetValue((_x - 1, _y + 1, _k), out value)) { continue; } break; case 7: if (!P.TryGetValue((_x, _y + 1, _k), out value)) { continue; } break; case 8: if (!P.TryGetValue((_x + 1, _y + 1, _k), out value)) { continue; } break; default: Current = default(TValue); return false; } break; } Current = value; return true; } public void Reset() { _idx = -1; } } private readonly float _scale; private readonly Dictionary<(int, int, TKey), TValue> _sections; public float SectorWidth { get; } = sectorWidth; ICollection<(Vector3, TKey)> IDictionary<(Vector3, TKey), TValue>.Keys { get { throw new NotSupportedException(); } } IEnumerable<(Vector3, TKey)> IReadOnlyDictionary<(Vector3, TKey), TValue>.Keys { get { throw new NotSupportedException(); } } public Dictionary<(int, int, TKey), TValue>.ValueCollection Values => _sections.Values; ICollection IDictionary<(Vector3, TKey), TValue>.Values => _sections.Values; IEnumerable IReadOnlyDictionary<(Vector3, TKey), TValue>.Values => _sections.Values; public int Count => _sections.Count; bool ICollection>.IsReadOnly => false; public TValue this[(Vector3, TKey) key] { get { return _sections[GetKey(key)]; } set { _sections[GetKey(key)] = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private (int, int, TKey) GetKey((Vector3 pos, TKey key) key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) return (Mathf.RoundToInt(key.pos.x * _scale), Mathf.RoundToInt(key.pos.z * _scale), key.key); } public void Add((Vector3, TKey) key, TValue value) { _sections.Add(GetKey(key), value); } bool IDictionary<(Vector3, TKey), TValue>.ContainsKey((Vector3, TKey) key) { return _sections.ContainsKey(GetKey(key)); } bool IReadOnlyDictionary<(Vector3, TKey), TValue>.ContainsKey((Vector3, TKey) key) { return _sections.ContainsKey(GetKey(key)); } bool IDictionary<(Vector3, TKey), TValue>.Remove((Vector3, TKey) key) { return _sections.Remove(GetKey(key)); } public bool TryGetValue((Vector3, TKey) key, out TValue value) { return _sections.TryGetValue(GetKey(key), out value); } public void Clear() { _sections.Clear(); } public bool TryGetValue((Vector3, TKey) key, bool includeAdjacent, out TValue value) { var (num, num2, item) = GetKey(key); if (_sections.TryGetValue((num, num2, item), out value)) { return true; } if (!includeAdjacent) { return false; } if (_sections.TryGetValue((num - 1, num2 - 1, item), out value)) { return true; } if (_sections.TryGetValue((num, num2 - 1, item), out value)) { return true; } if (_sections.TryGetValue((num + 1, num2 - 1, item), out value)) { return true; } if (_sections.TryGetValue((num - 1, num2, item), out value)) { return true; } if (_sections.TryGetValue((num + 1, num2, item), out value)) { return true; } if (_sections.TryGetValue((num - 1, num2 + 1, item), out value)) { return true; } if (_sections.TryGetValue((num, num2 + 1, item), out value)) { return true; } if (_sections.TryGetValue((num + 1, num2 + 1, item), out value)) { return true; } return false; } void ICollection>.Add(KeyValuePair<(Vector3, TKey), TValue> item) { throw new NotSupportedException(); } bool ICollection>.Contains(KeyValuePair<(Vector3, TKey), TValue> item) { throw new NotSupportedException(); } void ICollection>.CopyTo(KeyValuePair<(Vector3, TKey), TValue>[] array, int arrayIndex) { throw new NotSupportedException(); } bool ICollection>.Remove(KeyValuePair<(Vector3, TKey), TValue> item) { throw new NotSupportedException(); } IEnumerator> IEnumerable>.GetEnumerator() { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { throw new NotSupportedException(); } public AdjacentEnumerator EnumerateAdjacent((Vector3, TKey) key) { return new AdjacentEnumerator(_sections, GetKey(key)); } } public static class SectorDictionary { public static TValue GetOrAdd(this SectorDictionary @this, Vector3 key) where TValue : new() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!@this.TryGetValue(key, out TValue value)) { @this.Add(key, value = new TValue()); } return value; } public static bool TryAdd(this SectorDictionary> @this, Vector3 key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) HashSet set = @this.GetOrAdd(key); if (!set.Add(zdo)) { return false; } if (autoRemoveOnDestroyed) { zdo.Destroyed += delegate(ServersideQoLZDO x) { set.Remove(x); }; } return true; } public static bool TryAdd(this SectorDictionary> @this, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return @this.TryAdd(zdo.ZDO.GetPosition(), zdo, autoRemoveOnDestroyed); } public static bool TryAdd(this SectorDictionary> @this, Vector3 key, TValue value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return @this.GetOrAdd(key).Add(value); } public static void Add(this SectorDictionary @this, Vector3 key, TValue value) where TCollection : class, ICollection, new() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) @this.GetOrAdd(key).Add(value); } public static void Add(this SectorDictionary @this, Vector3 key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TCollection : class, ICollection, new() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) TCollection collection = @this.GetOrAdd(key); collection.Add(zdo); if (autoRemoveOnDestroyed) { zdo.Destroyed += delegate(ServersideQoLZDO x) { collection.Remove(x); }; } } public static void Add(this SectorDictionary @this, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TCollection : class, ICollection, new() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) @this.Add(zdo.ZDO.GetPosition(), zdo, autoRemoveOnDestroyed); } public static bool TryAdd(this SectorDictionary @this, Vector3 key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TCollection : class, ICollection, new() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) TCollection collection = @this.GetOrAdd(key); if (collection.Contains(zdo)) { return false; } collection.Add(zdo); if (autoRemoveOnDestroyed) { zdo.Destroyed += delegate(ServersideQoLZDO x) { collection.Remove(x); }; } return true; } public static bool TryAdd(this SectorDictionary @this, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TCollection : class, ICollection, new() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return @this.TryAdd(zdo.ZDO.GetPosition(), zdo, autoRemoveOnDestroyed); } public static bool Remove(this SectorDictionary @this, Vector3 key, TValue value) where TCollection : class, ICollection { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (@this.TryGetValue(key, out TCollection value2) && value2.Remove(value)) { if (value2.Count == 0) { @this.Remove(key, out var _); } return true; } return false; } public static bool Remove(this SectorDictionary @this, ServersideQoLZDO zdo) where TCollection : class, ICollection { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return @this.Remove(zdo.ZDO.GetPosition(), zdo); } public static TValue GetOrAdd(this SectorDictionary @this, (Vector3, TKey) key) where TKey : notnull where TValue : new() { if (!@this.TryGetValue(key, out TValue value)) { @this.Add(key, value = new TValue()); } return value; } public static bool TryAdd(this SectorDictionary> @this, (Vector3, TKey) key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TKey : notnull { HashSet set = @this.GetOrAdd(key); if (!set.Add(zdo)) { return false; } if (autoRemoveOnDestroyed) { zdo.Destroyed += delegate(ServersideQoLZDO x) { set.Remove(x); }; } return true; } public static bool TryAdd(this SectorDictionary> @this, TKey key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TKey : notnull { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return @this.TryAdd((zdo.ZDO.GetPosition(), key), zdo, autoRemoveOnDestroyed); } public static bool TryAdd(this SectorDictionary> @this, (Vector3, TKey) key, TValue value) where TKey : notnull { return @this.GetOrAdd(key).Add(value); } public static void Add(this SectorDictionary @this, (Vector3, TKey) key, TValue value) where TKey : notnull where TCollection : class, ICollection, new() { @this.GetOrAdd(key).Add(value); } public static void Add(this SectorDictionary @this, (Vector3, TKey) key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TKey : notnull where TCollection : class, ICollection, new() { TCollection collection = @this.GetOrAdd(key); collection.Add(zdo); if (autoRemoveOnDestroyed) { zdo.Destroyed += delegate(ServersideQoLZDO x) { collection.Remove(x); }; } } public static void Add(this SectorDictionary @this, TKey key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TKey : notnull where TCollection : class, ICollection, new() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) @this.Add((zdo.ZDO.GetPosition(), key), zdo, autoRemoveOnDestroyed); } public static bool TryAdd(this SectorDictionary @this, (Vector3, TKey) key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TKey : notnull where TCollection : class, ICollection, new() { TCollection collection = @this.GetOrAdd(key); if (collection.Contains(zdo)) { return false; } collection.Add(zdo); if (autoRemoveOnDestroyed) { zdo.Destroyed += delegate(ServersideQoLZDO x) { collection.Remove(x); }; } return true; } public static bool TryAdd(this SectorDictionary @this, TKey key, ServersideQoLZDO zdo, bool autoRemoveOnDestroyed = true) where TKey : notnull where TCollection : class, ICollection, new() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return @this.TryAdd((zdo.ZDO.GetPosition(), key), zdo, autoRemoveOnDestroyed); } public static bool Remove(this SectorDictionary @this, (Vector3, TKey) key, TValue value) where TKey : notnull where TCollection : class, ICollection { if (@this.TryGetValue(key, out TCollection value2) && value2.Remove(value)) { if (value2.Count == 0) { @this.Remove(key, out var _); } return true; } return false; } public static bool Remove(this SectorDictionary @this, TKey key, ZDO zdo) where TKey : notnull where TCollection : class, ICollection { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return @this.Remove((zdo.GetPosition(), key), zdo); } } [BepInPlugin("ArgusMagnus.ServersideQoL", "ServersideQoL", "1.99.8")] public sealed class ServersideQoLPlugin : ServersideQoLPluginBase { private sealed class SectorState { public List Peers { get; } = new List(); public HashSet Changed { get; } = new HashSet(); public HashSet Repeat { get; } = new HashSet(); } private sealed class DummyPrefabInfo : PrefabInfo { public static DummyPrefabInfo Instance { get; } = new DummyPrefabInfo(); private DummyPrefabInfo() { Init(null, 0, "Dummy", null); } } [HarmonyPatch] private static class PrefabChangedPatches { [HarmonyTargetMethods] public static IEnumerable GetTargetMethods() { ZDO zdo = new ZDO(); yield return new Action(zdo.SetPrefab).Method; yield return new Action(zdo.Deserialize).Method; yield return new Action(zdo.Load).Method; yield return new Action(zdo.LoadOldFormat).Method; yield return new Action(zdo.Reset).Method; } [HarmonyPostfix] public static void OnPrefabChanged(ZDO __instance) { ServersideQoLZDO serversideQoLZDO = __instance.ServersideQoLZDO; if (serversideQoLZDO.UpdatePrefab()) { ServersideQoLPluginBase.Instance.OnPrefabChanged(serversideQoLZDO); } } } [HarmonyPatch] private static class DataOrOwnerRevisionChangedPatches { [HarmonyTargetMethods] public static IEnumerable GetTargetMethods() { return new <>z__ReadOnlyArray(new MethodInfo[2] { typeof(ZDO).GetProperty("DataRevision", BindingFlags.Instance | BindingFlags.Public).SetMethod, typeof(ZDO).GetProperty("OwnerRevision", BindingFlags.Instance | BindingFlags.Public).SetMethod }); } [HarmonyPostfix] public static void OnDataOrOwnerRevisionChanged(ZDO __instance) { ServersideQoLZDO serversideQoLZDO = __instance.ServersideQoLZDO; if (serversideQoLZDO.UpdateOwnerAndDataRevisions()) { ServersideQoLPluginBase.Instance.OnDataOrOwnerRevisionChanged(serversideQoLZDO); } } } [HarmonyPatch(typeof(ZoneSystem), "SendGlobalKeys")] private static class ZoneSystemSendGlobalKeys { private static readonly Dictionary __prevKeys = new Dictionary(); public static void Prefix(ZoneSystem __instance, long peer) { if (peer != ZRoutedRpc.Everybody) { return; } bool flag = false; if (ServersideQoLPluginBase.Instance.GlobalKeysChanged != null && !__prevKeys.Keys.SequenceEqual(__instance.m_globalKeysValues.Keys)) { flag = true; ServersideQoLPluginBase.Instance.GlobalKeysChanged(); } if (ServersideQoLPluginBase.Instance.GlobalKeyValuesChanged != null && !__prevKeys.SequenceEqual>(__instance.m_globalKeysValues)) { flag = true; ServersideQoLPluginBase.Instance.GlobalKeyValuesChanged(); } if (!flag) { return; } __prevKeys.Clear(); foreach (var (key, value) in __instance.m_globalKeysValues) { __prevKeys.Add(key, value); } } private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown ConstructorInfo constructor = typeof(List).GetConstructor(new Type[1] { typeof(IEnumerable) }); MethodInfo method = new Func, long, List>(ModfiyGlobalKeys).Method; return new CodeMatcher().Start().Insert(instructions).Start() .MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch(new CodeInstruction(OpCodes.Newobj, (object)constructor), (string)null) }) .Advance(1) .Insert((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Call, (object)method) }) .ThrowIfInvalid("Failed to apply patch ZoneSystemSendGlobalKeys.Transpiler") .InstructionEnumeration(); static List ModfiyGlobalKeys(List globalKeys, long peer) { PlayerState stateForPeerID = Processor.Instance().GetStateForPeerID(peer); if (stateForPeerID == null) { return globalKeys; } foreach (KeyValuePair globalKeyModification in stateForPeerID.GlobalKeyModifications) { var (key, flag2) = (KeyValuePair)(ref globalKeyModification); if (!flag2) { globalKeys.Remove(key); } else if (!globalKeys.Contains(key)) { globalKeys.Add(key); } } return globalKeys; } } } internal static readonly int PluginGuidHash = StringExtensionMethods.GetStableHashCode("argusmagnus.ServersideQoL", true); private static readonly HashSet __plugins = new HashSet(); private readonly Dictionary _processorsById = new Dictionary(); private readonly List _enabledProcessors = new List(); private Func _prefabInfoFactory; private readonly ConcurrentDictionary _prefabInfos = new ConcurrentDictionary(); private readonly GameVersion ExpectedGameVersion = GameVersion.ParseGameVersion("0.221"); private const uint ExpectedNetworkVersion = 35u; private const uint ExpectedItemDataVersion = 106u; private const uint ExpectedWorldVersion = 36u; private uint _unfinishedProcessingInRow; private readonly Dictionary _sectors = new Dictionary(); private readonly HashSet _sectorsToProcess = new HashSet(); private List _repeat = new List(); private SectorState? _currentlyProcessing; private readonly List _unregister = new List(); private List<(Processor, double)>? _processingTimes; [CompilerGenerated] private IReadOnlyDictionary k__BackingField; public const string Author = "ArgusMagnus"; public const string PluginName = "ServersideQoL"; public const string PluginGuid = "ArgusMagnus.ServersideQoL"; public const string PluginVersion = "1.99.8"; public const string PluginInformationalVersion = "1.99.8-beta"; internal static Harmony HarmonyInstance { get; } = new Harmony("ArgusMagnus.ServersideQoL"); internal IReadOnlyDictionary Processors => _processorsById; internal IReadOnlyDictionary PieceTablesByPieceName => k__BackingField ?? ((Func>)delegate { HashSet hashSet = new HashSet(); Dictionary dictionary = new Dictionary(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { PieceTable val = prefab.GetComponent()?.m_itemData.m_shared.m_buildPieces; if (val != null && hashSet.Add(val)) { foreach (GameObject piece in val.m_pieces) { dictionary.TryAdd(((Object)piece).name, val); } } } return dictionary; })(); private DateTimeOffset BuildTimestamp { get; } = new DateTimeOffset(639215507610781825L, default(TimeSpan)); public event Action? GlobalKeysChanged; public event Action? GlobalKeyValuesChanged; internal static void RegisterPlugin(IServersideQoLPlugin plugin) { __plugins.Add(plugin); } protected override Config CreateConfigSingleton(ConfigFile configFile, Logger logger) { return new Config(configFile, logger); } private void Start() { ((MonoBehaviour)this).StartCoroutine((IEnumerator)CallExecute()); IEnumerator CallExecute() { bool pluginsInitialized = false; while (true) { if (ZNet.instance == null) { yield return (YieldInstruction?)new WaitForSeconds(0.2f); } else if (!ZNet.instance.IsServer()) { ServersideQoLPluginBase.Logger.LogWarning("Mod should only be installed on the host"); yield return (YieldInstruction?)new WaitForSeconds(5f); } else { while (ZDOMan.instance == null || ZNetScene.instance == null || ZNet.World == null) { yield return (YieldInstruction?)new WaitForSeconds(0.2f); } if (!pluginsInitialized) { pluginsInitialized = true; if (!InitializePlugins()) { break; } } if (!Initialize()) { yield return (YieldInstruction?)new WaitForSeconds(5f); } else { ZNetPeer localPeer = null; if (!ZNet.instance.IsDedicated()) { while (Player.m_localPlayer == null) { yield return (YieldInstruction?)new WaitForSeconds(0.2f); } localPeer = new ZNetPeer((ISocket)(object)new DummySocket(), true) { m_uid = ZDOMan.GetSessionID(), m_characterID = ((Character)Player.m_localPlayer).GetZDOID(), m_server = true }; } PeersEnumerable peers = new PeersEnumerable(localPeer); while (true) { yield return null; if (ZNet.instance == null) { break; } int num = (ZNet.instance.IsDedicated() ? 10 : 30); int num2 = ((Application.targetFrameRate < 0) ? (2 * num) : Application.targetFrameRate); double num3 = 1.0 / (double)num; double num4 = 1.0 / (double)Time.unscaledDeltaTime; if ((double)Time.unscaledDeltaTime > num3) { if (base.Config.DiagnosticLogs.Value) { ServersideQoLPluginBase.Logger.LogInfo($"No time budget available, actual FPS: {num4}, min FPS: {num}, target FPS: {num2}"); } } else { double num5 = Math.Min(1.0, (num4 - (double)num) / (double)(num2 - num)); double timeBudgetSeconds = (num3 - (double)Time.unscaledDeltaTime) * num5; try { Execute(peers, timeBudgetSeconds); } catch (OperationCanceledException) { yield break; } catch (Exception data) { ServersideQoLPluginBase.Logger.LogError(data); yield break; } } } } } } HarmonyInstance.UnpatchSelf(); } } private bool InitializePlugins() { List list = null; TypeExtensionBuilder typeExtensionBuilder = new TypeExtensionBuilder(); int num = 0; foreach (IServersideQoLPlugin _plugin in __plugins) { try { _plugin.RegisterProcessors(); } catch (Exception ex) { ServersideQoLPluginBase.Logger.LogError(FormattableString.Invariant($"Failed to register processors for plugin {_plugin.GetType().FullName}: {ex}")); (list ?? (list = new List())).Add(_plugin); continue; } if (_plugin.Processors.Count == 0 && !(_plugin is ServersideQoLPlugin)) { ServersideQoLPluginBase.Logger.LogWarning(FormattableString.Invariant($"No processors registered for plugin {_plugin.GetType().FullName}")); (list ?? (list = new List())).Add(_plugin); continue; } foreach (Processor processor2 in _plugin.Processors) { if (!_processorsById.TryAdd(processor2.Attribute.Id, processor2)) { Processor processor = _processorsById[processor2.Attribute.Id]; ServersideQoLPluginBase.Logger.LogError("Processor " + processor2.GetType().FullName + " is using the same ID as " + processor.GetType().FullName + " and will be ignored"); } else { processor2.AddPrefabInfoInterfaceInternal(typeExtensionBuilder); if (!(_plugin is ServersideQoLPlugin)) { num++; } if (_plugin.Config.Enabled.Value) { _enabledProcessors.Add(processor2); } } } } if (list != null) { foreach (IServersideQoLPlugin item in list) { __plugins.Remove(item); } } if (!typeExtensionBuilder.HasInterfaces) { ServersideQoLPluginBase.Logger.LogWarning("No plugins registered"); return false; } if (num == 0) { ServersideQoLPluginBase.Logger.LogWarning("No processors registered"); return false; } SortProcessors(_enabledProcessors, isPrefabList: false); _prefabInfoFactory = typeExtensionBuilder.GetFactory(); foreach (IServersideQoLPlugin _plugin2 in __plugins) { _plugin2.Config.ConfigChanged += OnConfigChanged; } return true; } protected override void RegisterProcessors(IProcessorCollection processors) { processors.Add().Add().Add(); } private void AddChanged(ServersideQoLZDO zdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Vector2s sector = zdo.ZDO.GetSector(); if (!_sectors.TryGetValue(sector, out SectorState value)) { _sectors.Add(sector, value = new SectorState()); value.Changed.Add(zdo); } else if (_currentlyProcessing != value) { value.Changed.Add(zdo); } else if (!value.Changed.Contains(zdo)) { value.Repeat.Add(zdo); } } private void OnPrefabChanged(ServersideQoLZDO zdo) { PrefabInfo value; if (!zdo.ZDO.IsValid()) { value = null; } else if (!_prefabInfos.TryGetValue(zdo.ZDO.GetPrefab(), out value)) { AddChanged(zdo); } zdo.PrefabInfo = value; if (value != null) { List enabledProcessors = value.EnabledProcessors; if (enabledProcessors != null && enabledProcessors.Count > 0) { AddChanged(zdo); } } } private void OnDataOrOwnerRevisionChanged(ServersideQoLZDO zdo) { if (zdo.HasProcessors) { AddChanged(zdo); } } private bool Initialize() { //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Invalid comparison between Unknown and I4 //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Invalid comparison between Unknown and I4 //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) foreach (IServersideQoLPlugin _plugin in __plugins) { IConfig config = _plugin.Config; config.ConfigChanged -= OnConfigChanged; config.ConfigChanged += OnConfigChanged; } Config config2 = base.Config; ServersideQoLPluginBase.Logger.LogInfo(FormattableString.Invariant($"Enabled: {config2.Enabled.Value}, DiagnosticLogs: {config2.DiagnosticLogs.Value}")); if (!config2.Enabled.Value) { return false; } if (Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.dedicatedserver", out var value)) { ServersideQoLPluginBase.Logger.LogWarning("Many features are incompatible with " + value.Metadata.Name); } if (config2.DiagnosticLogs.Value) { Logger logger = ServersideQoLPluginBase.Logger; string separator = Environment.NewLine + " "; List list = new List(); list.Add("Config:"); list.AddRange(__plugins.Where((IServersideQoLPlugin x) => x.Config.Enabled.Value).SelectMany((IServersideQoLPlugin x) => ((IEnumerable>)x.Config.ConfigFile).Select((KeyValuePair keyValuePair) => FormattableString.Invariant(FormattableStringFactory.Create("{0}[{1}].[{2}] = {3}", (!keyValuePair.Value.BoxedValue.Equals(keyValuePair.Value.DefaultValue)) ? "*" : "", keyValuePair.Key.Section, keyValuePair.Key.Key, keyValuePair.Value.BoxedValue))))); logger.LogInfo(string.Join(separator, list.ToArray())); } bool flag = false; bool flag2 = false; uint num = (uint)typeof(Version).GetField("c_networkVersion").GetValue(null); Item val = (Item)typeof(Version).GetField("c_ItemDataVersion").GetValue(null); World val2 = (World)typeof(Version).GetField("c_WorldVersion").GetValue(null); if (num != 37) { ServersideQoLPluginBase.Logger.LogWarning(FormattableString.Invariant($"Unsupported network version: {num}, expected: {37u}")); flag = true; flag2 |= !ConfigBase.Instance.IgnoreNetworkVersionCheck.Value; } if ((int)val != 108) { ServersideQoLPluginBase.Logger.LogWarning(FormattableString.Invariant($"Unsupported item data version: {val:D} [{val}], expected: {(object)(Item)108:D} [{(object)(Item)108}]")); flag = true; flag2 |= !ConfigBase.Instance.IgnoreItemDataVersionCheck.Value; } if ((int)val2 != 40) { ServersideQoLPluginBase.Logger.LogWarning(FormattableString.Invariant($"Unsupported world version: {val2:D} [{val2}], expected: {(object)(World)40:D} [{(object)(World)40}]")); flag = true; flag2 |= !ConfigBase.Instance.IgnoreWorldVersionCheck.Value; } if (flag) { if (flag2) { ServersideQoLPluginBase.Logger.LogError("Version checks failed. Mod execution is stopped"); return false; } ServersideQoLPluginBase.Logger.LogError("Version checks failed, but you chose to ignore the checks (config). Continuing..."); } foreach (ServersideQoLZDO item in _sectors.Values.SelectMany((SectorState x) => x.Changed)) { if (item.ZDO.IsValid()) { ServersideQoLZDO serversideQoLZDO = item; if (serversideQoLZDO.PrefabInfo == null) { PrefabInfo prefabInfo = (serversideQoLZDO.PrefabInfo = GetPrefabInfo(item.ZDO.GetPrefab())); } } } Processor.StaticInitialize(); foreach (Processor enabledProcessor in _enabledProcessors) { enabledProcessor.Initialize(); } return true; } private void OnConfigChanged(object sender, SettingChangedEventArgs e) { IConfig config = (IConfig)sender; if (base.Config.DiagnosticLogs.Value || (object)e.ChangedSetting == base.Config.DiagnosticLogs) { ServersideQoLPluginBase.Logger.LogInfo($"Config changed: [{e.ChangedSetting.Definition.Section}].[{e.ChangedSetting.Definition.Key}] = {e.ChangedSetting.BoxedValue}"); } if ((object)e.ChangedSetting == base.Config.DiagnosticLogs && base.Config.DiagnosticLogs.Value) { Logger logger = ServersideQoLPluginBase.Logger; string separator = Environment.NewLine + " "; List list = new List(); list.Add("Config:"); list.AddRange(((IEnumerable>)base.Config.ConfigFile).Select((KeyValuePair x) => FormattableString.Invariant($"[{x.Key.Section}].[{x.Key.Key}] = {x.Value.BoxedValue}"))); logger.LogInfo(string.Join(separator, list.ToArray())); } if ((object)config.Enabled != e.ChangedSetting) { return; } if (config.Enabled.Value) { foreach (Processor processor in config.Plugin.Processors) { _enabledProcessors.Add(processor); } SortProcessors(_enabledProcessors, isPrefabList: false); } else { foreach (Processor processor2 in config.Plugin.Processors) { _enabledProcessors.Remove(processor2); } } foreach (PrefabInfo value in _prefabInfos.Values) { if (value == null) { continue; } if (config.Enabled.Value) { foreach (Processor processor3 in config.Plugin.Processors) { value.EnabledProcessors.Add(processor3); } SortProcessors(value.EnabledProcessors, isPrefabList: true); continue; } foreach (Processor processor4 in config.Plugin.Processors) { value.EnabledProcessors.Remove(processor4); } } if (!config.Enabled.Value) { return; } foreach (Processor processor5 in config.Plugin.Processors) { processor5.Initialize(); } foreach (ServersideQoLZDO item in from x in ZDOMan.instance.GetObjects() select x.ServersideQoLZDO) { item.ReregisterAll(); OnDataOrOwnerRevisionChanged(item); } } private void Execute(PeersEnumerable peers, double timeBudgetSeconds) { //IL_0047: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; peers.Update(); if (peers.Count == 0) { return; } double num = realtimeSinceStartupAsDouble + timeBudgetSeconds; _sectorsToProcess.Clear(); int num2 = Extensions.get_ActiveArea(ZoneSystem.instance); Vector2s key = default(Vector2s); foreach (Peer peer in peers) { Vector2s sector = peer.GetSector(); for (int i = sector.x - num2; i <= sector.x + num2; i++) { for (int j = sector.y - num2; j <= sector.y + num2; j++) { ((Vector2s)(ref key))..ctor(i, j); if (!_sectors.TryGetValue(key, out SectorState value)) { continue; } if (value != null) { HashSet changed = value.Changed; if (changed != null && changed.Count == 0) { HashSet repeat = value.Repeat; if (repeat != null && repeat.Count == 0) { continue; } } } value.Peers.Add(peer); _sectorsToProcess.Add(value); } } } if (_sectorsToProcess.Count == 0) { return; } Processor.StaticPreProcess(peers); foreach (Processor enabledProcessor in _enabledProcessors) { enabledProcessor.PreProcessInternal(peers); } int num3 = 0; int num4 = 0; foreach (SectorState item in _sectorsToProcess) { if (item.Repeat.Count != 0) { foreach (ServersideQoLZDO item2 in item.Repeat) { if (item2.ZDO.IsValid()) { if ((double)item2.ScheduleBefore > num) { _repeat.Add(item2); } else { item.Changed.Add(item2); } } } item.Repeat.Clear(); foreach (ServersideQoLZDO item3 in _repeat) { Vector2s sector2 = item3.ZDO.GetSector(); if (!_sectors.TryGetValue(sector2, out SectorState value2)) { _sectors.Add(sector2, value2 = new SectorState()); } value2.Repeat.Add(item3); } _repeat.Clear(); } if (item.Changed.Count != 0) { num4 += item.Changed.Count; _currentlyProcessing = item; foreach (ServersideQoLZDO item4 in item.Changed) { num3++; if (item4.ZDO.IsValid()) { ServersideQoLZDO serversideQoLZDO = item4; if (serversideQoLZDO.PrefabInfo == null) { PrefabInfo prefabInfo = (serversideQoLZDO.PrefabInfo = GetPrefabInfo(item4.ZDO.GetPrefab())); } if (item4.HasProcessors) { ProcessZdo(item.Peers, item4); } } } item.Changed.Clear(); _currentlyProcessing = null; } item.Peers.Clear(); } if (num3 < num4) { _unfinishedProcessingInRow++; } else { _unfinishedProcessingInRow = 0u; } } private void ProcessZdo(IReadOnlyList peers, ServersideQoLZDO zdo) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) zdo.ScheduleBefore = float.NaN; if (!zdo.ExclusivityCheckDone) { zdo.ExclusivityCheckDone = true; IReadOnlyList processors = zdo.Processors; if (processors.Count > 1) { Processor processor = null; foreach (Processor item in processors.Enumerate()) { if (item.ClaimExclusive(zdo)) { if (processor == null) { processor = item; } else if (base.Config.DiagnosticLogs.Value) { ServersideQoLPluginBase.Logger.LogError(FormattableString.Invariant($"ZDO {zdo.ZDO.m_uid} claimed exclusive by {item.GetType().Name} while already claimed by {processor.GetType().Name}")); } } } if (processor != null) { zdo.UnregisterAllExcept(processor); } } } bool flag = false; bool flag2 = false; _unregister.Clear(); foreach (Processor item2 in zdo.Processors.Enumerate()) { Processor.ProcessResult processResult = item2.ProcessInternal(peers, zdo); if (flag = (processResult & Processor.ProcessResult.DestroyZDO) != 0) { zdo.Destroy(); break; } if ((processResult & Processor.ProcessResult.RecreateZDO) != Processor.ProcessResult.Default) { flag2 = true; } bool flag3 = (processResult & Processor.ProcessResult.UnregisterProcessor) != 0; if (flag3) { _unregister.Add(item2); } if (!flag2 && !flag3 && (processResult & Processor.ProcessResult.ScheduleReprocessing) != Processor.ProcessResult.Default) { ScheduleReprocessing(zdo); } if ((processResult & Processor.ProcessResult.SkipOtherProcessors) != Processor.ProcessResult.Default) { break; } } if (!flag) { if (_unregister.Count > 0) { zdo.Unregister(_unregister); } if (flag2) { zdo.Recreate(); } } } private void SortProcessors(List processors, bool isPrefabList) { Dictionary> dictionary = new Dictionary>(processors.Count); Dictionary dictionary2 = new Dictionary(processors.Count); Dictionary> dictionary3 = processors.ToDictionary((Processor x) => x, (Processor x) => x.GetType().GetCustomAttributes().ToList()); HashSet hashSet = null; for (int num = processors.Count - 1; num >= 0; num--) { Processor processor = processors[num]; if (!isPrefabList && processor.Attribute.OnlyWhenDependedOn) { HashSet hashSet2 = hashSet; HashSet hashSet3 = hashSet2; if (hashSet3 == null) { HashSet hashSet4 = new HashSet(); foreach (Guid item2 in dictionary3.Values.SelectMany((List x) => x.Select((ProcessorDependencyAttribute processorDependencyAttribute) => processorDependencyAttribute.ProcessorId))) { hashSet4.Add(item2); } hashSet = hashSet4; } if (!hashSet.Contains(processor.Attribute.Id)) { processors.RemoveAt(num); continue; } } dictionary.Add(processor, new List()); dictionary2.Add(processor, 0); } Processor key; int value3; for (int num2 = processors.Count - 1; num2 >= 0; num2--) { Processor processor2 = processors[num2]; if (dictionary3.TryGetValue(processor2, out var value)) { foreach (ProcessorDependencyAttribute item3 in value) { if (!_processorsById.TryGetValue(item3.ProcessorId, out Processor value2) || !dictionary.ContainsKey(value2)) { if (!isPrefabList && item3.Required) { processors.RemoveAt(num2); break; } } else if (item3.RunBefore ?? false) { dictionary[processor2].Add(value2); key = value2; value3 = dictionary2[key]++; } else if ((!item3.RunBefore) ?? false) { dictionary[value2].Add(processor2); key = processor2; value3 = dictionary2[key]++; } } } } List list = new List(); foreach (KeyValuePair item4 in dictionary2) { item4.Deconstruct(out key, out value3); Processor item = key; if (value3 == 0) { list.Add(item); } } int count = processors.Count; processors.Clear(); while (list.Count > 0) { list.Sort((Processor a, Processor b) => b.Attribute.Priority.CompareTo(a.Attribute.Priority)); Processor processor3 = list[list.Count - 1]; list.RemoveAt(list.Count - 1); if (!isPrefabList && processor3.Attribute.Priority != 0 && list.Count > 0) { Processor processor4 = list[list.Count - 1]; if (processor4 != null && processor4.Attribute.Priority == processor3.Attribute.Priority) { ServersideQoLPluginBase.Logger.LogWarning($"Processors {processor3.GetType().FullName} and {processor4.GetType().FullName} share the same non-default priority ({processor3.Attribute.Priority})"); } } processors.Add(processor3); foreach (Processor item5 in dictionary[processor3]) { if (--dictionary2[item5] == 0) { list.Add(item5); } } } if (!isPrefabList && processors.Count != count) { IEnumerable values = from x in dictionary2 where x.Value > 0 select $"{x.Key.Attribute.Id} ({x.Key.GetType().FullName})"; ServersideQoLPluginBase.Logger.LogError("The following processors are not used due to cyclic dependencies: " + string.Join(", ", values)); } } internal void ScheduleReprocessing(ServersideQoLZDO zdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Vector2s sector = zdo.ZDO.GetSector(); if (!_sectors.TryGetValue(sector, out SectorState value)) { _sectors.Add(sector, value = new SectorState()); } value.Repeat.Add(zdo); } internal void ScheduleReprocessing(ServersideQoLZDO zdo, float delayInSeconds) { zdo.DelaySchedulingFor(delayInSeconds); ScheduleReprocessing(zdo); } internal PrefabInfo GetPrefabInfo(int prefab) { return _prefabInfos.GetOrAdd(prefab, delegate(int prefabHash) { PrefabInfo prefabInfo = null; GameObject prefab2 = ZNetScene.instance.GetPrefab(prefabHash); if (prefab2 != null) { ZNetView component = prefab2.GetComponent(); MonoBehaviour[] array = ((component != null) ? ((Component)component).gameObject.GetComponentsInChildren() : null); if (array != null) { prefabInfo = _prefabInfoFactory(); Dictionary> dictionary = null; foreach (IGrouping item in from x in array where ((object)x).GetType().Assembly == typeof(ZNetView).Assembly group x by ((object)x).GetType()) { List list = new List(); list.AddRange(item); IReadOnlyList value = new <>z__ReadOnlyList(list); (dictionary ?? (dictionary = new Dictionary>())).Add(item.Key, value); Type baseType = item.Key.BaseType; while (baseType != typeof(MonoBehaviour)) { dictionary.Add(baseType, value); baseType = baseType.BaseType; } } bool? flag = dictionary?.ContainsKey(typeof(Piece)); if (flag.HasValue && flag == true && PieceTablesByPieceName.TryGetValue(((Object)prefab2).name, out PieceTable value2)) { dictionary.Add(typeof(PieceTable), new <>z__ReadOnlySingleElementList((MonoBehaviour)(object)value2)); } prefabInfo.Init(prefab2, prefabHash, ((Object)prefab2).name, dictionary); foreach (IServersideQoLPlugin _plugin in __plugins) { foreach (Processor processor in _plugin.Processors) { if (processor.InitializePrefabInfoInternal(prefabInfo)) { prefabInfo.AvailableProcessors.Add(processor); if (_plugin.Config.Enabled.Value) { prefabInfo.EnabledProcessors.Add(processor); } } } } SortProcessors(prefabInfo.EnabledProcessors, isPrefabList: true); } } return prefabInfo ?? DummyPrefabInfo.Instance; }); } private void Awake() { ServersideQoLPluginBase.Logger.LogWarning(string.Format("You are running a pre-release version: {0} ({1})", "1.99.8-beta", BuildTimestamp.LocalDateTime)); OnAwake(); } private void OnAwake() { HarmonyInstance.PatchAll(typeof(ServersideQoLPlugin).Assembly); } } internal interface IServersideQoLPlugin { IConfig Config { get; } IReadOnlyCollection Processors { get; } void RegisterProcessors(); } public interface IProcessorCollection { IProcessorCollection Add() where T : Processor, new(); } public abstract class ServersideQoLPluginBase : BaseUnityPlugin, IServersideQoLPlugin { IConfig IServersideQoLPlugin.Config => GetConfig(); IReadOnlyCollection IServersideQoLPlugin.Processors => GetProcessors(); private protected ServersideQoLPluginBase() { } private protected abstract IConfig GetConfig(); private protected abstract IReadOnlyCollection GetProcessors(); private protected abstract void RegisterProcessors(); void IServersideQoLPlugin.RegisterProcessors() { RegisterProcessors(); } } public abstract class ServersideQoLPluginBase : ServersideQoLPluginBase where TSelf : ServersideQoLPluginBase where TConfig : ConfigBase { private sealed class ProcessorCollection(ServersideQoLPluginBase plugin, Logger logger) : IProcessorCollection { public IProcessorCollection Add() where T : Processor, new() { T val = Processor.Instance(); if (P._processors.Contains(val)) { return this; } val.Init(P, P); P._processors.Add(val); return this; } } private TConfig? _config; private readonly HashSet _processors = new HashSet(); public static TSelf Instance { get; private set; } = null; public TConfig Config => _config ?? throw new InvalidOperationException("Config has not been initialized yet"); public static Logger Logger { get; private set; } = null; public static BepInPlugin BepInPlugin { get; } = ((MemberInfo)typeof(TSelf)).GetCustomAttribute(); protected abstract TConfig CreateConfigSingleton(ConfigFile configFile, Logger logger); private protected sealed override IConfig GetConfig() { IConfig config = _config; if (config == null) { config = (_config = CreateConfigSingleton(((BaseUnityPlugin)this).Config, Logger)); config.Plugin = this; config.RaiseInitialized(); } return config; } private protected sealed override IReadOnlyCollection GetProcessors() { return _processors; } protected ServersideQoLPluginBase() { Instance = (TSelf)this; Logger = new Logger(BepInPlugin.Name); ServersideQoLPlugin.RegisterPlugin(this); } public static int RegisterServerVar(string name) { return StringExtensionMethods.GetStableHashCode(BepInPlugin.GUID + "." + name, true); } protected abstract void RegisterProcessors(IProcessorCollection processors); private protected sealed override void RegisterProcessors() { RegisterProcessors(new ProcessorCollection(this, Logger)); } } public sealed class ServersideQoLZDO(ZDO zdo) : IEquatable { private sealed class UnityObjectEqualityComparer : EqualityComparer where T : Object { public static UnityObjectEqualityComparer Instance { get; } = new UnityObjectEqualityComparer(); public override bool Equals(T x, T y) { object obj = x; string obj2 = ((obj != null) ? ((Object)obj).name : null); object obj3 = y; return obj2 == ((obj3 != null) ? ((Object)obj3).name : null); } public override int GetHashCode(T obj) { return ((Object)obj).name.GetHashCode(); } } private delegate T GetHandler(ZDO zdo, int hash, T defaultValue) where T : notnull; private delegate void SetHandler(ZDO zdo, int hash, T value) where T : notnull; private delegate bool RemoveHandler(ZDO zdo, int hash) where T : notnull; private interface IComponentFieldAccessor { void Return(); } private static class ComponentFieldAccessor { public static ComponentFieldAccessor Get(ServersideQoLZDO zdo, TComponent component) where TComponent : MonoBehaviour { return ComponentFieldAccessor.Get(zdo, component); } } public sealed class ComponentFieldAccessor : IComponentFieldAccessor where TComponent : MonoBehaviour { private static class ExpressionCache where T : notnull { private static readonly Dictionary<(string, int), Expression>> __cache = new Dictionary<(string, int), Expression>>(); public static Expression> Get(Func>> factory, string callerFilePath, int callerLineNo) { if (!__cache.TryGetValue((callerFilePath, callerLineNo), out Expression> value)) { __cache.Add((callerFilePath, callerLineNo), value = factory()); } return value; } } private sealed class FieldReference where T : notnull { private readonly int _hash; private readonly Func _getFieldValue; private static readonly Dictionary<(Type, string), FieldReference> __cacheByFieldName = new Dictionary<(Type, string), FieldReference>(); private static readonly Dictionary<(Type, string, int), FieldReference> __cacheByLocation = new Dictionary<(Type, string, int), FieldReference>(); private static readonly (GetHandler Getter, SetHandler Setter, RemoveHandler? Remover, IEqualityComparer EqualityComparer) Accessors = ((Func<(GetHandler, SetHandler, RemoveHandler, IEqualityComparer)>)delegate { if (typeof(T) == typeof(bool)) { return ((GetHandler)(object)(GetHandler)((ZDO zdo, int hash, bool defaultValue) => zdo.GetBool(hash, defaultValue)), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, bool value) { zdo.Set(hash, value); }, (RemoveHandler)(object)(RemoveHandler)((ZDO zdo, int hash) => zdo.RemoveInt(hash)), (IEqualityComparer)EqualityComparer.Default); } if (typeof(T) == typeof(int)) { return ((GetHandler)(object)(GetHandler)((ZDO zdo, int hash, int defaultValue) => zdo.GetInt(hash, defaultValue)), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, int value) { zdo.Set(hash, value, false); }, (RemoveHandler)(object)(RemoveHandler)((ZDO zdo, int hash) => zdo.RemoveInt(hash)), (IEqualityComparer)EqualityComparer.Default); } if (typeof(T) == typeof(float)) { return ((GetHandler)(object)(GetHandler)((ZDO zdo, int hash, float defaultValue) => zdo.GetFloat(hash, defaultValue)), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, float value) { zdo.Set(hash, value); }, (RemoveHandler)(object)(RemoveHandler)((ZDO zdo, int hash) => zdo.RemoveFloat(hash)), (IEqualityComparer)EqualityComparer.Default); } if (typeof(T) == typeof(string)) { return ((GetHandler, SetHandler, RemoveHandler?, IEqualityComparer))((GetHandler)(object)(GetHandler)((ZDO zdo, int hash, string defaultValue) => zdo.GetString(hash, defaultValue)), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, string value) { zdo.Set(hash, value); }, null, (IEqualityComparer)EqualityComparer.Default); } if (typeof(T) == typeof(Vector3)) { return ((GetHandler)(object)(GetHandler)((ZDO zdo, int hash, Vector3 defaultValue) => zdo.GetVec3(hash, defaultValue)), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, Vector3 value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) zdo.Set(hash, value); }, (RemoveHandler)(object)(RemoveHandler)((ZDO zdo, int hash) => zdo.RemoveVec3(hash)), (IEqualityComparer)EqualityComparer.Default); } if (typeof(T) == typeof(GameObject)) { return ((GetHandler, SetHandler, RemoveHandler?, IEqualityComparer))((GetHandler)(object)new GetHandler(GetGameObject), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, GameObject value) { zdo.Set(hash, ((Object)value).name); }, null, (IEqualityComparer)(object)UnityObjectEqualityComparer.Instance); } if (typeof(T) == typeof(ItemDrop)) { return ((GetHandler, SetHandler, RemoveHandler?, IEqualityComparer))((GetHandler)(object)new GetHandler(GetItemDrop), (SetHandler)(object)(SetHandler)delegate(ZDO zdo, int hash, ItemDrop value) { zdo.Set(hash, ((Object)value).name); }, null, (IEqualityComparer)(object)UnityObjectEqualityComparer.Instance); } throw new NotSupportedException(); static GameObject GetGameObject(ZDO zdo, int hash, GameObject defaultValue) { string text = zdo.GetString(hash, ""); if (string.IsNullOrEmpty(text)) { return defaultValue; } return ZNetScene.instance.GetPrefab(text) ?? defaultValue; } static ItemDrop GetItemDrop(ZDO zdo, int hash, ItemDrop defaultValue) { string text = zdo.GetString(hash, ""); if (!string.IsNullOrEmpty(text)) { GameObject prefab = ZNetScene.instance.GetPrefab(text); return ((prefab != null) ? prefab.GetComponent() : null) ?? defaultValue; } return defaultValue; } })(); private FieldReference(Type componentType, FieldInfo field) { _hash = StringExtensionMethods.GetStableHashCode(FormattableString.Invariant($"{componentType.Name}.{field.Name}"), true); ParameterExpression parameterExpression = Expression.Parameter(typeof(TComponent)); _getFieldValue = Expression.Lambda>(Expression.Field(parameterExpression, field), new ParameterExpression[1] { parameterExpression }).Compile(); } public static FieldReference Get(Type type, Func>> factory, string callerFilePath, int callerLineNo) { if (!__cacheByLocation.TryGetValue((type, callerFilePath, callerLineNo), out FieldReference value)) { Expression> expression = ExpressionCache.Get(factory, callerFilePath, callerLineNo); MemberExpression memberExpression = (MemberExpression)expression.Body; FieldInfo fieldInfo = (FieldInfo)memberExpression.Member; if (!__cacheByFieldName.TryGetValue((type, fieldInfo.Name), out value)) { __cacheByFieldName.Add((type, fieldInfo.Name), value = new FieldReference(type, fieldInfo)); } __cacheByLocation.Add((type, callerFilePath, callerLineNo), value); } return value; } public T GetValue(ComponentFieldAccessor componentFieldAccessor) { T val = _getFieldValue(componentFieldAccessor._component); if (!componentFieldAccessor.HasFields) { return val; } return Accessors.Getter(componentFieldAccessor._zdo.ZDO, _hash, val); } public ComponentFieldAccessor SetValue(ComponentFieldAccessor componentFieldAccessor, T value) { if (Accessors.Remover != null && Accessors.EqualityComparer.Equals(value, _getFieldValue(componentFieldAccessor._component))) { Accessors.Remover(componentFieldAccessor._zdo.ZDO, _hash); } else { if (!componentFieldAccessor.HasFields) { componentFieldAccessor.SetHasFields(value: true); } Accessors.Setter(componentFieldAccessor._zdo.ZDO, _hash, value); } return componentFieldAccessor; } public bool UpdateValue(ComponentFieldAccessor componentFieldAccessor, T value) { T val = _getFieldValue(componentFieldAccessor._component); if (Accessors.EqualityComparer.Equals(value, Accessors.Getter(componentFieldAccessor._zdo.ZDO, _hash, val))) { return false; } bool flag = Accessors.EqualityComparer.Equals(value, val); if (Accessors.Remover != null && flag) { Accessors.Remover(componentFieldAccessor._zdo.ZDO, _hash); } else { if (!componentFieldAccessor.HasFields && !flag) { componentFieldAccessor.SetHasFields(value: true); } Accessors.Setter(componentFieldAccessor._zdo.ZDO, _hash, value); } return true; } public ComponentFieldAccessor ResetValue(ComponentFieldAccessor componentFieldAccessor) { if (!componentFieldAccessor.HasFields) { return componentFieldAccessor; } if (Accessors.Remover != null) { Accessors.Remover(componentFieldAccessor._zdo.ZDO, _hash); } else { Accessors.Setter(componentFieldAccessor._zdo.ZDO, _hash, _getFieldValue(componentFieldAccessor._component)); } return componentFieldAccessor; } public bool UpdateResetValue(ComponentFieldAccessor componentFieldAccessor) { if (!componentFieldAccessor.HasFields) { return false; } if (Accessors.Remover != null) { return Accessors.Remover(componentFieldAccessor._zdo.ZDO, _hash); } T val = _getFieldValue(componentFieldAccessor._component); if (Accessors.EqualityComparer.Equals(Accessors.Getter(componentFieldAccessor._zdo.ZDO, _hash, val), val)) { return false; } Accessors.Setter(componentFieldAccessor._zdo.ZDO, _hash, val); return true; } } private static readonly Stack> __pool = new Stack>(); private static readonly Dictionary __hasComponentFieldsHashes = new Dictionary(); private ServersideQoLZDO _zdo; private TComponent _component; private bool? _hasComponentFields; private int _hasComponentFieldsHash; public bool HasFields { get { if (_zdo.HasFields) { bool valueOrDefault = _hasComponentFields == true; if (!_hasComponentFields.HasValue) { valueOrDefault = _zdo.ZDO.GetBool(_hasComponentFieldsHash, false); _hasComponentFields = valueOrDefault; return valueOrDefault; } return valueOrDefault; } return false; } } private ComponentFieldAccessor() { } public static ComponentFieldAccessor Get(ServersideQoLZDO zdo, TComponent component) { if (!__pool.TryPop(out ComponentFieldAccessor result)) { result = new ComponentFieldAccessor(); } result.Init(zdo, component); return result; } [MemberNotNull(new string[] { "_zdo", "_component" })] private void Init(ServersideQoLZDO zdo, TComponent component) { _zdo = zdo; _component = component; _hasComponentFields = null; Type type = ((object)component).GetType(); if (!__hasComponentFieldsHashes.TryGetValue(type, out _hasComponentFieldsHash)) { __hasComponentFieldsHashes.Add(type, _hasComponentFieldsHash = StringExtensionMethods.GetStableHashCode(FormattableString.Invariant(FormattableStringFactory.Create("{0}{1}", "HasFields", type.Name)), true)); } } void IComponentFieldAccessor.Return() { _zdo = null; _component = default(TComponent); __pool.Push(this); } private void SetHasFields(bool value) { if (value) { _zdo.SetComponentHasFields(); } if (_hasComponentFields != value) { ZDO zDO = _zdo.ZDO; int hasComponentFieldsHash = _hasComponentFieldsHash; bool? flag = (_hasComponentFields = value); zDO.Set(hasComponentFieldsHash, flag.Value); } } [MustBeOnUniqueLine] public bool GetBool(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).GetValue(this); } [MustBeOnUniqueLine] public float GetFloat(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).GetValue(this); } [MustBeOnUniqueLine] public int GetInt(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).GetValue(this); } [MustBeOnUniqueLine] public string GetString(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).GetValue(this); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, bool value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, float value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, int value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, Vector3 value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, string value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, GameObject value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Set(Func>> fieldExpressionFactory, ItemDrop value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).SetValue(this, value); } [MustBeOnUniqueLine] public bool UpdateValue(Func>> fieldExpressionFactory, bool value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, value); } [MustBeOnUniqueLine] public bool UpdateValue(Func>> fieldExpressionFactory, float value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, value); } [MustBeOnUniqueLine] public bool UpdateValue(Func>> fieldExpressionFactory, int value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, value); } [MustBeOnUniqueLine] public bool UpdateValue(Func>> fieldExpressionFactory, string value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, value); } [MustBeOnUniqueLine] public bool UpdateValue(Func>> fieldExpressionFactory, GameObject value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, value); } [MustBeOnUniqueLine] public bool UpdateValue(Func>> fieldExpressionFactory, ItemDrop value, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, value); } [MustBeOnUniqueLine] public ComponentFieldAccessor Reset(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).ResetValue(this); } [MustBeOnUniqueLine] public ComponentFieldAccessor Reset(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).ResetValue(this); } [MustBeOnUniqueLine] public ComponentFieldAccessor Reset(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).ResetValue(this); } [MustBeOnUniqueLine] public ComponentFieldAccessor Reset(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).ResetValue(this); } [MustBeOnUniqueLine] public ComponentFieldAccessor Reset(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).ResetValue(this); } [MustBeOnUniqueLine] public ComponentFieldAccessor Reset(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).ResetValue(this); } [MustBeOnUniqueLine] public bool UpdateResetValue(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } [MustBeOnUniqueLine] public bool UpdateResetValue(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } [MustBeOnUniqueLine] public bool UpdateResetValue(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } [MustBeOnUniqueLine] public bool UpdateResetValue(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } [MustBeOnUniqueLine] public bool UpdateResetValue(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } [MustBeOnUniqueLine] public bool UpdateResetValue(Func>> fieldExpressionFactory, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } [MustBeOnUniqueLine] public bool SetOrReset(Func>> fieldExpressionFactory, bool set, bool setValue, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { if (!set) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, setValue); } [MustBeOnUniqueLine] public bool SetOrReset(Func>> fieldExpressionFactory, bool set, float setValue, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { if (!set) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, setValue); } [MustBeOnUniqueLine] public bool SetOrReset(Func>> fieldExpressionFactory, bool set, int setValue, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { if (!set) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, setValue); } [MustBeOnUniqueLine] public bool SetOrReset(Func>> fieldExpressionFactory, bool set, string setValue, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { if (!set) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, setValue); } [MustBeOnUniqueLine] public bool SetOrReset(Func>> fieldExpressionFactory, bool set, GameObject setValue, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { if (!set) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, setValue); } [MustBeOnUniqueLine] public bool SetOrReset(Func>> fieldExpressionFactory, bool set, ItemDrop setValue, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNo = -1) { if (!set) { return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateResetValue(this); } return FieldReference.Get(((object)_component).GetType(), fieldExpressionFactory, callerFilePath, callerLineNo).UpdateValue(this, setValue); } } public readonly struct ZDOVars { private readonly ZDO _zdo; private static readonly int _animationCraftingHash = ZSyncAnimation.GetHash("crafting"); public ZDOVars(ZDO zdo) { _zdo = zdo; } private void ValidateOwnership(string filePath, int lineNo) { _ = ServersideQoLPluginBase.Instance.Config.DiagnosticLogs.Value; } public int GetState(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_state, defaultValue); } public void SetState(int value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_state, value, false); } public long GetCreator(long defaultValue = 0L) { return _zdo.GetLong(ZDOVars.s_creator, defaultValue); } public void SetCreator(long value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_creator, value); } public bool GetInUse(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_inUse, defaultValue); } public void SetInUse(bool value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_inUse, value); } public float GetFuel(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_fuel, defaultValue); } public void SetFuel(float value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_fuel, value); } public bool GetPiece(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_piece, defaultValue); } public void SetPiece(bool value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_piece, value); } public byte[]? GetItems(byte[]? defaultValue = null) { return _zdo.GetByteArray(ZDOVars.s_items, defaultValue); } public void SetItems(byte[]? value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_items, value); } public string GetTag(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_tag, defaultValue); } public void SetTag(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_tag, value); } public byte[]? GetData(byte[]? defaultValue = null) { return _zdo.GetByteArray(ZDOVars.s_data, defaultValue); } public void SetData(byte[]? value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_data, value); } public float GetStamina(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_stamina, defaultValue); } public float GetEitr(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_eitr, defaultValue); } public long GetPlayerID(long defaultValue = 0L) { return _zdo.GetLong(ZDOVars.s_playerID, defaultValue); } public void SetPlayerID(long value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_playerID, value); } public string GetPlayerName(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_playerName, defaultValue); } public void SetPlayerName(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_playerName, value); } public string GetFollow(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_follow, defaultValue); } public void SetFollow(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_follow, value); } public int GetRightItem(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_rightItem, defaultValue); } public int GetLeftItem(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_leftItem, defaultValue); } public string GetText(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_text, defaultValue); } public void SetText(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_text, value); } public string GetItem(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_item, defaultValue); } public void SetItem(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_item, value); } public string GetItem(int idx, string defaultValue = "") { return _zdo.GetString(FormattableString.Invariant($"item{idx}"), defaultValue); } public void SetItem(int idx, string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(FormattableString.Invariant($"item{idx}"), value); } public int GetQueued(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_queued, defaultValue); } public void SetQueued(int value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_queued, value, false); } public bool GetTamed(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_tamed, defaultValue); } public void SetTamed(bool value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_tamed, value); } public float GetTameTimeLeft(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_tameTimeLeft, defaultValue); } public void SetTameTimeLeft(float value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_tameTimeLeft, value); } public int GetAmmo(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_ammo, defaultValue); } public void SetAmmo(int value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_ammo, value, false); } public string GetAmmoType(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_ammoType, defaultValue); } public void SetAmmoType(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_ammoType, value); } public float GetGrowStart(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_growStart, defaultValue); } public void SetGrowStart(float value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_growStart, value); } public DateTime GetSpawnTime(DateTime defaultValue = default(DateTime)) { return new DateTime(_zdo.GetLong(ZDOVars.s_spawnTime, defaultValue.Ticks)); } public void SetSpawnTime(DateTime value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_spawnTime, value.Ticks); } public float GetHealth(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_health, defaultValue); } public void SetHealth(float value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_health, value); } public string GetHealthString(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_health, defaultValue); } public void SetHealth(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_health, value); } public void RemoveHealth([CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.RemoveFloat(ZDOVars.s_health); } public int GetPermitted(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_permitted, defaultValue); } public void SetPermitted(int value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_permitted, value, false); } public int GetLevel(int defaultValue = 1) { return _zdo.GetInt(ZDOVars.s_level, defaultValue); } public void SetLevel(int value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_level, value, false); } public bool GetPatrol(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_patrol, defaultValue); } public void SetPatrol(bool value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_patrol, value); } public Vector3 GetPatrolPoint(Vector3 defaultValue = default(Vector3)) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return _zdo.GetVec3(ZDOVars.s_patrolPoint, defaultValue); } public void SetPatrolPoint(Vector3 value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_patrolPoint, value); } public Vector3 GetSpawnPoint(Vector3 defaultValue = default(Vector3)) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return _zdo.GetVec3(ZDOVars.s_spawnPoint, defaultValue); } public void SetSpawnPoint(Vector3 value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_spawnPoint, value); } public int GetEmoteID(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_emoteID, defaultValue); } public Emotes GetEmote(Emotes defaultValue = (Emotes)(-1)) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!Enum.TryParse(_zdo.GetString(ZDOVars.s_emote, ""), ignoreCase: true, out Emotes result)) { return defaultValue; } return result; } public bool GetAnimationIsEncumbered(bool defaultValue = false) { return _zdo.GetBool(PrivateAccessor.ZSyncAnimationZDOSalt + PrivateAccessor.CharacterAnimationHashEncumbered, defaultValue); } public bool GetAnimationInWater(bool defaultValue = false) { return _zdo.GetBool(PrivateAccessor.ZSyncAnimationZDOSalt + PrivateAccessor.CharacterAnimationHashInWater, defaultValue); } public bool GetAnimationIsCrouching(bool defaultValue = false) { return _zdo.GetBool(PrivateAccessor.ZSyncAnimationZDOSalt + PrivateAccessor.PlayerAnimationHashCrouching, defaultValue); } public int GetAnimationCrafting(int defaultValue = 0) { return _zdo.GetInt(PrivateAccessor.ZSyncAnimationZDOSalt + _animationCraftingHash, defaultValue); } public DateTime GetTameLastFeeding(DateTime defaultValue = default(DateTime)) { return new DateTime(_zdo.GetLong(ZDOVars.s_tameLastFeeding, defaultValue.Ticks)); } public void SetTameLastFeeding(DateTime value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_tameLastFeeding, value.Ticks); } public bool GetEventCreature(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_eventCreature, defaultValue); } public bool GetInBed(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_inBed, defaultValue); } public int GetLocation(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_location, defaultValue); } public int GetSeed(int defaultValue = 0) { return _zdo.GetInt(ZDOVars.s_seed, defaultValue); } public bool GetAttachJoint(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_attachJointHash, defaultValue); } public long GetUser(long defaultValue = 0L) { return _zdo.GetLong(ZDOVars.s_user, defaultValue); } public bool GetIsDead(bool defaultValue = false) { return _zdo.GetBool(ZDOVars.s_dead, defaultValue); } public long GetOwner(long defaultValue = 0L) { return _zdo.GetLong(ZDOVars.s_owner, defaultValue); } public void SetOwner(long value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_owner, value); } public string GetOwnerName(string defaultValue = "") { return _zdo.GetString(ZDOVars.s_ownerName, defaultValue); } public void SetOwnerName(string value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_ownerName, value); } public float GetScaleScalar(float defaultValue = 0f) { return _zdo.GetFloat(ZDOVars.s_scaleScalarHash, defaultValue); } public void SetScaleScalar(float value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_scaleScalarHash, value); } public Vector3 GetScale(Vector3 defaultValue = default(Vector3)) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return _zdo.GetVec3(ZDOVars.s_scaleHash, defaultValue); } public void SetScale(Vector3 value, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) ValidateOwnership(filePath, lineNo); _zdo.Set(ZDOVars.s_scaleHash, value); } public void RemoveScale([CallerFilePath] string filePath = "", [CallerLineNumber] int lineNo = 0) { ValidateOwnership(filePath, lineNo); _zdo.RemoveVec3(ZDOVars.s_scaleHash); } } private static readonly Dictionary> __processors = new Dictionary>(); private static readonly ZPackage __pkg = new ZPackage(); private static readonly Stack> __componentFieldAccessorCache = new Stack>(); private static bool _onDestroyedSubscribed; [CompilerGenerated] private PrefabInfo? k__BackingField; private Action? _destroyed; private bool? _hasFields; private static readonly int __hasFieldsHash = StringExtensionMethods.GetStableHashCode("HasFields", true); private int _prevPrefab = -1; private ushort _prevOwnerRev = ushort.MaxValue; private uint _prevDataRev = uint.MaxValue; public ZDO ZDO { get; } = zdo; internal PrefabInfo? PrefabInfo { [CompilerGenerated] get { return k__BackingField; } set { Dictionary componentFieldAccessors = ComponentFieldAccessors; if (componentFieldAccessors != null) { foreach (IComponentFieldAccessor value2 in componentFieldAccessors.Values) { value2.Return(); } componentFieldAccessors.Clear(); __componentFieldAccessorCache.Push(componentFieldAccessors); } k__BackingField = value; Processors = value?.EnabledProcessors ?? new List(); HasProcessors = Processors.Count != 0; ExclusivityCheckDone = false; _hasFields = null; ComponentFieldAccessors = null; ScheduleBefore = float.NaN; _destroyed = null; } } public ZDOVars Vars => new ZDOVars(ZDO); internal bool HasProcessors { get; private set; } internal IReadOnlyList Processors { get; private set; } = Array.Empty(); internal bool ExclusivityCheckDone { get; set; } public bool HasFields { get { bool valueOrDefault = _hasFields == true; if (!_hasFields.HasValue) { valueOrDefault = ZDO.GetBool(__hasFieldsHash, false); _hasFields = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } internal Dictionary? ComponentFieldAccessors { get; private set; } internal float ScheduleBefore { get; set; } = float.NaN; public Timestamp OwnerTimestamp { get; private set; } public event Action? Destroyed { add { if (!_onDestroyedSubscribed) { ZDOMan instance = ZDOMan.instance; instance.m_onZDODestroyed = (Action)Delegate.Combine(instance.m_onZDODestroyed, new Action(OnDestroyed)); _onDestroyedSubscribed = true; } _destroyed = (Action)Delegate.Combine(_destroyed, value); } remove { _destroyed = (Action)Delegate.Remove(_destroyed, value); } } public TPrefabInfo? GetProcessorPrefabInfo() where TPrefabInfo : notnull, ProcessorPrefabInfo { PrefabInfo? prefabInfo = PrefabInfo; if (prefabInfo == null) { return null; } return prefabInfo.GetExtension>().PrefabInfo; } [Conditional("DEBUG")] public void AssertHasProcessorPrefabInfo() where TPrefabInfo : notnull, ProcessorPrefabInfo { } public void DelaySchedulingFor(float delayInSeconds) { float num = Time.realtimeSinceStartup + delayInSeconds; if (!(num > ScheduleBefore)) { ScheduleBefore = num; } } public void SetComponentHasFields() { if ((!_hasFields) ?? true) { ZDO zDO = ZDO; int _hasFieldsHash = __hasFieldsHash; bool? flag = (_hasFields = true); zDO.Set(_hasFieldsHash, flag.Value); } } internal bool UpdatePrefab() { int prefab = ZDO.GetPrefab(); if (prefab == _prevPrefab) { return false; } _prevPrefab = prefab; return true; } internal bool UpdateOwnerAndDataRevisions() { if (ZDO.OwnerRevision != _prevOwnerRev) { OwnerTimestamp = Timestamp.Now; } else if (ZDO.DataRevision == _prevDataRev) { return false; } ushort ownerRevision = ZDO.OwnerRevision; uint dataRevision = ZDO.DataRevision; _prevOwnerRev = ownerRevision; _prevDataRev = dataRevision; return true; } private static void OnDestroyed(ZDO zdo) { zdo.ServersideQoLZDO._destroyed?.Invoke(zdo.ServersideQoLZDO); } internal void Unregister(IReadOnlyList processors) { Processors = UnregisterCore(processors, Processors ?? Array.Empty()); HasProcessors = Processors.Count != 0; static IReadOnlyList UnregisterCore(IReadOnlyList list, IReadOnlyList zdoProcessors) { if (zdoProcessors.Count == 0) { return zdoProcessors; } int num = 0; foreach (Processor item in zdoProcessors.Enumerate()) { bool flag = true; foreach (Processor item2 in list.Enumerate()) { if (item == item2) { flag = false; break; } } if (flag) { num = (num, item.GetType()).GetHashCode(); } } if (!__processors.TryGetValue(num, out IReadOnlyList value)) { List list2 = new List(); __processors.Add(num, value = list2); foreach (Processor item3 in zdoProcessors.Enumerate()) { bool flag2 = true; foreach (Processor item4 in list.Enumerate()) { if (item3 == item4) { flag2 = false; break; } } if (flag2) { list2.Add(item3); } } } return value; } } public void UnregisterAllExcept(Processor keep) { Processors = UnregisterAllExceptCore(keep, Processors ?? Array.Empty()); HasProcessors = Processors.Count != 0; static IReadOnlyList UnregisterAllExceptCore(Processor processor, IReadOnlyList zdoProcessors) { if (!zdoProcessors.Contains(processor)) { return Array.Empty(); } int hashCode = (0, processor.GetType()).GetHashCode(); if (!__processors.TryGetValue(hashCode, out IReadOnlyList value)) { __processors.Add(hashCode, value = new <>z__ReadOnlySingleElementList(processor)); } return value; } } public void UnregisterAll() { Processors = Array.Empty(); HasProcessors = false; } public void ReregisterAll() { Processors = PrefabInfo?.EnabledProcessors ?? new List(); HasProcessors = Processors.Count != 0; } public ComponentFieldAccessor Fields() where TComponent : MonoBehaviour { Dictionary result = ComponentFieldAccessors; if (result == null || !result.TryGetValue(typeof(TComponent), out var value)) { if (PrefabInfo == null) { throw new InvalidOperationException("PrefabInfo is null"); } value = ComponentFieldAccessor.Get(this, PrefabInfo.GetRequiredComponent()); if (!__componentFieldAccessorCache.TryPop(out result)) { result = new Dictionary(); } result.Add(typeof(TComponent), value); } return (ComponentFieldAccessor)value; } public void Destroy() { ClaimOwnershipInternal(); ZDOMan.instance.DestroyZDO(ZDO); } public ServersideQoLZDO CreateClone(bool cloneProcessors) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) int prefab = ZDO.GetPrefab(); Vector3 position = ZDO.GetPosition(); long owner = ZDO.GetOwner(); __pkg.Clear(); ZDO.Serialize(__pkg); __pkg.Size(); ZDO val = ZDOMan.instance.CreateNewZDO(position, prefab); __pkg.SetPos(0); val.Deserialize(__pkg); val.SetOwnerInternal(owner); val.ServersideQoLZDO.PrefabInfo = PrefabInfo; if (cloneProcessors) { val.ServersideQoLZDO.Processors = Processors; val.ServersideQoLZDO.HasProcessors = HasProcessors; val.ServersideQoLZDO.ExclusivityCheckDone = ExclusivityCheckDone; } return val.ServersideQoLZDO; } public ServersideQoLZDO Recreate() { ServersideQoLZDO serversideQoLZDO = CreateClone(cloneProcessors: true); PrefabInfo prefabInfo = PrefabInfo; if (prefabInfo != null && prefabInfo.ReleaseOwnershipOnRecreate) { serversideQoLZDO.ReleaseOwnershipInternal(); } Destroy(); return serversideQoLZDO; } public TimeSpan GetTimeSinceSpawned() { return ZNet.instance.GetTime() - Vars.GetSpawnTime(); } public void ClaimOwnership() { ZDO.SetOwner(ZDOMan.GetSessionID()); } public void ClaimOwnershipInternal() { ZDO.SetOwnerInternal(ZDOMan.GetSessionID()); } public void ReleaseOwnership() { ZDO.SetOwner(0L); } public void ReleaseOwnershipInternal() { ZDO.SetOwnerInternal(0L); } public bool IsOwnerOrUnassigned() { if (ZDO.HasOwner()) { return ZDO.IsOwner(); } return true; } public void SetModAsCreator(Processor.CreatorMarkers marker = Processor.CreatorMarkers.None) { Vars.SetCreator((long)ServersideQoLPlugin.PluginGuidHash | (long)((ulong)marker << 32), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\ServersideQoLZDO.cs", 311); } public bool IsModCreator(out Processor.CreatorMarkers marker) { marker = Processor.CreatorMarkers.None; if ((int)Vars.GetCreator(0L) != ServersideQoLPlugin.PluginGuidHash) { return false; } marker = (Processor.CreatorMarkers)((ulong)Vars.GetCreator(0L) >> 32); return true; } public bool IsModCreator() { Processor.CreatorMarkers marker; return IsModCreator(out marker); } public bool IsAnyCloserThan(IReadOnlyList peers, float distance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) distance *= distance; Vector3 position = ZDO.GetPosition(); foreach (Peer item in peers.Enumerate()) { if (Utils.DistanceSqr(item.RefPos, position) < distance) { return true; } } return false; } public bool Equals(ServersideQoLZDO? other) { return ZDO.Equals(other?.ZDO); } public override bool Equals(object obj) { return Equals(obj as ServersideQoLZDO); } public override int GetHashCode() { return ((object)ZDO).GetHashCode(); } [Conditional("DEBUG")] public void AssertIs() where T : MonoBehaviour { } [Conditional("DEBUG")] public void AssertIsAll() where T1 : MonoBehaviour where T2 : MonoBehaviour { } } public static class StatusEffects { public static int Wishbone { get; } = StringExtensionMethods.GetStableHashCode("Wishbone", true); public static int Demister { get; } = StringExtensionMethods.GetStableHashCode("Demister", true); public static int Megingjord { get; } = StringExtensionMethods.GetStableHashCode("BeltStrength", true); } [Processor("c79b3771-b9a8-46e9-b3eb-5ffe6c9708b4", OnlyWhenDependedOn = true)] public sealed class TameableRegistryProcessor : Processor { public sealed record PrefabInfo(Tameable Tameable, MonsterAI MonsterAI) : ProcessorPrefabInfo(); private sealed class TameableStateImpl(ServersideQoLZDO zdo, PrefabInfo prefabInfo) : TameableState() { private readonly ServersideQoLZDO _zdo = zdo; private readonly PrefabInfo _prefabInfo = prefabInfo; private States _state; public override PrefabInfo PrefabInfo => prefabInfo; public override States State => _state; public Vector3 LastKey { get; set; } public void SetState(States state) { _state = state; } } private readonly Dictionary _states = new Dictionary(); public SectorDictionary> Tameables { get; } = new SectorDictionary>(64f); public TameableState? GetState(ServersideQoLZDO zdo) { if (!_states.TryGetValue(zdo, out TameableStateImpl value)) { return null; } return value; } protected internal override void Initialize() { _states.Clear(); } protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList peers, PrefabInfo prefabInfo) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!_states.TryGetValue(zdo, out TameableStateImpl value)) { _states.Add(zdo, value = new TameableStateImpl(zdo, prefabInfo)); zdo.Destroyed += delegate(ServersideQoLZDO x) { _states.Remove(x); }; SectorDictionary> tameables = Tameables; Vector3 key = (value.LastKey = zdo.ZDO.GetPosition()); tameables.Add(key, zdo); } else if (Tameables.TryAdd(zdo)) { Tameables[value.LastKey].Remove(zdo); value.LastKey = zdo.ZDO.GetPosition(); } if (zdo.Vars.GetTamed()) { value.SetState(TameableState.States.Tamed); } else { float num = zdo.Fields().GetFloat(() => (Tameable x) => x.m_tamingTime, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL\\TameableRegistryProcessor.cs", 40); float tameTimeLeft = zdo.Vars.GetTameTimeLeft(num); if (tameTimeLeft < num) { value.SetState(TameableState.States.Taming); } else { value.SetState(TameableState.States.Wild); } } return ProcessResult.Default; } } public abstract class TameableState { public enum States { Wild, Taming, Tamed } public abstract TameableRegistryProcessor.PrefabInfo PrefabInfo { get; } public abstract States State { get; } private protected TameableState() { } } public readonly struct Timestamp : IEquatable, IComparable { private readonly float _realtimeSinceStartup; public static Timestamp Now => new Timestamp(Time.realtimeSinceStartup); public float Seconds => _realtimeSinceStartup; private Timestamp(float realtimeSinceStartup) { _realtimeSinceStartup = realtimeSinceStartup; } public Timestamp AddSeconds(float seconds) { return new Timestamp(_realtimeSinceStartup + seconds); } public bool Equals(Timestamp other) { return _realtimeSinceStartup == other._realtimeSinceStartup; } public int CompareTo(Timestamp other) { return _realtimeSinceStartup.CompareTo(other._realtimeSinceStartup); } public override bool Equals(object obj) { if (obj is Timestamp other) { return Equals(other); } return false; } public override int GetHashCode() { return _realtimeSinceStartup.GetHashCode(); } public static bool operator ==(Timestamp left, Timestamp right) { return left._realtimeSinceStartup == right._realtimeSinceStartup; } public static bool operator !=(Timestamp left, Timestamp right) { return left._realtimeSinceStartup != right._realtimeSinceStartup; } public static bool operator <(Timestamp left, Timestamp right) { return left._realtimeSinceStartup < right._realtimeSinceStartup; } public static bool operator <=(Timestamp left, Timestamp right) { return left._realtimeSinceStartup <= right._realtimeSinceStartup; } public static bool operator >(Timestamp left, Timestamp right) { return left._realtimeSinceStartup > right._realtimeSinceStartup; } public static bool operator >=(Timestamp left, Timestamp right) { return left._realtimeSinceStartup >= right._realtimeSinceStartup; } } internal static class TypeExtensionBuilder { private static string __moduleName = typeof(ServersideQoLPlugin).Assembly.GetName().Name + ".Dynamic"; private static readonly ModuleBuilder __moduleBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(__moduleName), AssemblyBuilderAccess.Run).DefineDynamicModule(__moduleName); internal static TypeBuilder DefineType(string name, Type baseType) { return __moduleBuilder.DefineType(__moduleName + "." + name, TypeAttributes.NotPublic, baseType); } } public sealed class TypeExtensionBuilder where TBaseInterface : class where TBaseType : class, TBaseInterface { private static readonly ConstructorInfo __baseCtor; private readonly string _typeName = typeName ?? typeof(TBaseType).Name; private TypeBuilder? _typeBuilder; private Type? _type; private ConstructorInfo? _constructorInfo; private Func? _factory; private HashSet? _interfaces; public bool HasInterfaces => (object)_typeBuilder != null; public TypeExtensionBuilder(string? typeName = null) { } static TypeExtensionBuilder() { if (!typeof(TBaseInterface).IsInterface) { throw new ArgumentException(typeof(TBaseInterface).FullName + " is not an interface type."); } Type typeFromHandle = typeof(TBaseType); if ((object)typeFromHandle == null || !typeFromHandle.IsClass || typeFromHandle.IsSealed) { throw new ArgumentException(typeof(TBaseType).FullName + " must be valid base class (not sealed)"); } __baseCtor = typeof(TBaseType).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) ?? throw new ArgumentException(typeof(TBaseType).FullName + ": No parameterless constructor found"); } public void AddInterface() where TInterface : TBaseInterface { if ((object)_type != null) { throw new InvalidOperationException("The type has already been created"); } Type typeFromHandle = typeof(TInterface); if (!typeFromHandle.IsInterface) { throw new ArgumentException(typeFromHandle.FullName + " is not an interface type."); } if (typeFromHandle == typeof(TBaseInterface)) { throw new ArgumentException(typeFromHandle.FullName + " is the base interface and cannot be registered."); } if (!(_interfaces ?? (_interfaces = new HashSet())).Add(typeFromHandle)) { return; } List list = typeFromHandle.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList(); List list2 = new List(); list2.AddRange(from x in list.OfType() where (object)x != null && (object)x.GetMethod != null && (object)x.SetMethod != null select x); IReadOnlyList readOnlyList = new <>z__ReadOnlyList(list2); foreach (PropertyInfo item in readOnlyList) { list.Remove(item); list.Remove(item.GetMethod); list.Remove(item.SetMethod); } if (list.Count != 0) { throw new ArgumentException(typeFromHandle.FullName + " contains unsupported members. Only properties with both get and set accessors are supported."); } if ((object)_typeBuilder == null) { _typeBuilder = TypeExtensionBuilder.DefineType(_typeName, typeof(TBaseType)); ConstructorBuilder constructorBuilder = _typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator iLGenerator = constructorBuilder.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, __baseCtor); iLGenerator.Emit(OpCodes.Ret); } _typeBuilder.AddInterfaceImplementation(typeFromHandle); foreach (PropertyInfo item2 in readOnlyList) { Type propertyType = item2.PropertyType; string name = item2.Name; FieldBuilder field = _typeBuilder.DefineField("_" + typeFromHandle.Name + "_" + name + "_backing", propertyType, FieldAttributes.Private); string name2 = typeFromHandle.Name + "_get_" + name; MethodBuilder methodBuilder = _typeBuilder.DefineMethod(name2, MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask, propertyType, Type.EmptyTypes); ILGenerator iLGenerator2 = methodBuilder.GetILGenerator(); iLGenerator2.Emit(OpCodes.Ldarg_0); iLGenerator2.Emit(OpCodes.Ldfld, field); iLGenerator2.Emit(OpCodes.Ret); string name3 = typeFromHandle.Name + "_set_" + name; MethodBuilder methodBuilder2 = _typeBuilder.DefineMethod(name3, MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask, typeof(void), new Type[1] { propertyType }); ILGenerator iLGenerator3 = methodBuilder2.GetILGenerator(); iLGenerator3.Emit(OpCodes.Ldarg_0); iLGenerator3.Emit(OpCodes.Ldarg_1); iLGenerator3.Emit(OpCodes.Stfld, field); iLGenerator3.Emit(OpCodes.Ret); _typeBuilder.DefineMethodOverride(methodBuilder, item2.GetMethod); _typeBuilder.DefineMethodOverride(methodBuilder2, item2.SetMethod); } } public Type Build() { if ((object)_type != null) { return _type; } if ((object)_typeBuilder == null) { throw new InvalidOperationException("No interfaces have been added"); } _type = _typeBuilder.CreateType(); _typeBuilder = null; _interfaces = null; return _type; } public ConstructorInfo GetConstructorInfo() { return _constructorInfo ?? (_constructorInfo = Build().GetConstructor(Type.EmptyTypes)); } public Func GetFactory() { return _factory ?? (_factory = Expression.Lambda>(Expression.Convert(Expression.New(GetConstructorInfo()), typeof(TBaseType)), Array.Empty()).Compile()); } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] public sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] public sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] public sealed class MemberNotNullWhenAttribute : Attribute { public string[] Members { get; } public bool ReturnValue { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace System.Runtime.CompilerServices { [EditorBrowsable(EditorBrowsableState.Never)] public static class IsExternalInit { } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] public sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; init; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] public sealed class RequiredMemberAttribute : Attribute { } }