Decompiled source of PerspexModpack v1.1.64
BepInEx/plugins/Hearthstone.dll
Decompiled 9 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Valheim HearthStone Mod")] [assembly: AssemblyDescription("Adds a ConsumableItem that will bring you home")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("HearthStone")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("97d58a4d-8886-44f9-ba81-73da0e389949")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.0")] [module: UnverifiableCode] namespace Hearthstone; [BepInPlugin("twentyoneZ.mods.Hearthstone_Revolution", "Hearthstone Revolution by TwentyOneZ", "1.0.4")] [BepInDependency("com.jotunn.jotunn", "2.9.0")] public class Hearthstone : BaseUnityPlugin { public const string sharedName = "Hearthstone"; public const string PluginGUID = "twentyoneZ.mods.Hearthstone_Revolution"; private Harmony harmony = new Harmony("twentyoneZ.mods.Hearthstone_Revolution"); public static ConfigEntry<string> item1; public static ConfigEntry<string> item2; public static ConfigEntry<string> item3; public static ConfigEntry<int> itemCost1; public static ConfigEntry<int> itemCost2; public static ConfigEntry<int> itemCost3; public static ConfigEntry<bool> allowTeleportWithoutRestriction; public static ConfigEntry<bool> allowTeleportWhileTargeted; public static ConfigEntry<bool> allowTeleportWhileEncumbered; public static ConfigEntry<bool> allowTeleportWhileInWater; public static ConfigEntry<bool> needsToBeResting; public static ConfigEntry<bool> writeDebugOutput; private static CustomItem m_hearthStoneItem; private static string m_lastPositionString; public static bool IsOwner { get; set; } private static string PositionFile { get { string customItemDataFolder = Paths.CustomItemDataFolder; if (!Directory.Exists(customItemDataFolder)) { Directory.CreateDirectory(customItemDataFolder); } string text = Path.Combine(customItemDataFolder, "HSPosition.txt"); Debug("using Position File: " + text); return text; } } public static void Debug(string value) { if (writeDebugOutput.Value) { Logger.LogMessage((object)value); } } private void Awake() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Expected O, but got Unknown //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Expected O, but got Unknown //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Expected O, but got Unknown //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Expected O, but got Unknown ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; ((BaseUnityPlugin)this).Config.SettingChanged += delegate { GenerateRecipe(); }; item1 = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RecipeItem1", "Stone", new ConfigDescription("Recipe item 1 - leave blank for none", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); itemCost1 = ((BaseUnityPlugin)this).Config.Bind<int>("General", "itemCost1", 2, new ConfigDescription("Amount of item 1 required to craft the Hearthstone", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); item2 = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RecipeItem2", "Coins", new ConfigDescription("Recipe item 2 - leave blank for none", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); itemCost2 = ((BaseUnityPlugin)this).Config.Bind<int>("General", "itemCost2", 10, new ConfigDescription("Amount of item 2 required to craft the Hearthstone", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); item3 = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RecipeItem3", "Carrot", new ConfigDescription("Recipe item 3 - leave blank for none", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); itemCost3 = ((BaseUnityPlugin)this).Config.Bind<int>("General", "itemCost3", 5, new ConfigDescription("Amount of item 3 required to craft the Hearthstone", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); writeDebugOutput = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "writeDebugOutput", true, new ConfigDescription("Write debug output?", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); allowTeleportWithoutRestriction = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "allowTeleportWithoutRestriction", false, new ConfigDescription("Allow teleport without restriction", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); allowTeleportWhileTargeted = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "allowTeleportWhileTargeted", true, new ConfigDescription("Allow teleport while targeted", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); allowTeleportWhileEncumbered = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "allowTeleportWhileEncumbered", false, new ConfigDescription("Allow teleport while encumbered", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); allowTeleportWhileInWater = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "allowTeleportWhileInWater", false, new ConfigDescription("Allow teleport while in water", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); needsToBeResting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "needsToBeResting", true, new ConfigDescription("Require to be resting to teleport (make a safe campfire and sit around)", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); harmony.PatchAll(); GetHearthStonePositionString(); PrefabManager.OnVanillaPrefabsAvailable += AddOrUpdateHearthStoneItem; ItemManager.OnItemsRegistered += ItemManager_OnItemsRegistered; SynchronizationManager.OnConfigurationSynchronized += SynchronizationManager_OnConfigurationSynchronized; SynchronizationManager.OnAdminStatusChanged += SynchronizationManager_OnAdminStatusChanged; } private void SynchronizationManager_OnAdminStatusChanged() { Debug(SynchronizationManager.Instance.PlayerIsAdmin ? "No Admin anymore" : "You are admin"); } private void SynchronizationManager_OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs e) { Debug(e.InitialSynchronization ? "Recieved Initial Config" : "Updated Config"); GenerateRecipe(); } private void Update() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); if (!((Object)(object)hoverObject == (Object)null)) { Interactable componentInParent = hoverObject.GetComponentInParent<Interactable>(); if (IsOwner && componentInParent is Bed && Input.GetKeyDown((KeyCode)112)) { SetHearthStonePosition(); ((Character)Player.m_localPlayer).Message((MessageType)2, "You have updated your HearthStone location", 0, (Sprite)null); } } } private void ItemManager_OnItemsRegistered() { ItemManager.OnItemsRegistered -= ItemManager_OnItemsRegistered; GenerateRecipe(); } private void GenerateRecipe() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown List<Requirement> rqs; if (m_hearthStoneItem != null && ObjectDB.instance.m_items.Any()) { if (m_hearthStoneItem.Recipe == null) { Recipe obj = ScriptableObject.CreateInstance<Recipe>(); ((Object)obj).name = "Recipe_Hearthstone"; obj.m_item = m_hearthStoneItem.ItemDrop; CustomRecipe recipe = new CustomRecipe(obj, true, true) { FixRequirementReferences = true }; m_hearthStoneItem.Recipe = recipe; } rqs = new List<Requirement>(); AddRq(item1, itemCost1); AddRq(item2, itemCost2); AddRq(item3, itemCost3); if (m_hearthStoneItem.Recipe != null && (Object)(object)m_hearthStoneItem.Recipe.Recipe != (Object)null) { m_hearthStoneItem.Recipe.Recipe.m_resources = rqs.ToArray(); } } void AddRq(ConfigEntry<string> item, ConfigEntry<int> amount) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown try { if (item != null && !string.IsNullOrEmpty(item.Value) && amount.Value > 0) { ItemDrop component = ObjectDB.instance.GetItemPrefab(item.Value).GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { rqs.Add(new Requirement { m_amount = amount.Value, m_resItem = component }); } } } catch (Exception ex) { Debug(ex.Message); } } } private void AddOrUpdateHearthStoneItem() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown if (m_hearthStoneItem != null) { return; } AssetBundle val = AssetUtils.LoadAssetBundleFromResources("hs", typeof(Hearthstone).Assembly); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"Bundle could not be loaded!"); return; } GameObject val2 = val.LoadAsset<GameObject>("Assets/_Custom/Hearthstone.prefab"); if ((Object)(object)val2 == (Object)null) { Logger.LogWarning((object)"Prefab could not be loaded!"); return; } SharedData shared = val2.GetComponent<ItemDrop>().m_itemData.m_shared; if (shared == null) { Logger.LogWarning((object)"Shared ItemData could not be loaded!"); return; } ItemConfig val3 = new ItemConfig { Name = shared.m_name, Requirements = BuildRequirementConfigs(), Icons = shared.m_icons, Description = shared.m_description }; m_hearthStoneItem = new CustomItem(val, "Assets/_Custom/Hearthstone.prefab", true, val3); ItemManager.Instance.AddItem(m_hearthStoneItem); GenerateRecipe(); } private static RequirementConfig[] BuildRequirementConfigs() { //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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown List<RequirementConfig> list = new List<RequirementConfig>(); if (itemCost1.Value > 0 && !string.IsNullOrEmpty(item1.Value)) { list.Add(new RequirementConfig { Amount = itemCost1.Value, Item = item1.Value }); } if (itemCost2.Value > 0 && !string.IsNullOrEmpty(item2.Value)) { list.Add(new RequirementConfig { Amount = itemCost2.Value, Item = item2.Value }); } if (itemCost3.Value > 0 && !string.IsNullOrEmpty(item3.Value)) { list.Add(new RequirementConfig { Amount = itemCost3.Value, Item = item3.Value }); } return list.ToArray(); } public static Vector3 GetHearthStonePosition() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) CultureInfo provider = new CultureInfo("en-US"); Vector3 zero = Vector3.zero; string hearthStonePositionString = GetHearthStonePositionString(); if (string.IsNullOrEmpty(hearthStonePositionString)) { return zero; } string[] array = hearthStonePositionString.Split(new char[1] { '|' }); try { return new Vector3(float.Parse(array[0], provider), float.Parse(array[1], provider), float.Parse(array[2], provider)); } catch { return Vector3.zero; } } private static string GetHearthStonePositionString() { if (string.IsNullOrEmpty(m_lastPositionString) && File.Exists(PositionFile)) { m_lastPositionString = File.ReadAllText(PositionFile); } return m_lastPositionString; } private static void SetHearthStonePosition() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) CultureInfo cultureInfo = new CultureInfo("en-US"); string text = ((Component)Player.m_localPlayer).transform.position.x.ToString(cultureInfo) + "|" + ((Component)Player.m_localPlayer).transform.position.y.ToString(cultureInfo) + "|" + ((Component)Player.m_localPlayer).transform.position.z.ToString(cultureInfo); File.WriteAllText(PositionFile, text); m_lastPositionString = text; } } internal class Patches { [HarmonyPatch(typeof(Player), "ConsumeItem")] public static class ConsumePatch { private static bool Prefix(ItemData item) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: 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_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) string name = item.m_shared.m_name; if (string.IsNullOrEmpty(name)) { return false; } if (name == "Hearthstone") { if (!((Humanoid)Player.m_localPlayer).IsTeleportable() && !Hearthstone.allowTeleportWithoutRestriction.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport carrying those items", 0, (Sprite)null); return false; } if (Player.m_localPlayer.IsTargeted() && !Hearthstone.allowTeleportWhileTargeted.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while spotted by anyone", 0, (Sprite)null); return false; } if (((Character)Player.m_localPlayer).IsEncumbered() && !Hearthstone.allowTeleportWhileEncumbered.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while encumbered", 0, (Sprite)null); return false; } if (((Character)Player.m_localPlayer).InWater() && !Hearthstone.allowTeleportWhileInWater.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while in water", 0, (Sprite)null); return false; } if (!((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect("Resting") && Hearthstone.needsToBeResting.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You have to be resting to teleport", 0, (Sprite)null); return false; } Vector3 hearthStonePosition = Hearthstone.GetHearthStonePosition(); if (hearthStonePosition == Vector3.zero) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You need to set hearthstone spawn point", 0, (Sprite)null); return false; } ((Character)Player.m_localPlayer).TeleportTo(hearthStonePosition, ((Component)Player.m_localPlayer).transform.rotation, true); } if (name == "Marketstone") { if (!((Humanoid)Player.m_localPlayer).IsTeleportable() && !Hearthstone.allowTeleportWithoutRestriction.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport carrying those items", 0, (Sprite)null); return false; } if (Player.m_localPlayer.IsTargeted() && !Hearthstone.allowTeleportWhileTargeted.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while spotted by anyone", 0, (Sprite)null); return false; } if (((Character)Player.m_localPlayer).IsEncumbered() && !Hearthstone.allowTeleportWhileEncumbered.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while encumbered", 0, (Sprite)null); return false; } if (((Character)Player.m_localPlayer).InWater() && !Hearthstone.allowTeleportWhileInWater.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while in water", 0, (Sprite)null); return false; } if (!((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect("Resting") && Hearthstone.needsToBeResting.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You have to be resting to teleport", 0, (Sprite)null); return false; } LocationInstance val = default(LocationInstance); if (ZoneSystem.instance.FindClosestLocation("Vendor_BlackForest", Vector3.zero, ref val)) { Vector3 val2 = val.m_position + Vector3.up; ((Character)Player.m_localPlayer).TeleportTo(val2, ((Component)Player.m_localPlayer).transform.rotation, true); } else { Vector3 val3 = default(Vector3); if (!ZoneSystem.instance.GetLocationIcon("Vendor_BlackForest", ref val3)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "I have to find the market first.", 0, (Sprite)null); return false; } Vector3 val2 = val3 + Vector3.up; ((Character)Player.m_localPlayer).TeleportTo(val2, ((Component)Player.m_localPlayer).transform.rotation, true); } } if (name == "Deathstone") { if (!((Humanoid)Player.m_localPlayer).IsTeleportable() && !Hearthstone.allowTeleportWithoutRestriction.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport carrying those items", 0, (Sprite)null); return false; } if (Player.m_localPlayer.IsTargeted() && !Hearthstone.allowTeleportWhileTargeted.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while spotted by anyone", 0, (Sprite)null); return false; } if (((Character)Player.m_localPlayer).IsEncumbered() && !Hearthstone.allowTeleportWhileEncumbered.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while encumbered", 0, (Sprite)null); return false; } if (((Character)Player.m_localPlayer).InWater() && !Hearthstone.allowTeleportWhileInWater.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't teleport while in water", 0, (Sprite)null); return false; } if (!((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect("Resting") && Hearthstone.needsToBeResting.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You have to be resting to teleport", 0, (Sprite)null); return false; } LocationInstance val4 = default(LocationInstance); if (ZoneSystem.instance.FindClosestLocation("Vendor_BlackForest", Vector3.zero, ref val4)) { Vector3 val5 = val4.m_position + Vector3.up; ((Character)Player.m_localPlayer).TeleportTo(val5, ((Component)Player.m_localPlayer).transform.rotation, true); } else { Vector3 val6 = default(Vector3); if (!ZoneSystem.instance.GetLocationIcon("Vendor_BlackForest", ref val6)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "I have to find the market first.", 0, (Sprite)null); return false; } Vector3 val5 = val6 + Vector3.up; ((Character)Player.m_localPlayer).TeleportTo(val5, ((Component)Player.m_localPlayer).transform.rotation, true); } } return true; } } [HarmonyPatch(typeof(Bed), "GetHoverText")] private static class Bed_GetHoverText_Patch { private static void Postfix(Bed __instance, ref string __result, ZNetView ___m_nview) { if ((Object)(object)Player.m_localPlayer == (Object)null) { Hearthstone.IsOwner = false; } else if (___m_nview.GetZDO().GetLong("owner", 0L) == Player.m_localPlayer.GetPlayerID() || __instance.IsCurrent()) { Hearthstone.IsOwner = true; __result += "\n[<color=yellow><b>P</b></color>] Set hearthstone"; } else { Hearthstone.IsOwner = false; } } } [HarmonyPatch(typeof(ItemStand), "CanAttach")] public static class AttachPatch { [HarmonyPostfix] private static void Postfix(ItemStand __instance, ItemData item, ref bool __result) { if (!__result) { string text = item?.m_shared?.m_name; if (!string.IsNullOrEmpty(text)) { __result = text == "Hearthstone"; } } } } }
BepInEx/plugins/RepairRequiresCoins.dll
Decompiled 9 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace RepairRequiresMats; [BepInPlugin("aedenthorn.RepairRequiresMats", "Repair Requires Mats", "0.6.1")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(UITooltip), "LateUpdate")] private static class UITooltip_LateUpdate_Patch { private static void Postfix(UITooltip __instance, UITooltip ___m_current, GameObject ___m_tooltip) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (modEnabled.Value && (Object)(object)___m_current == (Object)(object)__instance && (Object)(object)___m_tooltip != (Object)null && ((Object)((Component)___m_current).transform).name == "RepairButton") { ___m_tooltip.transform.position = Input.mousePosition + new Vector3(-200f, -100f); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRepair")] private static class InventoryGui_UpdateRepair_Patch { private static void Postfix(InventoryGui __instance, ref List<ItemData> ___m_tempWornItems) { //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Expected O, but got Unknown //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Expected O, but got Unknown if (!modEnabled.Value || !___m_tempWornItems.Any()) { return; } List<RepairItemData> list = new List<RepairItemData>(); List<RepairItemData> list2 = new List<RepairItemData>(); List<RepairItemData> list3 = new List<RepairItemData>(); List<RepairItemData> list4 = new List<RepairItemData>(); List<string> list5 = new List<string>(); foreach (ItemData ___m_tempWornItem in ___m_tempWornItems) { if (!Traverse.Create((object)__instance).Method("CanRepair", new object[1] { ___m_tempWornItem }).GetValue<bool>()) { list4.Add(new RepairItemData(___m_tempWornItem)); continue; } List<Requirement> list6 = RepairReqs(___m_tempWornItem); if (list6 == null) { list.Add(new RepairItemData(___m_tempWornItem)); continue; } List<string> list7 = new List<string>(); foreach (Requirement item in list6) { if (item.m_amount != 0) { list7.Add($"{item.m_amount}/{((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item.m_resItem.m_itemData.m_shared.m_name, -1, true)} {Localization.instance.Localize(item.m_resItem.m_itemData.m_shared.m_name)}"); } } bool flag = true; foreach (Requirement item2 in list6) { if (Object.op_Implicit((Object)(object)item2.m_resItem)) { int amount = item2.m_amount; if (((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item2.m_resItem.m_itemData.m_shared.m_name, -1, true) < amount) { flag = false; break; } } } if (!flag) { list3.Add(new RepairItemData(___m_tempWornItem, list7)); } else { list2.Add(new RepairItemData(___m_tempWornItem, list7)); } } orderedWornItems = new List<ItemData>(); foreach (RepairItemData item3 in list) { list5.Add("<color=#" + hasEnoughTooltipColor.Value + ">" + Localization.instance.Localize(item3.item.m_shared.m_name) + ": Free</color>"); orderedWornItems.Add(item3.item); } foreach (RepairItemData item4 in list2) { list5.Add("<color=#" + hasEnoughTooltipColor.Value + ">" + Localization.instance.Localize(item4.item.m_shared.m_name) + ": " + string.Join(", ", item4.reqstring) + "</color>"); orderedWornItems.Add(item4.item); } foreach (RepairItemData item5 in list3) { list5.Add("<color=#" + notEnoughTooltipColor.Value + ">" + Localization.instance.Localize(item5.item.m_shared.m_name) + ": " + string.Join(", ", item5.reqstring) + "</color>"); orderedWornItems.Add(item5.item); } foreach (RepairItemData item6 in list4) { orderedWornItems.Add(item6.item); } ___m_tempWornItems = new List<ItemData>(orderedWornItems); if (showAllRepairsInToolTip.Value) { UITooltip val = (UITooltip)typeof(UITooltip).GetField("m_current", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); GameObject val2 = (GameObject)typeof(UITooltip).GetField("m_tooltip", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); if (!((Object)(object)val2 == (Object)null) && !(((Object)((Component)val).transform).name != "RepairButton")) { ((Component)Utils.FindChild(val2.transform, "Text", (IterativeSearchType)0)).GetComponent<TMP_Text>().richText = true; ((Component)Utils.FindChild(val2.transform, "Text", (IterativeSearchType)0)).GetComponent<TMP_Text>().alignment = (TextAlignmentOptions)1026; ((Component)Utils.FindChild(val2.transform, "Text", (IterativeSearchType)0)).GetComponent<TMP_Text>().text = "<b><color=#" + titleTooltipColor.Value + ">" + Localization.instance.Localize("$inventory_repairbutton") + "</color></b>\r\n" + string.Join("\r\n", list5); } } } } [HarmonyPatch(typeof(InventoryGui), "CanRepair")] private static class InventoryGui_CanRepair_Patch { private static void Postfix(ItemData item, ref bool __result) { if (!modEnabled.Value || !modEnabled.Value || !Environment.StackTrace.Contains("RepairOneItem") || Environment.StackTrace.Contains("HaveRepairableItems") || !__result || item?.m_shared == null || !((Object)(object)Player.m_localPlayer != (Object)null) || orderedWornItems.Count <= 0) { return; } if (orderedWornItems[0] != item) { __result = false; return; } List<Requirement> list = RepairReqs(item, log: true); if (list == null) { return; } List<string> list2 = new List<string>(); foreach (Requirement item2 in list) { if (item2?.m_resItem?.m_itemData?.m_shared != null) { list2.Add($"{item2.m_amount}/{((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item2.m_resItem.m_itemData.m_shared.m_name, -1, true)} {Localization.instance.Localize(item2.m_resItem.m_itemData.m_shared.m_name)}"); } } bool flag = true; foreach (Requirement item3 in list) { if (Object.op_Implicit((Object)(object)item3.m_resItem)) { int amount = item3.m_amount; if (((Humanoid)Player.m_localPlayer).GetInventory().CountItems(item3.m_resItem.m_itemData.m_shared.m_name, -1, true) < amount) { flag = false; break; } } } string text; if (flag) { Player.m_localPlayer.ConsumeResources(list.ToArray(), 1, -1); text = "Used " + string.Join(", ", list2) + " to repair " + Localization.instance.Localize(item.m_shared.m_name); __result = true; } else { text = "Require " + string.Join(", ", list2) + " to repair " + item.m_shared.m_name; __result = false; } ((Character)Player.m_localPlayer).Message((MessageType)1, text, 0, (Sprite)null); Dbgl(text); } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals("repairmod reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { "Repair Items config reloaded" }).GetValue(); return false; } return true; } } private static bool isDebug = true; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> showAllRepairsInToolTip; public static ConfigEntry<float> materialRequirementMult; public static ConfigEntry<string> titleTooltipColor; public static ConfigEntry<string> hasEnoughTooltipColor; public static ConfigEntry<string> notEnoughTooltipColor; public static ConfigEntry<int> nexusID; private static List<ItemData> orderedWornItems = new List<ItemData>(); private static BepInExPlugin context; private static Assembly epicLootAssembly; private static MethodInfo epicLootIsMagic; private static MethodInfo epicLootGetRarity; private static MethodInfo epicLootGetEnchantCosts; public static void Dbgl(string str = "", bool pref = true) { if (isDebug) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 215, "Nexus mod ID for updates"); showAllRepairsInToolTip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowAllRepairsInToolTip", true, "Show all repairs in tooltip when hovering over repair button."); titleTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TitleTooltipColor", "FFFFFFFF", "Color to use in tooltip title."); hasEnoughTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HasEnoughTooltipColor", "FFFFFFFF", "Color to use in tooltip for items with enough resources to repair."); notEnoughTooltipColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "NotEnoughTooltipColor", "FF0000FF", "Color to use in tooltip for items with enough resources to repair."); materialRequirementMult = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaterialRequirementMult", 0.5f, "Multiplier for amount of each material required."); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private void Start() { if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot")) { epicLootAssembly = ((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType().Assembly; epicLootIsMagic = epicLootAssembly.GetType("EpicLoot.ItemDataExtensions").GetMethod("IsMagic", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); epicLootGetRarity = epicLootAssembly.GetType("EpicLoot.ItemDataExtensions").GetMethod("GetRarity", BindingFlags.Static | BindingFlags.Public); epicLootGetEnchantCosts = epicLootAssembly.GetType("EpicLoot.Crafting.EnchantTabController").GetMethod("GetEnchantCosts", BindingFlags.Static | BindingFlags.Public); Dbgl($"Loaded Epic Loot assembly; epicLootIsMagic {epicLootIsMagic != null}, epicLootGetRarity {epicLootGetRarity != null}, epicLootGetEnchantCosts {epicLootGetEnchantCosts != null}"); } } private static List<Requirement> RepairReqs(ItemData item, bool log = false) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown float num = (item.GetMaxDurability() - item.m_durability) / item.GetMaxDurability(); Recipe recipe = ObjectDB.instance.GetRecipe(item); if (recipe == null) { return null; } List<Requirement> list = new List<Requirement>(recipe.m_resources); bool flag = false; if (epicLootAssembly != null) { try { MethodInfo methodInfo = epicLootIsMagic; object[] parameters = (object[])(object)new ItemData[1] { item }; flag = (bool)methodInfo.Invoke(null, parameters); } catch { } } if (flag) { try { MethodInfo methodInfo2 = epicLootGetRarity; object[] parameters = (object[])(object)new ItemData[1] { item }; int num2 = (int)methodInfo2.Invoke(null, parameters); foreach (KeyValuePair<ItemDrop, int> item2 in (List<KeyValuePair<ItemDrop, int>>)epicLootGetEnchantCosts.Invoke(null, new object[2] { item, num2 })) { list.Add(new Requirement { m_amount = item2.Value, m_resItem = item2.Key }); } } catch { } } List<Requirement> list2 = new List<Requirement>(); for (int i = 0; i < list.Count; i++) { Requirement val = new Requirement { m_resItem = list[i].m_resItem, m_amount = list[i].m_amount, m_amountPerLevel = list[i].m_amountPerLevel, m_recover = list[i].m_recover }; int num3 = 0; for (int num4 = item.m_quality; num4 > 0; num4--) { if (val.m_resItem.m_itemData.m_shared.m_name.ToLower().Contains("item_coins")) { num3 += val.GetAmount(num4); } } int num5 = Mathf.RoundToInt((float)num3 * num * materialRequirementMult.Value); if (num5 > 0) { val.m_amount = num5; list2.Add(val); } } if (!list2.Any()) { return null; } return list2; } } internal class RepairItemData : ItemData { public List<string> reqstring; public ItemData item; public RepairItemData(ItemData item, List<string> reqstring = null) { this.reqstring = reqstring; this.item = item; } }
BepInEx/plugins/VLDamageFix.dll
Decompiled 9 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using EpicMMOSystem; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimLegends")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimLegends")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f0baf009-4135-4368-9987-850698809493")] [assembly: AssemblyFileVersion("0.4.9.3")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.9.3")] [module: UnverifiableCode] namespace ValheimLegends; public class AnimationClipOverrides : List<KeyValuePair<AnimationClip, AnimationClip>> { public AnimationClip this[string name] { get { return Find((KeyValuePair<AnimationClip, AnimationClip> x) => ((Object)x.Key).name == name).Value; } set { int num = FindIndex((KeyValuePair<AnimationClip, AnimationClip> x) => ((Object)x.Key).name == name); if (num != -1) { base[num] = new KeyValuePair<AnimationClip, AnimationClip>(base[num].Key, value); } } } public AnimationClipOverrides(int capacity) : base(capacity) { } } public class Class_Berserker { private static int Script_Layermask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece_nonsolid", "vehicle", "viewblock", "piece" }); private static int Player_Layermask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece_nonsolid", "terrain", "vehicle" }); private static GameObject GO_CastFX; public static void Execute_Dash(Player player, ref float altitude, ref Rigidbody playerBody) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036e: 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_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0337: 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_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Expected O, but got Unknown //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: 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_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_perfectblock"), ((Component)player).transform.position, Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_stonegolem_attack_hit"), ((Component)player).transform.position, Quaternion.identity); float num = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.DisciplineSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddPhysicDamage() / 40f + LevelSystem.Instance.getAddAttackSpeed() / 40f, 0f, 0.5f)); float num2 = 0.6f + num * 0.015f * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_berserkerDash; if (((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Berserk") || ((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Execute")) { SE_Berserk sE_Berserk = (SE_Berserk)(object)((Character)player).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("SE_VL_Berserk")); if ((Object)(object)sE_Berserk != (Object)null) { num2 *= sE_Berserk.damageModifier; } } Vector3 lookDir = ((Character)player).GetLookDir(); lookDir.y = 0f; ((Component)player).transform.rotation = Quaternion.LookRotation(lookDir); Vector3 val = default(Vector3); Vector3 forward = ((Component)player).transform.forward; Vector3 position = ((Component)player).transform.position; Vector3 val2 = ((Component)player).transform.position; val2.y += 0.1f; List<int> list = new List<int>(); float num3 = 1f; int i; for (i = 0; i <= 10; i++) { RaycastHit val3 = default(RaycastHit); bool flag = false; for (int j = 0; j <= 10; j++) { Vector3 val4 = Vector3.MoveTowards(((Component)player).transform.position, ((Component)player).transform.position + forward * 100f, (float)i + (float)j * 0.1f); val4.y = val2.y; if (val4.y < ZoneSystem.instance.GetGroundHeight(val4)) { val2.y = ZoneSystem.instance.GetGroundHeight(val4) + 1f; val4.y = val2.y; } flag = Physics.SphereCast(val4, 0.05f, forward, ref val3, float.PositiveInfinity, Script_Layermask); if (flag && Object.op_Implicit((Object)(object)((RaycastHit)(ref val3)).collider)) { val = ((RaycastHit)(ref val3)).point; break; } } position = Vector3.MoveTowards(((Component)player).transform.position, ((Component)player).transform.position + forward * 100f, (float)i); position.y = ((ZoneSystem.instance.GetSolidHeight(position) - ZoneSystem.instance.GetGroundHeight(position) <= 1f) ? ZoneSystem.instance.GetSolidHeight(position) : ZoneSystem.instance.GetGroundHeight(position)); if (flag && Vector3.Distance(new Vector3(position.x, val2.y, position.z), val) <= 1f) { val2 = Vector3.MoveTowards(val, val2, 1f); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_beehive_hit"), val2, Quaternion.identity); break; } Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_beehive_hit"), val2, Quaternion.identity); ((Vector3)(ref val2))..ctor(position.x, val2.y, position.z); foreach (Character allCharacter in Character.GetAllCharacters()) { HitData val5 = new HitData(); val5.m_damage = ((Humanoid)player).GetCurrentWeapon().GetDamage(); val5.ApplyModifier(Random.Range(0.8f, 1.2f) * num2 / num3); val5.m_point = allCharacter.GetCenterPoint(); val5.m_dir = ((Component)allCharacter).transform.position - position; val5.m_skill = ValheimLegends.DisciplineSkill; float num4 = Vector3.Distance(((Component)allCharacter).transform.position, position); if (!BaseAI.IsEnemy(allCharacter, (Character)(object)player) || !(num4 <= 3f) || list.Contains(((Object)allCharacter).GetInstanceID())) { continue; } SE_Execute sE_Execute = (SE_Execute)(object)((Character)player).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("SE_VL_Execute")); if ((Object)(object)sE_Execute != (Object)null) { val5.ApplyModifier(sE_Execute.damageBonus); sE_Execute.hitCount--; if (sE_Execute.hitCount <= 0) { ((Character)player).GetSEMan().RemoveStatusEffect((StatusEffect)(object)sE_Execute, false); } } num3 += 0.6f; allCharacter.Damage(val5); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_crit"), allCharacter.GetCenterPoint(), Quaternion.identity); list.Add(((Object)allCharacter).GetInstanceID()); } } list.Clear(); if (i > 10 && ZoneSystem.instance.GetSolidHeight(val2) - val2.y <= 2f) { val2.y = ZoneSystem.instance.GetSolidHeight(val2); } playerBody.position = val2; altitude = 0f; ((Component)player).transform.rotation = Quaternion.LookRotation(forward); } public static void Process_Input(Player player, ref float altitude) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) new Random(); if (VL_Utility.Ability3_Input_Down) { if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability3_CD")) { if (player.GetStamina() > VL_Utility.GetDashCost(player)) { StatusEffect val = (StatusEffect)(object)(SE_Ability3_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability3_CD)); val.m_ttl = VL_Utility.GetDashCooldown(player); ((Character)player).GetSEMan().AddStatusEffect(val, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetDashCost(player), false); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(player)).SetTrigger("swing_longsword2"); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_Potion_stamina_medium"), ((Component)player).transform.position, Quaternion.identity); ValheimLegends.isChargingDash = true; ValheimLegends.dashCounter = 0; ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetDashSkillGain(player)); } else { ((Character)player).Message((MessageType)1, "Not enough stamina for Dash: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetDashCost(player) + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else if (VL_Utility.Ability2_Input_Down) { if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability2_CD")) { if (player.GetStamina() > VL_Utility.GetBerserkCost(player)) { StatusEffect val2 = (StatusEffect)(object)(SE_Ability2_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability2_CD)); val2.m_ttl = VL_Utility.GetBerserkCooldown(player); ((Character)player).GetSEMan().AddStatusEffect(val2, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetBerserkCost(player), false); ValheimLegends.shouldUseGuardianPower = false; player.StartEmote("challenge", true); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_GP_Stone"), ((Character)player).GetCenterPoint(), Quaternion.identity); float num = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.AlterationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddCriticalChance() / 40f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); SE_Berserk sE_Berserk = (SE_Berserk)(object)ScriptableObject.CreateInstance(typeof(SE_Berserk)); ((StatusEffect)sE_Berserk).m_ttl = SE_Berserk.m_baseTTL; sE_Berserk.speedModifier = 1.2f + 0.006f * num; sE_Berserk.damageModifier = 1.2f + 0.006f * num * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_berserkerBerserk; sE_Berserk.healthAbsorbPercent = 0.2f + 0.002f * num; ((Character)player).GetSEMan().AddStatusEffect((StatusEffect)(object)sE_Berserk, false, 0, 0f); ((Character)player).RaiseSkill(ValheimLegends.AlterationSkill, VL_Utility.GetBerserkSkillGain(player)); } else { ((Character)player).Message((MessageType)1, "Not enough stamina for Berserk: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetBerserkCost(player) + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else { if (!VL_Utility.Ability1_Input_Down) { return; } if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability1_CD")) { if (player.GetStamina() > VL_Utility.GetExecuteCost(player)) { StatusEffect val3 = (StatusEffect)(object)(SE_Ability1_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability1_CD)); val3.m_ttl = VL_Utility.GetExecuteCooldown(player); ((Character)player).GetSEMan().AddStatusEffect(val3, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetExecuteCost(player), false); player.StartEmote("point", true); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_backstab"), ((Character)player).GetCenterPoint(), Quaternion.identity); float num2 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.DisciplineSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddPhysicDamage() / 40f + LevelSystem.Instance.getAddAttackSpeed() / 40f, 0f, 0.5f)); SE_Execute sE_Execute = (SE_Execute)(object)ScriptableObject.CreateInstance(typeof(SE_Execute)); sE_Execute.hitCount = Mathf.RoundToInt(3f + 0.04f * num2); sE_Execute.damageBonus = 1.4f + 0.005f * num2 * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_berserkerExecute; sE_Execute.staggerForce = 1.5f + 0.005f * num2; if (((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Execute")) { StatusEffect statusEffect = ((Character)player).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("SE_VL_Execute")); ((Character)player).GetSEMan().RemoveStatusEffect(statusEffect, false); } ((Character)player).GetSEMan().AddStatusEffect((StatusEffect)(object)sE_Execute, false, 0, 0f); ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetExecuteSkillGain(player)); } else { ((Character)player).Message((MessageType)1, "Not enough stamina for Execute: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetExecuteCost(player) + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } } } public class Class_Druid { private static int Script_Layermask = LayerMask.GetMask(new string[11] { "Default", "static_solid", "Default_small", "piece_nonsolid", "terrain", "vehicle", "piece", "viewblock", "character", "character_net", "character_ghost" }); private static GameObject GO_CastFX; private static GameObject GO_Root; private static Projectile P_Root; private static StatusEffect SE_Root; private static GameObject GO_RootDefender; private static int rootCount; private static int rootTotal; private static int rootCountTrigger; public static void Process_Input(Player player, float altitude) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_077a: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0183: 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_0192: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Unknown result type (might be due to invalid IL or missing references) //IL_07c7: Unknown result type (might be due to invalid IL or missing references) //IL_07cc: Unknown result type (might be due to invalid IL or missing references) //IL_07cf: Unknown result type (might be due to invalid IL or missing references) //IL_07d5: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Unknown result type (might be due to invalid IL or missing references) //IL_0807: Unknown result type (might be due to invalid IL or missing references) //IL_0811: Unknown result type (might be due to invalid IL or missing references) //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_081b: Unknown result type (might be due to invalid IL or missing references) //IL_081d: Unknown result type (might be due to invalid IL or missing references) //IL_0824: Expected O, but got Unknown //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_0858: Unknown result type (might be due to invalid IL or missing references) //IL_085f: Unknown result type (might be due to invalid IL or missing references) //IL_0864: Unknown result type (might be due to invalid IL or missing references) //IL_086c: Unknown result type (might be due to invalid IL or missing references) //IL_0878: Unknown result type (might be due to invalid IL or missing references) //IL_087d: Unknown result type (might be due to invalid IL or missing references) //IL_0887: Unknown result type (might be due to invalid IL or missing references) //IL_08ae: Unknown result type (might be due to invalid IL or missing references) //IL_07fd: Unknown result type (might be due to invalid IL or missing references) //IL_0901: Unknown result type (might be due to invalid IL or missing references) //IL_0906: Unknown result type (might be due to invalid IL or missing references) //IL_091a: Unknown result type (might be due to invalid IL or missing references) //IL_091c: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_09fc: Unknown result type (might be due to invalid IL or missing references) //IL_0a20: Unknown result type (might be due to invalid IL or missing references) //IL_0a25: Unknown result type (might be due to invalid IL or missing references) //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_0650: Unknown result type (might be due to invalid IL or missing references) //IL_0655: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_0672: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_067e: Unknown result type (might be due to invalid IL or missing references) //IL_0683: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_0725: Unknown result type (might be due to invalid IL or missing references) //IL_072a: Unknown result type (might be due to invalid IL or missing references) //IL_073e: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_060d: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Unknown result type (might be due to invalid IL or missing references) //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_0a9b: Unknown result type (might be due to invalid IL or missing references) //IL_0aa1: Unknown result type (might be due to invalid IL or missing references) //IL_0aab: Unknown result type (might be due to invalid IL or missing references) //IL_0ab0: Unknown result type (might be due to invalid IL or missing references) //IL_0abb: Unknown result type (might be due to invalid IL or missing references) //IL_0ac5: Unknown result type (might be due to invalid IL or missing references) //IL_0aca: Unknown result type (might be due to invalid IL or missing references) //IL_0acf: Unknown result type (might be due to invalid IL or missing references) //IL_0ad2: Unknown result type (might be due to invalid IL or missing references) //IL_0ade: Unknown result type (might be due to invalid IL or missing references) //IL_0ae4: Unknown result type (might be due to invalid IL or missing references) //IL_0aee: Unknown result type (might be due to invalid IL or missing references) //IL_0af3: Unknown result type (might be due to invalid IL or missing references) //IL_0afe: Unknown result type (might be due to invalid IL or missing references) //IL_0b08: Unknown result type (might be due to invalid IL or missing references) //IL_0b12: Unknown result type (might be due to invalid IL or missing references) //IL_0b17: Unknown result type (might be due to invalid IL or missing references) //IL_0b1c: Unknown result type (might be due to invalid IL or missing references) //IL_0b1f: Unknown result type (might be due to invalid IL or missing references) //IL_0b2b: Unknown result type (might be due to invalid IL or missing references) //IL_0b31: Unknown result type (might be due to invalid IL or missing references) //IL_0b3b: Unknown result type (might be due to invalid IL or missing references) //IL_0b45: Unknown result type (might be due to invalid IL or missing references) //IL_0b4a: Unknown result type (might be due to invalid IL or missing references) //IL_0b4f: Unknown result type (might be due to invalid IL or missing references) //IL_0b52: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_1322: Unknown result type (might be due to invalid IL or missing references) //IL_1327: Unknown result type (might be due to invalid IL or missing references) //IL_134b: Unknown result type (might be due to invalid IL or missing references) //IL_1350: Unknown result type (might be due to invalid IL or missing references) //IL_13de: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Expected O, but got Unknown //IL_054c: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_0b66: Unknown result type (might be due to invalid IL or missing references) //IL_0b6b: Unknown result type (might be due to invalid IL or missing references) //IL_0c7a: Unknown result type (might be due to invalid IL or missing references) //IL_0c7f: Unknown result type (might be due to invalid IL or missing references) //IL_0bfb: Unknown result type (might be due to invalid IL or missing references) //IL_0c00: Unknown result type (might be due to invalid IL or missing references) //IL_0c45: Unknown result type (might be due to invalid IL or missing references) //IL_0c4a: Unknown result type (might be due to invalid IL or missing references) //IL_0c57: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_149a: Unknown result type (might be due to invalid IL or missing references) //IL_0d14: Unknown result type (might be due to invalid IL or missing references) //IL_0d1f: Unknown result type (might be due to invalid IL or missing references) //IL_0d29: Unknown result type (might be due to invalid IL or missing references) //IL_0d2e: Unknown result type (might be due to invalid IL or missing references) //IL_0d34: Unknown result type (might be due to invalid IL or missing references) //IL_0d60: Unknown result type (might be due to invalid IL or missing references) //IL_0d6b: Unknown result type (might be due to invalid IL or missing references) //IL_0d97: Unknown result type (might be due to invalid IL or missing references) //IL_0d9c: Unknown result type (might be due to invalid IL or missing references) //IL_0da1: Unknown result type (might be due to invalid IL or missing references) //IL_0da6: Unknown result type (might be due to invalid IL or missing references) //IL_0da9: Unknown result type (might be due to invalid IL or missing references) //IL_0daa: Unknown result type (might be due to invalid IL or missing references) //IL_0e9f: Unknown result type (might be due to invalid IL or missing references) //IL_103a: Unknown result type (might be due to invalid IL or missing references) //IL_0e7f: Unknown result type (might be due to invalid IL or missing references) //IL_0e84: Unknown result type (might be due to invalid IL or missing references) //IL_0e4a: Unknown result type (might be due to invalid IL or missing references) //IL_0e4f: Unknown result type (might be due to invalid IL or missing references) //IL_0e5c: Unknown result type (might be due to invalid IL or missing references) //IL_1134: Unknown result type (might be due to invalid IL or missing references) //IL_1139: Unknown result type (might be due to invalid IL or missing references) //IL_11b5: Unknown result type (might be due to invalid IL or missing references) //IL_11ba: Unknown result type (might be due to invalid IL or missing references) //IL_11da: Unknown result type (might be due to invalid IL or missing references) //IL_11df: Unknown result type (might be due to invalid IL or missing references) new Random(); Vector3 val = default(Vector3); if (VL_Utility.Ability3_Input_Down) { if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability3_CD")) { ValheimLegends.shouldUseGuardianPower = false; if (player.GetStamina() >= VL_Utility.GetRootCost && !ValheimLegends.isChanneling) { ValheimLegends.isChanneling = true; StatusEffect val2 = (StatusEffect)(object)(SE_Ability3_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability3_CD)); val2.m_ttl = VL_Utility.GetRootCooldownTime; ((Character)player).GetSEMan().AddStatusEffect(val2, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetRootCost, false); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Player.m_localPlayer)).SetTrigger("gpower"); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Player.m_localPlayer)).SetSpeed(0.3f); float num = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.ConjurationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddStamina() / 200f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); rootCount = 0; rootCountTrigger = 32 - Mathf.RoundToInt(0.12f * num); rootTotal = 0; Vector3 val3 = ((Component)player).transform.right * 2.5f; if (Random.Range(0f, 1f) < 0.5f) { val3 *= -1f; } val = ((Component)player).transform.position + ((Component)player).transform.up * 3f + ((Character)player).GetLookDir() * 2f + val3; GO_Root = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("gdking_root_projectile"), new Vector3(val.x, val.y, val.z), Quaternion.identity); P_Root = GO_Root.GetComponent<Projectile>(); ((Object)P_Root).name = "Root"; P_Root.m_respawnItemOnHit = false; P_Root.m_spawnOnHit = null; P_Root.m_ttl = 35f; P_Root.m_gravity = 0f; P_Root.m_rayRadius = 0.1f; Traverse.Create((object)P_Root).Field("m_skill").SetValue((object)ValheimLegends.ConjurationSkill); ((Component)P_Root).transform.localRotation = Quaternion.LookRotation(((Character)player).GetLookDir()); GO_Root.transform.localScale = Vector3.one * 1.5f; ((Character)player).RaiseSkill(ValheimLegends.ConjurationSkill, VL_Utility.GetRootSkillGain); } else { ((Character)player).Message((MessageType)1, "Not enough stamina to channel Root: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetRootCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else if (VL_Utility.Ability3_Input_Pressed && player.GetStamina() > VL_Utility.GetRootCostPerUpdate && ValheimLegends.isChanneling && Mathf.Max(0f, altitude - ((Component)player).transform.position.y) <= 2f) { rootCount++; VL_Utility.SetTimer(); ((Character)player).UseStamina(VL_Utility.GetRootCostPerUpdate * (float)rootTotal, false); ValheimLegends.isChanneling = true; if (rootCount < rootCountTrigger) { return; } ((Character)player).RaiseSkill(ValheimLegends.ConjurationSkill, 0.06f); float num2 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.ConjurationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddStamina() / 200f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); rootCount = 0; if ((Object)(object)GO_Root != (Object)null && (Object)(object)GO_Root.transform != (Object)null) { RaycastHit val4 = default(RaycastHit); Vector3 position = ((Component)player).transform.position; Vector3 val5 = ((!Physics.Raycast(((Character)player).GetEyePoint(), ((Character)player).GetLookDir(), ref val4, float.PositiveInfinity, Script_Layermask) || !Object.op_Implicit((Object)(object)((RaycastHit)(ref val4)).collider)) ? (position + ((Character)player).GetLookDir() * 1000f) : ((RaycastHit)(ref val4)).point); HitData val6 = new HitData(); val6.m_damage.m_pierce = Random.Range(10f + 0.6f * num2, 15f + 1.2f * num2) * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_druidVines; val6.m_pushForce = 2f; rootTotal++; Vector3 val7 = Vector3.MoveTowards(GO_Root.transform.position, val5, 1f); if ((Object)(object)P_Root != (Object)null && ((Object)P_Root).name == "Root") { P_Root.Setup((Character)(object)player, (val7 - GO_Root.transform.position) * 75f, -1f, val6, (ItemData)null, (ItemData)null); Traverse.Create((object)P_Root).Field("m_skill").SetValue((object)ValheimLegends.ConjurationSkill); } } GO_Root = null; Vector3 val8 = ((Component)player).transform.right * 2.5f; if (Random.Range(0f, 1f) < 0.5f) { val8 *= -1f; } val = ((Component)player).transform.position + ((Component)player).transform.up * 3f + ((Character)player).GetLookDir() * 2f + val8; GO_Root = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("gdking_root_projectile"), new Vector3(val.x, val.y, val.z), Quaternion.identity); P_Root = GO_Root.GetComponent<Projectile>(); ((Object)P_Root).name = "Root"; P_Root.m_respawnItemOnHit = false; P_Root.m_spawnOnHit = null; P_Root.m_ttl = rootCountTrigger + 1; P_Root.m_gravity = 0f; P_Root.m_rayRadius = 0.1f; Traverse.Create((object)P_Root).Field("m_skill").SetValue((object)ValheimLegends.ConjurationSkill); ((Component)P_Root).transform.localRotation = Quaternion.LookRotation(((Character)player).GetLookDir()); GO_Root.transform.localScale = Vector3.one * 1.5f; } else if (((VL_Utility.Ability3_Input_Up || player.GetStamina() <= VL_Utility.GetRootCostPerUpdate) && ValheimLegends.isChanneling) || Mathf.Max(0f, altitude - ((Component)player).transform.position.y) > 2f) { if ((Object)(object)GO_Root != (Object)null && (Object)(object)GO_Root.transform != (Object)null) { RaycastHit val9 = default(RaycastHit); Vector3 position2 = ((Component)player).transform.position; Vector3 val10 = ((!Physics.Raycast(((Character)player).GetEyePoint(), ((Character)player).GetLookDir(), ref val9, float.PositiveInfinity, Script_Layermask) || !Object.op_Implicit((Object)(object)((RaycastHit)(ref val9)).collider)) ? (position2 + ((Character)player).GetLookDir() * 1000f) : ((RaycastHit)(ref val9)).point); HitData val11 = new HitData(); val11.m_damage.m_pierce = 10f; val11.m_pushForce = 10f; val11.SetAttacker((Character)(object)player); Vector3 val12 = Vector3.MoveTowards(GO_Root.transform.position, val10, 1f); P_Root.Setup((Character)(object)player, (val12 - GO_Root.transform.position) * 65f, -1f, val11, (ItemData)null, (ItemData)null); Traverse.Create((object)P_Root).Field("m_skill").SetValue((object)ValheimLegends.ConjurationSkill); } rootTotal = 0; GO_Root = null; ValheimLegends.isChanneling = false; } else if (VL_Utility.Ability2_Input_Down) { if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability2_CD")) { if (player.GetStamina() >= VL_Utility.GetDefenderCost) { Vector3 lookDir = ((Character)player).GetLookDir(); lookDir.y = 0f; ((Component)player).transform.rotation = Quaternion.LookRotation(lookDir); ValheimLegends.shouldUseGuardianPower = false; StatusEffect val13 = (StatusEffect)(object)(SE_Ability2_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability2_CD)); val13.m_ttl = VL_Utility.GetDefenderCooldownTime; ((Character)player).GetSEMan().AddStatusEffect(val13, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetDefenderCost, false); float num3 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.ConjurationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddStamina() / 200f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Player.m_localPlayer)).SetTrigger("gpower"); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_WishbonePing"), ((Component)player).transform.position, Quaternion.identity); GameObject prefab = ZNetScene.instance.GetPrefab("TentaRoot"); CharacterTimedDestruction component = prefab.GetComponent<CharacterTimedDestruction>(); if ((Object)(object)component != (Object)null) { component.m_timeoutMin = 24f + 0.3f * num3; component.m_timeoutMax = component.m_timeoutMin; component.m_triggerOnAwake = true; ((Behaviour)component).enabled = true; } List<Vector3> list = new List<Vector3>(); list.Clear(); val = ((Component)player).transform.position + ((Character)player).GetLookDir() * 5f + ((Component)player).transform.right * 5f; list.Add(val); val = ((Component)player).transform.position + ((Character)player).GetLookDir() * 5f + ((Component)player).transform.right * 5f * -1f; list.Add(val); val = ((Component)player).transform.position + ((Character)player).GetLookDir() * 5f * -1f; list.Add(val); for (int i = 0; i < list.Count; i++) { GO_RootDefender = Object.Instantiate<GameObject>(prefab, list[i], Quaternion.identity); Character component2 = GO_RootDefender.GetComponent<Character>(); if ((Object)(object)component2 != (Object)null) { SE_RootsBuff sE_RootsBuff = (SE_RootsBuff)(object)ScriptableObject.CreateInstance(typeof(SE_RootsBuff)); ((StatusEffect)sE_RootsBuff).m_ttl = SE_RootsBuff.m_baseTTL; sE_RootsBuff.damageModifier = 0.5f + 0.015f * num3 * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_druidDefenders; sE_RootsBuff.staminaRegen = 0.5f + 0.05f * num3; sE_RootsBuff.summoner = player; sE_RootsBuff.centerPoint = ((Component)player).transform.position; component2.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_RootsBuff, false, 0, 0f); component2.SetMaxHealth(30f + 6f * num3); ((Component)component2).transform.localScale = (0.75f + 0.005f * num3) * Vector3.one; component2.m_faction = (Faction)0; component2.SetTamed(true); } Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_Potion_stamina_medium"), ((Component)component2).transform.position, Quaternion.identity); } GameObject prefab2 = ZNetScene.instance.GetPrefab("VL_Deathsquit"); CharacterTimedDestruction component3 = prefab2.GetComponent<CharacterTimedDestruction>(); if ((Object)(object)component3 != (Object)null) { component3.m_timeoutMin = 24f + 0.3f * num3; component3.m_timeoutMax = component3.m_timeoutMin; component3.m_triggerOnAwake = true; ((Behaviour)component3).enabled = true; } int num4 = 2 + Mathf.RoundToInt(0.05f * num3); for (int j = 0; j < num4; j++) { val = ((Component)player).transform.position + ((Component)player).transform.up * 4f + (((Character)player).GetLookDir() * Random.Range(0f - (5f + 0.1f * num3), 5f + 0.1f * num3) + ((Component)player).transform.right * Random.Range(0f - (5f + 0.1f * num3), 5f + 0.1f * num3)); Character component4 = Object.Instantiate<GameObject>(prefab2, val, Quaternion.identity).GetComponent<Character>(); component4.m_name = "Drusquito"; if ((Object)(object)component4 != (Object)null) { SE_Companion sE_Companion = (SE_Companion)(object)ScriptableObject.CreateInstance(typeof(SE_Companion)); ((StatusEffect)sE_Companion).m_ttl = 60f; sE_Companion.damageModifier = 0.05f + 0.0075f * num3 * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_druidDefenders; sE_Companion.summoner = player; component4.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_Companion, false, 0, 0f); ((Component)component4).transform.localScale = (0.4f + 0.005f * num3) * Vector3.one; component4.m_faction = (Faction)0; component4.SetTamed(true); } Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_float_hitwater"), ((Component)component4).transform.position, Quaternion.identity); } ((Character)player).RaiseSkill(ValheimLegends.ConjurationSkill, VL_Utility.GetDefenderSkillGain); } else { ((Character)player).Message((MessageType)1, "Not enough stamina to summon root defenders: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetDefenderCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else if (VL_Utility.Ability1_Input_Down) { if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability1_CD")) { if (((Character)player).IsBlocking()) { if (((Humanoid)player).GetInventory() == null) { return; } ItemData val14 = null; ItemData val15 = null; ItemDrop val16 = null; ItemDrop[] array = Resources.FindObjectsOfTypeAll(typeof(ItemDrop)) as ItemDrop[]; foreach (ItemDrop val17 in array) { if (val17.m_itemData.m_shared.m_name.ToLower().Contains("spirit binding vial")) { val16 = val17; break; } } for (int l = 0; l < ((Humanoid)player).GetInventory().GetHeight(); l++) { if (val15 != null) { break; } for (int m = 0; m < ((Humanoid)player).GetInventory().GetWidth(); m++) { val14 = ((Humanoid)player).GetInventory().GetItemAt(m, l); if (val14 != null) { if (val14.m_shared.m_name == "$item_ancientseed") { val15 = val14; } if (val15 != null) { break; } } } } if (val15 == null) { ((Character)player).Message((MessageType)1, "You need an Ancient Seed to create a Spirit Binding Vial.", 0, (Sprite)null); } else if (player.GetStamina() >= VL_Utility.GetRegenerationCost) { ((Character)player).RaiseSkill(ValheimLegends.AlterationSkill, VL_Utility.GetRegenerationSkillGain); StatusEffect val18 = (StatusEffect)(object)(SE_Ability1_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability1_CD)); float num5 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.AlterationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddCriticalChance() / 40f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); val18.m_ttl = VL_Utility.GetHealCooldownTime * 20f / (1f + num5 / 150f); ((Character)player).GetSEMan().AddStatusEffect(val18, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetRegenerationCost, false); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Humanoid)localPlayer).GetInventory().RemoveOneItem(val15); } ItemDrop.DropItem(val16.m_itemData, 1, ((Component)player).transform.position, Quaternion.identity); player.StartEmote("cheer", true); ((Character)player).Message((MessageType)1, "Consumed 1 " + val15.m_shared.m_name + " to create a " + val16.m_itemData.m_shared.m_name + ".", 0, (Sprite)null); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_Potion_stamina_medium"), ((Component)player).transform.position, Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_WishbonePing"), ((Component)player).transform.position, Quaternion.identity); } else { ((Character)player).Message((MessageType)1, "Not enough stamina to Create Spirit Binding Vial: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetHealCost.ToString("#.#") + ")", 0, (Sprite)null); } } else if (player.GetStamina() >= VL_Utility.GetRegenerationCost) { StatusEffect val19 = (StatusEffect)(object)(SE_Ability1_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability1_CD)); val19.m_ttl = VL_Utility.GetRegenerationCooldownTime; ((Character)player).GetSEMan().AddStatusEffect(val19, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetRegenerationCost, false); float num6 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.AlterationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddCriticalChance() / 40f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); player.StartEmote("cheer", true); GO_CastFX = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_guardstone_permitted_add"), ((Character)player).GetCenterPoint(), Quaternion.identity); GO_CastFX = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_WishbonePing"), ((Component)player).transform.position, Quaternion.identity); SE_Regeneration sE_Regeneration = (SE_Regeneration)(object)ScriptableObject.CreateInstance(typeof(SE_Regeneration)); ((StatusEffect)sE_Regeneration).m_ttl = SE_Regeneration.m_baseTTL; ((StatusEffect)sE_Regeneration).m_icon = ZNetScene.instance.GetPrefab("TrophyGreydwarfShaman").GetComponent<ItemDrop>().m_itemData.GetIcon(); sE_Regeneration.m_HealAmount = 0.5f + 0.4f * num6 * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_druidRegen; sE_Regeneration.doOnce = false; List<Character> list2 = new List<Character>(); list2.Clear(); Character.GetCharactersInRange(((Character)player).GetCenterPoint(), 30f + 0.2f * num6, list2); foreach (Character item in list2) { if (!BaseAI.IsEnemy((Character)(object)player, item)) { if ((Object)(object)item == (Object)(object)Player.m_localPlayer) { item.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_Regeneration, true, 0, 0f); } else if (item.IsPlayer()) { item.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode(((Object)sE_Regeneration).name), true, 0, 0f); } else { item.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_Regeneration, true, 0, 0f); } } } ((Character)player).RaiseSkill(ValheimLegends.AlterationSkill, VL_Utility.GetRegenerationSkillGain); } else { ((Character)player).Message((MessageType)1, "Not enough stamina to for Regeneration: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetRegenerationCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else { ValheimLegends.isChanneling = false; } } } public class Class_Duelist { private static int ScriptChar_Layermask = LayerMask.GetMask(new string[11] { "Default", "static_solid", "Default_small", "piece_nonsolid", "terrain", "vehicle", "piece", "viewblock", "character", "character_net", "character_ghost" }); private static GameObject GO_CastFX; private static GameObject GO_QuickShot; private static Projectile P_QuickShot; public static ItemDrop coinsItem; public static List<int> challengedDeath = new List<int>(); public static List<int> challengedMastery = new List<int>(); public static void Execute_Slash(Player player) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_VL_BlinkStrike"), ((Character)player).GetCenterPoint() + ((Character)player).GetLookDir() * 3f, Quaternion.LookRotation(((Character)player).GetLookDir())); float num = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.DisciplineSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddPhysicDamage() / 40f + LevelSystem.Instance.getAddAttackSpeed() / 40f, 0f, 0.5f)); float num2 = (1.25f + num / 300f) * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_duelistSeismicSlash; Vector3 val = ((Character)player).GetEyePoint() + ((Character)player).GetLookDir() * 6f; List<Character> list = new List<Character>(); list.Clear(); Character.GetCharactersInRange(val, 6f, list); foreach (Character item in list) { if (!BaseAI.IsEnemy((Character)(object)player, item) || !VL_Utility.LOS_IsValid(item, val, val)) { continue; } _ = ((Component)item).transform.position - ((Component)player).transform.position; HitData val2 = new HitData(); val2.m_damage = ((Humanoid)player).GetCurrentWeapon().GetDamage(); val2.ApplyModifier(Random.Range(0.8f, 1.2f) * num2); val2.m_pushForce = 25f + 0.1f * num; val2.m_point = item.GetEyePoint(); val2.m_dir = ((Component)player).transform.position - ((Component)item).transform.position; val2.m_skill = ValheimLegends.DisciplineSkill; item.Damage(val2); if (challengedMastery == null || !challengedMastery.Contains(((Object)item).GetInstanceID())) { continue; } challengedMastery.Remove(((Object)item).GetInstanceID()); ItemDrop.DropItem(ValheimLegends.coinsItem.m_itemData, 1, ((Component)player).transform.position, Quaternion.identity); int num3 = Mathf.CeilToInt(Mathf.Sqrt(item.GetMaxHealth()) + (1f + LevelSystem.Instance.getAddCriticalChance() / 40f) * Mathf.Sqrt(item.GetMaxHealth())); if (num3 < LevelSystem.Instance.getLevel()) { Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_coins_destroyed"), ((Character)player).GetCenterPoint(), Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_coin_stack_destroyed"), ((Character)player).GetCenterPoint(), Quaternion.identity); } else { Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_coins_pile_destroyed"), ((Character)player).GetCenterPoint(), Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_coin_pile_destroyed"), ((Character)player).GetCenterPoint(), Quaternion.identity); } ItemDrop[] array = Resources.FindObjectsOfTypeAll(typeof(ItemDrop)) as ItemDrop[]; foreach (ItemDrop val3 in array) { if (val3.m_itemData.m_shared.m_name.ToLower().Contains("$item_wood")) { break; } } if (((Humanoid)player).GetInventory().CanAddItem(ValheimLegends.coinsItem.m_itemData.m_dropPrefab, num3)) { ((Humanoid)player).GetInventory().AddItem(ValheimLegends.coinsItem.m_itemData.m_dropPrefab, num3); } else { ItemDrop.DropItem(ValheimLegends.coinsItem.m_itemData, num3, ((Component)player).transform.position, Quaternion.identity); } ((Character)player).Message((MessageType)1, "Spoiled " + num3.ToString("#") + " coins from " + item.GetHoverName() + "!", 0, (Sprite)null); } } public static void Process_Input(Player player, ref Rigidbody playerBody) { //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Invalid comparison between Unknown and I4 //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Invalid comparison between Unknown and I4 //IL_072a: Unknown result type (might be due to invalid IL or missing references) //IL_0736: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Invalid comparison between Unknown and I4 //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Invalid comparison between Unknown and I4 //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Invalid comparison between Unknown and I4 //IL_07ef: Unknown result type (might be due to invalid IL or missing references) //IL_07f6: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0e45: Unknown result type (might be due to invalid IL or missing references) //IL_0e69: Unknown result type (might be due to invalid IL or missing references) //IL_0e6e: Unknown result type (might be due to invalid IL or missing references) //IL_0e83: Unknown result type (might be due to invalid IL or missing references) //IL_0e8e: Unknown result type (might be due to invalid IL or missing references) //IL_0e98: Unknown result type (might be due to invalid IL or missing references) //IL_0e9d: Unknown result type (might be due to invalid IL or missing references) //IL_0ea3: Unknown result type (might be due to invalid IL or missing references) //IL_0ead: Unknown result type (might be due to invalid IL or missing references) //IL_0eb2: Unknown result type (might be due to invalid IL or missing references) //IL_0eb7: Unknown result type (might be due to invalid IL or missing references) //IL_0ec9: Unknown result type (might be due to invalid IL or missing references) //IL_0ece: Unknown result type (might be due to invalid IL or missing references) //IL_0ee8: Unknown result type (might be due to invalid IL or missing references) //IL_0eeb: Unknown result type (might be due to invalid IL or missing references) //IL_0ef0: Unknown result type (might be due to invalid IL or missing references) //IL_0f0e: Unknown result type (might be due to invalid IL or missing references) //IL_0f10: Unknown result type (might be due to invalid IL or missing references) //IL_0f9a: Unknown result type (might be due to invalid IL or missing references) //IL_0f9c: Unknown result type (might be due to invalid IL or missing references) //IL_0fa1: Unknown result type (might be due to invalid IL or missing references) //IL_0fc4: Unknown result type (might be due to invalid IL or missing references) //IL_0fd0: Unknown result type (might be due to invalid IL or missing references) //IL_0fd7: Unknown result type (might be due to invalid IL or missing references) //IL_0fdd: Unknown result type (might be due to invalid IL or missing references) //IL_0875: Unknown result type (might be due to invalid IL or missing references) //IL_0881: Unknown result type (might be due to invalid IL or missing references) //IL_100d: Unknown result type (might be due to invalid IL or missing references) //IL_1013: Unknown result type (might be due to invalid IL or missing references) //IL_101d: Unknown result type (might be due to invalid IL or missing references) //IL_1022: Unknown result type (might be due to invalid IL or missing references) //IL_1027: Unknown result type (might be due to invalid IL or missing references) //IL_1029: Unknown result type (might be due to invalid IL or missing references) //IL_1030: Expected O, but got Unknown //IL_108f: Unknown result type (might be due to invalid IL or missing references) //IL_1094: Unknown result type (might be due to invalid IL or missing references) //IL_1099: Unknown result type (might be due to invalid IL or missing references) //IL_109b: Unknown result type (might be due to invalid IL or missing references) //IL_10a2: Unknown result type (might be due to invalid IL or missing references) //IL_10a7: Unknown result type (might be due to invalid IL or missing references) //IL_10af: Unknown result type (might be due to invalid IL or missing references) //IL_10bb: Unknown result type (might be due to invalid IL or missing references) //IL_10c0: Unknown result type (might be due to invalid IL or missing references) //IL_10ca: Unknown result type (might be due to invalid IL or missing references) //IL_10f1: Unknown result type (might be due to invalid IL or missing references) //IL_110e: Unknown result type (might be due to invalid IL or missing references) //IL_1005: Unknown result type (might be due to invalid IL or missing references) //IL_0a61: Unknown result type (might be due to invalid IL or missing references) //IL_0a66: Unknown result type (might be due to invalid IL or missing references) //IL_0a82: Unknown result type (might be due to invalid IL or missing references) //IL_0a87: Unknown result type (might be due to invalid IL or missing references) //IL_0a1d: Unknown result type (might be due to invalid IL or missing references) //IL_0a22: Unknown result type (might be due to invalid IL or missing references) //IL_0a3e: Unknown result type (might be due to invalid IL or missing references) //IL_0a43: Unknown result type (might be due to invalid IL or missing references) //IL_0b80: Unknown result type (might be due to invalid IL or missing references) new Random(); if (VL_Utility.Ability3_Input_Down) { if (challengedDeath == null) { challengedDeath = new List<int>(); challengedDeath.Clear(); } if (challengedDeath.Count > 50) { challengedDeath.Clear(); } if (challengedMastery == null) { challengedMastery = new List<int>(); challengedMastery.Clear(); } if (challengedMastery.Count > 50) { challengedMastery.Clear(); } if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability3_CD")) { if (((Character)player).IsBlocking()) { if (Traverse.Create((object)player).Field("m_leftItem").GetValue<ItemData>() == null && ((Humanoid)player).GetCurrentWeapon() != null && (int)((Humanoid)player).GetCurrentWeapon().m_shared.m_itemType != 14 && ((int)((Humanoid)player).GetCurrentWeapon().m_shared.m_skillType == 1 || (int)((Humanoid)player).GetCurrentWeapon().m_shared.m_skillType == 2 || (int)((Humanoid)player).GetCurrentWeapon().m_shared.m_skillType == 7 || (int)((Humanoid)player).GetCurrentWeapon().m_shared.m_skillType == 5)) { float num = ((Humanoid)player).GetCurrentWeapon().GetMaxDurability() * (1f - ((Humanoid)player).GetCurrentWeapon().GetDurabilityPercentage()); if (num > 0f) { float num2 = num * 4f * (1f - LevelSystem.Instance.getStaminaReduction() / 100f); float num3 = num; if (player.GetStamina() < num2) { num3 = player.GetStamina() / (4f * (1f - LevelSystem.Instance.getStaminaReduction() / 100f)); } float num4 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.DisciplineSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddPhysicDamage() / 40f + LevelSystem.Instance.getAddAttackSpeed() / 40f, 0f, 0.5f)); StatusEffect val = (StatusEffect)(object)(SE_Ability3_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability3_CD)); val.m_ttl = 60f + num3 * 2f * (1f - LevelSystem.Instance.getAddCriticalChance() / 40f); ((Character)player).GetSEMan().AddStatusEffect(val, false, 0, 0f); ((Character)player).UseStamina(num3 * 10f * (1f - LevelSystem.Instance.getAddCriticalChance() / 40f) * (1f - num4 / 300f), false); ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); currentWeapon.m_durability += num3; Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_VL_BlinkStrike"), ((Character)player).GetCenterPoint() + ((Character)player).GetLookDir() * 3f, Quaternion.LookRotation(((Character)player).GetLookDir())); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(player)).SetTrigger("knife_stab1"); ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetBlinkStrikeSkillGain); } else { ((Character)player).Message((MessageType)1, "You don't need to Sharpen you weapon.", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "You can only Sharpen an equipped bladed single one-handed weapon (swords, knives, axes or spears).", 0, (Sprite)null); } } else if (player.GetStamina() >= VL_Utility.GetBlinkStrikeCost) { StatusEffect val2 = (StatusEffect)(object)(SE_Ability3_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability3_CD)); val2.m_ttl = VL_Utility.GetBlinkStrikeCooldownTime; ((Character)player).GetSEMan().AddStatusEffect(val2, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetBlinkStrikeCost, false); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(player)).SetTrigger("knife_stab1"); ValheimLegends.isChanneling = true; ValheimLegends.isChargingDash = true; ValheimLegends.dashCounter = 0; ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetBlinkStrikeSkillGain); } else { ((Character)player).Message((MessageType)1, "Not enough stamina for S. Slash : (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetBlinkStrikeCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else if (VL_Utility.Ability2_Input_Down) { if (challengedDeath == null) { challengedDeath = new List<int>(); challengedDeath.Clear(); } if (challengedDeath.Count > 50) { challengedDeath.Clear(); } if (challengedMastery == null) { challengedMastery = new List<int>(); challengedMastery.Clear(); } if (challengedMastery.Count > 50) { challengedMastery.Clear(); } if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability2_CD")) { if (player.GetStamina() >= VL_Utility.GetRiposteCost) { StatusEffect val3 = (StatusEffect)(object)(SE_Ability2_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability2_CD)); val3.m_ttl = VL_Utility.GetRiposteCooldownTime; ((Character)player).GetSEMan().AddStatusEffect(val3, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetRiposteCost, false); _ = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.DisciplineSkillDef)).m_level; Mathf.Clamp(LevelSystem.Instance.getAddPhysicDamage() / 40f + LevelSystem.Instance.getAddAttackSpeed() / 40f, 0f, 0.5f); GO_CastFX = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_perfectblock"), ((Component)player).transform.position, Quaternion.identity); GO_CastFX = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_backstab"), ((Character)player).GetCenterPoint(), Quaternion.identity); SE_Riposte sE_Riposte = (SE_Riposte)(object)ScriptableObject.CreateInstance(typeof(SE_Riposte)); sE_Riposte.playerBody = playerBody; ((Character)player).GetSEMan().AddStatusEffect((StatusEffect)(object)sE_Riposte, false, 0, 0f); ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetRiposteSkillGain); } else { ((Character)player).Message((MessageType)1, "Not enough stamina for Riposte: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetRiposteCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else if (VL_Utility.Ability1_Input_Down) { if (challengedDeath == null) { challengedDeath = new List<int>(); challengedDeath.Clear(); } if (challengedDeath.Count > 50) { challengedDeath.Clear(); } if (challengedMastery == null) { challengedMastery = new List<int>(); challengedMastery.Clear(); } if (challengedMastery.Count > 50) { challengedMastery.Clear(); } if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability1_CD")) { ValheimLegends.DefineCoins(); if (!((Object)(object)ValheimLegends.coinsItem != (Object)null)) { return; } if (((Character)player).IsBlocking()) { if (!((Character)player).GetSEMan().HaveStatusEffect("SE_VL_Ability1_CD")) { RaycastHit val4 = default(RaycastHit); _ = ((Component)player).transform.position; Physics.SphereCast(((Character)player).GetEyePoint(), 0.2f, ((Character)player).GetLookDir(), ref val4, 200f, ScriptChar_Layermask); VL_Utility.SetTimer(); if ((Object)(object)((RaycastHit)(ref val4)).collider != (Object)null && (Object)(object)((Component)((RaycastHit)(ref val4)).collider).gameObject != (Object)null) { Character val5 = null; ((Component)((RaycastHit)(ref val4)).collider).gameObject.TryGetComponent<Character>(ref val5); bool flag = (Object)(object)val5 != (Object)null; List<Component> list = new List<Component>(); list.Clear(); ((Component)((RaycastHit)(ref val4)).collider).gameObject.GetComponents<Component>(list); if ((Object)(object)val5 == (Object)null) { val5 = (Character)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent(typeof(Character)); flag = (Object)(object)val5 != (Object)null; if ((Object)(object)val5 == (Object)null) { val5 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInChildren<Character>(); flag = (Object)(object)val5 != (Object)null; } } if (flag && !val5.IsPlayer()) { if ((challengedDeath != null && !challengedDeath.Contains(((Object)val5).GetInstanceID())) || (challengedMastery != null && !challengedMastery.Contains(((Object)val5).GetInstanceID()))) { if (Vector3.Distance(((Component)player).transform.position, ((Component)val5).transform.position) <= 70f) { if (player.GetStamina() >= VL_Utility.GetQuickShotCost) { int num5 = Mathf.CeilToInt(Mathf.Sqrt(val5.GetMaxHealth())); if (((Humanoid)player).GetInventory() != null && ((Humanoid)player).GetInventory().HaveItem(ValheimLegends.coinsItem.m_itemData.m_shared.m_name, true) && ((Humanoid)player).GetInventory().CountItems("$item_coins", -1, true) >= num5) { ItemData val6 = null; ItemData val7 = null; for (int i = 0; i < ((Humanoid)player).GetInventory().GetHeight(); i++) { if (val7 != null) { break; } for (int j = 0; j < ((Humanoid)player).GetInventory().GetWidth(); j++) { val6 = ((Humanoid)player).GetInventory().GetItemAt(j, i); if (val6 != null) { if (val6.m_shared.m_name == "$item_coins" && ((Humanoid)player).GetInventory().GetItemAt(j, i).m_stack >= num5) { val7 = val6; } if (val7 != null) { break; } } } } for (int k = 0; k < num5; k++) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Humanoid)localPlayer).GetInventory().RemoveOneItem(val7); } } StatusEffect val8 = (StatusEffect)(object)(SE_Ability1_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability1_CD)); val8.m_ttl = VL_Utility.GetQuickShotCooldownTime * 4f; ((Character)player).GetSEMan().AddStatusEffect(val8, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetQuickShotCost, false); if (num5 < LevelSystem.Instance.getLevel()) { Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_coins_destroyed"), val5.GetCenterPoint(), Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_coin_stack_destroyed"), val5.GetCenterPoint(), Quaternion.identity); } else { Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_coins_pile_destroyed"), val5.GetCenterPoint(), Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_coin_pile_destroyed"), val5.GetCenterPoint(), Quaternion.identity); } player.StartEmote("point", true); ((Character)player).Message((MessageType)1, "Challenged " + val5.GetHoverName() + " to a duel worth of " + num5.ToString("#") + " coins!", 0, (Sprite)null); if (val5.IsOwner()) { if (Random.value < 0.33f) { ((Character)player).Message((MessageType)2, "Duel of Mastery!", 1, ValheimLegends.RiposteIcon); challengedMastery.Add(((Object)val5).GetInstanceID()); } else { ((Character)player).Message((MessageType)2, "Duel to the Death!", 1, ZNetScene.instance.GetPrefab("TrophySkeleton").GetComponent<ItemDrop>().m_itemData.GetIcon()); challengedDeath.Add(((Object)val5).GetInstanceID()); } } else { ((Character)player).Message((MessageType)2, "Duel of Mastery!", 1, ValheimLegends.RiposteIcon); challengedMastery.Add(((Object)val5).GetInstanceID()); } ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetQuickShotSkillGain); } else { ((Character)player).Message((MessageType)1, "You need " + num5.ToString("#") + " coins to challenge " + val5.GetHoverName() + ".", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Not enough stamina for Challenge: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetBackstabCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, val5.GetHoverName() + " is too far away to challenge!", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, val5.GetHoverName() + " was already challenged!", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Invalid target", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "No target", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else if (player.GetStamina() >= VL_Utility.GetQuickShotCost) { if (((Humanoid)player).GetInventory() != null && ((Humanoid)player).GetInventory().HaveItem(ValheimLegends.coinsItem.m_itemData.m_shared.m_name, true)) { ItemData val9 = null; ItemData val10 = null; for (int l = 0; l < ((Humanoid)player).GetInventory().GetHeight(); l++) { if (val10 != null) { break; } for (int m = 0; m < ((Humanoid)player).GetInventory().GetWidth(); m++) { val9 = ((Humanoid)player).GetInventory().GetItemAt(m, l); if (val9 != null) { if (val9.m_shared.m_name == "$item_coins" && ((Humanoid)player).GetInventory().GetItemAt(m, l).m_stack >= 0) { val10 = val9; } if (val10 != null) { break; } } } } Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Humanoid)localPlayer2).GetInventory().RemoveOneItem(val10); } float num6 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.DisciplineSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddPhysicDamage() / 40f + LevelSystem.Instance.getAddAttackSpeed() / 40f, 0f, 0.5f)); StatusEffect val11 = (StatusEffect)(object)(SE_Ability1_CD)(object)ScriptableObject.CreateInstance(typeof(SE_Ability1_CD)); val11.m_ttl = VL_Utility.GetQuickShotCooldownTime; ((Character)player).GetSEMan().AddStatusEffect(val11, false, 0, 0f); ((Character)player).UseStamina(VL_Utility.GetQuickShotCost + 0.5f * num6, false); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(player)).SetTrigger("interact"); GO_CastFX = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_smelter_add"), ((Component)player).transform.position, Quaternion.identity); Vector3 val12 = ((Component)player).transform.position + ((Component)player).transform.up * 1.2f + ((Character)player).GetLookDir() * 0.5f; Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("sfx_coins_destroyed"), ((Character)player).GetCenterPoint(), Quaternion.identity); GO_CastFX = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_VL_QuickShot"), val12, Quaternion.LookRotation(((Character)player).GetLookDir())); GO_QuickShot = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("Greydwarf_throw_projectile"), val12, Quaternion.identity); P_QuickShot = GO_QuickShot.GetComponent<Projectile>(); ((Object)P_QuickShot).name = "QuickShot"; P_QuickShot.m_respawnItemOnHit = false; P_QuickShot.m_spawnOnHit = null; P_QuickShot.m_ttl = 10f; P_QuickShot.m_gravity = 1.2f; P_QuickShot.m_rayRadius = 0.05f; P_QuickShot.m_hitNoise = 20f; ((Component)P_QuickShot).transform.localRotation = Quaternion.LookRotation(((Humanoid)player).GetAimDir(val12)); GO_QuickShot.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f); RaycastHit val13 = default(RaycastHit); Vector3 val14 = ((!Physics.Raycast(((Character)player).GetEyePoint(), ((Character)player).GetLookDir(), ref val13, float.PositiveInfinity, ScriptChar_Layermask) || !Object.op_Implicit((Object)(object)((RaycastHit)(ref val13)).collider)) ? (((Character)player).GetEyePoint() + ((Character)player).GetLookDir() * 1000f) : ((RaycastHit)(ref val13)).point); HitData val15 = new HitData(); val15.m_damage.m_pierce = Random.Range(10f + 1f * (num6 + (float)LevelSystem.Instance.getLevel()), 30f + 2f * (num6 + (float)LevelSystem.Instance.getLevel())) * VL_GlobalConfigs.g_DamageModifer * VL_GlobalConfigs.c_duelistHipShot; val15.m_pushForce = 1f; val15.m_skill = ValheimLegends.DisciplineSkill; Vector3 val16 = Vector3.MoveTowards(val12, val14, 1f); P_QuickShot.Setup((Character)(object)player, (val16 - GO_QuickShot.transform.position) * 100f, -1f, val15, (ItemData)null, (ItemData)null); Traverse.Create((object)P_QuickShot).Field("m_skill").SetValue((object)ValheimLegends.DisciplineSkill); GO_QuickShot = null; VL_Utility.RotatePlayerToTarget(player); ((Character)player).RaiseSkill(ValheimLegends.DisciplineSkill, VL_Utility.GetQuickShotSkillGain); } else { ((Character)player).Message((MessageType)1, "You need one coin to shoot.", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Not enough stamina to for Coin Shot: (" + player.GetStamina().ToString("#.#") + "/" + VL_Utility.GetQuickShotCost + ")", 0, (Sprite)null); } } else { ((Character)player).Message((MessageType)1, "Ability not ready", 0, (Sprite)null); } } else { ValheimLegends.isChanneling = false; } } } public class Class_Enchanter { public enum EnchanterAttackType { Charm = 10, Shock = 8, None = 0 } private static int Script_Layermask = LayerMask.GetMask(new string[8] { "Default", "static_solid", "Default_small", "piece_nonsolid", "terrain", "vehicle", "piece", "viewblock" }); private static int ScriptChar_Layermask = LayerMask.GetMask(new string[14] { "Default", "static_solid", "Default_small", "piece_nonsolid", "piece", "terrain", "vehicle", "viewblock", "character", "character_noenv", "character_trigger", "character_net", "character_ghost", "Water" }); private static bool zonechargeCharging = false; private static float zonechargeCount; private static int zonechargeChargeAmount; private static int zonechargeChargeAmountMax; private static float zonechargeSkillGain = 0f; public static EnchanterAttackType QueuedAttack; public static StatusEffect HasZoneBuffTime(Player p) { foreach (StatusEffect statusEffect in ((Character)p).GetSEMan().GetStatusEffects()) { if (statusEffect.m_name.StartsWith("Biome: ")) { return statusEffect; } } return null; } public static StatusEffect HasEnchantBuff(Character p) { foreach (StatusEffect statusEffect in p.GetSEMan().GetStatusEffects()) { if (statusEffect.m_name.StartsWith("Enchant ")) { return statusEffect; } } return null; } public static StatusEffect HasEnchantWeapon(Character p) { foreach (StatusEffect statusEffect in p.GetSEMan().GetStatusEffects()) { if (statusEffect.m_name.EndsWith(" Weapon")) { return statusEffect; } } return null; } public static StatusEffect HasEnchantArmor(Character p) { foreach (StatusEffect statusEffect in p.GetSEMan().GetStatusEffects()) { if (statusEffect.m_name.EndsWith(" Armor")) { return statusEffect; } } return null; } public static void Execute_Attack(Player player, ref Rigidbody playerBody, ref float altitude) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0336: 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_034a: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: 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_03c1: Expected O, but got Unknown //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) if (QueuedAttack == EnchanterAttackType.Charm) { float num = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.IllusionSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddAttackSpeed() / 40f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); Vector3 val = ((Character)player).GetEyePoint() + ((Component)player).transform.up * 0.1f + ((Character)player).GetLookDir() * 0.5f + ((Component)player).transform.right * 0.25f; GameObject val2 = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("VL_Charm"), val, Quaternion.identity); Projectile component = val2.GetComponent<Projectile>(); ((Object)component).name = "VL_Charm"; component.m_respawnItemOnHit = false; component.m_spawnOnHit = null; component.m_ttl = 30f * VL_GlobalConfigs.c_enchanterCharm; component.m_gravity = 0f; component.m_rayRadius = 0.01f; component.m_aoe = 1f + (float)LevelSystem.Instance.getLevel() * (1f + Mathf.Sqrt(num)) / 600f; ((Component)component).transform.localRotation = Quaternion.LookRotation(((Humanoid)player).GetAimDir(val)); val2.transform.localScale = Vector3.zero; RaycastHit val3 = default(RaycastHit); Vector3 position = ((Component)player).transform.position; Vector3 val4 = ((!Physics.Raycast(val, ((Character)player).GetLookDir(), ref val3, 1000f, ScriptChar_Layermask) || !Object.op_Implicit((Object)(object)((RaycastHit)(ref val3)).collider)) ? (position + ((Character)player).GetLookDir() * 1000f) : ((RaycastHit)(ref val3)).point); HitData val5 = new HitData(); val5.m_skill = ValheimLegends.IllusionSkill; Vector3 val6 = Vector3.MoveTowards(val2.transform.position, val4, 1f); component.Setup((Character)(object)player, (val6 - val2.transform.position) * 40f, -1f, val5, (ItemData)null, (ItemData)null); Traverse.Create((object)component).Field("m_skill").SetValue((object)ValheimLegends.IllusionSkill); } else { if (QueuedAttack != EnchanterAttackType.Shock) { return; } StatusEffect val7 = HasZoneBuffTime(player); if (!((Object)(object)val7 != (Object)null)) { return; } Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("fx_VL_Shock"), ((Character)player).GetEyePoint() + ((Character)player).GetLookDir() * 2.5f + ((Component)player).transform.right * 0.25f, Quaternion.LookRotation(((Character)player).GetLookDir())); float num2 = ((IEnumerable<Skill>)((Character)player).GetSkills().GetSkillList()).FirstOrDefault((Func<Skill, bool>)((Skill x) => x.m_info == ValheimLegends.AlterationSkillDef)).m_level * (1f + Mathf.Clamp(LevelSystem.Instance.getAddCriticalChance() / 40f + LevelSystem.Instance.getAddMagicDamage() / 80f, 0f, 0.5f)); Vector3 val8 = ((Character)player).GetEyePoint() + ((Character)player).GetLookDir() * 4f; List<Character> list = new List<Character>(); list.Clear(); Character.GetCharactersInRange(val8, 4f, list); foreach (Character item in list) { if (BaseAI.IsEnemy((Character)(object)player, item) && VL_Utility.LOS_IsValid(item, val8, val8)) { Vector3 dir = ((Component)item).transform.position - ((Component)player).transform.position; HitData val9 = new HitData(); val9.m_damage.m_lightning = 15f + num2 + val7.m_ttl * Random.Range(0.03f, 0.06f) * (1f + 0.1f * num2) * VL_GlobalConfigs.c_enchanterBiomeShock; val9.m_pushForce = 0f; val9.m_point = item.GetEyePoint(); val9.m_dir = dir; val9.m_skill = ValheimLegends.AlterationSkill; item.Damage(val9); item.Stagger(val9.m_dir); } } if (((Object)val7).name == "SE_VL_BiomeAsh") { SE_BiomeAsh sE_BiomeAsh = val7 as SE_BiomeAsh; if ((Object)(object)sE_BiomeAsh.biomeLight != (Object)null) { Object.Destroy((Object)(object)sE_BiomeAsh.biomeLight); } } ((Character)player).GetSEMan().RemoveStatusEffect(val7, false); } } public static void Process_Input(Player player, ref float altitude) { //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Invalid comparison between Unknown and I4 //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Invalid comparison between Unknown and I4 //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_1144: Unknown result type (might be due to invalid IL or missing references) //IL_115a: Unknown result type (might be due to invalid IL or missing references) //IL_0e9f: Unknown result type (might be due to invalid IL or missing references) //IL_0ea4: Unknown result type (might be due to invalid IL or missing references) //IL_06d0: Unknown result type (might be due to invalid IL or missing references) //IL_06d6: Invalid comparison between Unknown and I4 //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_12a0: Unknown result type (might be due to invalid IL or missing references) //IL_12c4: Unknown result type (might be due to invalid IL or missing references) //IL_12c9: Unknown result type (might be due to invalid IL or missing references) //IL_0f5d: Unknown result type (might be due to invalid IL or missing references) //IL_0f62: Unknown result type (might be due to invalid IL or missing references) //IL_07f0: Unknown result type (might be due to invalid IL or missing references) //IL_07f6: Invalid comparison between Unknown and I4 //IL_165d: Unknown result type (might be due to invalid IL or missing references) //IL_166e: Unknown result type (might be due to invalid IL or missing references) //IL_167a: Unknown result type (might be due to invalid IL or missing references) //IL_167f: Unknown r
BepInEx/plugins/UsefulTrophiesXP.dll
Decompiled 9 months agousing System.CodeDom.Compiler; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using EpicMMOSystem; using HarmonyLib; using UnityEngine; using ValheimLegends; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ClassLibrary1")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ClassLibrary1")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("fba93479-93ac-43d9-8ef2-cfb83bdb7b6d")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.1.1.0")] namespace UsefulTrophiesXP { [HarmonyPatch(typeof(Humanoid), "UseItem")] internal class UseItemPatch { public static bool Prefix(Player __instance, [HarmonyArgument(0)] Inventory inventory, [HarmonyArgument(1)] ItemData item, [HarmonyArgument(2)] bool fromInventoryGui, Inventory ___m_inventory, ZSyncAnimation ___m_zanim) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) string name = item.m_shared.m_name; if (name.Contains("$item_trophy_")) { string text = name.Substring(13); if (inventory == null) { inventory = ___m_inventory; } if (!inventory.ContainsItem(item)) { return false; } GameObject hoverObject = ((Humanoid)__instance).GetHoverObject(); if (!((Object)(object)hoverObject == (Object)null) && !fromInventoryGui) { Interactable componentInParent = hoverObject.GetComponentInParent<Interactable>(); if (componentInParent is ItemStand || componentInParent is OfferingBowl) { return true; } } float num = 10f; if (UsefulTrophiesXP.TrophyXPDict.TryGetValue(text, out var value)) { num = value * UsefulTrophiesXP.ExperienceModifier; } else { Debug.Log((object)("Unknown trophy for " + text + "!")); } inventory.RemoveOneItem(item); Player.m_localPlayer.m_skillLevelupEffects.Create(((Character)Player.m_localPlayer).GetHeadPoint(), Quaternion.identity, (Transform)null, 1f, -1); ValheimLegends.shouldUseGuardianPower = false; ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Player.m_localPlayer)).SetSpeed(2f); ((ZSyncAnimation)typeof(Player).GetField("m_zanim", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Player.m_localPlayer)).SetTrigger("gpower"); LevelSystem.Instance.AddExp((int)num, false); ((Character)__instance).Message((MessageType)1, $"Experience received: {num}", 0, (Sprite)null); return false; } return true; } } [BepInPlugin("gg.khairex.usefultrophies.twentyonez.EpicMMOPatch", "Useful Trophies Mod by Khairex, EpicMMO XP Patch by TwentyOneZ", "2.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] public class UsefulTrophiesXP : BaseUnityPlugin { public const string Id = "gg.khairex.usefultrophies.twentyonez.EpicMMOPatch"; public static bool EnableSellingTrophies = true; public static float ExperienceModifier = 1f; public static Dictionary<string, float> TrophyXPDict = new Dictionary<string, float> { { "deer", 40f }, { "boar", 133f }, { "neck", 400f }, { "greydwarf", 1200f }, { "greydwarfbrute", 1500f }, { "greydwarfshaman", 1200f }, { "skeleton", 800f }, { "skeletonpoison", 1500f }, { "troll", 1000f }, { "surtling", 2600f }, { "leech", 1800f }, { "draugr", 1500f }, { "draugrelite", 5000f }, { "blob", 1800f }, { "wraith", 5000f }, { "abomination", 200f }, { "wolf", 3500f }, { "fenring", 4000f }, { "hatchling", 3000f }, { "sgolem", 14000f }, { "ulv", 4000f }, { "cultist", 4000f }, { "goblin", 4500f }, { "goblinbrute", 13000f }, { "goblinshaman", 4000f }, { "lox", 7000f }, { "growth", 6000f }, { "deathsquito", 6000f }, { "serpent", 1500f }, { "hare", 400f }, { "gjall", 3600f }, { "tick", 4800f }, { "dvergr", 6000f }, { "seeker", 18000f }, { "seekerbrute", 25000f }, { "eikthyr", 200f }, { "elder", 500f }, { "bonemass", 900f }, { "dragonqueen", 1400f }, { "goblinking", 3000f }, { "seekerqueen", 4500f } }; public static Dictionary<string, int> TrophyGoldValueDict = new Dictionary<string, int> { { "deer", 15 }, { "boar", 10 }, { "neck", 10 }, { "greydwarf", 10 }, { "greydwarfbrute", 15 }, { "greydwarfshaman", 15 }, { "skeleton", 10 }, { "skeletonpoison", 15 }, { "troll", 50 }, { "surtling", 15 }, { "leech", 15 }, { "draugr", 15 }, { "draugrelite", 30 }, { "blob", 20 }, { "wraith", 30 }, { "abomination", 100 }, { "wolf", 25 }, { "fenring", 30 }, { "hatchling", 35 }, { "sgolem", 100 }, { "ulv", 50 }, { "cultist", 50 }, { "goblin", 35 }, { "goblinbrute", 50 }, { "goblinshaman", 50 }, { "lox", 150 }, { "growth", 50 }, { "deathsquito", 25 }, { "serpent", 250 }, { "hare", 40 }, { "gjall", 150 }, { "tick", 50 }, { "dvergr", 30 }, { "seeker", 50 }, { "seekerbrute", 100 }, { "eikthyr", 50 }, { "elder", 100 }, { "bonemass", 150 }, { "dragonqueen", 200 }, { "goblinking", 250 }, { "seekerqueen", 300 } }; public Harmony Harmony { get; } = new Harmony("gg.khairex.usefultrophies.twentyonez.EpicMMOPatch"); private void Awake() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition("GoldValue", "EnableSellingTrophies"); EnableSellingTrophies = ((BaseUnityPlugin)this).Config.Bind<bool>(val, true, (ConfigDescription)null).Value; ConfigDefinition val2 = new ConfigDefinition("XPModifier", "ExperienceModifier"); ExperienceModifier = ((BaseUnityPlugin)this).Config.Bind<float>(val2, 1f, (ConfigDescription)null).Value; List<ConfigDefinition> list = new List<ConfigDefinition>(); foreach (string key in TrophyXPDict.Keys) { list.Add(new ConfigDefinition("ExpScaling", key)); } foreach (ConfigDefinition item in list) { TrophyXPDict[item.Key] = ((BaseUnityPlugin)this).Config.Bind<float>(item, TrophyXPDict[item.Key], (ConfigDescription)null).Value; } List<ConfigDefinition> list2 = new List<ConfigDefinition>(); foreach (string key2 in TrophyGoldValueDict.Keys) { list2.Add(new ConfigDefinition("GoldValue", key2)); } foreach (ConfigDefinition item2 in list2) { TrophyGoldValueDict[item2.Key] = ((BaseUnityPlugin)this).Config.Bind<int>(item2, TrophyGoldValueDict[item2.Key], (ConfigDescription)null).Value; } Harmony.PatchAll(); } } } namespace UsefulTrophiesXP.Properties { [CompilerGenerated] [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.2.0.0")] internal sealed class Settings : ApplicationSettingsBase { private static Settings defaultInstance = (Settings)(object)SettingsBase.Synchronized((SettingsBase)(object)new Settings()); public static Settings Default => defaultInstance; } }
BepInEx/plugins/BuildingDemolish.dll
Decompiled 9 months agousing System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; 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: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] public class AedenthornUtils { public static bool IgnoreKeyPresses(bool extra = false) { if (!extra) { int result; if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { Chat instance = Chat.instance; result = ((instance != null && instance.HasFocus()) ? 1 : 0); } else { result = 1; } return (byte)result != 0; } int result2; if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { Chat instance2 = Chat.instance; if ((instance2 == null || !instance2.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible()) { TextViewer instance3 = TextViewer.instance; result2 = ((instance3 != null && instance3.IsVisible()) ? 1 : 0); goto IL_00d2; } } result2 = 1; goto IL_00d2; IL_00d2: return (byte)result2 != 0; } public static bool CheckKeyDown(string value) { try { return Input.GetKeyDown(value.ToLower()); } catch { return false; } } public static bool CheckKeyHeld(string value, bool req = true) { try { return Input.GetKey(value.ToLower()); } catch { return !req; } } } namespace BuildingDemolish; [BepInPlugin("aedenthorn.BuildingDemolish", "Building Demolish", "0.6.0")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " demolish")) { __instance.AddString(text); int num = DemolishPieces(destroyRadius.Value); __instance.AddString($"{((BaseUnityPlugin)context).Info.Metadata.Name} demolished {num} pieces"); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " demolish ")) { __instance.AddString(text); if (int.TryParse(text.Split(new char[1] { ' ' })[2], out var result)) { int num2 = DemolishPieces(result); __instance.AddString($"{((BaseUnityPlugin)context).Info.Metadata.Name} demolished {num2} pieces"); } else { __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " syntax error"); } return false; } return true; } } private static readonly bool isDebug = true; private static BepInExPlugin context; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<int> nexusID; public static ConfigEntry<bool> allowDestroyUncreated; public static ConfigEntry<bool> requireCraftingStation; public static ConfigEntry<float> destroyRadius; public static ConfigEntry<string> hotKey; public static int destroyMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "vehicle" }); public static void Dbgl(string str = "", bool pref = true) { if (isDebug) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 516, "Nexus mod ID for updates"); destroyRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DestroyRadius", 20f, "Radius of destruction"); allowDestroyUncreated = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowDestroyUncreated", false, "Allow destroying buildings not created by any player"); requireCraftingStation = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RequireCraftingStation", true, "Require a nearby crafting station to destroy corresponding pieces (this is a vanilla requirement)"); hotKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HotKey", ";", "Hotkey to initiate destruction"); if (modEnabled.Value) { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } } private void Update() { if (!AedenthornUtils.IgnoreKeyPresses(extra: true) && AedenthornUtils.CheckKeyDown(hotKey.Value)) { int num = DemolishPieces(destroyRadius.Value); Dbgl($"Demolished {num} pieces."); } } private static int DemolishPieces(float radius) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return 0; } int num = 0; Collider[] array = Physics.OverlapSphere(((Component)localPlayer).transform.position, radius, destroyMask); for (int i = 0; i < array.Length; i++) { Piece componentInParent = ((Component)array[i]).GetComponentInParent<Piece>(); if (!Object.op_Implicit((Object)(object)componentInParent) || (!componentInParent.IsCreator() && (componentInParent.GetCreator() != 0L || !allowDestroyUncreated.Value)) || !componentInParent.m_canBeRemoved || Location.IsInsideNoBuildLocation(((Component)componentInParent).transform.position) || !PrivateArea.CheckAccess(((Component)componentInParent).transform.position, 0f, true, false) || (requireCraftingStation.Value && !Traverse.Create((object)localPlayer).Method("CheckCanRemovePiece", new object[1] { componentInParent }).GetValue<bool>())) { continue; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && componentInParent.CanBeRemoved()) { num++; WearNTear component2 = ((Component)componentInParent).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component2)) { component2.Remove(); continue; } component.ClaimOwnership(); componentInParent.DropResources(); componentInParent.m_placeEffect.Create(((Component)componentInParent).transform.position, ((Component)componentInParent).transform.rotation, ((Component)componentInParent).gameObject.transform, 1f, -1); localPlayer.m_removeEffects.Create(((Component)componentInParent).transform.position, Quaternion.identity, (Transform)null, 1f, -1); ZNetScene.instance.Destroy(((Component)componentInParent).gameObject); } } return num; } }
BepInEx/plugins/Building.dll
Decompiled 9 months agousing 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 System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using SkillManager; using TMPro; using UnityEngine; [assembly: Guid("9BF5432D-9518-4D36-A6C2-A8C62D36B921")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyProduct("Building")] [assembly: AssemblyCompany("")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/Building")] [assembly: AssemblyTitle("Building")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyConfiguration("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<187735d1-a65e-42ae-bbcc-fc54343001cf>Embedded] internal sealed class <187735d1-a65e-42ae-bbcc-fc54343001cf>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<187735d1-a65e-42ae-bbcc-fc54343001cf>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <cd125ad8-3368-4672-9eaf-57b424100665>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <cd125ad8-3368-4672-9eaf-57b424100665>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <cd125ad8-3368-4672-9eaf-57b424100665>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<187735d1-a65e-42ae-bbcc-fc54343001cf>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContextAttribute : Attribute { public readonly byte Flag; public <856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Building { [BepInPlugin("org.bepinex.plugins.building", "Building", "1.2.5")] [<cd125ad8-3368-4672-9eaf-57b424100665>Nullable(0)] [BepInIncompatibility("org.bepinex.plugins.valheim_plus")] [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] public class Building : BaseUnityPlugin { [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] private enum Toggle { On = 1, Off = 0 } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ShowRangeAsPercent; } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class ChangeStaminaUsage { private static float stamina; [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] private static void Prefix(Player __instance, [<cd125ad8-3368-4672-9eaf-57b424100665>Nullable(2)] out ItemData __state) { __state = ((Humanoid)__instance).GetRightItem(); if (__state?.m_shared.m_name == "$item_hammer") { stamina = __state.m_shared.m_attack.m_attackStamina; Attack attack = __state.m_shared.m_attack; attack.m_attackStamina *= Mathf.Max(0f, 1f - ((Character)(object)__instance).GetSkillFactor("Building") * (float)staminaReductionPerLevel.Value); } } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(2)] private static void Finalizer(ItemData __state) { if (__state?.m_shared.m_name == "$item_hammer") { __state.m_shared.m_attack.m_attackStamina = stamina; } } } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] [HarmonyPatch(typeof(WearNTear), "OnPlaced")] public class AddZDO { public static bool forFree; [UsedImplicitly] [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] private static void Postfix(WearNTear __instance) { ((Component)__instance).GetComponent<ZNetView>().GetZDO().Set("BuildingSkill Level", ((Character)(object)Player.m_localPlayer).GetSkillFactor("Building")); __instance.m_health *= 1f + ((Component)__instance).GetComponent<ZNetView>().GetZDO().GetFloat("BuildingSkill Level", 0f) * (healthFactor.Value - 1f); if (freeBuildLevelRequirement.Value > 0) { forFree = Random.Range((float)freeBuildLevelRequirement.Value / 100f, 5.5f) <= ((Character)(object)Player.m_localPlayer).GetSkillFactor("Building"); } ((Component)__instance).GetComponent<ZNetView>().GetZDO().Set("BuildingSkill FreeBuild", forFree); if (((Humanoid)Player.m_localPlayer).GetRightItem() != null && ((Humanoid)Player.m_localPlayer).GetRightItem().m_shared.m_name.ToLower().Contains("hammer")) { ((Character)(object)Player.m_localPlayer).RaiseSkill("Building"); } } } [HarmonyPatch(typeof(WearNTear), "Awake")] [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] private class IncreaseHealth { [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] [UsedImplicitly] private static void Prefix(WearNTear __instance) { float health = __instance.m_health; float num = 1f; ZDO zDO = ((Component)__instance).GetComponent<ZNetView>().GetZDO(); __instance.m_health = health * ((num + ((zDO != null) ? new float?(zDO.GetFloat("BuildingSkill Level", 0f)) : null) * (healthFactor.Value - 1f)) ?? 1f); } } [HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")] [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] private class BuildHigher { [UsedImplicitly] [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] private static void Postfix(WearNTear __instance, ref float maxSupport, ref float minSupport, ref float horizontalLoss, ref float verticalLoss) { ZNetView nview = __instance.m_nview; float? obj; if (nview == null) { obj = null; } else { ZDO zDO = nview.GetZDO(); obj = ((zDO != null) ? new float?(zDO.GetFloat("BuildingSkill Level", 0f)) : null); } float num = obj ?? ((Character)(object)Player.m_localPlayer)?.GetSkillFactor("Building") ?? 0f; maxSupport *= 1f + num * (maximumSupportFactor.Value - 1f); horizontalLoss *= 1f - num * (1f - supportLossFactor.Value); verticalLoss *= 1f - num * (1f - supportLossFactor.Value); } } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] [HarmonyPatch(typeof(Player), "UpdatePlacement")] private class ResetFlag { private static void Finalizer() { AddZDO.forFree = false; } } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] [HarmonyPatch(typeof(Player), "ConsumeResources")] private class BuildingIsFree { private class SkipConsumeResourcesException : Exception { } [HarmonyPriority(800)] private static void Prefix() { if (AddZDO.forFree) { throw new SkipConsumeResourcesException(); } } [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] [return: <cd125ad8-3368-4672-9eaf-57b424100665>Nullable(2)] private static Exception Finalizer(Exception __exception) { if (!(__exception is SkipConsumeResourcesException)) { return __exception; } return null; } } [HarmonyPatch(typeof(Piece), "DropResources")] [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] private class RecoverResources { [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(1)] private static bool Prefix(Piece __instance) { return !((Component)__instance).GetComponent<ZNetView>().GetZDO().GetBool("BuildingSkill FreeBuild", false); } } [<cd125ad8-3368-4672-9eaf-57b424100665>Nullable(0)] [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class ReduceHammerDurabilityLoss { private static bool reduced; private static void Prefix(Player __instance) { reduced = false; if (durabilityUsageLevelRequirement.Value > 0 && (float)durabilityUsageLevelRequirement.Value <= ((Character)(object)__instance).GetSkillFactor("Building") * 100f) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); if (rightItem != null) { SharedData shared = rightItem.m_shared; shared.m_useDurabilityDrain *= 0.7f; reduced = true; } } } private static void Finalizer(Player __instance) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); if (rightItem != null && reduced) { SharedData shared = rightItem.m_shared; shared.m_useDurabilityDrain /= 0.7f; } } } private const string ModName = "Building"; private const string ModVersion = "1.2.5"; private const string ModGUID = "org.bepinex.plugins.building"; private static readonly ConfigSync configSync = new ConfigSync("org.bepinex.plugins.building") { DisplayName = "Building", CurrentVersion = "1.2.5", MinimumRequiredVersion = "1.2.5" }; private static ConfigEntry<Toggle> serverConfigLocked = null; private static ConfigEntry<float> maximumSupportFactor = null; private static ConfigEntry<float> supportLossFactor = null; private static ConfigEntry<float> healthFactor = null; private static ConfigEntry<int> freeBuildLevelRequirement = null; private static ConfigEntry<int> durabilityUsageLevelRequirement = null; private static ConfigEntry<float> experienceGainedFactor = null; private static ConfigEntry<int> experienceLoss = null; private static ConfigEntry<int> staminaReductionPerLevel = null; private static Skill building = null; private ConfigEntry<T> config<[<cd125ad8-3368-4672-9eaf-57b424100665>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description); configSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry<T> config<[<cd125ad8-3368-4672-9eaf-57b424100665>Nullable(2)] T>(string group, string name, T value, 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, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } public void Awake() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) building = new Skill("Building", "building-icon.png"); building.Description.English("Increases the health of pieces built by you and you can build higher."); building.Name.German("Bauen"); building.Description.German("Erhöht die Lebenspunkte von Bauten, die von dir errichtet wurden und du kannst höher bauen."); building.Configurable = false; serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); configSync.AddLockingConfigEntry<Toggle>(serverConfigLocked); maximumSupportFactor = config("2 - Building", "Maximum Support Factor", 1.5f, new ConfigDescription("Maximum support factor for building pieces at skill level 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>())); supportLossFactor = config("2 - Building", "Support Loss Factor", 0.75f, new ConfigDescription("Support loss factor for vertical and horizontal building at skill level 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>())); healthFactor = config("2 - Building", "Health Factor", 3f, new ConfigDescription("Health factor for building pieces at skill level 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); freeBuildLevelRequirement = config("2 - Building", "Free Build Level Requirement", 50, new ConfigDescription("Minimum required skill level to be able to receive free building pieces. 0 is disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); durabilityUsageLevelRequirement = config("2 - Building", "Durability Increase Level Requirement", 30, new ConfigDescription("Minimum required skill level to reduce the durability usage of hammers by 30%. 0 is disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); staminaReductionPerLevel = config("2 - Building", "Stamina Reduction per Level", 1, new ConfigDescription("Reduces the stamina usage while building. Percentage stamina reduction per level. 0 is disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); experienceGainedFactor = config("3 - Other", "Skill Experience Gain Factor", 1f, new ConfigDescription("Factor for experience gained for the building skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), Array.Empty<object>())); experienceGainedFactor.SettingChanged += [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] (object _, EventArgs _) => { building.SkillGainFactor = experienceGainedFactor.Value; }; building.SkillGainFactor = experienceGainedFactor.Value; experienceLoss = config("3 - Other", "Skill Experience Loss", 0, new ConfigDescription("How much experience to lose in the building skill on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); experienceLoss.SettingChanged += [<856f47ca-b3fa-4627-b5fb-589eb438cc28>NullableContext(0)] (object _, EventArgs _) => { building.SkillLoss = experienceLoss.Value; }; building.SkillLoss = experienceLoss.Value; Assembly executingAssembly = Assembly.GetExecutingAssembly(); new Harmony("org.bepinex.plugins.building").PatchAll(executingAssembly); } } } namespace Microsoft.CodeAnalysis { [<eeda3cba-b437-4975-ae4f-66faefb344fa>Embedded] [CompilerGenerated] internal sealed class <eeda3cba-b437-4975-ae4f-66faefb344fa>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [<eeda3cba-b437-4975-ae4f-66faefb344fa>Embedded] internal sealed class <93311208-800b-4489-ada2-c66b7c500ebc>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <93311208-800b-4489-ada2-c66b7c500ebc>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <93311208-800b-4489-ada2-c66b7c500ebc>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [<eeda3cba-b437-4975-ae4f-66faefb344fa>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContextAttribute : Attribute { public readonly byte Flag; public <6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace SkillManager { [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(1)] [PublicAPI] [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(0)] internal class Skill { [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(0)] public static class LocalizationCache { private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>(); internal static void LocalizationPostfix(Localization __instance, string language) { string key = localizations.FirstOrDefault([<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] (KeyValuePair<string, Localization> l) => l.Value == __instance).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance); } } public static Localization ForLanguage([<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] string language = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value)) { return value; } value = new Localization(); if (language != null) { value.SetupLanguage(language); } return value; } } [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(0)] [PublicAPI] public class LocalizeKey { private static readonly List<LocalizeKey> keys = new List<LocalizeKey>(); public readonly string Key; public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>(); public LocalizeKey(string key) { Key = key.Replace("$", ""); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value)) { __instance.AddWord(key.Key, value); } else if (key.Localizations.TryGetValue("alias", out value2)) { Localization.instance.AddWord(key.Key, Localization.instance.Localize(value2)); } } } } [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] private class ConfigurationManagerAttributes { [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] [UsedImplicitly] public string Category; } [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static class Patch_Skills_IsSkillValid { private static void Postfix(SkillType type, ref bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!__result && skills.ContainsKey(type)) { __result = true; } } } private static readonly Dictionary<SkillType, Skill> skills; internal static readonly Dictionary<string, Skill> skillByName; private readonly string skillName; private readonly string internalSkillName; private readonly SkillDef skillDef; public readonly LocalizeKey Name; public readonly LocalizeKey Description; private float skillEffectFactor = 1f; private int skillLoss = 5; public bool Configurable; private static bool InitializedTerminal; [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] private static Localization _english; [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] private static BaseUnityPlugin _plugin; private static bool hasConfigSync; [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] private static object _configSync; public float SkillGainFactor { get { return skillDef.m_increseStep; } set { skillDef.m_increseStep = value; this.SkillGainFactorChanged?.Invoke(value); } } public float SkillEffectFactor { get { return skillEffectFactor; } set { skillEffectFactor = value; this.SkillEffectFactorChanged?.Invoke(value); } } public int SkillLoss { get { return skillLoss; } set { skillLoss = value; this.SkillLossChanged?.Invoke(value); } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown object obj = _plugin; if (obj == null) { BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Assembly.GetExecutingAssembly().DefinedTypes.First([<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] private static object configSync { [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(2)] get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] [method: <6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(2)] [field: <93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] public event Action<float> SkillGainFactorChanged; [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] [method: <6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(2)] [field: <93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] public event Action<float> SkillEffectFactorChanged; [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] [method: <6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(2)] [field: <93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] public event Action<float> SkillLossChanged; public Skill(string englishName, string icon) : this(englishName, loadSprite(icon, 64, 64)) { } public Skill(string englishName, Sprite icon) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown SkillType val = fromName(englishName); string text = new Regex("[^a-zA-Z]").Replace(englishName, "_"); skills[val] = this; skillByName[englishName] = this; skillDef = new SkillDef { m_description = "$skilldesc_" + text, m_icon = icon, m_increseStep = 1f, m_skill = val }; internalSkillName = text; skillName = englishName; Name = new LocalizeKey("skill_" + ((object)(SkillType)(ref val)).ToString()).English(englishName); Description = new LocalizeKey("skilldesc_" + text); } public static SkillType fromName(string englishName) { return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName)); } static Skill() { //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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01ab: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_023c: Expected O, but got Unknown skills = new Dictionary<SkillType, Skill>(); skillByName = new Dictionary<string, Skill>(); InitializedTerminal = false; hasConfigSync = true; Harmony val = new Harmony("org.bepinex.helpers.skillmanager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); } private static void Patch_FejdStartup() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown foreach (Skill skill in skills.Values) { if (skill.Configurable) { string key = skill.Name.Key; string group = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim(); string category = Localization.instance.Localize(key).Trim(); ConfigEntry<float> skillGain = config(group, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillGainFactor = skillGain.Value; skillGain.SettingChanged += [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] (object _, EventArgs _) => { skill.SkillGainFactor = skillGain.Value; }; ConfigEntry<float> skillEffect = config(group, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillEffectFactor = skillEffect.Value; skillEffect.SettingChanged += [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] (object _, EventArgs _) => { skill.SkillEffectFactor = skillEffect.Value; }; ConfigEntry<int> skillLoss = config(group, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.skillLoss = skillLoss.Value; skillLoss.SettingChanged += [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] (object _, EventArgs _) => { skill.skillLoss = skillLoss.Value; }; } } } private static void Patch_Skills_GetSkillDef([<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] ref SkillDef __result, List<SkillDef> ___m_skills, SkillType type) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (__result == null) { SkillDef val = GetSkillDef(type); if (val != null) { ___m_skills.Add(val); __result = val; } } } private static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) foreach (SkillType key in skills.Keys) { SkillType current = key; Skill skill = skills[current]; if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase)) { Skill skill2 = __instance.GetSkill(current); skill2.m_level += value; skill2.m_level = Mathf.Clamp(skill2.m_level, 0f, 100f); ((Character)___m_player).Message((MessageType)1, "Skill increased " + Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref current)).ToString()) + ": " + (int)skill2.m_level, 0, skill2.m_info.m_icon); Console.instance.Print("Skill " + skill.internalSkillName + " = " + skill2.m_level); return false; } } return true; } private static bool Patch_Skills_CheatResetSkill(Skills __instance, string name) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) foreach (SkillType key in skills.Keys) { Skill skill = skills[key]; if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase)) { __instance.ResetSkill(key); Console.instance.Print("Skill " + skill.internalSkillName + " reset"); return false; } } return true; } private static void Patch_Skills_OnDeath_Prefix(Skills __instance, [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(new byte[] { 2, 1 })] ref Dictionary<SkillType, Skill> __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { __state = new Dictionary<SkillType, Skill>(); } foreach (KeyValuePair<SkillType, Skill> skill in skills) { if (__instance.m_skillData.TryGetValue(skill.Key, out var value)) { __state[skill.Key] = value; if (skill.Value.skillLoss > 0) { Skill obj = value; obj.m_level -= value.m_level * (float)skill.Value.SkillLoss / 100f; value.m_accumulator = 0f; } __instance.m_skillData.Remove(skill.Key); } } } private static void Patch_Skills_OnDeath_Finalizer(Skills __instance, [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(new byte[] { 2, 1 })] ref Dictionary<SkillType, Skill> __state) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } foreach (KeyValuePair<SkillType, Skill> item in __state) { __instance.m_skillData[item.Key] = item.Value; } __state = null; } private static void Patch_Terminal_InitTerminal_Prefix() { InitializedTerminal = Terminal.m_terminalInitialized; } private static void Patch_Terminal_InitTerminal() { if (!InitializedTerminal) { AddSkill(Terminal.commands["raiseskill"]); AddSkill(Terminal.commands["resetskill"]); } static void AddSkill(ConsoleCommand command) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher; command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)([<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] () => { List<string> list = fetcher.Invoke(); list.AddRange(skills.Values.Select([<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(0)] (Skill skill) => skill.internalSkillName)); return list; }); } } [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(2)] private static SkillDef GetSkillDef(SkillType skillType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!skills.ContainsKey(skillType)) { return null; } return skills[skillType].skillDef; } private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream); return memoryStream.ToArray(); } private static Texture2D loadTexture(string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name)); return val; } private static Sprite loadSprite(string name, int width, int height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero); } private static ConfigEntry<T> config<[<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] T>(string group, string name, T value, ConfigDescription description) { ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry<T> config<[<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(2)] T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } } [<93311208-800b-4489-ada2-c66b7c500ebc>Nullable(0)] [PublicAPI] [<6bbb7c97-c1a9-4081-86de-eee169dfb3d5>NullableContext(1)] internal static class SkillExtensions { public static float GetSkillFactor(this Character character, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static float GetSkillFactor(this Skills skills, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static void RaiseSkill(this Character character, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) character.RaiseSkill(Skill.fromName(name), value); } public static void RaiseSkill(this Skills skill, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) skill.RaiseSkill(Skill.fromName(name), value); } public static void LowerSkill(this Character character, string name, float factor = 1f) { character.GetSkills().LowerSkill(name, factor); } public static void LowerSkill(this Skills skills, string name, float factor) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (factor > 0f && skills.m_skillData.TryGetValue(Skill.fromName(name), out var value)) { Skill obj = value; obj.m_level -= value.m_level * factor; value.m_accumulator = 0f; } } } } namespace Microsoft.CodeAnalysis { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] 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] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace 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; } 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() { 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 = (from p in ZNet.instance.GetPeers() where adminList.Contains(p.m_rpc.GetSocket().GetHostName()) select p).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 : 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; } 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); } } } [HarmonyPrefix] [HarmonyPriority(800)] 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()) { BufferingSocket value = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value); 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) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = value; } } [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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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); foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues) { if (!isServer && configValue.Key.LocalBaseValue == null) { configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue; } configValue.Key.BaseConfig.BoxedValue = configValue.Value; } 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 " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName)); } else { Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match.")); } continue; } Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs")); return new ParsedConfigs(); } return parsedConfigs; } private static bool isWritableConfig(OwnConfigEntryBase config) { OwnConfigEntryBase config2 = config; ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2)); if (configSync == null) { return true; } return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt)); } private void serverLockedSettingChanged() { foreach (OwnConfigEntryBase allConfig in allConfigs) { configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig); } } private void resetConfigsFromServer() { foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null)) { item.BaseConfig.BoxedValue = item.LocalBaseValue; item.LocalBaseValue = null; } foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null)) { item2.BoxedValue = item2.LocalBaseValue; item2.LocalBaseValue = null; } lockedConfigChanged -= serverLockedSettingChanged; serverLockedSettingChanged(); } private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package) { ZNetPeer peer2 = peer; ZRoutedRpc rpc = ZRoutedRpc.instance; if (rpc == null) { yield break; } byte[] data = package.GetArray(); if (data != null && data.LongLength > 250000) { int fragments = (int)(1 + (data.LongLength - 1) / 250000); long packageIdentifier = ++packageCounter; int fragment = 0; while (fragment < fragments) { foreach (bool item in waitForQueue()) { yield return item; } if (peer2.m_socket.IsConnected()) { ZPackage fragmentedPackage = new ZPackage(); fragmentedPackage.Write((byte)2); fragmentedPackage.Write(packageIdentifier); fragmentedPackage.Write(fragment); fragmentedPackage.Write(fragments); fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray()); SendPackage(fragmentedPackage); if (fragment != fragments - 1) { yield return true; } int num = fragment + 1; fragment = num; continue; } break; } yield break; } foreach (bool item2 in waitForQueue()) { yield return item2; } SendPackage(package); void SendPackage(ZPackage pkg) { string text = Name + " ConfigSync"; if (isServer) { peer2.m_rpc.Invoke(text, new object[1] { pkg }); } else { rpc.InvokeRoutedRPC(peer2.m_server ? 0 : peer2.m_uid, text, new object[1] { pkg }); } } IEnumerable<bool> waitForQueue() { float timeout = Time.time + 30f; while (peer2.m_socket.GetSendQueueSize() > 20000) { if (Time.time > timeout) { Debug.Log((object)$"Disconnecting {peer2.m_uid} after 30 seconds config sending timeout"); peer2.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 }); ZNet.instance.Disconnect(peer2); break; } yield return false; } } } private IEnumerator sendZPackage(long target, ZPackage package) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return Enumerable.Empty<object>().GetEnumerator(); } List<ZNetPeer> list = (List<ZNetPeer>)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance); if (target != ZRoutedRpc.Everybody) { list = list.Where((ZNetPeer p) => p.m_uid == target).ToList(); } return sendZPackage(list, package); } private IEnumerator sendZPackage(List<ZNetPeer> peers, ZPackage package) { ZPackage package2 = package; if (!Object.op_Implicit((Object)(object)ZNet.instance)) { yield break; } byte[] rawData = package2.GetArray(); if (rawData != null && rawData.LongLength > 10000) { ZPackage compressedPackage = new ZPackage(); compressedPackage.Write((byte)4); MemoryStream output = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal)) { deflateStream.Write(rawData, 0, rawData.Length); } compressedPackage.Write(output.ToArray()); package2 = compressedPackage; } List<IEnumerator<bool>> writers = (from peer in peers where peer.IsReady() select peer into p select distributeConfigToPeers(p, package2)).ToList(); writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext()); while (writers.Count > 0) { yield return null; writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext()); } } private void Broadcast(long target, params ConfigEntryBase[] configs) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(configs); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private void Broadcast(long target, params CustomSyncedValueBase[] customValues) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(null, customValues); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private static OwnConfigEntryBase? configData(ConfigEntryBase config) { return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault(); } public static SyncedConfigEntry<T>? ConfigData<T>(ConfigEntry<T> config) { return ((ConfigEntryBase)config).Description.Tags?.OfType<SyncedConfigEntry<T>>().SingleOrDefault(); } private static T configAttribute<T>(ConfigEntryBase config) { return config.Description.Tags.OfType<T>().First(); } private static Type configType(ConfigEntryBase config) { return configType(config.SettingType); } private static Type configType(Type type) { return type.IsEnum ? Enum.GetUnderlyingType(type) : type; } private static ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase>? configs = null, IEnumerable<CustomSyncedValueBase>? customValues = null, IEnumerable<PackageEntry>? packageEntries = null, bool partial = true) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>(); List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>(); ZPackage val = new ZPackage(); val.Write((byte)(partial ? 1 : 0)); val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0)); foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>()) { AddEntryToPackage(val, item); } foreach (CustomSyncedValueBase item2 in list2) { AddEntryToPackage(val, new PackageEntry { section = "Internal", key = item2.Identifier, type = item2.Type, value = item2.BoxedValue }); } foreach (ConfigEntryBase item3 in list) { AddEntryToPackage(val, new PackageEntry { section = item3.Definition.Section, key = item3.Definition.Key, type = configType(item3), value = item3.BoxedValue }); } return val; } private static void AddEntryToPackage(ZPackage package, PackageEntry entry) { package.Write(entry.section); package.Write(entry.key); package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type)); AddValueToZPackage(package, entry.value); } private static string GetZPackageTypeString(Type type) { return type.AssemblyQualifiedName; } private static void AddValueToZPackage(ZPackage package, object? value) { Type type = value?.GetType(); if (value is Enum) { value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture); } else { if (value is ICollection collection) { package.Write(collection.Count); { foreach (object item in collection) { AddValueToZPackage(package, item); } return; } } if ((object)type != null && type.IsValueType && !type.IsPrimitive) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); package.Write(fields.Length); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { package.Write(GetZPackageTypeString(fieldInfo.FieldType)); AddValueToZPackage(package, fieldInfo.GetValue(value)); } return; } } ZRpc.Serialize(new object[1] { value }, ref package); } private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type) { if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = package.ReadInt(); if (num != fields.Length) { throw new InvalidDeserializationTypeException { received = $"(field count: {num})", expected = $"(field count: {fields.Length})" }; } object uninitializedObject = FormatterServices.GetUninitializedObject(type); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { string text = package.ReadString(); if (text != GetZPackageTypeString(fieldInfo.FieldType)) { throw new InvalidDeserializationTypeException { received = text, expected = GetZPackageTypeString(fieldInfo.FieldType), field = fieldInfo.Name }; } fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType)); } return uninitializedObject; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { int num2 = package.ReadInt(); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type); Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments); FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); for (int j = 0; j < num2; j++) { object obj = ReadValueWithTypeFromZPackage(package, type2); dictionary.Add(field.GetValue(obj), field2.GetValue(obj)); } return dictionary; } if (type != typeof(List<string>) && type.IsGenericType) { Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]); if ((object)type3 != null && type3.IsAssignableFrom(type)) { int num3 = package.ReadInt(); object obj2 = Activator.CreateInstance(type); MethodInfo method = type3.GetMethod("Add"); for (int k = 0; k < num3; k++) { method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) }); } return obj2; } } ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type); List<object> source = new List<object>(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source); return source.First(); } } [HarmonyPatch] [PublicAPI] internal class VersionCheck { private static readonly HashSet<VersionCheck> versionChecks; private static readonly Dictionary<string, string> notProcessedNames; public string Name; private string? displayName; private string? currentVersion; private string? minimumRequiredVersion; public bool ModRequired = true; private string? ReceivedCurrentVersion; private string? ReceivedMinimumRequiredVersion; private readonly List<ZRpc> ValidatedClients = new List<ZRpc>(); private ConfigSync? ConfigSync; public string DisplayName { get { return displayName ?? Name; } set { displayName = value; } } public string CurrentVersion { get { return currentVersion ?? "0.0.0"; } set { currentVersion = value; } } public string MinimumRequiredVersion { get { return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0"); } set { minimumRequiredVersion = value; } } private static void PatchServerSync() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null)); if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0) { return; } Harmony val = new Harmony("org.bepinex.helpers.ServerSync"); foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) }) where t.IsClass select t) { val.PatchAll(item); } } static VersionCheck() { versionChecks = new HashSet<VersionCheck>(); notProcessedNames = new Dictionary<string, string>(); typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1] { new Action(PatchServerSync) }); } public VersionCheck(string name) { Name = name; ModRequired = true; versionChecks.Add(this); } public VersionCheck(ConfigSync configSync) { ConfigSync = configSync; Name = ConfigSync.Name; versionChecks.Add(this); } public void Initialize() { ReceivedCurrentVersion = null; ReceivedMinimumRequiredVersion = null; if (ConfigSync != null) { Name = ConfigSync.Name; DisplayName = ConfigSync.DisplayName; CurrentVersion = ConfigSync.CurrentVersion; MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion; ModRequired = ConfigSync.ModRequired; } } private bool IsVersionOk() { if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null) { return !ModRequired; } bool flag = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion); bool flag2 = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion); return flag && flag2; } private string ErrorClient() { if (ReceivedMinimumRequiredVersion == null) { return "Mod " + DisplayName + " must not be installed."; } return (new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)) ? ("Mod " + DisplayName + " requires maximum " + ReceivedCurrentVersion + ". Installed is version " + CurrentVersion + ".") : ("Mod " + DisplayName + " requires minimum " + ReceivedMinimumRequiredVersion + ". Installed is version " + CurrentVersion + "."); } private string ErrorServer(ZRpc rpc) { return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion; } private string Error(ZRpc? rpc = null) { return (rpc == null) ? ErrorClient() : ErrorServer(rpc); } private static VersionCheck[] GetFailedClient() { return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray(); } private static VersionCheck[] GetFailedServer(ZRpc rpc) { ZRpc rpc2 = rpc; return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc2)).ToArray(); } private static void Logout() { Game.instance.Logout(true, true); AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3); } private static void DisconnectClient(ZRpc rpc) { rpc.Invoke("Error", new object[1] { 3 }); } private static void CheckVersion(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, null); } private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action<ZRpc, ZPackage>? original) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); bool flag = false; foreach (VersionCheck versionCheck in versionChecks) { if (!(text != versionCheck.Name)) { Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + ".")); versionCheck.ReceivedMinimumRequiredVersion = text2; versionCheck.ReceivedCurrentVersion = text3; if (ZNet.instance.IsServer() && versionCheck.IsVersionOk()) { versionCheck.ValidatedClients.Add(rpc); } flag = true; } } if (flag) { return; } pkg.SetPos(0); if (original != null) { original(rpc, pkg); if (pkg.GetPos() == 0) { notProcessedNames.Add(text, text3); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPrefix] private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance) { VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient()); if (array.Length == 0) { return true; } VersionCheck[] array2 = array; foreach (VersionCheck versionCheck in array2) { Debug.LogWarning((object)versionCheck.Error(rpc)); } if (__instance.IsServer()) { DisconnectClient(rpc); } else { Logout(); } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown notProcessedNames.Clear(); IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc); if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck"))) { object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")]; Action<ZRpc, ZPackage> action = (Action<ZRpc, ZPackage>)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)delegate(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, action); }); } else { peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)CheckVersion); } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.Initialize(); if (versionCheck.ModRequired || __instance.IsServer()) { Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + ".")); ZPackage val = new ZPackage(); val.Write(versionCheck.Name); val.Write(versionCheck.MinimumRequiredVersion); val.Write(versionCheck.CurrentVersion); peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val }); } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPrefix] private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance) { if (!__instance.IsServer()) { return; } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.ValidatedClients.Remove(peer.m_rpc); } } [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] private static void ShowConnectionError(FejdStartup __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3) { return; } VersionCheck[] failedClient = GetFailedClient(); if (failedClient.Length != 0) { string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error())); TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + text; } foreach (KeyValuePair<string, string> item in notProcessedNames.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> kv) => kv.Key)) { if (!__instance.m_connectionFailedError.text.Contains(item.Key)) { TMP_Text connectionFailedError2 = __instance.m_connectionFailedError; connectionFailedError2.text = connectionFailedError2.text + "\n" + item.Key + " (Version: " + item.Value + ")"; } } } } }
BepInEx/plugins/Professions.dll
Decompiled 9 months agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Professions; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Guid("6A561CBA-69AC-46B3-9095-15E99C3121EC")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyProduct("Professions")] [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/Professions")] [assembly: AssemblyTitle("Professions")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<2a278b7f-9d60-4fb7-af10-0d8334a40073>Embedded] internal sealed class <2a278b7f-9d60-4fb7-af10-0d8334a40073>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [<2a278b7f-9d60-4fb7-af10-0d8334a40073>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <0f599e97-3333-4107-b0b5-ba674f05d9ec>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <0f599e97-3333-4107-b0b5-ba674f05d9ec>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <0f599e97-3333-4107-b0b5-ba674f05d9ec>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<2a278b7f-9d60-4fb7-af10-0d8334a40073>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContextAttribute : Attribute { public readonly byte Flag; public <a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContextAttribute(byte P_0) { Flag = P_0; } } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] public class ProfessionPanel : MonoBehaviour { [Header("Stuff To replace")] public Image SelectionBKG; public Image ContentBkg; public Text header; public Image linebreak; public Text description; [Header("Skill Element")] public GameObject SkillElementGO; public Skill_Element skill_element; public RectTransform panelToInstantiateIn; public GameObject InstantiateSkill(Sprite icon, string title, string desc, string buttontext) { GameObject obj = Object.Instantiate<GameObject>(SkillElementGO, (Transform)(object)panelToInstantiateIn); Skill_Element component = obj.GetComponent<Skill_Element>(); component.m_icon.sprite = icon; component.m_desc.text = desc; component.m_Title.text = title; component.buttontxt.text = buttontext; return obj; } public void Awake() { GameObject gameObject = ((Component)((Component)this).transform.parent).gameObject; Image component = ((Component)gameObject.transform.Find("Menu/MenuRoot/Menu/ornament")).gameObject.GetComponent<Image>(); Image component2 = ((Component)gameObject.transform.Find("Inventory_screen/root/Player/Bkg")).gameObject.GetComponent<Image>(); TMP_FontAsset font = ((TMP_Text)((Component)gameObject.transform.Find("Inventory_screen/root/Player/Armor/ac_text")).gameObject.GetComponent<TextMeshProUGUI>()).font; description.font = font.sourceFontFile; header.font = font.sourceFontFile; header.text = "Select Profession"; linebreak.sprite = component.sprite; ContentBkg.sprite = component2.sprite; ((Graphic)ContentBkg).material = ((Graphic)component2).material; ((Graphic)SelectionBKG).material = ((Graphic)component2).material; SelectionBKG.sprite = component2.sprite; } } [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] public class Skill_Element : MonoBehaviour { [Header("Stuff To replace")] public Image m_icon; public Text m_Title; public Text m_desc; public Button Select; public Text buttontxt; public Image[] configOptions; public static Sprite blockUsage; public static Sprite blockExperience; public static GameObject tooltipPrefab; public void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) Button component = ((Component)((Component)Menu.instance).transform.Find("MenuRoot/ExitConfirm/dialog/Button_yes")).GetComponent<Button>(); ((Selectable)Select).spriteState = ((Selectable)component).spriteState; ((Selectable)Select).transition = (Transition)2; ((Component)Select).GetComponent<Image>().sprite = ((Component)component).GetComponent<Image>().sprite; Image[] array = configOptions; for (int i = 0; i < array.Length; i++) { ((Component)array[i]).GetComponent<UITooltip>().m_tooltipPrefab = tooltipPrefab; } } public void UpdateImageDisplay(global::Professions.Professions.ProfessionToggle toggle) { int num = 0; switch (toggle) { case global::Professions.Professions.ProfessionToggle.BlockUsage: { UITooltip component2 = ((Component)configOptions[num]).GetComponent<UITooltip>(); component2.m_text = "If you do not pick this profession, you will not be able to perform these actions."; component2.m_topic = "Usage blocked"; configOptions[num++].sprite = blockUsage; break; } case global::Professions.Professions.ProfessionToggle.BlockExperience: { UITooltip component = ((Component)configOptions[num]).GetComponent<UITooltip>(); component.m_text = "If you do not pick this profession, you will still be able to perform these actions, but will not gain experience."; component.m_topic = "Experience blocked"; configOptions[num++].sprite = blockExperience; break; } } for (int i = 0; i < configOptions.Length; i++) { ((Component)configOptions[i]).gameObject.SetActive(i < num); } } public void Toggle(bool selected, bool maxProfessionsReached) { ((Selectable)Select).interactable = global::Professions.Professions.allowUnselect.Value == global::Professions.Professions.Toggle.On; if (selected) { buttontxt.text = ((global::Professions.Professions.allowUnselect.Value == global::Professions.Professions.Toggle.On) ? "Unlearn" : "Selected"); } else if (!maxProfessionsReached) { buttontxt.text = "Select"; } else { buttontxt.text = "Unlock"; } } } namespace Professions { public static class Blockers { [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] private class BlockBlacksmithing { private static bool CheckBlacksmithingItem(SharedData item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 ItemType itemType = item.m_itemType; if ((int)itemType != 4 && (int)itemType != 7 && (int)itemType != 12 && (int)itemType != 6 && (int)itemType != 11 && (int)itemType != 5 && (int)itemType != 17 && (int)itemType != 14) { if ((int)item.m_itemType == 3) { return !item.m_attack.m_consumeItem; } return false; } return true; } [HarmonyPriority(0)] private static void Postfix(InventoryGui __instance) { if (__instance.InCraftTab() || __instance.InUpradeTab()) { ItemDrop val = __instance.m_selectedRecipe.Key?.m_item; if (val != null && CheckBlacksmithingItem(val.m_itemData.m_shared) && !isAllowed(Professions.Profession.Blacksmithing)) { ((Selectable)__instance.m_craftButton).interactable = false; ((Component)__instance.m_craftButton).GetComponentInChildren<Text>().text = "You cannot perform this action, because you are not a blacksmith."; } } } } [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [HarmonyPatch] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] public static class BlockBlacksmithingSmelter { private static IEnumerable<MethodInfo> TargetMethods() { return new MethodInfo[2] { AccessTools.DeclaredMethod(typeof(Smelter), "OnAddOre", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Smelter), "OnAddFuel", (Type[])null, (Type[])null) }; } private static bool Prefix(Smelter __instance, ref bool __result) { switch (((Component)__instance).GetComponent<Piece>().m_name) { case "$piece_smelter": case "$piece_blastfurnace": if (isAllowed(Professions.Profession.Blacksmithing)) { return true; } __result = false; ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a blacksmith.", 0, (Sprite)null); return false; case "$piece_windmill": if (isAllowed(Professions.Profession.Farming)) { return true; } __result = false; ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a farmer.", 0, (Sprite)null); return false; default: return true; } } } [HarmonyPatch(typeof(PieceTable), "SetCategory")] private class BlockBuilding { private static bool Prefix(int index) { if (index != 2 || isAllowed(Professions.Profession.Building)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a builder.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(PieceTable), "PrevCategory")] private class BlockBuildingHotkeyPrev { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Postfix(PieceTable __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)__instance.m_selectedCategory == 2 && !isAllowed(Professions.Profession.Building)) { __instance.PrevCategory(); } } } [HarmonyPatch(typeof(PieceTable), "NextCategory")] private class BlockBuildingHotkeyNext { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Postfix(PieceTable __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)__instance.m_selectedCategory == 2 && !isAllowed(Professions.Profession.Building)) { __instance.NextCategory(); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] private class BlockCookingCrafting { [HarmonyPriority(0)] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Postfix(InventoryGui __instance) { ItemDrop val = __instance.m_selectedRecipe.Key?.m_item; if (val != null && val.m_itemData.m_shared.m_food > 0f && val.m_itemData.m_shared.m_foodStamina > 0f && !isAllowed(Professions.Profession.Cooking)) { ((Selectable)__instance.m_craftButton).interactable = false; ((Component)__instance.m_craftButton).GetComponentInChildren<Text>().text = "You cannot perform this action, because you are not a cook."; } } } [HarmonyPatch(typeof(CookingStation), "Interact")] private class BlockCookingStation { private static bool Prefix() { if (isAllowed(Professions.Profession.Cooking)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a cook.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(ItemData), "IsEquipable")] private class BlockFarmingCultivator { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Postfix(ItemData __instance, ref bool __result) { if (__instance.m_shared.m_name == "$item_cultivator" && !isAllowed(Professions.Profession.Farming)) { __result = false; } } } [HarmonyPatch(typeof(Pickable), "Interact")] private class BlockFarmingPickingPlants { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static bool Prefix(Pickable __instance) { if (!__instance.m_nview.GetZDO().GetBool("Farming Custom Grown", false) || isAllowed(Professions.Profession.Farming)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a farmer.", 0, (Sprite)null); return false; } } [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [HarmonyPatch(typeof(Plant), "Grow")] private class SaveCustomGrownPlantState { private static GameObject TransferInfo(GameObject pickable) { pickable.GetComponent<ZNetView>().GetZDO().Set("Farming Custom Grown", true); return pickable; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo transferInfo = AccessTools.DeclaredMethod(typeof(SaveCustomGrownPlantState), "TransferInfo", (Type[])null, (Type[])null); MethodInfo instantiator = typeof(Object).GetMethods().First([<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] (MethodInfo m) => m.Name == "Instantiate" && m.IsGenericMethodDefinition && (from p in m.GetParameters().Skip(1) select p.ParameterType).SequenceEqual(new Type[2] { typeof(Vector3), typeof(Quaternion) })).MakeGenericMethod(typeof(GameObject)); foreach (CodeInstruction instruction in instructions) { yield return instruction; if (instruction.opcode == OpCodes.Call && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)instantiator)) { yield return new CodeInstruction(OpCodes.Call, (object)transferInfo); } } } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [HarmonyPatch] public static class BlockLumberjacking { private static IEnumerable<MethodInfo> TargetMethods() { return new MethodInfo[3] { AccessTools.DeclaredMethod(typeof(TreeLog), "Damage", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(TreeBase), "Damage", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Destructible), "Damage", (Type[])null, (Type[])null) }; } private static void Prefix(object __instance, HitData hit) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if (isAllowed(Professions.Profession.Lumberjacking) || !((Object)(object)hit.GetAttacker() == (Object)(object)Player.m_localPlayer)) { return; } Destructible val = (Destructible)((__instance is Destructible) ? __instance : null); if (val == null || (int)val.m_destructibleType == 2) { if (!(__instance is TreeLog) && !(__instance is TreeBase)) { hit.m_damage.m_slash = 0f; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a lumberjack.", 0, (Sprite)null); hit.m_damage.m_chop = 0f; } } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [HarmonyPatch] public static class BlockMining { private static IEnumerable<MethodInfo> TargetMethods() { return new MethodInfo[3] { AccessTools.DeclaredMethod(typeof(MineRock), "Damage", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(MineRock5), "Damage", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Destructible), "Damage", (Type[])null, (Type[])null) }; } private static void Prefix(object __instance, HitData hit) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0034: 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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 if (isAllowed(Professions.Profession.Mining) || !((Object)(object)hit.GetAttacker() == (Object)(object)Player.m_localPlayer)) { return; } Destructible val = (Destructible)((__instance is Destructible) ? __instance : null); if (val != null) { DamageModifiers damages = val.m_damages; if ((int)damages.m_pickaxe <= 0 || (int)damages.m_chop != 0 || (int)val.m_destructibleType == 2) { return; } } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a miner.", 0, (Sprite)null); hit.m_damage.m_pickaxe = 0f; } } [HarmonyPatch(typeof(Character), "Damage")] private class BlockRanching { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static bool Prefix(Character __instance, HitData hit) { if (!__instance.IsTamed() || isAllowed(Professions.Profession.Ranching) || (Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a rancher.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(ShipControlls), "Interact")] private class BlockSailing { private static bool Prefix() { if (isAllowed(Professions.Profession.Sailing)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a sailor.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(CraftingStation), "Interact")] private class BlockAlchemyStation { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static bool Prefix(CraftingStation __instance) { if (!((Object)__instance).name.StartsWith("opalchemy", StringComparison.Ordinal) || isAllowed(Professions.Profession.Alchemy)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not an alchemist.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(Incinerator), "OnIncinerate")] private class BlockAlchemyIncinerator { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static bool Prefix(Incinerator __instance) { if (!((Object)__instance).name.StartsWith("opcauldron", StringComparison.Ordinal) || isAllowed(Professions.Profession.Alchemy)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not an alchemist.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(CraftingStation), "Interact")] private class BlockGemcuttersTable { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static bool Prefix(CraftingStation __instance) { if (!((Object)__instance).name.StartsWith("op_transmution_table", StringComparison.Ordinal) || isAllowed(Professions.Profession.Jewelcrafting)) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a jeweler.", 0, (Sprite)null); return false; } } [HarmonyPatch(typeof(Pickable), "Interact")] private class BlockForaging { private class SkipForagingException : Exception { } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [HarmonyPriority(800)] private static void Prefix(Pickable __instance) { if (__instance.m_respawnTimeMinutes == 0 || ((Object)__instance.m_itemPrefab).name == "Wood" || isAllowed(Professions.Profession.Foraging)) { return; } ((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot perform this action, because you are not a forager.", 0, (Sprite)null); throw new SkipForagingException(); } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [return: <0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(2)] private static Exception Finalizer(Exception __exception) { if (!(__exception is SkipForagingException)) { return __exception; } return null; } } [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] private class BlockExploration { [HarmonyPriority(800)] private static bool Prefix() { return isAllowed(Professions.Profession.Exploration); } } private static bool isAllowed(Professions.Profession profession) { if (Professions.blockOtherProfessions[profession].Value == Professions.ProfessionToggle.BlockUsage) { return Professions.selectedProfessions(Player.m_localPlayer).Contains(profession); } return true; } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] public static class Helper { private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream("Professions." + name)?.CopyTo(memoryStream); return memoryStream.ToArray(); } private static Texture2D loadTexture(string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name)); return val; } public static Sprite loadSprite(string name, int width, int height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero); } public static string getHumanFriendlyTime(int seconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); if (timeSpan.TotalSeconds < 60.0) { return "less than 1 minute"; } string text = ""; if (timeSpan.TotalDays >= 1.0) { text = text + $"{(int)timeSpan.TotalDays} day" + ((timeSpan.TotalDays >= 2.0) ? "s" : ""); } if (timeSpan.Hours >= 1) { if (timeSpan.TotalDays >= 1.0) { text += " and "; } text = text + $"{timeSpan.Hours} hour" + ((timeSpan.Hours >= 2) ? "s" : ""); } if (timeSpan.Minutes >= 1) { if (timeSpan.TotalDays >= 1.0 || timeSpan.Hours >= 1) { text += " and "; } text = text + $"{timeSpan.Minutes} minute" + ((timeSpan.Minutes >= 2) ? "s" : ""); } return text; } } [BepInPlugin("org.bepinex.plugins.professions", "Professions", "1.4.1")] [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(0)] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] [BepInIncompatibility("org.bepinex.plugins.valheim_plus")] public class Professions : BaseUnityPlugin { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] public enum Toggle { On = 1, Off = 0 } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] public enum ProfessionToggle { Ignored, [Description("Block Experience")] BlockExperience, [Description("Block Usage")] BlockUsage } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] public enum Profession { Blacksmithing, Building, Cooking, Farming, Lumberjacking, Mining, Ranching, Sailing, Alchemy, Jewelcrafting, Foraging, Exploration } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public int? Order; } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class AddRPCs { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Postfix(ZNet __instance, ZNetPeer peer) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (__instance.IsServer()) { peer.m_rpc.Register("Professions GetServerTime", new Method(onServerTimeRequest)); } else { peer.m_rpc.Register<long>("Professions GetServerTime", (Action<ZRpc, long>)onServerTimeReceived); } } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] [HarmonyPatch(typeof(Menu), "Update")] private class PreventMainMenu { public static bool AllowMainMenu = true; private static bool Prefix() { if (!professionPanelInstance.activeSelf) { return AllowMainMenu; } return false; } } [HarmonyPatch(typeof(Hud), "Awake")] [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] public static class InstantiateSelectPanel { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Prefix(Hud __instance) { Transform transform = ((Component)((Component)__instance).gameObject.GetComponentInParent<Localize>()).gameObject.transform; professionPanelInstance = Object.Instantiate<GameObject>(professionPanel, transform, false); professionPanelInstance.SetActive(false); professionPanelInstance.transform.SetSiblingIndex(((Component)MessageHud.instance).transform.GetSiblingIndex()); Skill_Element.tooltipPrefab = InventoryGui.instance.m_playerGrid.m_elementPrefab.GetComponent<UITooltip>().m_tooltipPrefab; } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] [HarmonyPatch(typeof(Skills), "Awake")] public static class PopulateSelectPanel { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static void Postfix(Skills __instance) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected I4, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Professions.professionPanelInstance)) { return; } GameObject professionPanelInstance = Professions.professionPanelInstance; ProfessionPanel professionPanel = ((professionPanelInstance != null) ? professionPanelInstance.GetComponent<ProfessionPanel>() : null); if (professionPanel == null || ((Transform)professionPanel.panelToInstantiateIn).childCount != 0) { return; } professionPanelElements.Clear(); Profession[] array = (Profession[])Enum.GetValues(typeof(Profession)); foreach (Profession profession in array) { SkillType skillType = fromProfession(profession); Skill skill = __instance.GetSkill(skillType); if (skill.m_info == null) { __instance.m_skillData.Remove(skillType); continue; } GameObject val = professionPanel.InstantiateSkill(skill.m_info.m_icon, Localization.instance.Localize("$skill_" + (int)fromProfession(profession)), professionDescriptions[profession], "Select"); professionPanelElements[profession] = val; val.SetActive(blockOtherProfessions[profession].Value != ProfessionToggle.Ignored); ((UnityEvent)val.GetComponent<Skill_Element>().Select.onClick).AddListener((UnityAction)delegate { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) if (selectedProfessions(Player.m_localPlayer).Contains(profession)) { if (allowUnselect.Value == Toggle.On && professionChangeCooldown.Value > 0f && Player.m_localPlayer.m_knownStations.TryGetValue("Professions LastProfessionChange", out var value)) { int num = value + (int)(professionChangeCooldown.Value * 3600f) - (int)((DateTimeOffset)serverTime).ToUnixTimeSeconds(); if (num > 0) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You can change your profession in " + Helper.getHumanFriendlyTime(num) + ".", 0, (Sprite)null); return; } } Player.m_localPlayer.m_skills.m_skillData.Remove(skillType); Player.m_localPlayer.m_knownStations["Professions LastProfessionChange"] = (int)((DateTimeOffset)serverTime).ToUnixTimeSeconds(); } else { if (!Player.m_localPlayer.m_knownStations.TryGetValue("Professions extraProfessionsSlots", out var value2)) { Player.m_localPlayer.m_knownStations["Professions extraProfessionsSlots"] = 0; value2 = 0; } if (selectedProfessions(Player.m_localPlayer).Count >= maximumAllowedProfessions.Value + value2) { if (((Humanoid)Player.m_localPlayer).GetInventory() != null) { ItemData val2 = null; ItemData val3 = null; int num2 = Mathf.CeilToInt(Mathf.Pow(1.6f, (float)(maximumAllowedProfessions.Value + value2))); for (int j = 0; j < ((Humanoid)Player.m_localPlayer).GetInventory().GetHeight(); j++) { if (val3 != null) { break; } for (int k = 0; k < ((Humanoid)Player.m_localPlayer).GetInventory().GetWidth(); k++) { val2 = ((Humanoid)Player.m_localPlayer).GetInventory().GetItemAt(k, j); if (val2 != null) { if (val2.m_shared.m_name.ToLower() == "craftsman trophy" && ((Humanoid)Player.m_localPlayer).GetInventory().GetItemAt(k, j).m_stack >= num2) { val3 = val2; } if (val3 != null) { break; } } } } if (val3 == null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You need Craftsman Trophy x " + num2.ToString("#") + ".", 0, (Sprite)null); } else { for (int l = 0; l < num2; l++) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Humanoid)localPlayer).GetInventory().RemoveOneItem(val3); } } Player.m_localPlayer.StartEmote("cheer", true); ((Character)Player.m_localPlayer).Message((MessageType)2, "Consumed Craftsman Trophy x " + num2.ToString("#") + ".", 0, (Sprite)null); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_Potion_stamina_medium"), ((Component)Player.m_localPlayer).transform.position, Quaternion.identity); Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab("vfx_WishbonePing"), ((Component)Player.m_localPlayer).transform.position, Quaternion.identity); Player.m_localPlayer.m_knownStations["Professions extraProfessionsSlots"] = value2 + 1; } } } else { Player.m_localPlayer.m_skills.GetSkill(skillType).m_level = 1f; } } UpdateSelectPanelSelections(); }); } } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] [HarmonyPatch(typeof(Skills), "RaiseSkill")] private class PreventExperience { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static bool Prefix(Skills __instance, SkillType skillType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Profession? profession = fromSkill(skillType); if (profession.HasValue) { Profession valueOrDefault = profession.GetValueOrDefault(); if (!(__instance.GetSkillFactor(skillType) > 0f)) { return blockOtherProfessions[valueOrDefault].Value == ProfessionToggle.Ignored; } } return true; } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] [HarmonyPatch] private class DisablePlayerInputInProfessionMenu { [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(1)] private static IEnumerable<MethodInfo> TargetMethods() { return new MethodInfo[2] { AccessTools.DeclaredMethod(typeof(StoreGui), "IsVisible", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(TextInput), "IsVisible", (Type[])null, (Type[])null) }; } private static void Postfix(ref bool __result) { GameObject professionPanelInstance = Professions.professionPanelInstance; if (professionPanelInstance != null && professionPanelInstance.activeSelf) { __result = true; } } } private const string ModName = "Professions"; private const string ModVersion = "1.4.1"; private const string ModGUID = "org.bepinex.plugins.professions"; private static readonly ConfigSync configSync = new ConfigSync("org.bepinex.plugins.professions") { DisplayName = "Professions", CurrentVersion = "1.4.1", MinimumRequiredVersion = "1.4.1" }; private static ConfigEntry<Toggle> serverConfigLocked = null; private static ConfigEntry<KeyboardShortcut> professionPanelHotkey = null; private static ConfigEntry<int> maximumAllowedProfessions = null; public static ConfigEntry<Toggle> allowUnselect = null; private static ConfigEntry<float> professionChangeCooldown = null; public static readonly Dictionary<Profession, ConfigEntry<ProfessionToggle>> blockOtherProfessions = new Dictionary<Profession, ConfigEntry<ProfessionToggle>>(); private static DateTime serverTime = DateTime.Now; private int configOrder; private static readonly Dictionary<Profession, string> professionDescriptions = new Dictionary<Profession, string> { { Profession.Blacksmithing, "A blacksmith uses the smelter and forge to smelt ore and craft armor and weapons." }, { Profession.Building, "A builder uses the hammer to construct floors, walls and roofs for shelter." }, { Profession.Cooking, "A cook creates lavish meals." }, { Profession.Farming, "A farmer uses the cultivator to cultivate land to plant crops and harvest them." }, { Profession.Lumberjacking, "A lumberjack uses an axe to cut trees to collect all kind of woods." }, { Profession.Mining, "A miner uses a pickaxe to mine stone and ore." }, { Profession.Ranching, "A rancher can tame certain animals and breed them for their meat." }, { Profession.Sailing, "A sailor uses ships to explore the vast ocean and discover new islands." }, { Profession.Alchemy, "An alchemist creates powerful potions, flasks and elixirs." }, { Profession.Jewelcrafting, "A jeweler cuts powerful magic gems and adds sockets to equipment." }, { Profession.Foraging, "A forager collects berries and mushrooms." }, { Profession.Exploration, "An explorer explores the world and searches treasure chests." } }; private static GameObject professionPanel = null; [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(2)] private static GameObject professionPanelInstance; private static readonly Dictionary<Profession, GameObject> professionPanelElements = new Dictionary<Profession, GameObject>(); [<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(2)] private readonly Assembly bepinexConfigManager = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager"); private ConfigEntry<T> config<[<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown description = new ConfigDescription(description.Description, description.AcceptableValues, CollectionExtensions.AddItem<object>((IEnumerable<object>)description.Tags, (object)new ConfigurationManagerAttributes { Order = configOrder-- }).ToArray()); ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description); configSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry<T> config<[<0f599e97-3333-4107-b0b5-ba674f05d9ec>Nullable(2)] T>(string group, string name, T value, 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, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } private static SkillType fromProfession(Profession profession) { return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(profession.ToString())); } private static Profession? fromSkill(SkillType skill) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ((IEnumerable<Profession>)(Profession[])Enum.GetValues(typeof(Profession))).Select((Func<Profession, Profession?>)((Profession p) => p)).FirstOrDefault((Profession? p) => skill == fromProfession(p.Value)); } public void Awake() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) try { Type configManagerType = bepinexConfigManager?.GetType("ConfigurationManager.ConfigurationManager"); object configManager = ((configManagerType == null) ? null : Chainloader.ManagerObject.GetComponent(configManagerType)); serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); configSync.AddLockingConfigEntry<Toggle>(serverConfigLocked); maximumAllowedProfessions = config("1 - General", "Maximum Number of Professions", 1, new ConfigDescription("Sets the maximum number of professions a player is allowed to have at the same time.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>())); allowUnselect = config("1 - General", "Allow Profession Change", Toggle.Off, "If on, players can unselect professions and select new ones."); ConfigurationManagerAttributes changeCooldownAttributes = new ConfigurationManagerAttributes { Browsable = (allowUnselect.Value == Toggle.On) }; allowUnselect.SettingChanged += [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] (object _, EventArgs _) => { changeCooldownAttributes.Browsable = allowUnselect.Value == Toggle.On; reloadConfigDisplay(); }; professionChangeCooldown = config("1 - General", "Profession Change Cooldown", 0f, new ConfigDescription("Time between profession changes. Uses real time hours. Use 0 to disable this.", (AcceptableValueBase)null, new object[1] { changeCooldownAttributes })); professionPanelHotkey = config<KeyboardShortcut>("1 - General", "Profession Panel Hotkey", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "Key or key combination to open the profession panel.", synchronizedSetting: false); Profession[] array = (Profession[])Enum.GetValues(typeof(Profession)); foreach (Profession profession in array) { blockOtherProfessions[profession] = config("2 - Professions", $"{profession} behaviour", ProfessionToggle.BlockExperience, "Ignored: The skill is not considered a profession and can be used by everyone.\nBlock Experience: If you did not pick the skills profession, you will not get any experience for this skill.\nBlock Usage: If you did not pick the skills profession, you will not be able to perform the action that would grant you experience for the skill."); blockOtherProfessions[profession].SettingChanged += [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] (object _, EventArgs _) => { if (professionPanelElements.TryGetValue(profession, out var value)) { value.SetActive(blockOtherProfessions[profession].Value != ProfessionToggle.Ignored); } }; } Assembly executingAssembly = Assembly.GetExecutingAssembly(); new Harmony("org.bepinex.plugins.professions").PatchAll(executingAssembly); professionPanel = LoadAssetBundle("professionSelect").LoadAsset<GameObject>("ProfessionPanel"); Skill_Element.blockExperience = Helper.loadSprite("blockxp.png", 20, 20); Skill_Element.blockUsage = Helper.loadSprite("blockusage.png", 20, 20); void reloadConfigDisplay() { configManagerType?.GetMethod("BuildSettingList").Invoke(configManager, Array.Empty<object>()); } } catch (Exception arg) { Debug.LogError((object)$"Professions Awake failed. Shutting down, to prevent further issues with the professions. Exception:\n{arg}"); Application.Quit(); } } [<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(2)] private static void onServerTimeReceived(ZRpc rpc, long time) { serverTime = new DateTime(time); } private static void onServerTimeRequest(ZRpc rpc) { rpc.Invoke("Professions GetServerTime", new object[1] { DateTime.Now.Ticks }); } private static void requestServerTime() { if (ZNet.instance.IsServer()) { onServerTimeReceived(null, DateTime.Now.Ticks); } else { ZNet.instance.GetServerPeer().m_rpc.Invoke("Professions GetServerTime", Array.Empty<object>()); } } private void Update() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) PreventMainMenu.AllowMainMenu = true; if (Player.m_localPlayer == null) { return; } KeyboardShortcut value = professionPanelHotkey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && (professionPanelInstance.activeSelf || ((Character)Player.m_localPlayer).TakeInput())) { professionPanelInstance.SetActive(!professionPanelInstance.activeSelf); if (professionPanelInstance.activeSelf) { UpdateSelectPanelSelections(); requestServerTime(); } } if (professionPanelInstance.activeSelf && Input.GetKey((KeyCode)27)) { professionPanelInstance.SetActive(false); PreventMainMenu.AllowMainMenu = false; } } private static void UpdateSelectPanelSelections() { List<Profession> list = selectedProfessions(Player.m_localPlayer); if (!Player.m_localPlayer.m_knownStations.TryGetValue("Professions extraProfessionsSlots", out var value)) { Player.m_localPlayer.m_knownStations["Professions extraProfessionsSlots"] = 0; value = 0; } foreach (KeyValuePair<Profession, GameObject> professionPanelElement in professionPanelElements) { Skill_Element component = professionPanelElement.Value.GetComponent<Skill_Element>(); component.Toggle(list.Contains(professionPanelElement.Key), list.Count >= maximumAllowedProfessions.Value + value); component.UpdateImageDisplay(blockOtherProfessions[professionPanelElement.Key].Value); } int num = Mathf.CeilToInt(Mathf.Pow(1.6f, (float)(maximumAllowedProfessions.Value + value))); professionPanelInstance.GetComponent<ProfessionPanel>().description.text = string.Format("You have {0} / {1} professions selected.\nYou need Craftsman Trophy x {2} to unlock another profession.\nYou are{3} allowed to change your professions{4}.", list.Count, maximumAllowedProfessions.Value + value, num, (allowUnselect.Value == Toggle.Off) ? " not" : "", (professionChangeCooldown.Value > 0f && allowUnselect.Value == Toggle.On) ? (" every " + Helper.getHumanFriendlyTime((int)(professionChangeCooldown.Value * 3600f))) : ""); } private static AssetBundle LoadAssetBundle(string bundleName) { string name = typeof(Professions).Assembly.GetManifestResourceNames().Single([<a759d5d3-f43a-4d2a-8046-86fb09ec6a69>NullableContext(0)] (string s) => s.EndsWith(bundleName)); return AssetBundle.LoadFromStream(typeof(Professions).Assembly.GetManifestResourceStream(name)); } public static List<Profession> selectedProfessions(Player player) { return selectedProfessions(player.m_skills); } private static List<Profession> selectedProfessions(Skills skills) { Skill value; return ((Profession[])Enum.GetValues(typeof(Profession))).Where((Profession profession) => blockOtherProfessions[profession].Value != 0 && skills.m_skillData.TryGetValue(fromProfession(profession), out value) && value.m_level > 0f).ToList(); } } } namespace Microsoft.CodeAnalysis { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] 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; } } [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] 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; } 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() { 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 = (from p in ZNet.instance.GetPeers() where adminList.Contains(p.m_rpc.GetSocket().GetHostName()) select p).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 : 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; } 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); } } } [HarmonyPrefix] [HarmonyPriority(800)] 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()) { BufferingSocket value = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value); 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) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = value; } } [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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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); foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues) { if (!isServer && configValue.Key.LocalBaseValue == null) { configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue; } configValue.Key.BaseConfig.BoxedValue = configValue.Value; } 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 " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName)); } else { Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match.")); } continue; } Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs")); return new ParsedConfigs(); } return parsedConfigs; } private static bool isWritableConfig(OwnConfigEntryBase config) { OwnConfigEntryBase config2 = config; ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2)); if (configSync == null) { return true; } return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt)); } private void serverLockedSettingChanged() { foreach (OwnConfigEntryBase allConfig in allConfigs) { configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig); } } private void resetConfigsFromServer() { foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null)) { item.BaseConfig.BoxedValue = item.LocalBaseValue; item.LocalBaseValue = null; } foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null)) { item2.BoxedValue = item2.LocalBaseValue; item2.LocalBaseValue = null; } lockedConfigChanged -= serverLockedSettingChanged; serverLockedSettingChanged(); } private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package) { ZNetPeer peer2 = peer; ZRoutedRpc rpc = ZRoutedRpc.instance; if (rpc == null) { yield break; } byte[] data = package.GetArray(); if (data != null && data.LongLength > 250000) { int fragments = (int)(1 + (data.LongLength - 1) / 250000); long packageIdentifier = ++packageCounter; int fragment = 0; while (fragment < fragments) { foreach (bool item in waitForQueue()) { yield return item; } if (peer2.m_socket.IsConnected()) { ZPackage fragmentedPackage = new ZPackage(); fragmentedPackage.Write((byte)2); fragmentedPackage.Write(packageIdentifier); fragmentedPackage.Write(fragment); fragmentedPackage.Write(fragments); fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray()); SendPackage(fragmentedPackage); if (fragment != fragments - 1) { yield return true; } int num = fragment + 1; fragment = num; continue; } break; } yield break; } foreach (bool item2 in waitForQueue()) { yield return item2; } SendPackage(package); void SendPackage(ZPackage pkg) { string text = Name + " ConfigSync"; if (isServer) { peer2.m_rpc.Invoke(text, new object[1] { pkg }); } else { rpc.InvokeRoutedRPC(peer2.m_server ? 0 : peer2.m_uid, text, new object[1] { pkg }); } } IEnumerable<bool> waitForQueue() { float timeout = Time.time + 30f; while (peer2.m_socket.GetSendQueueSize() > 20000) { if (Time.time > timeout) { Debug.Log((object)$"Disconnecting {peer2.m_uid} after 30 seconds config sending timeout"); peer2.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 }); ZNet.instance.Disconnect(peer2); break; } yield return false; } } } private IEnumerator sendZPackage(long target, ZPackage package) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return Enumerable.Empty<object>().GetEnumerator(); } List<ZNetPeer> list = (List<ZNetPeer>)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance); if (target != ZRoutedRpc.Everybody) { list = list.Where((ZNetPeer p) => p.m_uid == target).ToList(); } return sendZPackage(list, package); } private IEnumerator sendZPackage(List<ZNetPeer> peers, ZPackage package) { ZPackage package2 = package; if (!Object.op_Implicit((Object)(object)ZNet.instance)) { yield break; } byte[] rawData = package2.GetArray(); if (rawData != null && rawData.LongLength > 10000) { ZPackage compressedPackage = new ZPackage(); compressedPackage.Write((byte)4); MemoryStream output = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal)) { deflateStream.Write(rawData, 0, rawData.Length); } compressedPackage.Write(output.ToArray()); package2 = compressedPackage; } List<IEnumerator<bool>> writers = (from peer in peers where peer.IsReady() select peer into p select distributeConfigToPeers(p, package2)).ToList(); writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext()); while (writers.Count > 0) { yield return null; writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext()); } } private void Broadcast(long target, params ConfigEntryBase[] configs) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(configs); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private void Broadcast(long target, params CustomSyncedValueBase[] customValues) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(null, customValues); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private static OwnConfigEntryBase? configData(ConfigEntryBase config) { return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault(); } public static SyncedConfigEntry<T>? ConfigData<T>(ConfigEntry<T> config) { return ((ConfigEntryBase)config).Description.Tags?.OfType<SyncedConfigEntry<T>>().SingleOrDefault(); } private static T configAttribute<T>(ConfigEntryBase config) { return config.Description.Tags.OfType<T>().First(); } private static Type configType(ConfigEntryBase config) { return configType(config.SettingType); } private static Type configType(Type type) { return type.IsEnum ? Enum.GetUnderlyingType(type) : type; } private static ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase>? configs = null, IEnumerable<CustomSyncedValueBase>? customValues = null, IEnumerable<PackageEntry>? packageEntries = null, bool partial = true) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>(); List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>(); ZPackage val = new ZPackage(); val.Write((byte)(partial ? 1 : 0)); val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0)); foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>()) { AddEntryToPackage(val, item); } foreach (CustomSyncedValueBase item2 in list2) { AddEntryToPackage(val, new PackageEntry { section = "Internal", key = item2.Identifier, type = item2.Type, value = item2.BoxedValue }); } foreach (ConfigEntryBase item3 in list) { AddEntryToPackage(val, new PackageEntry { section = item3.Definition.Section, key = item3.Definition.Key, type = configType(item3), value = item3.BoxedValue }); } return val; } private static void AddEntryToPackage(ZPackage package, PackageEntry entry) { package.Write(entry.section); package.Write(entry.key); package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type)); AddValueToZPackage(package, entry.value); } private static string GetZPackageTypeString(Type type) { return type.AssemblyQualifiedName; } private static void AddValueToZPackage(ZPackage package, object? value) { Type type = value?.GetType(); if (value is Enum) { value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture); } else { if (value is ICollection collection) { package.Write(collection.Count); { foreach (object item in collection) { AddValueToZPackage(package, item); } return; } } if ((object)type != null && type.IsValueType && !type.IsPrimitive) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); package.Write(fields.Length); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { package.Write(GetZPackageTypeString(fieldInfo.FieldType)); AddValueToZPackage(package, fieldInfo.GetValue(value)); } return; } } ZRpc.Serialize(new object[1] { value }, ref package); } private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type) { if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = package.ReadInt(); if (num != fields.Length) { throw new InvalidDeserializationTypeException { received = $"(field count: {num})", expected = $"(field count: {fields.Length})" }; } object uninitializedObject = FormatterServices.GetUninitializedObject(type); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { string text = package.ReadString(); if (text != GetZPackageTypeString(fieldInfo.FieldType)) { throw new InvalidDeserializationTypeException { received = text, expected = GetZPackageTypeString(fieldInfo.FieldType), field = fieldInfo.Name }; } fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType)); } return uninitializedObject; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { int num2 = package.ReadInt(); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type); Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments); FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); for (int j = 0; j < num2; j++) { object obj = ReadValueWithTypeFromZPackage(package, type2); dictionary.Add(field.GetValue(obj), field2.GetValue(obj)); } return dictionary; } if (type != typeof(List<string>) && type.IsGenericType) { Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]); if ((object)type3 != null && type3.IsAssignableFrom(type)) { int num3 = package.ReadInt(); object obj2 = Activator.CreateInstance(type); MethodInfo method = type3.GetMethod("Add"); for (int k = 0; k < num3; k++) { method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) }); } return obj2; } } ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type); List<object> source = new List<object>(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source); return source.First(); } } [PublicAPI] [HarmonyPatch] internal class VersionCheck { private static readonly HashSet<VersionCheck> versionChecks; private static readonly Dictionary<string, string> notProcessedNames; public string Name; private string? displayName; private string? currentVersion; private string? minimumRequiredVersion; public bool ModRequired = true; private string? ReceivedCurrentVersion; private string? ReceivedMinimumRequiredVersion; private readonly List<ZRpc> ValidatedClients = new List<ZRpc>(); private ConfigSync? ConfigSync; public string DisplayName { get { return displayName ?? Name; } set { displayName = value; } } public string CurrentVersion { get { return currentVersion ?? "0.0.0"; } set { currentVersion = value; } } public string MinimumRequiredVersion { get { return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0"); } set { minimumRequiredVersion = value; } } private static void PatchServerSync() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null)); if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0) { return; } Harmony val = new Harmony("org.bepinex.helpers.ServerSync"); foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) }) where t.IsClass select t) { val.PatchAll(item); } } static VersionCheck() { versionChecks = new HashSet<VersionCheck>(); notProcessedNames = new Dictionary<string, string>(); typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1] { new Action(PatchServerSync) }); } public VersionCheck(string name) { Name = name; ModRequired = true; versionChecks.Add(this); } public VersionCheck(ConfigSync configSync) { ConfigSync = configSync; Name = ConfigSync.Name; versionChecks.Add(this); } public void Initialize() { ReceivedCurrentVersion = null; ReceivedMinimumRequiredVersion = null; if (ConfigSync != null) { Name = ConfigSync.Name; DisplayName = ConfigSync.DisplayName; CurrentVersion = ConfigSync.CurrentVersion; MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion; ModRequired = ConfigSync.ModRequired; } } private bool IsVersionOk() { if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null) { return !ModRequired; } bool flag = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion); bool flag2 = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion); return flag && flag2; } private string ErrorClient() { if (ReceivedMinimumRequiredVersion == null) { return "Mod " + DisplayName + " must not be installed."; } return (new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)) ? ("Mod " + DisplayName + " requires maximum " + ReceivedCurrentVersion + ". Installed is version " + CurrentVersion + ".") : ("Mod " + DisplayName + " requires minimum " + ReceivedMinimumRequiredVersion + ". Installed is version " + CurrentVersion + "."); } private string ErrorServer(ZRpc rpc) { return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion; } private string Error(ZRpc? rpc = null) { return (rpc == null) ? ErrorClient() : ErrorServer(rpc); } private static VersionCheck[] GetFailedClient() { return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray(); } private static VersionCheck[] GetFailedServer(ZRpc rpc) { ZRpc rpc2 = rpc; return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc2)).ToArray(); } private static void Logout() { Game.instance.Logout(true, true); AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3); } private static void DisconnectClient(ZRpc rpc) { rpc.Invoke("Error", new object[1] { 3 }); } private static void CheckVersion(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, null); } private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action<ZRpc, ZPackage>? original) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); bool flag = false; foreach (VersionCheck versionCheck in versionChecks) { if (!(text != versionCheck.Name)) { Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + ".")); versionCheck.ReceivedMinimumRequiredVersion = text2; versionCheck.ReceivedCurrentVersion = text3; if (ZNet.instance.IsServer() && versionCheck.IsVersionOk()) { versionCheck.ValidatedClients.Add(rpc); } flag = true; } } if (flag) { return; } pkg.SetPos(0); if (original != null) { original(rpc, pkg); if (pkg.GetPos() == 0) { notProcessedNames.Add(text, text3); } } } [HarmonyPrefix] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance) { VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient()); if (array.Length == 0) { return true; } VersionCheck[] array2 = array; foreach (VersionCheck versionCheck in array2) { Debug.LogWarning((object)versionCheck.Error(rpc)); } if (__instance.IsServer()) { DisconnectClient(rpc); } else { Logout(); } return false; } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPrefix] private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown notProcessedNames.Clear(); IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc); if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck"))) { object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")]; Action<ZRpc, ZPackage> action = (Action<ZRpc, ZPackage>)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)delegate(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, action); }); } else { peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)CheckVersion); } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.Initialize(); if (versionCheck.ModRequired || __instance.IsServer()) { Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + ".")); ZPackage val = new ZPackage(); val.Write(versionCheck.Name); val.Write(versionCheck.MinimumRequiredVersion); val.Write(versionCheck.CurrentVersion); peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val }); } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPrefix] private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance) { if (!__instance.IsServer()) { return; } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.ValidatedClients.Remove(peer.m_rpc); } } [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] private static void ShowConnectionError(FejdStartup __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3) { return; } VersionCheck[] failedClient = GetFailedClient(); if (failedClient.Length != 0) { string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error())); TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + text; } foreach (KeyValuePair<string, string> item in notProcessedNames.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> kv) => kv.Key)) { if (!__instance.m_connectionFailedError.text.Contains(item.Key)) { TMP_Text connectionFailedError2 = __instance.m_connectionFailedError; connectionFailedError2.text = connectionFailedError2.text + "\n" + item.Key + " (Version: " + item.Value + ")"; } } } } }