Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LazyVikings v1.2.3
LazyVikings.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using LazyVikings.Utils; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("blacks7ar")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.3")] [assembly: AssemblyInformationalVersion("1.0.0+a9222403da6dc673fd5c452f017b941a45ae564e")] [assembly: AssemblyProduct("LazyVikings")] [assembly: AssemblyTitle("LazyVikings")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LazyVikings { [BepInPlugin("blacks7ar.LazyVikings", "LazyVikings", "1.2.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private const string modGUID = "blacks7ar.LazyVikings"; public const string modName = "LazyVikings"; public const string modAuthor = "blacks7ar"; public const string modVersion = "1.2.3"; public const string modLink = "https://valheim.thunderstore.io/package/blacks7ar/LazyVikings/"; private static readonly Harmony _harmony = new Harmony("blacks7ar.LazyVikings"); private static readonly ConfigSync _configSync = new ConfigSync("blacks7ar.LazyVikings") { DisplayName = "LazyVikings", CurrentVersion = "1.2.3", MinimumRequiredVersion = "1.2.3" }; private static ConfigEntry<Toggle> _serverConfigLocked; public static ConfigEntry<Toggle> _enableBeehive; public static ConfigEntry<float> _beehiveRadius; public static ConfigEntry<Toggle> _enableBlastFurnace; public static ConfigEntry<float> _blastfurnaceRadius; public static ConfigEntry<Automation> _blastfurnaceAutomation; public static ConfigEntry<Toggle> _blastfurnaceIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _blastfurnaceAllowAllOres; public static ConfigEntry<Toggle> _enableEitrRefinery; public static ConfigEntry<float> _eitrrefineryRadius; public static ConfigEntry<Automation> _eitrrefineryAutomation; public static ConfigEntry<Toggle> _eitrrefineryIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableKiln; public static ConfigEntry<float> _kilnRadius; public static ConfigEntry<Automation> _kilnAutomation; public static ConfigEntry<Toggle> _kilnIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _kilnProcessAllWoods; public static ConfigEntry<int> _kilnProductThreshold; public static ConfigEntry<Toggle> _enableSmelter; public static ConfigEntry<float> _smelterRadius; public static ConfigEntry<Automation> _smelterAutomation; public static ConfigEntry<Toggle> _smelterIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableSpinningWheel; public static ConfigEntry<float> _spinningwheelRadius; public static ConfigEntry<Automation> _spinningwheelAutomation; public static ConfigEntry<Toggle> _spinningwheelIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableWindmill; public static ConfigEntry<float> _windmillRadius; public static ConfigEntry<Automation> _windmillAutomation; public static ConfigEntry<Toggle> _windmillIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableSapCollector; public static ConfigEntry<float> _sapcollectorRadius; public static ConfigEntry<Toggle> _enableFermenter; public static ConfigEntry<float> _fermenterRadius; public static ConfigEntry<Automation> _fermenterAutomation; public static ConfigEntry<Toggle> _fermenterIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableSteelKiln; public static ConfigEntry<float> _steelKilnRadius; public static ConfigEntry<Automation> _steelKilnAutomation; public static ConfigEntry<Toggle> _steelKilnIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableSteelSlackTub; public static ConfigEntry<float> _steelSlackTubRadius; public static ConfigEntry<Automation> _steelSlackTubAutomation; public static ConfigEntry<Toggle> _steelSlackTubIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _leaveOne; public static ConfigEntry<Toggle> _mustHave; public static ConfigEntry<Toggle> _enableHotTub; public static ConfigEntry<Toggle> _hotTubIgnorePrivateAreaCheck; public static ConfigEntry<float> _hotTubRadius; public static ConfigEntry<Toggle> _enableCookingStation; public static ConfigEntry<float> _cookingStationRadius; public static ConfigEntry<Automation> _cookingStationAutomation; public static ConfigEntry<Toggle> _cookingStationIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableIronCookingStation; public static ConfigEntry<float> _ironCookingStationIronRadius; public static ConfigEntry<Automation> _ironCookingStationIronAutomation; public static ConfigEntry<Toggle> _ironCookingStationIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableStoneOven; public static ConfigEntry<float> _stoneOvenRadius; public static ConfigEntry<Automation> _stoneOvenAutomation; public static ConfigEntry<Toggle> _stoneOvenIgnorePrivateAreaCheck; public static ConfigEntry<Toggle> _enableFireplace; public static ConfigEntry<Toggle> _fireplaceIgnorePrivateCheck; public static ConfigEntry<float> _fireplaceRadius; public static bool _hasOdinSteelWorks; private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedConfig = true) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedConfig ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val); _configSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedConfig; return val2; } public void Awake() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Expected O, but got Unknown //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Expected O, but got Unknown //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Expected O, but got Unknown //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Expected O, but got Unknown //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Expected O, but got Unknown //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Expected O, but got Unknown //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Expected O, but got Unknown //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Expected O, but got Unknown //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Expected O, but got Unknown //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Expected O, but got Unknown //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Expected O, but got Unknown //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Expected O, but got Unknown //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Expected O, but got Unknown //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Expected O, but got Unknown //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Expected O, but got Unknown //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Expected O, but got Unknown //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Expected O, but got Unknown //IL_0622: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Expected O, but got Unknown //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0666: Expected O, but got Unknown //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_068d: Expected O, but got Unknown //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Expected O, but got Unknown //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Expected O, but got Unknown //IL_0709: Unknown result type (might be due to invalid IL or missing references) //IL_0714: Expected O, but got Unknown //IL_0730: Unknown result type (might be due to invalid IL or missing references) //IL_073b: Expected O, but got Unknown //IL_0757: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Expected O, but got Unknown //IL_0790: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Expected O, but got Unknown //IL_07b7: Unknown result type (might be due to invalid IL or missing references) //IL_07c2: Expected O, but got Unknown //IL_07de: Unknown result type (might be due to invalid IL or missing references) //IL_07e9: Expected O, but got Unknown //IL_0805: Unknown result type (might be due to invalid IL or missing references) //IL_0810: Expected O, but got Unknown //IL_083e: Unknown result type (might be due to invalid IL or missing references) //IL_0849: Expected O, but got Unknown //IL_0865: Unknown result type (might be due to invalid IL or missing references) //IL_0870: Expected O, but got Unknown //IL_088c: Unknown result type (might be due to invalid IL or missing references) //IL_0897: Expected O, but got Unknown //IL_08b3: Unknown result type (might be due to invalid IL or missing references) //IL_08be: Expected O, but got Unknown //IL_08ec: Unknown result type (might be due to invalid IL or missing references) //IL_08f7: Expected O, but got Unknown //IL_0913: Unknown result type (might be due to invalid IL or missing references) //IL_091e: Expected O, but got Unknown //IL_093a: Unknown result type (might be due to invalid IL or missing references) //IL_0945: Expected O, but got Unknown //IL_0973: Unknown result type (might be due to invalid IL or missing references) //IL_097e: Expected O, but got Unknown //IL_099a: Unknown result type (might be due to invalid IL or missing references) //IL_09a5: Expected O, but got Unknown //IL_09d5: Unknown result type (might be due to invalid IL or missing references) //IL_09e0: Expected O, but got Unknown //IL_09fc: Unknown result type (might be due to invalid IL or missing references) //IL_0a07: Expected O, but got Unknown //IL_0a35: Unknown result type (might be due to invalid IL or missing references) //IL_0a40: Expected O, but got Unknown //IL_0a5c: Unknown result type (might be due to invalid IL or missing references) //IL_0a67: Expected O, but got Unknown //IL_0a83: Unknown result type (might be due to invalid IL or missing references) //IL_0a8e: Expected O, but got Unknown //IL_0aaa: Unknown result type (might be due to invalid IL or missing references) //IL_0ab5: Expected O, but got Unknown //IL_0ae3: Unknown result type (might be due to invalid IL or missing references) //IL_0aee: Expected O, but got Unknown //IL_0b0a: Unknown result type (might be due to invalid IL or missing references) //IL_0b15: Expected O, but got Unknown ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; _serverConfigLocked = config("01- ServerSync", "Lock Configuration", Toggle.On, new ConfigDescription("If On, the configuration is locked and can be changed by server admins only.", (AcceptableValueBase)null, Array.Empty<object>())); _configSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked); _leaveOne = config("02- General", "Leave One", Toggle.On, new ConfigDescription("If On, always leaves one item of each material on the container.", (AcceptableValueBase)null, Array.Empty<object>())); _mustHave = config("02- General", "Must Have", Toggle.Off, new ConfigDescription("If On, only deposits items to containers if the item already exist on that container.", (AcceptableValueBase)null, Array.Empty<object>())); _enableBeehive = config("03- Beehive", "Enable", Toggle.On, new ConfigDescription("Enable/Disables beehive automation.", (AcceptableValueBase)null, Array.Empty<object>())); _beehiveRadius = config("03- Beehive", "Radius", 5f, new ConfigDescription("Beehives container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _enableBlastFurnace = config("04- Blast Furnace", "Enable", Toggle.On, new ConfigDescription("Enable/Disables blast furnace automation.", (AcceptableValueBase)null, Array.Empty<object>())); _blastfurnaceAutomation = config("04- Blast Furnace", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _blastfurnaceRadius = config("04- Blast Furnace", "Radius", 5f, new ConfigDescription("Blast furnace container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _blastfurnaceIgnorePrivateAreaCheck = config("04- Blast Furnace", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for blast furnaces.", (AcceptableValueBase)null, Array.Empty<object>())); _blastfurnaceAllowAllOres = config("04- Blast Furnace", "Allow All Ores", Toggle.Off, new ConfigDescription("If On, all ores will be process by the blast furnace.", (AcceptableValueBase)null, Array.Empty<object>())); _enableCookingStation = config("05- Cooking Station", "Enable", Toggle.On, new ConfigDescription("Enable/Disables cooking station automation.", (AcceptableValueBase)null, Array.Empty<object>())); _cookingStationAutomation = config("05- Cooking Station", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _cookingStationRadius = config("05- Cooking Station", "Radius", 5f, new ConfigDescription("Cooking station container detection radius.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _cookingStationIgnorePrivateAreaCheck = config("05- Cooking Station", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, Ignores private area check for cooking stations.", (AcceptableValueBase)null, Array.Empty<object>())); _enableEitrRefinery = config("06- Eitr Refinery", "Enable", Toggle.On, new ConfigDescription("Enable/Disables eitr refinery automation.", (AcceptableValueBase)null, Array.Empty<object>())); _eitrrefineryAutomation = config("06- Eitr Refinery", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _eitrrefineryRadius = config("06- Eitr Refinery", "Radius", 5f, new ConfigDescription("Eitr refinery container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _eitrrefineryIgnorePrivateAreaCheck = config("06- Eitr Refinery", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for eitr refinerys.", (AcceptableValueBase)null, Array.Empty<object>())); _enableFermenter = config("07- Fermenter", "Enable", Toggle.On, new ConfigDescription("Enable/Disables fermenter automation.", (AcceptableValueBase)null, Array.Empty<object>())); _fermenterAutomation = config("07- Fermenter", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _fermenterRadius = config("07- Fermenter", "Radius", 5f, new ConfigDescription("Fermenter container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _fermenterIgnorePrivateAreaCheck = config("07- Fermenter", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for fermenters.", (AcceptableValueBase)null, Array.Empty<object>())); _enableHotTub = config("08- Hot Tub", "Enable", Toggle.On, new ConfigDescription("Enable/Disable hot tub automation.", (AcceptableValueBase)null, Array.Empty<object>())); _hotTubRadius = config("08- Hot Tub", "Radius", 5f, new ConfigDescription("Hot tub container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _hotTubIgnorePrivateAreaCheck = config("08- Hot Tub", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for hot tubs.", (AcceptableValueBase)null, Array.Empty<object>())); _enableIronCookingStation = config("09- Iron Cooking Station", "Enable", Toggle.On, new ConfigDescription("Enable/Disables iron cooking station.", (AcceptableValueBase)null, Array.Empty<object>())); _ironCookingStationIronAutomation = config("09- Iron Cooking Station", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _ironCookingStationIronRadius = config("09- Iron Cooking Station", "Radius", 5f, new ConfigDescription("Iron cooking station container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _ironCookingStationIgnorePrivateAreaCheck = config("09- Iron Cooking Station", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for iron cooking stations.", (AcceptableValueBase)null, Array.Empty<object>())); _enableKiln = config("10- Kiln", "Enable", Toggle.On, new ConfigDescription("Enable/Disables kiln automation.", (AcceptableValueBase)null, Array.Empty<object>())); _kilnAutomation = config("10- Kiln", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _kilnRadius = config("10- Kiln", "Radius", 5f, new ConfigDescription("Kiln container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _kilnIgnorePrivateAreaCheck = config("10- Kiln", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for kilns.", (AcceptableValueBase)null, Array.Empty<object>())); _kilnProcessAllWoods = config("10- Kiln", "Process All Woods", Toggle.Off, new ConfigDescription("If On, finewood and corewood will also be process into coal.", (AcceptableValueBase)null, Array.Empty<object>())); _kilnProductThreshold = config("10- Kiln", "Product Threshold", 0, new ConfigDescription("Kiln's product threshold before it stops auto fueling.\nNOTE: Set to 0 to disable.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 500), Array.Empty<object>())); _enableSapCollector = config("11- SapCollector", "Enable", Toggle.On, new ConfigDescription("Enable/Disables sap collector automation.", (AcceptableValueBase)null, Array.Empty<object>())); _sapcollectorRadius = config("11- SapCollector", "Radius", 5f, new ConfigDescription("SapCollector container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _enableSmelter = config("12- Smelter", "Enable", Toggle.On, new ConfigDescription("Enable/Disables smelter automation.", (AcceptableValueBase)null, Array.Empty<object>())); _smelterAutomation = config("12- Smelter", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _smelterRadius = config("12- Smelter", "Radius", 5f, new ConfigDescription("Smelter container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _smelterIgnorePrivateAreaCheck = config("12- Smelter", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for smelters.", (AcceptableValueBase)null, Array.Empty<object>())); _enableSpinningWheel = config("13- Spinning Wheel", "Enable", Toggle.On, new ConfigDescription("Enable/Disables spinning wheel automation.", (AcceptableValueBase)null, Array.Empty<object>())); _spinningwheelAutomation = config("13- Spinning Wheel", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _spinningwheelRadius = config("13- Spinning Wheel", "Radius", 5f, new ConfigDescription("Spinning wheel container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _spinningwheelIgnorePrivateAreaCheck = config("13- Spinning Wheel", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for spinning wheels.", (AcceptableValueBase)null, Array.Empty<object>())); _enableStoneOven = config("14- Stone Oven", "Enable", Toggle.On, new ConfigDescription("Enable/Disables stone oven automation.", (AcceptableValueBase)null, Array.Empty<object>())); _stoneOvenAutomation = config("14- Stone Oven", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _stoneOvenRadius = config("14- Stone Oven", "Radius", 5f, new ConfigDescription("Stone oven container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _stoneOvenIgnorePrivateAreaCheck = config("14- Stone Oven", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for stone ovens.", (AcceptableValueBase)null, Array.Empty<object>())); _enableWindmill = config("15- Windmill", "Enable", Toggle.On, new ConfigDescription("Enable/Disables windmill automation.", (AcceptableValueBase)null, Array.Empty<object>())); _windmillAutomation = config("15- Windmill", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _windmillRadius = config("15- Windmill", "Radius", 5f, new ConfigDescription("Windmill container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _windmillIgnorePrivateAreaCheck = config("15- Windmill", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for windmills.", (AcceptableValueBase)null, Array.Empty<object>())); _enableFireplace = config("16- Fireplace", "Enable", Toggle.On, new ConfigDescription("Enable/Disable fire pits, torches and other lights automation.", (AcceptableValueBase)null, Array.Empty<object>())); _fireplaceRadius = config("16- Fireplace", "Radius", 5f, new ConfigDescription("Fireplace container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _fireplaceIgnorePrivateCheck = config("16- Fireplace", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for fire pits, torches and other lights.", (AcceptableValueBase)null, Array.Empty<object>())); _hasOdinSteelWorks = Helper.CheckOdinSteelWorksMod(); if (_hasOdinSteelWorks) { _enableSteelKiln = config("17- Steel Kiln", "Enable", Toggle.On, new ConfigDescription("Enable/Disables steel kiln automation.", (AcceptableValueBase)null, Array.Empty<object>())); _steelKilnAutomation = config("17- Steel Kiln", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _steelKilnRadius = config("17- Steel Kiln", "Radius", 5f, new ConfigDescription("Steel Kiln container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _steelKilnIgnorePrivateAreaCheck = config("17- Steel Kiln", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for steel kiln.", (AcceptableValueBase)null, Array.Empty<object>())); _enableSteelSlackTub = config("18- Steel Slack Tub", "Enable", Toggle.On, new ConfigDescription("Enable/Disables steel slack tub automation.", (AcceptableValueBase)null, Array.Empty<object>())); _steelSlackTubAutomation = config("18- Steel Slack Tub", "Automation", Automation.Both, new ConfigDescription("Choose what to automate.", (AcceptableValueBase)null, Array.Empty<object>())); _steelSlackTubRadius = config("18- Steel Slack Tub", "Radius", 5f, new ConfigDescription("Steel slack tub container detection range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); _steelSlackTubIgnorePrivateAreaCheck = config("18- Steel Slack Tub", "Ignore Private Area Check", Toggle.On, new ConfigDescription("If On, ignores private area check for steel slack tub.", (AcceptableValueBase)null, Array.Empty<object>())); } ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; ((BaseUnityPlugin)this).Config.Save(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } } } namespace LazyVikings.Utils { public enum Automation { Deposit, Fuel, Both } public static class Helper { private static readonly ConcurrentDictionary<float, Stopwatch> _stopwatches = new ConcurrentDictionary<float, Stopwatch>(); public static bool CheckOdinSteelWorksMod() { if (!Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.odinssteelworks")) { return false; } Logging.LogInfo("OdinSteelWorks detected.. applying patch!"); return true; } public static List<Container> GetNearbyContainers(GameObject gameObject, float radius, bool checkWard = true) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) string[] array = new string[3] { "piece", "item", "vehicle" }; IOrderedEnumerable<Collider> orderedEnumerable = Enumerable.OrderBy(Physics.OverlapSphere(gameObject.transform.position, radius, LayerMask.GetMask(array)), (Collider x) => Vector3.Distance(((Component)x).gameObject.transform.position, gameObject.transform.position)); List<Container> list = new List<Container>(); foreach (Collider item in orderedEnumerable) { Container componentInParent = ((Component)item).GetComponentInParent<Container>(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { bool flag = componentInParent.CheckAccess(Player.m_localPlayer.GetPlayerID()); if (checkWard) { flag = flag && PrivateArea.CheckAccess(((Component)item).gameObject.transform.position, 0f, false, true); } Piece componentInParent2 = ((Component)componentInParent).GetComponentInParent<Piece>(); bool flag2 = (Object)(object)((Component)componentInParent).GetComponentInParent<Vagon>() != (Object)null; bool flag3 = (Object)(object)((Component)componentInParent).GetComponentInParent<Ship>() != (Object)null; if ((Object)(object)componentInParent2 != (Object)null && flag && componentInParent.GetInventory() != null && !flag2 && !flag3 && componentInParent2.IsPlacedByPlayer()) { list.Add(componentInParent); } } } return list; } private static float GetGameObjectPositionHash(GameObject gameObject) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Vector3 position = gameObject.transform.position; return 1000f * position.x + position.y + 0.001f * position.z; } public static Stopwatch GetGameObjectStopwatch(GameObject gameObject) { float gameObjectPositionHash = GetGameObjectPositionHash(gameObject); if (_stopwatches.TryGetValue(gameObjectPositionHash, out var value)) { return value; } value = new Stopwatch(); _stopwatches.TryAdd(gameObjectPositionHash, value); return value; } public static List<ItemData> GetNearbyItemsFromContainers(IEnumerable<Container> nearbyContainers) { return Enumerable.ToList(Enumerable.SelectMany(nearbyContainers, (Container nearbyContainer) => nearbyContainer.GetInventory().GetAllItems())); } public static int GetItemAmounts(IEnumerable<ItemData> itemList, ItemData itemData) { return Enumerable.Sum(Enumerable.Where(itemList, (ItemData item) => item.m_shared.m_name == itemData.m_shared.m_name), (ItemData item) => item.m_stack); } private static bool ContainerContainsItem(Container container, ItemData itemData) { if ((Object)(object)container == (Object)null || !container.m_nview.IsValid() || !container.m_nview.IsOwner() || container.m_inventory == null) { return false; } return Enumerable.Any(container.GetInventory().GetAllItems(), (ItemData item) => item.m_shared.m_name == itemData.m_shared.m_name); } public static int DeductItemFromContainerLeaveOne(Container container, ItemData itemData, int amount = 1) { if (!ContainerContainsItem(container, itemData)) { return 0; } int num = 0; List<ItemData> allItems = container.GetInventory().GetAllItems(); foreach (ItemData item in Enumerable.Where(allItems, (ItemData item) => item.m_shared.m_name == itemData.m_shared.m_name)) { if (Plugin._leaveOne.Value != Toggle.On || GetItemAmounts(allItems, item) != 1) { int num2 = Mathf.Min(item.m_stack, amount); item.m_stack -= num2; amount -= num2; num += num2; if (amount <= 0) { break; } } } if (num == 0) { return 0; } allItems.RemoveAll((ItemData x) => x.m_stack <= 0); container.m_inventory.m_inventory = allItems; container.Save(); container.GetInventory().Changed(); return num; } public static int DeductItemFromContainer(Container container, ItemData itemData, int amount = 1) { if (!ContainerContainsItem(container, itemData)) { return 0; } int num = 0; List<ItemData> allItems = container.GetInventory().GetAllItems(); foreach (ItemData item in Enumerable.Where(allItems, (ItemData item) => item.m_shared.m_name == itemData.m_shared.m_name)) { int num2 = Mathf.Min(item.m_stack, amount); item.m_stack -= num2; amount -= num2; num += num2; if (amount <= 0) { break; } } if (num == 0) { return 0; } allItems.RemoveAll((ItemData x) => x.m_stack <= 0); container.m_inventory.m_inventory = allItems; container.Save(); container.GetInventory().Changed(); return num; } public static int DeductItemFromAllNearbyContainers(GameObject gameObject, float radius, ItemData itemData, int amount, bool checkWard = true) { List<Container> nearbyContainers = GetNearbyContainers(gameObject, radius, checkWard); if (amount == 0) { return 0; } int num = 0; foreach (int item in Enumerable.Select(Enumerable.Where(nearbyContainers, (Container item) => (Object)(object)item != (Object)null && item.m_nview.IsValid() && item.m_nview.IsOwner() && item.m_inventory != null && num != amount), (Container item) => DeductItemFromContainerLeaveOne(item, itemData, amount))) { num += item; amount -= item; } return num; } } public static class Logging { private static readonly ManualLogSource LVLogger = Logger.CreateLogSource("LazyVikings"); public static void LogDebug(string debug) { LVLogger.LogDebug((object)debug); } public static void LogInfo(string info) { LVLogger.LogInfo((object)info); } public static void LogWarning(string warning) { LVLogger.LogWarning((object)warning); } public static void LogError(string error) { LVLogger.LogError((object)error); } } public enum Toggle { On = 1, Off = 0 } } namespace LazyVikings.Patches { [HarmonyPatch] public class BeehivePatch { private static readonly MethodInfo _methodInfo = AccessTools.Method(typeof(BeehivePatch), "DepositToContainers", (Type[])null, (Type[])null); [HarmonyTranspiler] [HarmonyPatch(typeof(Beehive), "UpdateBees")] public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown if (Plugin._enableBeehive.Value == Toggle.Off) { return instructions; } List<CodeInstruction> list = Enumerable.ToList(instructions); int num = list.Count - 2; list.Insert(++num, new CodeInstruction(OpCodes.Ldarga, (object)0)); list.Insert(++num, new CodeInstruction(OpCodes.Call, (object)_methodInfo)); return Enumerable.AsEnumerable(list); } private static void DepositToContainers(ref Beehive __instance) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) Beehive beehive = __instance; float radius = Math.Min(50f, Math.Max(1f, Plugin._beehiveRadius.Value)); List<Container> nearbyContainers = Helper.GetNearbyContainers(((Component)beehive).gameObject, radius); if (beehive.GetHoneyLevel() != beehive.m_maxHoney) { return; } while (beehive.GetHoneyLevel() > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)((Component)beehive.m_honeyItem).gameObject).name); ZNetView.m_forceDisableInit = true; GameObject val = Object.Instantiate<GameObject>(itemPrefab); ZNetView.m_forceDisableInit = false; ItemDrop component = val.GetComponent<ItemDrop>(); bool mustHaveItem2 = Plugin._mustHave.Value == Toggle.On; bool num = SpawnInsideContainers(component, mustHaveItem2); Object.Destroy((Object)(object)val); if (!num) { return; } } if (beehive.GetHoneyLevel() == 0) { beehive.m_spawnEffect.Create(beehive.m_spawnPoint.position, Quaternion.identity, (Transform)null, 1f, -1); } bool SpawnInsideContainers(ItemDrop item, bool mustHaveItem) { using (List<Container>.Enumerator enumerator = nearbyContainers.GetEnumerator()) { if (enumerator.MoveNext()) { Container current = enumerator.Current; Inventory inventory = current.GetInventory(); if ((mustHaveItem && !inventory.HaveItem(item.m_itemData.m_shared.m_name, true)) || !inventory.AddItem(item.m_itemData)) { return false; } beehive.m_nview.GetZDO().Set("level", beehive.GetHoneyLevel() - 1); current.Save(); current.GetInventory().Changed(); return true; } } if (mustHaveItem) { return SpawnInsideContainers(item, mustHaveItem: false); } return false; } } } [HarmonyPatch] public class CookingStationPatch { [HarmonyPrefix] [HarmonyPatch(typeof(CookingStation), "UpdateCooking")] private static void UpdateCooking_Prefix(CookingStation __instance) { //IL_04bf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return; } Stopwatch gameObjectStopwatch = Helper.GetGameObjectStopwatch(((Component)__instance).gameObject); if (gameObjectStopwatch.IsRunning && gameObjectStopwatch.ElapsedMilliseconds < 1000) { return; } gameObjectStopwatch.Restart(); float value = 0f; bool flag = false; bool flag2 = false; bool flag3 = false; switch (__instance.m_name) { case "$piece_cookingstation": if (Plugin._enableCookingStation.Value == Toggle.Off) { return; } value = Plugin._cookingStationRadius.Value; flag = Plugin._cookingStationIgnorePrivateAreaCheck.Value == Toggle.On; flag2 = Plugin._cookingStationAutomation.Value == Automation.Both || Plugin._cookingStationAutomation.Value == Automation.Fuel; flag3 = Plugin._cookingStationAutomation.Value == Automation.Both || Plugin._cookingStationAutomation.Value == Automation.Deposit; break; case "$piece_cookingstation_iron": if (Plugin._enableIronCookingStation.Value == Toggle.Off) { return; } value = Plugin._ironCookingStationIronRadius.Value; flag = Plugin._ironCookingStationIgnorePrivateAreaCheck.Value == Toggle.On; flag2 = Plugin._ironCookingStationIronAutomation.Value == Automation.Both || Plugin._ironCookingStationIronAutomation.Value == Automation.Fuel; flag3 = Plugin._ironCookingStationIronAutomation.Value == Automation.Both || Plugin._ironCookingStationIronAutomation.Value == Automation.Deposit; break; case "$piece_oven": if (Plugin._enableStoneOven.Value == Toggle.Off) { return; } value = Plugin._stoneOvenRadius.Value; flag = Plugin._stoneOvenIgnorePrivateAreaCheck.Value == Toggle.On; flag2 = Plugin._stoneOvenAutomation.Value == Automation.Both || Plugin._stoneOvenAutomation.Value == Automation.Fuel; flag3 = Plugin._stoneOvenAutomation.Value == Automation.Both || Plugin._stoneOvenAutomation.Value == Automation.Deposit; break; } value = Math.Min(50f, Math.Max(1f, value)); int num = __instance.GetFreeSlot(); int num2 = __instance.m_maxFuel - (int)Math.Ceiling(__instance.GetFuel()); if (flag2) { if (Object.op_Implicit((Object)(object)__instance.m_fuelItem) && num2 > 0) { ItemData itemData = __instance.m_fuelItem.m_itemData; int num3 = Helper.DeductItemFromAllNearbyContainers(((Component)__instance).gameObject, value, itemData, 1, !flag); for (int i = 0; i < num3; i++) { __instance.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } } if (num != -1) { foreach (Container nearbyContainer in Helper.GetNearbyContainers(((Component)__instance).gameObject, value)) { foreach (ItemConversion item in __instance.m_conversion) { ItemData itemData2 = item.m_from.m_itemData; int num4 = Helper.DeductItemFromContainerLeaveOne(nearbyContainer, itemData2); if (num4 > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)((Component)item.m_from).gameObject).name); for (int j = 0; j < num4; j++) { __instance.m_nview.InvokeRPC("RPC_AddItem", new object[1] { ((Object)itemPrefab).name }); } num -= num4; if (num == -1) { return; } } } } } } if (!flag3) { return; } string text = default(string); float num5 = default(float); Status val = default(Status); for (int k = 0; k < __instance.m_slots.Length; k++) { __instance.GetSlot(k, ref text, ref num5, ref val); if (text != "" && __instance.IsItemDone(text)) { GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(text); ZNetView.m_forceDisableInit = true; GameObject val2 = Object.Instantiate<GameObject>(itemPrefab2); ZNetView.m_forceDisableInit = false; ItemDrop component = val2.GetComponent<ItemDrop>(); bool mustHaveItem2 = Plugin._mustHave.Value == Toggle.On; bool num6 = SpawnInsideContainers(component, mustHaveItem2); Object.Destroy((Object)(object)val2); if (!num6) { __instance.m_nview.InvokeRPC("RPC_RemoveDoneItem", new object[2] { __instance.m_slots[k].position, 1 }); } else { __instance.SetSlot(k, "", 0f, (Status)0); __instance.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetSlotVisual", new object[2] { k, "" }); } break; } } bool SpawnInsideContainers(ItemDrop item, bool mustHaveItem) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) List<Container> nearbyContainers = Helper.GetNearbyContainers(((Component)__instance).gameObject, value, !flag); if (nearbyContainers.Count == 0) { return false; } float num7 = ((value > 50f) ? 50f : ((!(value < 1f)) ? value : 1f)); value = num7; using (List<Container>.Enumerator enumerator3 = nearbyContainers.GetEnumerator()) { if (enumerator3.MoveNext()) { Container current3 = enumerator3.Current; Inventory inventory = current3.GetInventory(); if ((mustHaveItem && !inventory.HaveItem(item.m_itemData.m_shared.m_name, true)) || !inventory.AddItem(item.m_itemData)) { return false; } __instance.m_pickEffector.Create(((Component)__instance).transform.position, ((Component)__instance).transform.rotation, (Transform)null, 1f, -1); current3.Save(); current3.GetInventory().Changed(); return true; } } if (mustHaveItem) { return SpawnInsideContainers(item, mustHaveItem: false); } return false; } } } [HarmonyPatch] public class FermenterPatch { private static readonly MethodInfo _methodDepositToContainers = AccessTools.Method(typeof(FermenterPatch), "DepositToContainers", (Type[])null, (Type[])null); private static readonly MethodInfo _methodSetActive = AccessTools.Method(typeof(GameObject), "SetActive", (Type[])null, (Type[])null); private static readonly MethodInfo _methodTap = AccessTools.Method(typeof(FermenterPatch), "Tap", (Type[])null, (Type[])null); private static readonly MethodInfo _methodAddItemFromNearbyContainers = AccessTools.Method(typeof(FermenterPatch), "AddItemFromNearbyContainers", (Type[])null, (Type[])null); [HarmonyTranspiler] [HarmonyPatch(typeof(Fermenter), "DelayedTap")] private static IEnumerable<CodeInstruction> DelayedTapTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown if (Plugin._enableFermenter.Value == Toggle.Off || Plugin._fermenterAutomation.Value == Automation.Fuel) { return instructions; } List<CodeInstruction> list = Enumerable.ToList(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Brfalse) { int index = i; list.Insert(++i, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(++i, new CodeInstruction(OpCodes.Ldloca, (object)0)); list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)_methodDepositToContainers)); list.Insert(++i, new CodeInstruction(OpCodes.Brtrue, list[index].operand)); return Enumerable.AsEnumerable(list); } } return instructions; } [HarmonyTranspiler] [HarmonyPatch(typeof(Fermenter), "SlowUpdate")] private static IEnumerable<CodeInstruction> SlowUpdateTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown if (Plugin._enableFermenter.Value == Toggle.Off) { return instructions; } List<CodeInstruction> list = Enumerable.ToList(instructions); int num = 0; bool flag = false; for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], _methodSetActive)) { num++; } if (num == 3) { list.Insert(++i, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)_methodAddItemFromNearbyContainers)); flag = true; break; } } if (!flag) { return instructions; } flag = false; for (int num2 = list.Count - 1; num2 >= 0; num2--) { if (CodeInstructionExtensions.Calls(list[num2], _methodSetActive)) { list.Insert(++num2, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(++num2, new CodeInstruction(OpCodes.Call, (object)_methodTap)); return Enumerable.AsEnumerable(list); } } return instructions; } private static bool DepositToContainers(Fermenter __instance, ref ItemConversion itemConversion) { float radius = Math.Min(50f, Math.Max(1f, Plugin._fermenterRadius.Value)); bool flag = Plugin._fermenterIgnorePrivateAreaCheck.Value == Toggle.On; List<Container> nearbyContainers = Helper.GetNearbyContainers(((Component)__instance).gameObject, radius, !flag); int num = 0; for (int i = 0; i < itemConversion.m_producedItems; i++) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)((Component)itemConversion.m_to).gameObject).name); ZNetView.m_forceDisableInit = true; GameObject val = Object.Instantiate<GameObject>(itemPrefab); ZNetView.m_forceDisableInit = false; ItemDrop component = val.GetComponent<ItemDrop>(); bool mustHaveItem2 = Plugin._mustHave.Value == Toggle.On; bool num2 = SpawnInsideContainers(component, mustHaveItem2); Object.Destroy((Object)(object)val); if (!num2) { ItemConversion obj = itemConversion; obj.m_producedItems -= num; return false; } num++; } return true; bool SpawnInsideContainers(ItemDrop item, bool mustHaveItem) { using (List<Container>.Enumerator enumerator = nearbyContainers.GetEnumerator()) { if (enumerator.MoveNext()) { Container current = enumerator.Current; Inventory inventory = current.GetInventory(); if ((mustHaveItem && !inventory.HaveItem(item.m_itemData.m_shared.m_name, true)) || !inventory.AddItem(item.m_itemData)) { return false; } current.Save(); current.GetInventory().Changed(); return true; } } if (mustHaveItem) { return SpawnInsideContainers(item, mustHaveItem: false); } return false; } } private static void Tap(Fermenter __instance) { if (Plugin._fermenterAutomation.Value == Automation.Deposit || Plugin._fermenterAutomation.Value == Automation.Both) { __instance.m_nview.InvokeRPC("RPC_Tap", Array.Empty<object>()); } } private static void AddItemFromNearbyContainers(Fermenter __instance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (Plugin._fermenterAutomation.Value == Automation.Deposit || (int)__instance.GetStatus() != 0 || !__instance.m_nview.IsOwner()) { return; } Stopwatch gameObjectStopwatch = Helper.GetGameObjectStopwatch(((Component)__instance).gameObject); if (gameObjectStopwatch.IsRunning && gameObjectStopwatch.ElapsedMilliseconds <= 1000) { return; } float radius = Math.Min(50f, Math.Max(1f, Plugin._fermenterRadius.Value)); bool flag = Plugin._fermenterIgnorePrivateAreaCheck.Value == Toggle.On; using (IEnumerator<ItemData> enumerator = Enumerable.Select(Enumerable.Where(Enumerable.Select(Helper.GetNearbyContainers(((Component)__instance).gameObject, radius, !flag), (Container container) => new { container = container, item = __instance.FindCookableItem(container.GetInventory()) }), <>h__TransparentIdentifier0 => <>h__TransparentIdentifier0.item != null && Helper.DeductItemFromContainer(<>h__TransparentIdentifier0.container, <>h__TransparentIdentifier0.item) != 0), <>h__TransparentIdentifier0 => <>h__TransparentIdentifier0.item).GetEnumerator()) { if (enumerator.MoveNext()) { ItemData current = enumerator.Current; __instance.m_nview.InvokeRPC("RPC_AddItem", new object[1] { ((Object)current.m_dropPrefab).name }); } } gameObjectStopwatch.Restart(); } } [HarmonyPatch] public class FireplacePatch { [HarmonyPrefix] [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] private static void UpdateFireplace_Prefix(Fireplace __instance) { if ((Object)(object)__instance == (Object)null || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner() || Plugin._enableFireplace.Value == Toggle.Off) { return; } Stopwatch gameObjectStopwatch = Helper.GetGameObjectStopwatch(((Component)__instance).gameObject); if (gameObjectStopwatch.IsRunning && gameObjectStopwatch.ElapsedMilliseconds < 1000) { return; } gameObjectStopwatch.Restart(); float value = Plugin._fireplaceRadius.Value; bool flag = Plugin._fireplaceIgnorePrivateCheck.Value == Toggle.On; value = Math.Min(50f, Math.Max(1f, value)); float @float = __instance.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); float num = __instance.m_maxFuel - (float)(int)Math.Ceiling(@float); if (Object.op_Implicit((Object)(object)__instance.m_fuelItem) && num > 0f && __instance.m_canRefill && !__instance.m_infiniteFuel) { ItemData itemData = __instance.m_fuelItem.m_itemData; int num2 = Helper.DeductItemFromAllNearbyContainers(((Component)__instance).gameObject, value, itemData, 1, !flag); for (int i = 0; i < num2; i++) { __instance.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } } } } [HarmonyPatch] public class SapCollectorPatch { private static readonly MethodInfo _methodInfo = AccessTools.Method(typeof(SapCollectorPatch), "DepositToContainers", (Type[])null, (Type[])null); [HarmonyTranspiler] [HarmonyPatch(typeof(SapCollector), "UpdateTick")] public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown if (Plugin._enableSapCollector.Value == Toggle.Off) { return instructions; } List<CodeInstruction> list = Enumerable.ToList(instructions); int num = list.Count - 2; list.Insert(++num, new CodeInstruction(OpCodes.Ldarga, (object)0)); list.Insert(++num, new CodeInstruction(OpCodes.Call, (object)_methodInfo)); return Enumerable.AsEnumerable(list); } private static void DepositToContainers(ref SapCollector __instance) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) SapCollector sapCollector = __instance; float radius = Math.Min(50f, Math.Max(1f, Plugin._sapcollectorRadius.Value)); List<Container> nearbyContainers = Helper.GetNearbyContainers(((Component)sapCollector).gameObject, radius); if (sapCollector.GetLevel() != sapCollector.m_maxLevel) { return; } while (sapCollector.GetLevel() > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)((Component)sapCollector.m_spawnItem).gameObject).name); ZNetView.m_forceDisableInit = true; GameObject val = Object.Instantiate<GameObject>(itemPrefab); ZNetView.m_forceDisableInit = false; ItemDrop component = val.GetComponent<ItemDrop>(); bool mustHaveItem2 = Plugin._mustHave.Value == Toggle.On; bool num = SpawnInsideContainers(component, mustHaveItem2); Object.Destroy((Object)(object)val); if (!num) { return; } } if (sapCollector.GetLevel() == 0) { sapCollector.m_spawnEffect.Create(sapCollector.m_spawnPoint.position, Quaternion.identity, (Transform)null, 1f, -1); } bool SpawnInsideContainers(ItemDrop item, bool mustHaveItem) { using (List<Container>.Enumerator enumerator = nearbyContainers.GetEnumerator()) { if (enumerator.MoveNext()) { Container current = enumerator.Current; Inventory inventory = current.GetInventory(); if ((mustHaveItem && !inventory.HaveItem(item.m_itemData.m_shared.m_name, true)) || !inventory.AddItem(item.m_itemData)) { return false; } sapCollector.m_nview.GetZDO().Set("level", sapCollector.GetLevel() - 1); current.Save(); current.GetInventory().Changed(); return true; } } if (mustHaveItem) { return SpawnInsideContainers(item, mustHaveItem: false); } return false; } } } [HarmonyPatch] public class SmelterPatch { private static readonly MethodInfo _methodInfo = AccessTools.Method(typeof(SmelterPatch), "DontProcessAllWoods", (Type[])null, (Type[])null); [HarmonyTranspiler] [HarmonyPatch(typeof(Smelter), "FindCookableItem")] public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown if (Plugin._enableKiln.Value == Toggle.Off) { return instructions; } int num = -1; List<CodeInstruction> list = Enumerable.ToList(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Stloc_1) { list.Insert(++i, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(++i, new CodeInstruction(OpCodes.Ldloc_1, (object)null)); list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)_methodInfo)); num = i; } else if (num != -1 && list[i].opcode == OpCodes.Brfalse) { list.Insert(++num, new CodeInstruction(OpCodes.Brtrue, list[i].operand)); return Enumerable.AsEnumerable(list); } } return instructions; } [HarmonyPrefix] [HarmonyPatch(typeof(Smelter), "Awake")] private static void Awake_Prefix(ref Smelter __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown if (!(__instance.m_name != "$piece_blastfurnace") && Plugin._enableBlastFurnace.Value == Toggle.On && Plugin._blastfurnaceAllowAllOres.Value == Toggle.On) { __instance.m_conversion.AddRange(new List<ItemConversion> { new ItemConversion { m_from = ObjectDB.instance.GetItemPrefab("CopperOre").GetComponent<ItemDrop>(), m_to = ObjectDB.instance.GetItemPrefab("Copper").GetComponent<ItemDrop>() }, new ItemConversion { m_from = ObjectDB.instance.GetItemPrefab("IronScrap").GetComponent<ItemDrop>(), m_to = ObjectDB.instance.GetItemPrefab("Iron").GetComponent<ItemDrop>() }, new ItemConversion { m_from = ObjectDB.instance.GetItemPrefab("SilverOre").GetComponent<ItemDrop>(), m_to = ObjectDB.instance.GetItemPrefab("Silver").GetComponent<ItemDrop>() }, new ItemConversion { m_from = ObjectDB.instance.GetItemPrefab("TinOre").GetComponent<ItemDrop>(), m_to = ObjectDB.instance.GetItemPrefab("Tin").GetComponent<ItemDrop>() }, new ItemConversion { m_from = ObjectDB.instance.GetItemPrefab("CopperScrap").GetComponent<ItemDrop>(), m_to = ObjectDB.instance.GetItemPrefab("Copper").GetComponent<ItemDrop>() }, new ItemConversion { m_from = ObjectDB.instance.GetItemPrefab("IronOre").GetComponent<ItemDrop>(), m_to = ObjectDB.instance.GetItemPrefab("Iron").GetComponent<ItemDrop>() } }); } } [HarmonyPrefix] [HarmonyPatch(typeof(Smelter), "Spawn")] private static bool Spawn_Prefix(string ore, int stack, ref Smelter __instance) { if ((Object)(object)__instance == (Object)null) { return false; } Smelter smelter = __instance; if (!smelter.m_nview.IsOwner()) { return true; } switch (__instance.m_name) { case "$piece_charcoalkiln": if (Plugin._enableKiln.Value == Toggle.On && (Plugin._kilnAutomation.Value == Automation.Deposit || Plugin._kilnAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._kilnRadius.Value)), Plugin._kilnIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$piece_smelter": if (Plugin._enableSmelter.Value == Toggle.On && (Plugin._smelterAutomation.Value == Automation.Deposit || Plugin._smelterAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._smelterRadius.Value)), Plugin._smelterIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$piece_blastfurnace": if (Plugin._enableBlastFurnace.Value == Toggle.On && (Plugin._blastfurnaceAutomation.Value == Automation.Deposit || Plugin._blastfurnaceAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._blastfurnaceRadius.Value)), Plugin._blastfurnaceIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$piece_spinningwheel": if (Plugin._enableSpinningWheel.Value == Toggle.On && (Plugin._spinningwheelAutomation.Value == Automation.Deposit || Plugin._spinningwheelAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._spinningwheelRadius.Value)), Plugin._spinningwheelIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$piece_windmill": if (Plugin._enableWindmill.Value == Toggle.On && (Plugin._windmillAutomation.Value == Automation.Deposit || Plugin._windmillAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._windmillRadius.Value)), Plugin._windmillIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$piece_eitrrefinery": if (Plugin._enableEitrRefinery.Value == Toggle.On && (Plugin._eitrrefineryAutomation.Value == Automation.Deposit || Plugin._eitrrefineryAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._eitrrefineryRadius.Value)), Plugin._eitrrefineryIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$cws_stone_kiln": if (Plugin._enableSteelKiln.Value == Toggle.On && (Plugin._steelKilnAutomation.Value == Automation.Deposit || Plugin._steelKilnAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._steelKilnRadius.Value)), Plugin._steelKilnIgnorePrivateAreaCheck.Value == Toggle.On); } break; case "$cws_slack_tub": if (Plugin._enableSteelSlackTub.Value == Toggle.On && (Plugin._steelSlackTubAutomation.Value == Automation.Deposit || Plugin._steelSlackTubAutomation.Value == Automation.Both)) { return Spawn(Math.Min(50f, Math.Max(1f, Plugin._steelSlackTubRadius.Value)), Plugin._steelSlackTubIgnorePrivateAreaCheck.Value == Toggle.On); } break; } return true; bool Spawn(float depositRadius, bool ignorePrivateAreaCheck) { List<Container> nearbyContainers = Helper.GetNearbyContainers(((Component)smelter).gameObject, depositRadius, !ignorePrivateAreaCheck); ItemDrop itemDrop; if (nearbyContainers.Count != 0) { float num = ((depositRadius > 50f) ? 50f : ((!(depositRadius < 1f)) ? depositRadius : 1f)); depositRadius = num; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)((Component)smelter.GetItemConversion(ore).m_to).gameObject).name); ZNetView.m_forceDisableInit = true; GameObject val = Object.Instantiate<GameObject>(itemPrefab); ZNetView.m_forceDisableInit = false; itemDrop = val.GetComponent<ItemDrop>(); itemDrop.m_itemData.m_stack = stack; bool result = SpawnInsideContainer(Plugin._mustHave.Value == Toggle.On); Object.Destroy((Object)(object)val); return result; } return true; bool SpawnInsideContainer(bool mustHaveItem) { //IL_006c: 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) foreach (Container item in nearbyContainers) { Inventory inventory = item.GetInventory(); if ((!mustHaveItem || inventory.HaveItem(itemDrop.m_itemData.m_shared.m_name, true)) && inventory.AddItem(itemDrop.m_itemData)) { Transform transform = ((Component)smelter).transform; smelter.m_produceEffects.Create(transform.position, transform.rotation, (Transform)null, 1f, -1); item.Save(); item.GetInventory().Changed(); return false; } } if (!mustHaveItem) { return SpawnInsideContainer(mustHaveItem: false); } return true; } } } [HarmonyPrefix] [HarmonyPatch(typeof(Smelter), "UpdateSmelter")] private static void UpdateSmelter_Prefix(Smelter __instance) { if ((Object)(object)__instance == (Object)null || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsOwner()) { return; } Stopwatch gameObjectStopwatch = Helper.GetGameObjectStopwatch(((Component)__instance).gameObject); if (gameObjectStopwatch.IsRunning && gameObjectStopwatch.ElapsedMilliseconds < 1000) { return; } gameObjectStopwatch.Restart(); float val = 0f; bool flag = false; bool flag2 = false; switch (__instance.m_name) { case "$piece_charcoalkiln": if (Plugin._enableKiln.Value == Toggle.Off || Plugin._kilnAutomation.Value == Automation.Deposit) { return; } val = Plugin._kilnRadius.Value; flag = Plugin._kilnIgnorePrivateAreaCheck.Value == Toggle.On; flag2 = true; break; case "$piece_smelter": if (Plugin._enableSmelter.Value == Toggle.Off || Plugin._smelterAutomation.Value == Automation.Deposit) { return; } val = Plugin._smelterRadius.Value; flag = Plugin._smelterIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$piece_blastfurnace": if (Plugin._enableBlastFurnace.Value == Toggle.Off || Plugin._blastfurnaceAutomation.Value == Automation.Deposit) { return; } val = Plugin._blastfurnaceRadius.Value; flag = Plugin._blastfurnaceIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$piece_spinningwheel": if (Plugin._enableSpinningWheel.Value == Toggle.Off || Plugin._spinningwheelAutomation.Value == Automation.Deposit) { return; } val = Plugin._spinningwheelRadius.Value; flag = Plugin._spinningwheelIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$piece_windmill": if (Plugin._enableWindmill.Value == Toggle.Off || Plugin._windmillAutomation.Value == Automation.Deposit) { return; } val = Plugin._windmillRadius.Value; flag = Plugin._windmillIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$piece_eitrrefinery": if (Plugin._enableEitrRefinery.Value == Toggle.Off || Plugin._eitrrefineryAutomation.Value == Automation.Deposit) { return; } val = Plugin._eitrrefineryRadius.Value; flag = Plugin._eitrrefineryIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$piece_bathtub": if (Plugin._enableHotTub.Value == Toggle.Off) { return; } val = Plugin._hotTubRadius.Value; flag = Plugin._hotTubIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$cws_stone_kiln": if (Plugin._enableSteelKiln.Value == Toggle.Off || Plugin._steelKilnAutomation.Value == Automation.Deposit || !Plugin._hasOdinSteelWorks) { return; } val = Plugin._steelKilnRadius.Value; flag = Plugin._steelKilnIgnorePrivateAreaCheck.Value == Toggle.On; break; case "$cws_slack_tub": if (Plugin._enableSteelSlackTub.Value == Toggle.Off || Plugin._steelSlackTubAutomation.Value == Automation.Deposit || !Plugin._hasOdinSteelWorks) { return; } val = Plugin._steelSlackTubRadius.Value; flag = Plugin._steelSlackTubIgnorePrivateAreaCheck.Value == Toggle.On; break; } val = Math.Min(50f, Math.Max(1f, val)); int num = __instance.m_maxOre - __instance.GetQueueSize(); int num2 = __instance.m_maxFuel - (int)Math.Ceiling(__instance.GetFuel()); if (Object.op_Implicit((Object)(object)__instance.m_fuelItem) && num2 > 0) { ItemData itemData = __instance.m_fuelItem.m_itemData; int num3 = Helper.DeductItemFromAllNearbyContainers(((Component)__instance).gameObject, val, itemData, 1, !flag); for (int i = 0; i < num3; i++) { __instance.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } } if (num <= 0) { return; } List<Container> nearbyContainers = Helper.GetNearbyContainers(((Component)__instance).gameObject, val); foreach (Container item in nearbyContainers) { foreach (ItemConversion item2 in __instance.m_conversion) { if (flag2) { bool flag3 = Plugin._kilnProcessAllWoods.Value == Toggle.Off; if (flag3) { string name = item2.m_from.m_itemData.m_shared.m_name; bool flag4 = ((name == "$item_finewood" || name == "$item_roundlog") ? true : false); flag3 = flag4; } if (flag3) { continue; } int num4 = ((Plugin._kilnProductThreshold.Value >= 0) ? Plugin._kilnProductThreshold.Value : 0); if (num4 > 0 && Helper.GetItemAmounts(Helper.GetNearbyItemsFromContainers(nearbyContainers), item2.m_to.m_itemData) >= num4) { return; } } ItemData itemData2 = item2.m_from.m_itemData; int num5 = Helper.DeductItemFromContainerLeaveOne(item, itemData2); if (num5 > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)((Component)item2.m_from).gameObject).name); for (int j = 0; j < num5; j++) { __instance.m_nview.InvokeRPC("RPC_AddOre", new object[1] { ((Object)itemPrefab).name }); } num -= num5; if (num == 0) { return; } } } } } private static bool DontProcessAllWoods(Smelter smelter, ItemConversion itemConversion) { bool flag = smelter.m_name == "$piece_charcoalkiln" && Plugin._kilnProcessAllWoods.Value == Toggle.Off; if (flag) { string name = itemConversion.m_from.m_itemData.m_shared.m_name; bool flag2 = ((name == "$item_finewood" || name == "$item_roundlog") ? true : false); flag = flag2; } return flag; } } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace ServerSync { [PublicAPI] internal abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] internal class SyncedConfigEntry<T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; base..ctor(); } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] internal class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = Enumerable.First(configSyncs); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!Enumerable.SequenceEqual(adminList.GetList(), CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = Enumerable.ToList(Enumerable.Where(ZNet.instance.GetPeers(), delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); })); List<ZNetPeer> nonAdminPeer = Enumerable.ToList(Enumerable.Except(ZNet.instance.GetPeers(), adminPeer)); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>(); public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ZPlayFabSocket, ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; ((ZPlayFabSocket)this)..ctor(); } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPriority(800)] [HarmonyPrefix] private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (!__instance.IsServer()) { return; } BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket"); object? value = fieldInfo.GetValue(val); ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null); if (val2 != null) { typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId); } fieldInfo.SetValue(val, bufferingSocket); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = bufferingSocket; } [HarmonyPostfix] private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary<Assembly, BufferingSocket> __state2 = __state; ZNetPeer peer; if (__instance2.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance2).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc2.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List<PackageEntry> entries = new List<PackageEntry>(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc2.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(Enumerable.Select(configSync.allConfigs, (OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package)); } SendBufferedData(); } } } private class PackageEntry { public string section = null; public string key = null; public Type type = null; public object? value; } [HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")] private static class PreventSavingServerInfo { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, ref string __result) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase)) { return true; } __result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType); return false; } } [HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")] private static class PreventConfigRereadChangingValues { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, string value) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null) { return true; } try { ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType); } catch (Exception ex) { Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}"); } return false; } } private class InvalidDeserializationTypeException : Exception { public string expected = null; public string received = null; public string field = ""; } public static bool ProcessingServerUpdate; public readonly string Name; public string? DisplayName; public string? CurrentVersion; public string? MinimumRequiredVersion; public bool ModRequired = false; private bool? forceConfigLocking; private bool isSourceOfTruth = true; private static readonly HashSet<ConfigSync> configSyncs; private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>(); private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>(); private static bool isServer; private static bool lockExempt; private OwnConfigEntryBase? lockedConfig = null; private const byte PARTIAL_CONFIGS = 1; private const byte FRAGMENTED_CONFIG = 2; private const byte COMPRESSED_CONFIG = 4; private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>(); private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>(); private static long packageCounter; public bool IsLocked { get { bool? flag = forceConfigLocking; bool num; if (!flag.HasValue) { if (lockedConfig == null) { goto IL_0052; } num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0; } else { num = flag.GetValueOrDefault(); } if (!num) { goto IL_0052; } int result = ((!lockExempt) ? 1 : 0); goto IL_0053; IL_0053: return (byte)result != 0; IL_0052: result = 0; goto IL_0053; } set { forceConfigLocking = value; } } public bool IsAdmin => lockExempt || isSourceOfTruth; public bool IsSourceOfTruth { get { return isSourceOfTruth; } private set { if (value != isSourceOfTruth) { isSourceOfTruth = value; this.SourceOfTruthChanged?.Invoke(value); } } } public bool InitialSyncDone { get; private set; } = false; public event Action<bool>? SourceOfTruthChanged; private event Action? lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet<ConfigSync>(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry) { ConfigEntry<T> configEntry2 = configEntry; OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2); SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry<T>(configEntry2); AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, Enumerable.ToArray(Enumerable.Concat(Enumerable.Concat(new object[1] { new ConfigurationManagerAttributes() }, ((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()), new SyncedConfigEntry<T>[1] { syncedEntry }))); configEntry2.SettingChanged += delegate { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry<T>(lockingConfig); lockingConfig.SettingChanged += delegate { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry<T>)lockedConfig; } internal void AddCustomValue(CustomSyncedValueBase customValue) { CustomSyncedValueBase customValue2 = customValue; if (Enumerable.Contains(Enumerable.Concat(Enumerable.Select(allCustomValues, (CustomSyncedValueBase v) => v.Identifier), new string[1] { "serverversion" }), customValue2.Identifier)) { throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)"); } allCustomValues.Add(customValue2); allCustomValues = new HashSet<CustomSyncedValueBase>(Enumerable.OrderByDescending(allCustomValues, (CustomSyncedValueBase v) => v.Priority)); customValue2.ValueChanged += delegate { if (!ProcessingServerUpdate) { Broadcast(ZRoutedRpc.Everybody, customValue2); } }; } private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package) { lockedConfigChanged += serverLockedSettingChanged; IsSourceOfTruth = false; if (HandleConfigSyncRPC(0L, package, clientUpdate: false)) { InitialSyncDone = true; } } private void RPC_FromOtherClientConfigSync(long sender, ZPackage package) { HandleConfigSyncRPC(sender, package, clientUpdate: true); } private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown try { if (isServer && IsLocked) { ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc; object obj; if (currentRpc == null) { obj = null; } else { ISocket socket = currentRpc.GetSocket(); obj = ((socket != null) ? socket.GetHostName() : null); } string text = (string)obj; if (text != null) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text })))) { return false; } } } cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv) { if (kv.Key < DateTimeOffset.Now.Ticks) { configValueCache.Remove(kv.Value); return true; } return false; }); byte b = package.ReadByte(); if ((b & 2u) != 0) { long num = package.ReadLong(); string text2 = sender.ToString() + num; if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value)) { value = new SortedDictionary<int, byte[]>(); configValueCache[text2] = value; cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2)); } int key = package.ReadInt(); int num2 = package.ReadInt(); value.Add(key, package.ReadByteArray()); if (value.Count < num2) { return false; } configValueCache.Remove(text2); package = new ZPackage(Enumerable.ToArray(Enumerable.SelectMany(value.Values, (byte[] a) => a))); b = package.ReadByte(); } ProcessingServerUpdate = true; if ((b & 4u) != 0) { byte[] buffer = package.ReadByteArray(); MemoryStream stream = new MemoryStream(buffer); MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) { deflateStream.CopyTo(memoryStream); } package = new ZPackage(memoryStream.ToArray()); b = package.ReadByte(); } if ((b & 1) == 0) { resetConfigsFromServer(); } ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package); ConfigFile val2 = null; bool saveOnConfigSet = false; foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues) { if (!isServer && configValue.Key.LocalBaseValue == null) { configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue; } if (val2 == null) { val2 = configValue.Key.BaseConfig.ConfigFile; saveOnConfigSet = val2.SaveOnConfigSet; val2.SaveOnConfigSet = false; } configValue.Key.BaseConfig.BoxedValue = configValue.Value; } if (val2 != null) { val2.SaveOnConfigSet = saveOnConfigSet; val2.Save(); } foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues) { if (!isServer) { CustomSyncedValueBase key2 = customValue.Key; if (key2.LocalBaseValue == null) { key2.LocalBaseValue = customValue.Key.BoxedValue; } } customValue.Key.BoxedValue = customValue.Value; } Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name)); if (!isServer) { serverLockedSettingChanged(); } return true; } finally { ProcessingServerUpdate = false; } } private ParsedConfigs ReadConfigsFromPackage(ZPackage package) { ParsedConfigs parsedConfigs = new ParsedConfigs(); Dictionary<string, OwnConfigEntryBase> dictionary = Enumerable.ToDictionary(Enumerable.Where(allConfigs, (OwnConfigEntryBase c) => c.SynchronizedConfig), (OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c); Dictionary<string, CustomSyncedValueBase> dictionary2 = Enumerable.ToDictionary(allCustomValues, (CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c); int num = package.ReadInt(); for (int i = 0; i < num; i++) { string text = package.ReadString(); string text2 = package.ReadString(); string text3 = package.ReadString(); Type type = Type.GetType(text3); if (text3 == "" || type != null) { object obj; try { obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type)); } catch (InvalidDeserializationTypeException ex) { Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected)); continue; } OwnConfigEntryBase value2; if (text == "Internal") { CustomSyncedValueBase value; if (text2 == "serverversion") { if (obj?.ToString() != CurrentVersion) { Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown"))); } } else if (text2 == "lockexempt") { if (obj is bool flag) { lockExempt = flag; } } else if (dictionary2.TryGetValue(text2, out value)) { if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3) { parsedConfigs.customValues[value] = obj; continue; } Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName)); } } else if (dictionary.TryGetValue(text + "_" + text2, out value2)) { Type type2 = configType(value2.BaseConfig); if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3) { parsedConfigs.configValues[value2] = obj; continue; } Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName)); } else { Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match.")); } continue; } Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs")); return new ParsedConfigs(); } return parsedConfigs; } private static bool isWritableConfig(OwnConfigEntryBase config) { OwnConfigEntryBase c