Decompiled source of Mistward v0.7.1

plugins/Mistward.dll

Decompiled a month ago
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.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Mistward.common;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Mistward")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mistward")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace Mistward
{
	internal class Config
	{
		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<float> MistwardRange;

		public Config(ConfigFile Config)
		{
			cfg = Config;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(Config);
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_001b: 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_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging for Mistward.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			MistwardRange = BindServerConfig("Mistward", "MistwardRange", 70f, "The distance the mistward effects.", advanced: false, 10f, 200f);
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, ConfigDescription configDescription)
		{
			return cfg.Bind<string>(catagory, key, value, configDescription);
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, bool advanced = false)
		{
			//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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, bool advanced = false)
		{
			//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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<short> BindServerConfig(string catagory, string key, short value, string description, bool advanced = false, short valmin = 0, short valmax = 150)
		{
			//IL_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			return cfg.Bind<short>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<short>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//IL_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
	[BepInPlugin("MidnightsFX.Mistward", "Mistward", "0.7.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Mistward : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.Mistward";

		public const string PluginName = "Mistward";

		public const string PluginVersion = "0.7.1";

		internal static AssetBundle EmbeddedResourceBundle;

		public Config cfg;

		private void Awake()
		{
			cfg = new Config(((BaseUnityPlugin)this).Config);
			EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Mistward.AssetsEmbedded.mistward", typeof(Mistward).Assembly);
			AddLocalizations();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary.Add("name", "Mistward");
			dictionary.Add("catagory", "Misc");
			dictionary.Add("prefab", "MFX_Mistward");
			dictionary.Add("sprite", "mistward_icon");
			dictionary.Add("requiredBench", "piece_stonecutter");
			new JotunnPiece(dictionary, new Dictionary<string, bool>(), new Dictionary<string, Tuple<int, bool>>
			{
				{
					"BlackMarble",
					Tuple.Create(30, item2: true)
				},
				{
					"Copper",
					Tuple.Create(15, item2: true)
				},
				{
					"Sap",
					Tuple.Create(10, item2: true)
				},
				{
					"BlackCore",
					Tuple.Create(1, item2: true)
				}
			});
		}

		internal static string ReadEmbeddedResourceFile(string filename)
		{
			using Stream stream = typeof(Mistward).Assembly.GetManifestResourceStream(filename);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		private void AddLocalizations()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Logger.LogDebug((object)"Loading Localizations.");
			string[] manifestResourceNames = typeof(Mistward).Assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (text.Contains("Localizations"))
				{
					string input = ReadEmbeddedResourceFile(text);
					string text2 = Regex.Replace(input, "\\/\\/.*", "");
					string[] array = text.Split(new char[1] { '.' });
					Logger.LogDebug((object)("Adding localization: " + array[2]));
					localization.AddJsonFile(array[2], text2);
				}
			}
		}
	}
}
namespace Mistward.common
{
	public class JotunnPiece
	{
		private Dictionary<string, string> PieceMetadata;

		private Dictionary<string, Tuple<int, bool>> RecipeData;

		private Dictionary<string, bool> PieceToggles;

		private Dictionary<string, Tuple<int, bool>> UpdatedRecipeData = new Dictionary<string, Tuple<int, bool>>();

		private GameObject ScenePrefab;

		private GameObject PiecePrefab;

		private Sprite PieceSprite;

		private ConfigEntry<bool> EnabledConfig;

		private ConfigEntry<string> RecipeConfig;

		private ConfigEntry<string> BuiltAt;

		private ConfigEntry<string> BuildCategory;

		private static ParticleSystemForceField mistward_pushfield;

		public JotunnPiece(Dictionary<string, string> metadata, Dictionary<string, bool> pieceToggles, Dictionary<string, Tuple<int, bool>> recipedata)
		{
			PieceMetadata = metadata;
			PieceToggles = pieceToggles;
			RecipeData = recipedata;
			PieceMetadata["short_item_name"] = string.Join("", metadata["name"].Split((string[]?)null, StringSplitOptions.RemoveEmptyEntries));
			if (!PieceToggles.ContainsKey("enabled"))
			{
				PieceToggles.Add("enabled", value: true);
			}
			PiecePrefab = Mistward.EmbeddedResourceBundle.LoadAsset<GameObject>("Assets/Custom/Pieces/" + PieceMetadata["catagory"] + "/" + PieceMetadata["prefab"] + ".prefab");
			PieceSprite = Mistward.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/" + PieceMetadata["sprite"] + ".png");
			InitItemConfigs();
			InitialPieceSetup();
			mistward_pushfield = ((Component)ExposedGameObjectExtension.FindDeepChild(PiecePrefab, "Particle_System_Force_Field", (IterativeSearchType)1)).GetComponent<ParticleSystemForceField>();
			mistward_pushfield.endRange = Config.MistwardRange.Value;
			Config.MistwardRange.SettingChanged += MistwardRangeChange;
			PrefabManager.OnPrefabsRegistered += SetSceneParentPrefab;
		}

		private void MistwardRangeChange(object sender, EventArgs e)
		{
			mistward_pushfield.endRange = Config.MistwardRange.Value;
			IEnumerable<GameObject> enumerable = from obj in Resources.FindObjectsOfTypeAll<GameObject>()
				where ((Object)obj).name.StartsWith(PieceMetadata["prefab"])
				select obj;
			if (Config.EnableDebugMode.Value)
			{
				Logger.LogInfo((object)$"Found in scene objects: {enumerable.Count()}");
			}
			foreach (GameObject item in enumerable)
			{
				if (Config.EnableDebugMode.Value)
				{
					Logger.LogInfo((object)("Found " + ((Object)item).name));
				}
				ParticleSystemForceField val = null;
				((Component)ExposedGameObjectExtension.FindDeepChild(item, "Particle_System_Force_Field", (IterativeSearchType)1)).TryGetComponent<ParticleSystemForceField>(ref val);
				if ((Object)(object)val != (Object)null)
				{
					if (Config.EnableDebugMode.Value)
					{
						Logger.LogInfo((object)$"{((Object)item).name} updating forcefield {Config.MistwardRange.Value}");
					}
					val.endRange = Config.MistwardRange.Value;
				}
			}
		}

		private void InitialPieceSetup()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			CreateAndUpdateRecipe();
			BuildCategory = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-category", "Misc", new ConfigDescription("Build piece Category.", (AcceptableValueBase)(object)PieceCategories.GetAcceptableValueList(), Array.Empty<object>()));
			BuildCategory.SettingChanged += CraftingCategory_SettingChanged;
			RequirementConfig[] array = (RequirementConfig[])(object)new RequirementConfig[UpdatedRecipeData.Count];
			int num = 0;
			foreach (KeyValuePair<string, Tuple<int, bool>> updatedRecipeDatum in UpdatedRecipeData)
			{
				array[num] = new RequirementConfig
				{
					Item = updatedRecipeDatum.Key,
					Amount = updatedRecipeDatum.Value.Item1,
					Recover = updatedRecipeDatum.Value.Item2
				};
				num++;
			}
			PieceConfig val = new PieceConfig
			{
				CraftingStation = (PieceMetadata["requiredBench"] ?? ""),
				PieceTable = PieceTables.Hammer,
				Category = BuildCategory.Value,
				Icon = PieceSprite,
				Requirements = array
			};
			PieceManager.Instance.AddPiece(new CustomPiece(PiecePrefab, true, val));
		}

		private void SetSceneParentPrefab()
		{
			IEnumerable<GameObject> source = from obj in Resources.FindObjectsOfTypeAll<GameObject>()
				where ((Object)obj).name == PieceMetadata["prefab"]
				select obj;
			if (Config.EnableDebugMode.Value)
			{
				Logger.LogInfo((object)string.Format("Found {0} scene parent objects: {1}", PieceMetadata["prefab"], source.Count()));
			}
			ScenePrefab = source.First();
		}

		private void CreateAndUpdateRecipe()
		{
			string text = "";
			foreach (KeyValuePair<string, Tuple<int, bool>> recipeDatum in RecipeData)
			{
				if (text.Length > 0)
				{
					text += "|";
				}
				text += $"{recipeDatum.Key},{recipeDatum.Value.Item1},{recipeDatum.Value.Item2}";
			}
			RecipeConfig = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-recipe", text, "Recipe to craft and upgrade costs. Find item ids: https://valheim.fandom.com/wiki/Item_IDs, at most 4 costs. Format: resouce_id,craft_cost,upgrade_cost eg: Wood,8,2|Iron,12,4|LeatherScraps,4,0", advanced: true);
			if (!PieceRecipeConfigUpdater(RecipeConfig.Value, startup: true))
			{
				Logger.LogWarning((object)(PieceMetadata["name"] + " has an invalid recipe. The default will be used instead."));
				PieceRecipeConfigUpdater(text, startup: true);
			}
			RecipeConfig.SettingChanged += BuildRecipeChanged_SettingChanged;
		}

		private void InitItemConfigs()
		{
			EnabledConfig = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-enabled", PieceToggles["enabled"], "Enable/Disable the " + PieceMetadata["name"] + ".");
			PieceToggles["enabled"] = EnabledConfig.Value;
			EnabledConfig.SettingChanged += BuildRecipeChanged_SettingChanged;
			BuiltAt = Config.BindServerConfig(PieceMetadata["name"] ?? "", PieceMetadata["short_item_name"] + "-requiredBench", PieceMetadata["requiredBench"], "The table required to allow building this piece, eg: 'forge', 'piece_workbench', 'blackforge', 'piece_artisanstation'.");
			PieceMetadata["requiredBench"] = BuiltAt.Value;
			BuiltAt.SettingChanged += RequiredBench_SettingChanged;
		}

		private void BuildRecipeChanged_SettingChanged(object sender, EventArgs e)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			if (sender.GetType() == typeof(ConfigEntry<string>))
			{
				ConfigEntry<string> val = (ConfigEntry<string>)sender;
				if (Config.EnableDebugMode.Value)
				{
					Logger.LogInfo((object)("Recieved new piece config " + val.Value));
				}
				if (!PieceRecipeConfigUpdater(val.Value))
				{
					return;
				}
			}
			RequirementConfig[] array = (RequirementConfig[])(object)new RequirementConfig[UpdatedRecipeData.Count];
			int num = 0;
			if (Config.EnableDebugMode.Value)
			{
				Logger.LogInfo((object)"Validating and building requirementsConfig");
			}
			foreach (KeyValuePair<string, Tuple<int, bool>> updatedRecipeDatum in UpdatedRecipeData)
			{
				if ((Object)(object)PrefabManager.Instance.GetPrefab(updatedRecipeDatum.Key) == (Object)null)
				{
					if (Config.EnableDebugMode.Value)
					{
						Logger.LogInfo((object)(updatedRecipeDatum.Key + " is not a valid prefab, skipping recipe update."));
					}
					return;
				}
				if (Config.EnableDebugMode.Value)
				{
					Logger.LogInfo((object)$"Checking entry {updatedRecipeDatum.Key} c:{updatedRecipeDatum.Value.Item1} r:{updatedRecipeDatum.Value.Item2}");
				}
				array[num] = new RequirementConfig
				{
					Item = updatedRecipeDatum.Key,
					Amount = updatedRecipeDatum.Value.Item1,
					Recover = updatedRecipeDatum.Value.Item2
				};
				num++;
			}
			if (PieceToggles["enabled"])
			{
				if (Config.EnableDebugMode.Value)
				{
					Logger.LogInfo((object)"Updating Piece.");
				}
				Requirement[] array2 = (Requirement[])(object)new Requirement[UpdatedRecipeData.Count];
				int num2 = 0;
				RequirementConfig[] array3 = array;
				foreach (RequirementConfig val2 in array3)
				{
					Requirement val3 = new Requirement();
					GameObject prefab = PrefabManager.Instance.GetPrefab(val2.Item.Replace("JVLmock_", ""));
					val3.m_resItem = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null);
					val3.m_amount = val2.Amount;
					val3.m_recover = val2.Recover;
					array2[num2] = val3;
					num2++;
				}
				if (Config.EnableDebugMode.Value)
				{
					Logger.LogInfo((object)$"Fixed mock requirements {array2.Length}.");
				}
				ScenePrefab.GetComponent<Piece>().m_resources = array2;
				if (Config.EnableDebugMode.Value)
				{
					Logger.LogInfo((object)$"New requirements set {ScenePrefab.GetComponent<Piece>().m_resources}.");
				}
			}
			else
			{
				ScenePrefab.GetComponent<Piece>().m_enabled = false;
			}
		}

		private void RequiredBench_SettingChanged(object sender, EventArgs e)
		{
			if (BuiltAt.Value == "" || BuiltAt.Value == null || BuiltAt.Value.ToLower() == "NONE")
			{
				Logger.LogInfo((object)"Setting required crafting station to none.");
				ScenePrefab.GetComponent<Piece>().m_craftingStation = null;
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab(BuiltAt.Value);
			CraftingStation val = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogWarning((object)("Required crafting station does not exist or does not have a crafting station componet, check your prefab name (" + BuiltAt.Value + ")."));
				return;
			}
			if (Config.EnableDebugMode.Value)
			{
				Logger.LogInfo((object)("Setting crafting station to " + BuiltAt.Value + "."));
			}
			ScenePrefab.GetComponent<Piece>().m_craftingStation = val;
		}

		private void CraftingCategory_SettingChanged(object sender, EventArgs e)
		{
			//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)
			ScenePrefab.GetComponent<Piece>().m_category = (PieceCategory)Enum.Parse(typeof(PieceCategory), PieceCategories.GetInternalName(BuildCategory.Value));
		}

		private bool PieceRecipeConfigUpdater(string rawrecipe, bool startup = false)
		{
			string[] array = rawrecipe.Split(new char[1] { '|' });
			Dictionary<string, Tuple<int, bool>> dictionary = new Dictionary<string, Tuple<int, bool>>();
			if (array.Length >= 1)
			{
				string[] array2 = array;
				foreach (string text in array2)
				{
					string[] array3 = text.Split(new char[1] { ',' });
					if (array3.Length != 3)
					{
						Logger.LogWarning((object)(text + " is invalid, it does not have enough segments. Proper format is: PREFABNAME,COST,REFUND_BOOL eg: Wood,8,false"));
						return false;
					}
					if (Config.EnableDebugMode.Value)
					{
						string text2 = "";
						string[] array4 = array3;
						foreach (string text3 in array4)
						{
							text2 = text2 + " " + text3;
						}
					}
					if (!startup && (Object)(object)PrefabManager.Instance.GetPrefab(array3[0]) == (Object)null)
					{
						Logger.LogWarning((object)(array3[0] + " is an invalid prefab and does not exist."));
						return false;
					}
					if (array3[0].Length == 0 || array3[1].Length == 0 || array3[2].Length == 0)
					{
						Logger.LogWarning((object)(text + " is invalid, one segment does not have enough data. Proper format is: PREFABNAME,CRAFT_COST,REFUND_BOOL eg: Wood,8,false"));
						return false;
					}
					if (!bool.TryParse(array3[2], out var result))
					{
						Logger.LogWarning((object)(text + " is invalid, the REFUND_BOOL could not be parsed to (true/false). Proper format is: PREFABNAME,CRAFT_COST,REFUND_BOOL eg: Wood,8,false"));
						return false;
					}
					if (Config.EnableDebugMode.Value)
					{
						Logger.LogInfo((object)("prefab: " + array3[0] + " c:" + array3[1] + " u:" + array3[2]));
					}
					dictionary.Add(array3[0], new Tuple<int, bool>(int.Parse(array3[1]), result));
				}
				UpdatedRecipeData.Clear();
				foreach (KeyValuePair<string, Tuple<int, bool>> item in dictionary)
				{
					UpdatedRecipeData.Add(item.Key, item.Value);
				}
				if (Config.EnableDebugMode.Value)
				{
					string text4 = "";
					foreach (KeyValuePair<string, Tuple<int, bool>> item2 in dictionary)
					{
						text4 += $" {item2.Key} c:{item2.Value.Item1} r:{item2.Value.Item2}";
					}
					Logger.LogInfo((object)("Updated recipe:" + text4));
				}
				return true;
			}
			Logger.LogWarning((object)("Invalid recipe: " + rawrecipe + ". defaults will be used. Check your prefab names."));
			UpdatedRecipeData = RecipeData;
			return false;
		}
	}
}