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 HipLantern v1.0.24
HipLantern.dll
Decompiled a month 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.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AzuExtendedPlayerInventory; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ExtraSlotsAPI; using HarmonyLib; using HipLantern.Compatibility; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Hip Lantern")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Hip Lantern")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("74d9df24-bd3c-4f53-b58e-f4171c9bd3ff")] [assembly: AssemblyFileVersion("1.0.24")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.24.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace HipLantern { [Serializable] public class HumanoidHipLantern { public ItemData lantern; public HumanoidHipLantern() { lantern = null; } } public static class HumanoidExtension { [HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")] public static class Humanoid_SetupVisEquipment_CustomItemType { private static void Postfix(Humanoid __instance, VisEquipment visEq) { if (!HipLantern.itemSlotUtility.Value) { ItemData hipLantern = __instance.GetHipLantern(); visEq.SetLanternItem((hipLantern != null) ? ((Object)hipLantern.m_dropPrefab).name : ""); } } } [HarmonyPatch(typeof(Humanoid), "GetEquipmentWeight")] public static class Humanoid_GetEquipmentWeight_CustomItemType { private static void Postfix(Humanoid __instance, ref float __result) { if (!HipLantern.itemSlotUtility.Value) { ItemData hipLantern = __instance.GetHipLantern(); if (hipLantern != null) { __result += hipLantern.m_shared.m_weight; } } } } private static readonly ConditionalWeakTable<Humanoid, HumanoidHipLantern> data = new ConditionalWeakTable<Humanoid, HumanoidHipLantern>(); public static HumanoidHipLantern GetLanternData(this Humanoid humanoid) { return data.GetOrCreateValue(humanoid); } public static ItemData GetHipLantern(this Humanoid humanoid) { return humanoid.GetLanternData().lantern; } public static ItemData SetHipLantern(this Humanoid humanoid, ItemData item) { return humanoid.GetLanternData().lantern = item; } } [Serializable] public class VisEquipmentHipLantern { public string m_lanternItem = ""; public List<GameObject> m_lanternItemInstances; public int m_currentlanternItemHash = 0; public static readonly int s_lanternItem = StringExtensionMethods.GetStableHashCode("LanternItem"); } public static class VisEquipmentExtension { [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] public static class VisEquipment_UpdateEquipmentVisuals_CustomItemType { private static void Prefix(VisEquipment __instance) { if (HipLantern.itemSlotUtility.Value) { return; } int hash = 0; ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null) { hash = zDO.GetInt(VisEquipmentHipLantern.s_lanternItem, 0); } else { VisEquipmentHipLantern lanternData = __instance.GetLanternData(); if (!string.IsNullOrEmpty(lanternData.m_lanternItem)) { hash = StringExtensionMethods.GetStableHashCode(lanternData.m_lanternItem); } } if (__instance.SetLanternEquipped(hash)) { __instance.UpdateLodgroup(); } } } private static readonly ConditionalWeakTable<VisEquipment, VisEquipmentHipLantern> data = new ConditionalWeakTable<VisEquipment, VisEquipmentHipLantern>(); public static VisEquipmentHipLantern GetLanternData(this VisEquipment visEquipment) { return data.GetOrCreateValue(visEquipment); } public static void SetLanternItem(this VisEquipment visEquipment, string name) { VisEquipmentHipLantern lanternData = visEquipment.GetLanternData(); if (!(lanternData.m_lanternItem == name)) { lanternData.m_lanternItem = name; if (visEquipment.m_nview.GetZDO() != null && visEquipment.m_nview.IsOwner()) { visEquipment.m_nview.GetZDO().Set(VisEquipmentHipLantern.s_lanternItem, (!string.IsNullOrEmpty(name)) ? StringExtensionMethods.GetStableHashCode(name) : 0, false); } } } public static bool SetLanternEquipped(this VisEquipment visEquipment, int hash) { VisEquipmentHipLantern lanternData = visEquipment.GetLanternData(); if (lanternData.m_currentlanternItemHash == hash) { return false; } if (lanternData.m_lanternItemInstances != null) { foreach (GameObject lanternItemInstance in lanternData.m_lanternItemInstances) { if (Object.op_Implicit((Object)(object)visEquipment.m_lodGroup)) { Utils.RemoveFromLodgroup(visEquipment.m_lodGroup, lanternItemInstance); } Object.Destroy((Object)(object)lanternItemInstance); } lanternData.m_lanternItemInstances = null; } lanternData.m_currentlanternItemHash = hash; if (hash != 0) { lanternData.m_lanternItemInstances = visEquipment.AttachArmor(hash, -1); } return true; } } internal static class CustomItemType { [HarmonyPatch(typeof(Humanoid), "EquipItem")] public static class Humanoid_EquipItem_CustomItemType { private static void Postfix(Humanoid __instance, ItemData item, ref bool __result, bool triggerEquipEffects) { if (!HipLantern.itemSlotUtility.Value && LanternItem.IsLanternItem(item)) { if (__instance.GetHipLantern() != null) { __instance.UnequipItem(__instance.GetHipLantern(), triggerEquipEffects); __instance.m_visEquipment.UpdateEquipmentVisuals(); } __instance.SetHipLantern(item); if (__instance.IsItemEquiped(item)) { item.m_equipped = true; __result = true; } __instance.SetupEquipment(); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] public static class Humanoid_UnequipItem_CustomItemType { private static void Postfix(Humanoid __instance, ItemData item) { if (!HipLantern.itemSlotUtility.Value && LanternItem.IsLanternItem(item) && __instance.GetHipLantern() == item) { __instance.SetHipLantern(null); __instance.SetupEquipment(); } } } [HarmonyPatch(typeof(Humanoid), "UnequipAllItems")] public class Humanoid_UnequipAllItems_CustomItemType { public static void Postfix(Humanoid __instance) { if (!HipLantern.itemSlotUtility.Value) { __instance.UnequipItem(__instance.GetHipLantern(), false); } } } [HarmonyPatch(typeof(Humanoid), "IsItemEquiped")] public static class Humanoid_IsItemEquiped_CustomItemType { private static void Postfix(Humanoid __instance, ItemData item, ref bool __result) { if (!HipLantern.itemSlotUtility.Value && LanternItem.IsLanternItem(item)) { __result = __result || __instance.GetHipLantern() == item; } } } [HarmonyPatch(typeof(ItemData), "IsEquipable")] public static class ItemDropItemData_IsEquipable_CustomItemType { private static void Postfix(ItemData __instance, ref bool __result) { if (!HipLantern.itemSlotUtility.Value) { __result = __result || LanternItem.IsLanternType(__instance); } } } [HarmonyPatch(typeof(Inventory), "Changed")] public static class Inventory_Changed_CustomItemType { private static void Prefix(Inventory __instance) { Player localPlayer = Player.m_localPlayer; if (__instance == ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null) && ((Humanoid)(object)Player.m_localPlayer).GetHipLantern() != null && !__instance.ContainsItem(((Humanoid)(object)Player.m_localPlayer).GetHipLantern())) { ((Humanoid)(object)Player.m_localPlayer).SetHipLantern(null); ((Humanoid)Player.m_localPlayer).SetupEquipment(); } } } [HarmonyPatch(typeof(ItemStand), "Awake")] public static class ItemStand_Awake_LanternStand { private static void Postfix(ItemStand __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_supportedTypes.Contains((ItemType)19) && !__instance.m_supportedTypes.Contains(LanternItem.GetItemType())) { __instance.m_supportedTypes.Add(LanternItem.GetItemType()); } } } } [BepInPlugin("shudnal.HipLantern", "Hip Lantern", "1.0.24")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class HipLantern : BaseUnityPlugin { [HarmonyPatch(typeof(ZNetView), "Awake")] public static class ZNetView_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ZSyncTransform), "Awake")] public static class ZSyncTransform_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ZSyncTransform), "OnEnable")] public static class ZSyncTransform_OnEnable_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ItemDrop), "Awake")] public static class ItemDrop_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ItemDrop), "Start")] public static class ItemDrop_Start_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } public const string pluginID = "shudnal.HipLantern"; public const string pluginName = "Hip Lantern"; public const string pluginVersion = "1.0.24"; private readonly Harmony harmony = new Harmony("shudnal.HipLantern"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.HipLantern") { DisplayName = "Hip Lantern", CurrentVersion = "1.0.24", MinimumRequiredVersion = "1.0.24" }; internal static HipLantern instance; private static ConfigEntry<bool> configLocked; private static ConfigEntry<bool> loggingEnabled; public static ConfigEntry<string> itemCraftingStation; public static ConfigEntry<int> itemMinStationLevel; public static ConfigEntry<string> itemRecipe; public static ConfigEntry<float> equipDuration; public static ConfigEntry<string> refuelCraftingStation; public static ConfigEntry<string> refuelRecipe; public static ConfigEntry<int> fuelMinutes; public static ConfigEntry<int> itemSlotType; public static ConfigEntry<bool> itemSlotUtility; public static ConfigEntry<bool> itemSlotAzuEPI; public static ConfigEntry<string> itemSlotNameAzuEPI; public static ConfigEntry<int> itemSlotIndexAzuEPI; public static ConfigEntry<bool> itemSlotExtraSlots; public static ConfigEntry<string> itemSlotNameExtraSlots; public static ConfigEntry<int> itemSlotIndexExtraSlots; public static ConfigEntry<bool> itemSlotExtraSlotsDiscovery; public static ConfigEntry<Color> lightColor; public static ConfigEntry<float> lightIntensityOutdoors; public static ConfigEntry<float> lightRangeOutdoors; public static ConfigEntry<float> lightShadowsOutdoors; public static ConfigEntry<float> lightIntensityIndoors; public static ConfigEntry<float> lightRangeIndoors; public static ConfigEntry<float> lightShadowsIndoors; public static ConfigEntry<float> lightIntensityStand; public static ConfigEntry<float> lightRangeStand; public static ConfigEntry<float> lightShadowsStand; public static ConfigEntry<float> attachScale; public static ConfigEntry<Vector3> attachPosition; public static ConfigEntry<Vector3> attachEuler; public static ConfigEntry<bool> lanternEnchantableEpicLoot; public static ConfigEntry<bool> lanternSocketableJewelcrafting; private const string c_rootObjectName = "_shudnalRoot"; private const string c_rootPrefabsName = "Prefabs"; private static GameObject rootObject; private static GameObject rootPrefabs; public static GameObject hipLanternPrefab; public static Sprite itemIcon; public static bool prefabInit = false; private void Awake() { instance = this; ConfigInit(); configSync.AddLockingConfigEntry<bool>(configLocked); harmony.PatchAll(); Game.isModded = true; LoadIcons(); UpdateCustomEquipSlot(); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); instance = null; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } public void ConfigInit() { //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) config("General", "NexusID", 2748, "Nexus mod ID for updates", synchronizedSetting: false); configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only"); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false); itemCraftingStation = config("Item", "Crafting station", "$piece_forge", "Station to craft item. Leave empty to craft with hands"); itemMinStationLevel = config("Item", "Crafting station level", 1, "Minimum level of station required to craft and repair"); itemRecipe = config("Item", "Recipe", "SurtlingCore:3,BronzeNails:10,FineWood:4", "Item recipe"); equipDuration = config("Item", "Equip duration", 1f, "Equip duration in seconds."); itemCraftingStation.SettingChanged += delegate { LanternItem.SetLanternRecipes(); }; itemMinStationLevel.SettingChanged += delegate { LanternItem.SetLanternRecipes(); }; itemRecipe.SettingChanged += delegate { LanternItem.SetLanternRecipes(); }; equipDuration.SettingChanged += delegate { LanternItem.PatchLanternItemOnConfigChange(); }; refuelCraftingStation = config("Item - Fuel", "Crafting station", "", "Station to refuel item. Leave empty to refuel with hands"); refuelRecipe = config("Item - Fuel", "Refuel recipe", "SurtlingCore:1", "Item recipe for refueling"); fuelMinutes = config("Item - Fuel", "Fuel minutes", 360, "Time in minutes required to consume all fuel"); refuelCraftingStation.SettingChanged += delegate { LanternItem.SetLanternRecipes(); }; refuelRecipe.SettingChanged += delegate { LanternItem.SetLanternRecipes(); }; fuelMinutes.SettingChanged += delegate { LanternItem.SetLanternRecipes(); }; refuelCraftingStation.SettingChanged += delegate { LanternItem.PatchLanternItemOnConfigChange(); }; refuelRecipe.SettingChanged += delegate { LanternItem.PatchLanternItemOnConfigChange(); }; fuelMinutes.SettingChanged += delegate { LanternItem.PatchLanternItemOnConfigChange(); }; itemSlotType = config("Item - Slot", "Slot type", 56, "Custom item slot type. Change it only if you have issues with other mods compatibility. Game restart is not needed."); itemSlotUtility = config("Item - Slot", "Use utility slot", defaultValue: false, "Just use utility slot. Custom slot setting will be ignored. Game restart is not needed."); itemSlotType.SettingChanged += delegate { LanternItem.PatchLanternItemOnConfigChange(); }; itemSlotUtility.SettingChanged += delegate { LanternItem.PatchLanternItemOnConfigChange(); UpdateCustomEquipSlot(); }; itemSlotAzuEPI = config("Item - Slot", "AzuEPI - Create slot", defaultValue: false, "Create custom equipment slot with AzuExtendedPlayerInventory. Slot will be created/removed on config change."); itemSlotNameAzuEPI = config("Item - Slot", "AzuEPI - Slot name", "Lantern", "Custom equipment slot name. Game restart is recommended after change."); itemSlotIndexAzuEPI = config("Item - Slot", "AzuEPI - Slot index", -1, "Slot index (position). Remove and add slot to apply changes."); itemSlotAzuEPI.SettingChanged += delegate { UpdateCustomEquipSlot(); }; itemSlotExtraSlots = config("Item - Slot", "ExtraSlots - Create slot", defaultValue: false, "Create custom equipment slot with ExtraSlots. Slot will be created/removed on config change."); itemSlotNameExtraSlots = config("Item - Slot", "ExtraSlots - Slot name", "Lantern", "Custom equipment slot name."); itemSlotIndexExtraSlots = config("Item - Slot", "ExtraSlots - Slot index", -1, "Slot index (position). Remove and add slot to apply changes."); itemSlotExtraSlotsDiscovery = config("Item - Slot", "ExtraSlots - Available after discovery", defaultValue: true, "If enabled - slot will be active only if you know Lantern item."); itemSlotExtraSlots.SettingChanged += delegate { UpdateCustomEquipSlot(); ExtraSlotsAPI.API.UpdateSlots(); }; lightColor = config<Color>("Light", "Color", new Color(1f, 0.62f, 0.48f), "Color of lantern light"); lightIntensityOutdoors = config("Light - Outdoors", "Intensity", 1f, "Intensity of light"); lightRangeOutdoors = config("Light - Outdoors", "Range", 30f, "Range of light"); lightShadowsOutdoors = config("Light - Outdoors", "Shadows strength", 0.8f, "Strength of shadows"); lightIntensityIndoors = config("Light - Indoors", "Intensity", 0.8f, "Intensity of light when in dungeons"); lightRangeIndoors = config("Light - Indoors", "Range", 25f, "Range of light when in dungeons"); lightShadowsIndoors = config("Light - Indoors", "Shadows strength", 0.9f, "Strength of shadows when in dungeons"); lightIntensityStand = config("Light - Stand", "Intensity", 0.8f, "Intensity of light when attached to item stand"); lightRangeStand = config("Light - Stand", "Range", 20f, "Range of light when attached to item stand"); lightShadowsStand = config("Light - Stand", "Shadows strength", 0f, "Strength of shadows when attached to item stand"); attachScale = config("Prefab - Attach", "Scale", 0.25f, "Local scale of attached prefab (localScale). Game restart required."); attachPosition = config<Vector3>("Prefab - Attach", "Position", new Vector3(-0.22f, -0.1f, 0.1f), "Local position of attached prefab (localPosition). Game restart required."); attachEuler = config<Vector3>("Prefab - Attach", "Rotation", new Vector3(306.55f, 215.5f, 117.64f), "Local rotation of attached prefab (localEulerAngles). Game restart required."); lanternEnchantableEpicLoot = config("Compatibility", "Make Lantern enchantable by EpicLoot", defaultValue: false, "Lantern will be made enchantable with enchants for Utility slot"); lanternSocketableJewelcrafting = config("Compatibility", "Make Lantern socketable by Jewelcrafting", defaultValue: false, "Lantern will be made socketable with gems effect from Utility slot"); } private ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description); SyncedConfigEntry<T> syncedConfigEntry = configSync.AddConfigEntry<T>(val); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } private void LoadIcons() { LoadIcon("lantern.png", ref itemIcon); } private void LoadIcon(string filename, ref Sprite icon) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Texture2D tex = new Texture2D(2, 2); if (LoadTexture(filename, ref tex)) { icon = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), Vector2.zero); } } private bool LoadTexture(string filename, ref Texture2D tex) { string text = Path.Combine(Paths.PluginPath, filename); if (File.Exists(text)) { LogInfo("Loaded image: " + text); return ImageConversion.LoadImage(tex, File.ReadAllBytes(text)); } Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); return ImageConversion.LoadImage(tex, array, true); } public static void UpdateCustomEquipSlot() { if (AzuExtendedPlayerInventory.API.IsLoaded()) { bool flag = AzuExtendedPlayerInventory.API.GetSlots().SlotNames.Any((string slotName) => slotName == itemSlotNameAzuEPI.Value); if (flag && (itemSlotUtility.Value || !itemSlotAzuEPI.Value)) { AzuExtendedPlayerInventory.API.RemoveSlot(itemSlotNameAzuEPI.Value); } else if (!flag && !itemSlotUtility.Value && itemSlotAzuEPI.Value) { AzuExtendedPlayerInventory.API.AddSlot(itemSlotNameAzuEPI.Value, (Player player) => ((Humanoid)(object)player).GetHipLantern(), (ItemData item) => LanternItem.IsLanternItem(item), itemSlotIndexAzuEPI.Value); } } else { if (!ExtraSlotsAPI.API.IsReady() || Chainloader.PluginInfos.ContainsKey("shudnal.ExtraSlotsCustomSlots")) { return; } bool flag2 = ExtraSlotsAPI.API.FindSlot("HipLantern") != null; if (!flag2 && !itemSlotUtility.Value && itemSlotExtraSlots.Value) { if (itemSlotIndexExtraSlots.Value < 0) { ExtraSlotsAPI.API.AddSlotAfter("HipLantern", () => itemSlotNameExtraSlots.Value, (ItemData item) => LanternItem.IsLanternItem(item), () => LanternItem.IsLanternSlotAvailable(), "CircletExtended"); } else { ExtraSlotsAPI.API.AddSlotWithIndex("HipLantern", itemSlotIndexExtraSlots.Value, () => itemSlotNameExtraSlots.Value, (ItemData item) => LanternItem.IsLanternItem(item), () => LanternItem.IsLanternSlotAvailable()); } } else if (flag2 && (itemSlotUtility.Value || !itemSlotExtraSlots.Value)) { ExtraSlotsAPI.API.RemoveSlot("HipLantern"); } } } private static void InitRootObject() { //IL_0023: 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_008c: Expected O, but got Unknown if ((Object)(object)rootObject == (Object)null) { rootObject = (GameObject)(((object)GameObject.Find("_shudnalRoot")) ?? ((object)new GameObject("_shudnalRoot"))); } Object.DontDestroyOnLoad((Object)(object)rootObject); if ((Object)(object)rootPrefabs == (Object)null) { Transform obj = rootObject.transform.Find("Prefabs"); rootPrefabs = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)rootPrefabs == (Object)null) { rootPrefabs = new GameObject("Prefabs"); rootPrefabs.transform.SetParent(rootObject.transform, false); rootPrefabs.SetActive(false); } } } internal static GameObject InitPrefabClone(GameObject prefabToClone, string prefabName) { InitRootObject(); if ((Object)(object)rootPrefabs.transform.Find(prefabName) != (Object)null) { return ((Component)rootPrefabs.transform.Find(prefabName)).gameObject; } prefabInit = true; GameObject val = Object.Instantiate<GameObject>(prefabToClone, rootPrefabs.transform, false); prefabInit = false; ((Object)val).name = prefabName; return val; } } internal static class LanternItem { [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) })] private class ItemDropItemData_GetTooltip_ItemTooltip { [HarmonyPriority(0)] private static void Postfix(ItemData item, ref string __result) { if (IsLanternItem(item)) { __result = __result.Replace("$item_durability", "$piece_fire_fuel"); } } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipment")] public static class Humanoid_UpdateEquipment_CustomItemType { private static void Finalizer(Humanoid __instance, float dt) { if (((Character)__instance).IsPlayer()) { ItemData hipLantern = __instance.GetHipLantern(); if (hipLantern != null && hipLantern.m_shared.m_useDurability && (!hipLantern.m_shared.m_canBeReparied || (Object)(object)((Player)((__instance is Player) ? __instance : null)).GetCurrentCraftingStation() == (Object)null)) { __instance.DrainEquipedItemDurability(hipLantern, dt); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_AddPrefab { private static void Postfix(ObjectDB __instance) { if (__instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null)) { RegisterHipLanternPrefab(); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_AddPrefab { private static void Postfix(ObjectDB __instance) { if (__instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null)) { RegisterHipLanternPrefab(); } } } [HarmonyPatch(typeof(FejdStartup), "OnDestroy")] public static class FejdStartup_OnDestroy_AddPrefab { private static void Prefix() { ClearPrefabReferences(); } } [HarmonyPatch(typeof(Player), "AddKnownItem")] public static class Player_AddKnownItem_LanternStats { private static void Postfix(ref ItemData item) { if (IsLanternItem(item)) { PatchLanternItemData(item); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public class Player_OnSpawned_LanternStats { public static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { PatchInventory(((Humanoid)__instance).GetInventory()); } } } [HarmonyPatch(typeof(Inventory), "Load")] public class Inventory_Load_LanternStats { public static void Postfix(Inventory __instance) { PatchInventory(__instance); } } [HarmonyPatch(typeof(ItemDrop), "Start")] public static class ItemDrop_Start_LanternStats { private static void Postfix(ref ItemDrop __instance) { if (IsLanternItem(__instance)) { PatchLanternItemData(__instance.m_itemData); } } } [HarmonyPatch(typeof(FejdStartup), "SetupGui")] public static class FejdStartup_SetupGui_AddLocalizedWords { private static void Postfix() { Localization_SetupLanguage_AddLocalizedWords.AddTranslations(Localization.instance, PlatformPrefs.GetString("language", "English")); } } [HarmonyPatch(typeof(Localization), "SetupLanguage")] public static class Localization_SetupLanguage_AddLocalizedWords { private static void Postfix(Localization __instance, string language) { AddTranslations(__instance, language); } public static void AddTranslations(Localization localization, string language) { localization.AddWord("$item_hiplantern".Replace("$", ""), GetItemName(language)); localization.AddWord("$item_hiplantern_description".Replace("$", ""), GetItemDescription(language)); } private static string GetItemName(string language) { if (1 == 0) { } string result = language switch { "Russian" => "Набедренный фонарь", "Chinese" => "髋关节灯", "Chinese_Trad" => "大腿燈", "French" => "Lanterne de cuisse", "German" => "Oberschenkellaterne", "Polish" => "Latarnia uda", "Korean" => "랜턴", "Spanish" => "Linterna de cadera", "Turkish" => "Kalça Feneri", "Dutch" => "Hippe Lantaarn", "Portuguese_Brazilian" => "Lanterna", "Japanese" => "ヒップランタン", "Ukrainian" => "Стегновий ліхтарик", _ => "Hip Lantern", }; if (1 == 0) { } return result; } private static string GetItemDescription(string language) { if (1 == 0) { } string result = language switch { "Russian" => "Небольшой портативный фонарь, который можно прикрепить к бедру.\nЭтот аксессуар обеспечивает тусклый свет, оставляя обе руки свободными для оружия.", "Chinese" => "一种可以挂在臀部的小型便携式灯笼。 \n该配件提供昏暗的光线,同时可以腾出双手来拿武器。", "Chinese_Trad" => "一種可以掛在臀部的小型便攜式燈籠。 \n此配件提供昏暗的光線,同時可以騰出雙手來拿武器。", "French" => "Une petite lanterne portable qui peut être fixée à la hanche.\nCet accessoire fournit une lumière tamisée tout en laissant les deux mains libres pour les armes.", "German" => "Eine kleine tragbare Laterne, die an der Hüfte befestigt werden kann.\nDieses Zubehör sorgt für gedämpftes Licht und lässt gleichzeitig beide Hände für Waffen frei.", "Polish" => "Mała przenośna latarka, którą można przymocować do biodra.\nTo akcesorium zapewnia przyćmione światło, pozostawiając obie ręce wolne dla broni.", "Korean" => "엉덩이에 부착할 수 있는 소형 휴대용 랜턴.\n이 액세서리는 양손을 자유롭게 사용하면서 희미한 조명을 제공합니다.", "Spanish" => "Una pequeña linterna portátil que se puede colocar en la cadera.\nEste accesorio proporciona una luz tenue y deja ambas manos libres para usar las armas.", "Turkish" => "Kalçaya takılabilen küçük, taşınabilir bir fener.\nBu aksesuar, her iki elinizi de silahlar için serbest bırakırken loş ışık sağlar.", "Dutch" => "Een kleine draagbare lantaarn die op de heup kan worden bevestigd.\nDit accessoire zorgt voor gedimd licht en laat beide handen vrij voor wapens.", "Portuguese_Brazilian" => "Uma pequena lanterna portátil que pode ser fixada no quadril.\nEste acessório fornece pouca luz enquanto deixa ambas as mãos livres para pegar armas.", "Japanese" => "腰に装着できる小型の携帯用ランタン。\n このアクセサリーは、両手を自由にして武器を扱えるようにしながら、薄暗い光を提供します。", "Ukrainian" => "Невеликий портативний ліхтар, який можна прикріпити до стегна.\nЦей аксесуар забезпечує приглушене світло, залишаючи обидві руки вільними для зброї.", _ => "A small portable lantern that can be attached to the hip.\nThis accessory provides dim light while leaving both hands free for weapons.", }; if (1 == 0) { } return result; } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] public class InventoryGui_DoCrafting_PreserveCustomData { public static readonly List<ItemData> lanternsBefore = new List<ItemData>(); public static readonly List<ItemData> lanternsAfter = new List<ItemData>(); public static void Prefix(InventoryGui __instance) { if (__instance.m_craftUpgradeItem == null && !((Object)(object)__instance.m_craftRecipe == (Object)null) && IsLanternItem(__instance.m_craftRecipe.m_item)) { lanternsBefore.AddRange(((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Where(IsLanternItem)); lanternsAfter.Clear(); } } [HarmonyPriority(0)] public static void Postfix() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) if (lanternsBefore.Count == 0) { return; } ItemData val = lanternsBefore.Find((ItemData item) => !((Humanoid)Player.m_localPlayer).GetInventory().m_inventory.Contains(item)); if (val != null && val.m_customData.Any()) { lanternsAfter.AddRange(((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Where(IsLanternItem)); ItemData newLantern = lanternsAfter.Find((ItemData item) => !lanternsBefore.Contains(item)); if (newLantern != null) { CollectionExtensions.Do<KeyValuePair<string, string>>((IEnumerable<KeyValuePair<string, string>>)val.m_customData, (Action<KeyValuePair<string, string>>)delegate(KeyValuePair<string, string> kvp) { newLantern.m_customData[kvp.Key] = kvp.Value; }); if (EpicLootCompat.IsInstalled) { ((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(newLantern); ItemDrop val2 = ItemDrop.DropItem(newLantern, 1, ((Component)Player.m_localPlayer).transform.position, ((Component)Player.m_localPlayer).transform.rotation); val2.OnPlayerDrop(); ((Humanoid)Player.m_localPlayer).Pickup(((Component)val2).gameObject, true, false); } } } lanternsBefore.Clear(); lanternsAfter.Clear(); } } public const string itemName = "HipLantern"; public static int itemHash = StringExtensionMethods.GetStableHashCode("HipLantern"); public const string itemDropName = "$item_hiplantern"; public const string itemDropDescription = "$item_hiplantern_description"; public static int s_lightMaskNonPlayer; public static int s_lightMaskPlayer; public const string c_pointLightName = "Point Light"; public const string c_spotLightName = "Spot Light"; public const float c_lightLodDistance = 40f; internal static bool IsLanternType(ItemData item) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return item != null && item.m_shared.m_itemType == GetItemType(); } internal static ItemType GetItemType() { //IL_001e: 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_0021: Unknown result type (might be due to invalid IL or missing references) if (HipLantern.itemSlotUtility.Value) { return (ItemType)18; } return (ItemType)HipLantern.itemSlotType.Value; } internal static bool IsLanternItem(ItemDrop item) { return (Object)(object)item != (Object)null && (IsLanternItemName(item.GetPrefabName(((Object)item).name)) || IsLanternItem(item.m_itemData)) && IsLanternType(item.m_itemData); } public static bool IsLanternItem(ItemData item) { return item != null && IsLanternItemByName(item) && IsLanternType(item); } public static bool IsLanternItem(SharedData item) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return item != null && item.m_itemType == GetItemType() && IsLanternItemDropName(item.m_name); } internal static bool IsLanternItemByName(ItemData item) { return item != null && (((Object)(object)item.m_dropPrefab != (Object)null && IsLanternItemName(((Object)item.m_dropPrefab).name)) || IsLanternItemDropName(item.m_shared.m_name)); } internal static bool IsLanternItemDropName(string name) { return name == "$item_hiplantern"; } internal static bool IsLanternItemName(string name) { return name == "HipLantern"; } internal static bool IsLanternKnown() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || Player.m_localPlayer.m_isLoading) { return true; } return Player.m_localPlayer.IsKnownMaterial("$item_hiplantern"); } internal static bool IsLanternSlotAvailable() { return HipLantern.itemSlotExtraSlots.Value && (!HipLantern.itemSlotExtraSlotsDiscovery.Value || IsLanternKnown()); } private static void CreateHipLanternPrefab() { //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Lantern"); if (!((Object)(object)itemPrefab == (Object)null)) { if (s_lightMaskNonPlayer == 0) { s_lightMaskNonPlayer = LayerMask.GetMask(new string[12] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle", "item" }); } if (s_lightMaskPlayer == 0) { s_lightMaskPlayer = LayerMask.GetMask(new string[1] { "character" }); } HipLantern.hipLanternPrefab = HipLantern.InitPrefabClone(itemPrefab, "HipLantern"); Object.DestroyImmediate((Object)(object)((Component)HipLantern.hipLanternPrefab.transform.Find("attach")).gameObject); Transform val = HipLantern.hipLanternPrefab.transform.Find("attach_back"); ((Object)val).name = "attach_BackTool_attach"; Transform val2 = val.Find("default"); Object.DestroyImmediate((Object)(object)((Component)val2.Find("SFX")).gameObject); val2.localScale = Vector3.one * HipLantern.attachScale.Value; val2.localPosition = HipLantern.attachPosition.Value; val2.localEulerAngles = HipLantern.attachEuler.Value; MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>(); ((Renderer)component).sharedMaterial = new Material(((Renderer)component).sharedMaterial) { name = ((Object)HipLantern.hipLanternPrefab).name + "_mat" }; Transform val3 = val2.Find("Point Light"); GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val2); ((Object)val4).name = "Spot Light"; Light component2 = val4.GetComponent<Light>(); component2.color = HipLantern.lightColor.Value; component2.cullingMask = s_lightMaskPlayer; component2.shadows = (LightShadows)0; component2.range = 1.5f; component2.intensity = 2f; LightLod component3 = val4.GetComponent<LightLod>(); component3.m_lightDistance = 40f; component3.m_baseRange = component2.range; val4.GetComponent<LightFlicker>().m_baseIntensity = component2.intensity; Light component4 = ((Component)val3).GetComponent<Light>(); component4.color = HipLantern.lightColor.Value; component4.cullingMask = s_lightMaskNonPlayer; component4.range = HipLantern.lightRangeOutdoors.Value; component4.intensity = HipLantern.lightIntensityOutdoors.Value; component4.shadowStrength = HipLantern.lightShadowsOutdoors.Value; LightFlicker component5 = ((Component)val3).GetComponent<LightFlicker>(); component5.m_baseIntensity = component4.intensity; component5.m_flickerIntensity *= 0.6f; component5.m_flickerSpeed *= 0.6f; component5.m_movement = 0.02f; LightLod component6 = ((Component)val3).GetComponent<LightLod>(); component6.m_lightDistance = 40f; component6.m_baseRange = component4.range; component6.m_baseShadowStrength = component4.shadowStrength; MainModule main = ((Component)val2.Find("flare")).GetComponent<ParticleSystem>().main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; float r = ((MinMaxGradient)(ref startColor)).color.r; startColor = ((MainModule)(ref main)).startColor; float g = ((MinMaxGradient)(ref startColor)).color.g; startColor = ((MainModule)(ref main)).startColor; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(r, g, ((MinMaxGradient)(ref startColor)).color.b, 0.025f)); ((Component)val2).gameObject.AddComponent<LanternLightController>(); Transform val5 = HipLantern.hipLanternPrefab.transform.Find("default"); ((Object)val5).name = "attach"; val5.localScale = Vector3.one * 0.57f; val5.localPosition = new Vector3(0f, 0.012f, 0f); ((Renderer)((Component)val5).GetComponent<MeshRenderer>()).sharedMaterial = ((Renderer)component).sharedMaterial; LightLod componentInChildren = ((Component)val5).GetComponentInChildren<LightLod>(true); ((Component)componentInChildren).transform.localPosition = new Vector3(0f, 0.2f, 0f); ((Component)componentInChildren).gameObject.SetActive(true); Transform val6 = val5.Find("flare"); val6.localPosition = new Vector3(0f, 0.2f, 0f); ((Component)val6).gameObject.SetActive(true); Ship? obj = ((IEnumerable<Ship>)Resources.FindObjectsOfTypeAll<Ship>()).FirstOrDefault((Func<Ship, bool>)((Ship ws) => ((Object)ws).name == "VikingShip")); Transform val7 = ((obj != null) ? ((Component)obj).transform.Find("ship/visual/Customize/TraderLamp/insects") : null); if (Object.op_Implicit((Object)(object)val7)) { val7 = Object.Instantiate<Transform>(val7, val5); ((Object)val7).name = "insects"; ((Component)val7).gameObject.SetActive(false); val7.localPosition = new Vector3(0f, 0.2f, 0f); } ((Component)val5).gameObject.AddComponent<LanternLightController>(); HipLantern.LogInfo("Created prefab " + ((Object)HipLantern.hipLanternPrefab).name); } } internal static void PatchLanternItemData(ItemData itemData, bool inventoryItemUpdate = true) { if (itemData != null) { itemData.m_dropPrefab = HipLantern.hipLanternPrefab; PatchLanternSharedData(itemData.m_shared); if (!inventoryItemUpdate) { itemData.m_durability = itemData.m_shared.m_maxDurability; } } } internal static void PatchLanternSharedData(SharedData itemSharedData) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) itemSharedData.m_icons[0] = HipLantern.itemIcon; itemSharedData.m_name = "$item_hiplantern"; itemSharedData.m_description = "$item_hiplantern_description"; itemSharedData.m_itemType = GetItemType(); itemSharedData.m_maxStackSize = 1; itemSharedData.m_maxQuality = 1; itemSharedData.m_movementModifier = 0f; itemSharedData.m_equipDuration = HipLantern.equipDuration.Value; itemSharedData.m_attachOverride = (ItemType)19; itemSharedData.m_useDurability = UseFuel(); itemSharedData.m_maxDurability = (UseFuel() ? HipLantern.fuelMinutes.Value : 200); itemSharedData.m_useDurabilityDrain = (UseFuel() ? 1f : 0f); itemSharedData.m_durabilityDrain = (UseFuel() ? (Time.fixedDeltaTime * (5f / 6f)) : 0f); itemSharedData.m_destroyBroken = false; itemSharedData.m_canBeReparied = !UseRefuel(); } private static void RegisterHipLanternPrefab() { ClearPrefabReferences(); if (!Object.op_Implicit((Object)(object)HipLantern.hipLanternPrefab)) { CreateHipLanternPrefab(); } if (!Object.op_Implicit((Object)(object)HipLantern.hipLanternPrefab)) { return; } ItemData val = HipLantern.hipLanternPrefab.GetComponent<ItemDrop>()?.m_itemData; PatchLanternItemData(val, inventoryItemUpdate: false); if (Object.op_Implicit((Object)(object)ObjectDB.instance) && !ObjectDB.instance.m_itemByHash.ContainsKey(itemHash)) { ObjectDB.instance.m_items.Add(HipLantern.hipLanternPrefab); ObjectDB.instance.m_itemByHash.Add(itemHash, HipLantern.hipLanternPrefab); if (val != null) { ObjectDB.instance.m_itemByData[val.m_shared] = HipLantern.hipLanternPrefab; } } if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !ZNetScene.instance.m_namedPrefabs.ContainsKey(itemHash)) { ZNetScene.instance.m_prefabs.Add(HipLantern.hipLanternPrefab); ZNetScene.instance.m_namedPrefabs.Add(itemHash, HipLantern.hipLanternPrefab); } SetLanternRecipes(); } internal static void SetLanternRecipes() { //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Expected O, but got Unknown //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } if (ObjectDB.instance.m_recipes.RemoveAll((Recipe x) => IsLanternItemName(((Object)x).name)) > 0) { HipLantern.LogInfo("Replaced recipe HipLantern"); } CraftingStation val = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe rec) => rec.m_craftingStation?.m_name == "$piece_workbench"))?.m_craftingStation; CraftingStation val2 = (string.IsNullOrWhiteSpace(HipLantern.itemCraftingStation.Value) ? null : ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe rec) => rec.m_craftingStation?.m_name == HipLantern.itemCraftingStation.Value))?.m_craftingStation); CraftingStation val3 = (string.IsNullOrWhiteSpace(HipLantern.refuelCraftingStation.Value) ? null : ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe rec) => rec.m_craftingStation?.m_name == HipLantern.refuelCraftingStation.Value))?.m_craftingStation); ItemDrop component = HipLantern.hipLanternPrefab.GetComponent<ItemDrop>(); Recipe val4 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val4).name = "HipLantern"; val4.m_amount = 1; val4.m_item = component; val4.m_enabled = true; val4.m_craftingStation = val2; val4.m_minStationLevel = ((!Object.op_Implicit((Object)(object)val2)) ? 1 : HipLantern.itemMinStationLevel.Value); val4.m_repairStation = (Object.op_Implicit((Object)(object)val2) ? null : (val3 ?? val)); List<Requirement> list = new List<Requirement>(); string[] array = HipLantern.itemRecipe.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length != 2) { continue; } int num = int.Parse(array2[1]); if (num > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0].Trim()); if (!((Object)(object)itemPrefab == (Object)null)) { list.Add(new Requirement { m_amount = num, m_resItem = itemPrefab.GetComponent<ItemDrop>() }); } } } val4.m_resources = list.ToArray(); ObjectDB.instance.m_recipes.Add(val4); if (!UseRefuel()) { return; } Recipe val5 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val5).name = "HipLantern"; val5.m_amount = 1; val5.m_minStationLevel = 1; val5.m_item = component; val5.m_enabled = true; val5.m_craftingStation = val3; List<Requirement> list2 = new List<Requirement> { new Requirement { m_amount = 1, m_resItem = component, m_recover = false } }; string[] array3 = HipLantern.refuelRecipe.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array3) { string[] array4 = text2.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array4.Length != 2) { continue; } int num2 = int.Parse(array4[1]); if (num2 > 0) { GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(array4[0].Trim()); if (!((Object)(object)itemPrefab2 == (Object)null)) { list2.Add(new Requirement { m_amount = num2, m_resItem = itemPrefab2.GetComponent<ItemDrop>(), m_recover = false }); } } } val5.m_resources = list2.ToArray(); ObjectDB.instance.m_recipes.Add(val5); } private static void ClearPrefabReferences() { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.m_itemByHash.ContainsKey(itemHash)) { ObjectDB.instance.m_items.Remove(ObjectDB.instance.m_itemByHash[itemHash]); ObjectDB.instance.m_itemByHash.Remove(itemHash); } if (Object.op_Implicit((Object)(object)ZNetScene.instance) && ZNetScene.instance.m_namedPrefabs.ContainsKey(itemHash)) { ZNetScene.instance.m_prefabs.Remove(ZNetScene.instance.m_namedPrefabs[itemHash]); ZNetScene.instance.m_namedPrefabs.Remove(itemHash); } } internal static bool UseFuel() { return HipLantern.fuelMinutes.Value > 0; } internal static bool UseRefuel() { return UseFuel() && !string.IsNullOrEmpty(HipLantern.refuelRecipe.Value); } internal static void PatchInventory(Inventory inventory) { if (inventory != null) { CollectionExtensions.DoIf<ItemData>((IEnumerable<ItemData>)inventory.GetAllItems(), (Func<ItemData, bool>)IsLanternItemByName, (Action<ItemData>)delegate(ItemData item) { PatchLanternItemData(item); }); } } internal static void PatchLanternItemOnConfigChange() { GameObject hipLanternPrefab = HipLantern.hipLanternPrefab; PatchLanternItemData((hipLanternPrefab == null) ? null : hipLanternPrefab.GetComponent<ItemDrop>()?.m_itemData, inventoryItemUpdate: false); Player localPlayer = Player.m_localPlayer; PatchInventory((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null); } } public class LanternLightController : MonoBehaviour { [HarmonyPatch(typeof(Humanoid), "SetupEquipment")] public static class Humanoid_SetupVisEquipment_AttachLayersFix { private static void Postfix(Humanoid __instance) { UpdateVisualsLayers(((Character)__instance).m_visual); } } private Light m_mainLight; private LightFlicker m_mainLightFlicker; private LightLod m_mainLightLod; private Light m_spotLight; private Character m_character; private Material m_material; private ItemDrop m_itemDrop; private GameObject m_visual; private GameObject m_insects; private GameObject m_flare; private float m_updateVisualTimer = 0f; private static readonly List<LanternLightController> Instances = new List<LanternLightController>(); private static readonly List<GameObject> visualsToPatch = new List<GameObject>(); private const int c_characterLayer = 9; private const int c_defaultLayer = 0; private void Awake() { m_mainLight = ((Component)((Component)this).transform.Find("Point Light")).GetComponent<Light>(); m_mainLightFlicker = ((Component)m_mainLight).GetComponent<LightFlicker>(); m_mainLightLod = ((Component)m_mainLight).GetComponent<LightLod>(); Transform obj = ((Component)this).transform.Find("Spot Light"); m_spotLight = ((obj != null) ? ((Component)obj).GetComponent<Light>() : null); m_material = ((Renderer)((Component)this).GetComponent<MeshRenderer>()).sharedMaterial; Transform obj2 = ((Component)this).transform.Find("insects"); m_insects = ((obj2 != null) ? ((Component)obj2).gameObject : null); Transform obj3 = ((Component)this).transform.Find("flare"); m_flare = ((obj3 != null) ? ((Component)obj3).gameObject : null); m_itemDrop = ((Component)this).GetComponentInParent<ItemDrop>(); } private void Start() { //IL_007c: 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) m_character = ((Component)((Component)this).transform.root).GetComponent<Character>(); Character character = m_character; m_visual = ((character != null) ? character.GetVisual() : null); UpdateVisualLayers(); ItemStand component = ((Component)((Component)this).transform.root).GetComponent<ItemStand>(); if (component != null && Utils.GetPrefabName(((Component)component).gameObject) == "itemstand") { ((Component)this).transform.localPosition = new Vector3(0f, 0.086f, -0.1f); ((Component)this).transform.localEulerAngles = new Vector3(90f, 0f, 0f); } } private void Update() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Invalid comparison between Unknown and I4 //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) m_mainLight.color = HipLantern.lightColor.Value; if (Object.op_Implicit((Object)(object)m_spotLight)) { m_spotLight.color = HipLantern.lightColor.Value; } if ((Object)(object)m_itemDrop != (Object)null) { ((Component)m_mainLight).gameObject.SetActive(false); GameObject flare = m_flare; if (flare != null) { flare.SetActive(IsTimeToLight()); } m_material.SetColor("_EmissionColor", HipLantern.lightColor.Value); } else if ((Object)(object)m_character == (Object)null) { m_mainLight.intensity = HipLantern.lightIntensityStand.Value; m_mainLightFlicker.m_baseIntensity = HipLantern.lightIntensityStand.Value; m_mainLight.range = HipLantern.lightRangeStand.Value; m_mainLight.shadowStrength = HipLantern.lightShadowsStand.Value; m_mainLightLod.m_lightDistance = 80f; m_mainLightLod.m_baseRange = HipLantern.lightRangeStand.Value; m_mainLightLod.m_baseShadowStrength = HipLantern.lightShadowsStand.Value; m_mainLight.shadows = (LightShadows)((m_mainLight.shadowStrength > 0f) ? 2 : 0); m_mainLightLod.m_shadowLod = (int)m_mainLight.shadows > 0; GameObject insects = m_insects; if (insects != null) { insects.SetActive(IsNightTime()); } GameObject flare2 = m_flare; if (flare2 != null) { flare2.SetActive(IsTimeToLight()); } m_material.SetColor("_EmissionColor", new Color(HipLantern.lightColor.Value.r + (m_flare.activeSelf ? 0.25f : 0.1f), HipLantern.lightColor.Value.g + (m_flare.activeSelf ? 0.25f : 0.1f), HipLantern.lightColor.Value.b + (m_flare.activeSelf ? 0.25f : 0.1f), HipLantern.lightColor.Value.a)); } else if (m_character.InInterior()) { m_mainLight.intensity = HipLantern.lightIntensityIndoors.Value; m_mainLightFlicker.m_baseIntensity = HipLantern.lightIntensityIndoors.Value; m_mainLight.range = HipLantern.lightRangeIndoors.Value; m_mainLight.shadowStrength = HipLantern.lightShadowsIndoors.Value; m_mainLightLod.m_lightDistance = Mathf.Max(HipLantern.lightRangeIndoors.Value + 10f, 40f); m_mainLightLod.m_baseRange = HipLantern.lightRangeIndoors.Value; m_mainLightLod.m_baseShadowStrength = HipLantern.lightShadowsIndoors.Value; m_mainLight.shadows = (LightShadows)((m_mainLight.shadowStrength > 0f) ? 2 : 0); m_material.SetColor("_EmissionColor", new Color(HipLantern.lightColor.Value.r + 0.25f, HipLantern.lightColor.Value.g + 0.25f, HipLantern.lightColor.Value.b + 0.25f, HipLantern.lightColor.Value.a)); } else { m_mainLight.intensity = HipLantern.lightIntensityOutdoors.Value; m_mainLightFlicker.m_baseIntensity = HipLantern.lightIntensityOutdoors.Value; m_mainLight.range = HipLantern.lightRangeOutdoors.Value; m_mainLight.shadowStrength = HipLantern.lightShadowsOutdoors.Value; m_mainLightLod.m_lightDistance = Mathf.Max(HipLantern.lightRangeOutdoors.Value + 10f, 40f); m_mainLightLod.m_baseRange = HipLantern.lightRangeOutdoors.Value; m_mainLightLod.m_baseShadowStrength = HipLantern.lightShadowsOutdoors.Value; m_mainLight.shadows = (LightShadows)(((Object)(object)m_character != (Object)null && m_mainLight.shadowStrength > 0f) ? 2 : 0); m_material.SetColor("_EmissionColor", new Color(HipLantern.lightColor.Value.r + 0.25f, HipLantern.lightColor.Value.g + 0.25f, HipLantern.lightColor.Value.b + 0.25f, HipLantern.lightColor.Value.a)); } } private void FixedUpdate() { if (m_updateVisualTimer > 0f) { m_updateVisualTimer = Mathf.Max(0f, m_updateVisualTimer - Time.fixedDeltaTime); if (m_updateVisualTimer == 0f) { UpdateVisualLayers(); } } } private void OnEnable() { Instances.Add(this); } private void OnDisable() { Instances.Remove(this); } private void UpdateVisualLayers() { HashSet<GameObject> lanternCharacters = (from lantern in Instances where (Object)(object)lantern.m_visual != (Object)null select lantern.m_visual).ToHashSet(); foreach (GameObject visual in visualsToPatch.Where((GameObject vis) => (Object)(object)vis != (Object)null)) { GameObject obj = visual; if (obj == null) { continue; } Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true); if (componentsInChildren != null) { CollectionExtensions.DoIf<Renderer>((IEnumerable<Renderer>)componentsInChildren, (Func<Renderer, bool>)((Renderer ren) => (Object)(object)ren != (Object)null), (Action<Renderer>)delegate(Renderer ren) { ((Component)ren).gameObject.layer = (lanternCharacters.Contains(visual) ? 9 : 0); }); } } visualsToPatch.Clear(); } private void StartUpdateVisualLayers() { m_updateVisualTimer = 0.5f; } internal static void UpdateVisualsLayers(GameObject visual) { visualsToPatch.Add(visual); LanternLightController lanternLightController = Instances.FirstOrDefault(); if ((Object)(object)lanternLightController == (Object)null) { visualsToPatch.RemoveAll((GameObject vis) => (Object)(object)vis == (Object)null); } else { lanternLightController.StartUpdateVisualLayers(); } } private bool IsNightTime() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return ((Component)this).transform.position.y > 3000f || EnvMan.IsNight(); } private bool IsTimeToLight() { if (IsNightTime()) { return true; } if (!EnvMan.IsDaylight() || !Object.op_Implicit((Object)(object)EnvMan.instance)) { return true; } float dayFraction = EnvMan.instance.GetDayFraction(); if (!(dayFraction <= 0.3f)) { return dayFraction >= 0.69f; } return true; } } } namespace HipLantern.Compatibility { internal static class EpicLootCompat { [HarmonyPatch] public static class EpicLoot_EnchantCostsHelper_CanBeMagicItem_TreatLanternAsUtility { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetSacrificeProducts", new Type[1] { typeof(ItemData) }, (Type[])null); if ((object)methodInfo != null) { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method is patched to make it work with custom backpack item type"); list.Add(methodInfo); } else { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetEnchantCost", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo2); } else { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetAugmentCost", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo3); } else { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method was not found"); } MethodInfo methodInfo4 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetReAugmentCost", (Type[])null, (Type[])null); if ((object)methodInfo4 != null) { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo4); } else { HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method was not found"); } MethodInfo methodInfo5 = AccessTools.Method(assembly.GetType("EpicLoot.EpicLoot"), "CanBeMagicItem", (Type[])null, (Type[])null); if ((object)methodInfo5 != null) { HipLantern.LogInfo("EpicLoot.EpicLoot:CanBeMagicItem method is patched to make it work with custom backpack item type"); list.Add(methodInfo5); } else { HipLantern.LogInfo("EpicLoot.EpicLoot:CanBeMagicItem method was not found"); } return list; } public static bool Prepare() { return IsInstalled && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData item, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (HipLantern.lanternEnchantableEpicLoot.Value && (__state = LanternItem.IsLanternItem(item))) { item.m_shared.m_itemType = (ItemType)18; } } public static void Postfix(ItemData item, bool __state) { if (__state) { LanternItem.PatchLanternItemData(item); } } } [HarmonyPatch] public static class EpicLoot_MagicItemEffectRequirements_argItemData_TreatLanternAsUtility { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "AllowByItemType", (Type[])null, (Type[])null); if ((object)methodInfo != null) { HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:AllowByItemType method is patched to make it work with custom backpack item type"); list.Add(methodInfo); } else { HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:AllowByItemType method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "ExcludeByItemType", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method is patched to make it work with custom backpack item type"); list.Add(methodInfo2); } else { HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "CheckRequirements", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:CheckRequirements method is patched to make it work with custom backpack item type"); list.Add(methodInfo3); } else { HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:CheckRequirements method was not found"); } return list; } public static bool Prepare() { return IsInstalled && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData itemData, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (HipLantern.lanternEnchantableEpicLoot.Value && (__state = LanternItem.IsLanternItem(itemData))) { itemData.m_shared.m_itemType = (ItemType)18; } } public static void Postfix(ItemData itemData, bool __state) { if (__state) { LanternItem.PatchLanternItemData(itemData); } } } public const string modGUID = "randyknapp.mods.epicloot"; public static Assembly assembly; public static bool IsInstalled => Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot"); } internal class JewelcraftingCompat { [HarmonyPatch] public static class Jewelcrafting_Utils_GetGemLocation_TreatLanternAsUtility { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["org.bepinex.plugins.jewelcrafting"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("Jewelcrafting.Utils"), "GetGemLocation", (Type[])null, (Type[])null); if ((object)methodInfo != null) { HipLantern.LogInfo("Jewelcrafting.Utils:GetGemLocation method is patched to make it work with lantern"); list.Add(methodInfo); } else { HipLantern.LogInfo("Jewelcrafting.Utils:GetGemLocation method was not found"); } return list; } public static bool Prepare() { return Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.jewelcrafting") && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(SharedData item, ref bool __state) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (HipLantern.lanternSocketableJewelcrafting.Value && (__state = LanternItem.IsLanternItem(item))) { item.m_itemType = (ItemType)18; } } public static void Postfix(SharedData item, bool __state) { if (__state) { LanternItem.PatchLanternSharedData(item); } } } [HarmonyPatch] public static class Jewelcrafting_Utils_IsSocketableItem_TreatLanternAsUtility { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["org.bepinex.plugins.jewelcrafting"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("Jewelcrafting.Utils"), "IsSocketableItem", new Type[1] { typeof(ItemData) }, (Type[])null); if ((object)methodInfo != null) { HipLantern.LogInfo("Jewelcrafting.Utils:IsSocketableItem method is patched to make it work with lantern"); list.Add(methodInfo); } else { HipLantern.LogInfo("Jewelcrafting.Utils:IsSocketableItem method was not found"); } return list; } public static bool Prepare() { return Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.jewelcrafting") && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData item, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (HipLantern.lanternSocketableJewelcrafting.Value && (__state = LanternItem.IsLanternItem(item))) { item.m_shared.m_itemType = (ItemType)18; } } public static void Postfix(ItemData item, bool __state) { if (__state) { LanternItem.PatchLanternItemData(item); } } } public const string modGUID = "org.bepinex.plugins.jewelcrafting"; public static Assembly assembly; } } 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 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 = configSyncs.First(); 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 (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(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 })); }).ToList(); List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); 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(configSync.allConfigs.Select((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, new object[1] { new ConfigurationManagerAttributes() }.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray()); 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 (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(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>(allCustomValues.OrderByDescending((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(value.Values.SelectMany((byte[] a) => a).ToArray()); 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 = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c); Dictionary<string, CustomSyncedValueBase> dictionary2 = allCustomValues.ToDictionary((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 " + (Displ