Decompiled source of Mining Caves v0.2.0

Plugins/VentureValheim.MiningCaves.dll

Decompiled 5 months 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;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("VentureValheim.MiningCaves")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VentureValheim.MiningCaves")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("291F2F3D-B629-453D-AF1A-1A7C815758DE")]
[assembly: AssemblyFileVersion("0.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace VentureValheim.MiningCaves
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.orianaventure.mod.MiningCaves", "MiningCaves", "0.2.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class MiningCavesPlugin : BaseUnityPlugin
	{
		private const string ModName = "MiningCaves";

		private const string ModVersion = "0.2.0";

		private const string Author = "com.orianaventure.mod";

		private const string ModGUID = "com.orianaventure.mod.MiningCaves";

		private readonly Harmony HarmonyInstance = new Harmony("com.orianaventure.mod.MiningCaves");

		public static readonly ManualLogSource MiningCavesLogger = Logger.CreateLogSource("MiningCaves");

		private static string ConfigFileName = "com.orianaventure.mod.MiningCaves.cfg";

		private static string ConfigFileFullPath;

		public static GameObject Root;

		public static ConfigEntry<bool> CE_AdminBypass;

		public static ConfigEntry<bool> CE_LockTerrain;

		public static ConfigEntry<string> CE_LockTerrainIgnoreItems;

		public static ConfigEntry<bool> CE_RemoveSilverWishbonePing;

		private readonly ConfigurationManagerAttributes AdminConfig = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};

		private readonly ConfigurationManagerAttributes ClientConfig = new ConfigurationManagerAttributes
		{
			IsAdminOnly = false
		};

		private DateTime _lastReloadTime;

		private const long RELOAD_DELAY = 10000000L;

		public static bool GetLockTerrain()
		{
			if (CE_AdminBypass.Value && SynchronizationManager.Instance.PlayerIsAdmin)
			{
				return false;
			}
			return CE_LockTerrain.Value;
		}

		public static string GetLockTerrainIgnoreItems()
		{
			return CE_LockTerrainIgnoreItems.Value;
		}

		public static bool GetRemoveSilverWishbonePing()
		{
			return CE_RemoveSilverWishbonePing.Value;
		}

		private void AddConfig<T>(string key, string section, string description, bool synced, T value, ref ConfigEntry<T> configEntry)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			string extendedDescription = GetExtendedDescription(description, synced);
			configEntry = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(extendedDescription, (AcceptableValueBase)null, new object[1] { synced ? AdminConfig : ClientConfig }));
		}

		public string GetExtendedDescription(string description, bool synchronizedSetting)
		{
			return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]");
		}

		public void Awake()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			AddConfig("AdminBypass", "General", "True to allow admins to bypass settings (boolean)", synced: true, value: false, ref CE_AdminBypass);
			AddConfig("LockTerrain", "General", "True to restrict actions that would alter the terrain such as mining or flattening (boolean)", synced: true, value: false, ref CE_LockTerrain);
			AddConfig("LockTerrainIgnoreItems", "General", "Prefab names of items to ignore for the terrain locking feature (comma-separated)", synced: true, "", ref CE_LockTerrainIgnoreItems);
			AddConfig("RemoveSilverWishbonePing", "General", "True to always remove the wishbone ping from silver veins (boolean)", synced: true, value: false, ref CE_RemoveSilverWishbonePing);
			ZoneManager.OnVanillaLocationsAvailable += CaveManager.AddMiningCaves;
			Root = new GameObject("MiningCavesRoot");
			Root.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)Root);
			MiningCavesLogger.LogInfo((object)"So you're mining stuff to craft with and crafting stuff to mine with?");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			HarmonyInstance.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			DateTime now = DateTime.Now;
			long num = now.Ticks - _lastReloadTime.Ticks;
			if (File.Exists(ConfigFileFullPath) && num >= 10000000)
			{
				try
				{
					MiningCavesLogger.LogInfo((object)"Attempting to reload configuration...");
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch
				{
					MiningCavesLogger.LogError((object)("There was an issue loading " + ConfigFileName));
				}
				_lastReloadTime = now;
				if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated())
				{
					TerrainManager.ApplyTerrainLocking();
				}
			}
		}

		static MiningCavesPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			CE_AdminBypass = null;
			CE_LockTerrain = null;
			CE_LockTerrainIgnoreItems = null;
			CE_RemoveSilverWishbonePing = null;
		}
	}
	public class CaveManager
	{
		public static void AddMiningCaves()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			GameObject prefab = PrefabManager.Instance.GetPrefab("rock4_copper_frac");
			if ((Object)(object)prefab != (Object)null)
			{
				TerrainModifier[] componentsInChildren = prefab.gameObject.GetComponentsInChildren<TerrainModifier>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
			}
			AssetBundle val = AssetUtils.LoadAssetBundleFromResources("vv_miningcaves", Assembly.GetExecutingAssembly());
			string text = "VV_CopperTinCave";
			GameObject obj = ZoneManager.Instance.CreateLocationContainer(val, text);
			LocationConfig val2 = new LocationConfig();
			val2.Biome = (Biome)8;
			val2.Quantity = 50;
			val2.ExteriorRadius = 12f;
			val2.HasInterior = true;
			val2.InteriorRadius = 35f;
			val2.MinAltitude = 3f;
			val2.MaxAltitude = 1000f;
			val2.Priotized = true;
			CustomLocation val3 = new CustomLocation(obj, true, val2);
			ZoneManager.Instance.AddCustomLocation(val3);
			string text2 = "VV_SilverCave";
			GameObject obj2 = ZoneManager.Instance.CreateLocationContainer(val, text2);
			LocationConfig val4 = new LocationConfig();
			val4.Biome = (Biome)4;
			val4.Quantity = 50;
			val4.ExteriorRadius = 16f;
			val4.HasInterior = true;
			val4.InteriorRadius = 40f;
			val4.MinAltitude = 90f;
			val4.MaxAltitude = 2000f;
			val4.Priotized = true;
			CustomLocation val5 = new CustomLocation(obj2, true, val4);
			ZoneManager.Instance.AddCustomLocation(val5);
			ZoneManager.OnVanillaLocationsAvailable -= AddMiningCaves;
		}
	}
	public class TerrainManager
	{
		protected struct OriginalTerrainComp
		{
			public string Name;

			public GameObject SpawnOnHit;

			public List<GameObject> Pieces;

			public OriginalTerrainComp(string name, GameObject spawnOnHit, List<GameObject> pieces)
			{
				Name = name;
				SpawnOnHit = spawnOnHit;
				Pieces = pieces;
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static class Patch_ObjectDB_Awake
		{
			private static void Postfix()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				Scene activeScene = SceneManager.GetActiveScene();
				if (((Scene)(ref activeScene)).name.Equals("main"))
				{
					_objectDBReady = true;
					ApplyTerrainLocking();
				}
				else
				{
					_objectDBReady = false;
				}
			}
		}

		private const string SUFFIX = "_VVMC";

		private static bool _objectDBReady = false;

		private static List<OriginalTerrainComp> _originalTerrainCompList = new List<OriginalTerrainComp>();

		public static HashSet<string> StringToSet(string str)
		{
			HashSet<string> hashSet = new HashSet<string>();
			if (!Utility.IsNullOrWhiteSpace(str))
			{
				List<string> list = str.Split(new char[1] { ',' }).ToList();
				for (int i = 0; i < list.Count; i++)
				{
					hashSet.Add(list[i].Trim());
				}
			}
			return hashSet;
		}

		public static bool GetItemDrop(string name, out ItemDrop item)
		{
			item = null;
			if (!Utility.IsNullOrWhiteSpace(name))
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(name));
				if ((Object)(object)itemPrefab == (Object)null)
				{
					itemPrefab = ObjectDB.instance.GetItemPrefab(name);
				}
				if ((Object)(object)itemPrefab != (Object)null)
				{
					item = itemPrefab.GetComponent<ItemDrop>();
					if ((Object)(object)item != (Object)null)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void RestoreOriginalValues()
		{
			foreach (OriginalTerrainComp originalTerrainComp in _originalTerrainCompList)
			{
				if (GetItemDrop(originalTerrainComp.Name, out ItemDrop item))
				{
					item.m_itemData.m_shared.m_spawnOnHitTerrain = originalTerrainComp.SpawnOnHit;
					if ((Object)(object)item.m_itemData.m_shared.m_buildPieces != (Object)null)
					{
						item.m_itemData.m_shared.m_buildPieces.m_pieces = originalTerrainComp.Pieces;
					}
				}
			}
			_originalTerrainCompList = new List<OriginalTerrainComp>();
		}

		private static bool RemoveHitTerrainFromTable(ref ItemDrop itemDrop, out List<GameObject> OriginalPieces)
		{
			bool flag = false;
			OriginalPieces = null;
			PieceTable buildPieces = itemDrop.m_itemData.m_shared.m_buildPieces;
			if ((Object)(object)buildPieces != (Object)null)
			{
				OriginalPieces = buildPieces.m_pieces;
				List<GameObject> list = new List<GameObject>();
				foreach (GameObject piece in buildPieces.m_pieces)
				{
					TerrainOp component = piece.GetComponent<TerrainOp>();
					if ((Object)(object)component != (Object)null)
					{
						if (component.m_settings.m_level || component.m_settings.m_smooth)
						{
							GameObject val = Object.Instantiate<GameObject>(piece, MiningCavesPlugin.Root.transform, false);
							((Object)val).name = Utils.GetPrefabName(val) + "_VVMC";
							TerrainOp component2 = val.GetComponent<TerrainOp>();
							component2.m_settings.m_level = false;
							component2.m_settings.m_smooth = false;
							itemDrop.m_itemData.m_shared.m_spawnOnHitTerrain = val;
							list.Add(val);
							flag = true;
							continue;
						}
						if (component.m_settings.m_raise)
						{
							flag = true;
							continue;
						}
					}
					list.Add(piece);
				}
				if (flag)
				{
					itemDrop.m_itemData.m_shared.m_buildPieces.m_pieces = list;
				}
			}
			return flag;
		}

		private static bool RemoveHitTerrain(ref ItemDrop itemDrop, out GameObject original)
		{
			original = itemDrop.m_itemData.m_shared.m_spawnOnHitTerrain;
			if ((Object)(object)original != (Object)null)
			{
				TerrainOp component = original.GetComponent<TerrainOp>();
				if ((Object)(object)component != (Object)null && (component.m_settings.m_raise || (Object)(object)component.m_spawnOnPlaced != (Object)null))
				{
					GameObject val = Object.Instantiate<GameObject>(original, MiningCavesPlugin.Root.transform, false);
					((Object)val).name = Utils.GetPrefabName(val) + "_VVMC";
					TerrainOp component2 = val.GetComponent<TerrainOp>();
					component2.m_settings.m_raise = false;
					component2.m_spawnOnPlaced = null;
					itemDrop.m_itemData.m_shared.m_spawnOnHitTerrain = val;
					return true;
				}
			}
			return false;
		}

		public static void ApplyTerrainLocking()
		{
			if (_objectDBReady)
			{
				RestoreOriginalValues();
				if (MiningCavesPlugin.GetLockTerrain())
				{
					RemoveToolTerrainChanges();
				}
				if (MiningCavesPlugin.GetRemoveSilverWishbonePing() || (MiningCavesPlugin.GetLockTerrain() && Utility.IsNullOrWhiteSpace(MiningCavesPlugin.GetLockTerrainIgnoreItems())))
				{
					RemoveWishbonePing();
				}
			}
		}

		private static void RemoveToolTerrainChanges()
		{
			HashSet<string> hashSet = StringToSet(MiningCavesPlugin.GetLockTerrainIgnoreItems());
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if (hashSet.Contains(((Object)item).name))
				{
					continue;
				}
				ItemDrop itemDrop = item.GetComponent<ItemDrop>();
				if (!((Object)(object)itemDrop == (Object)null))
				{
					GameObject original = null;
					List<GameObject> OriginalPieces = null;
					if (RemoveHitTerrainFromTable(ref itemDrop, out OriginalPieces) || RemoveHitTerrain(ref itemDrop, out original))
					{
						_originalTerrainCompList.Add(new OriginalTerrainComp(((Object)item).name, original, OriginalPieces));
					}
				}
			}
			MiningCavesPlugin.MiningCavesLogger.LogInfo((object)"Done removing terrain operations from tools.");
		}

		private static void RemoveWishbonePing()
		{
			GameObject prefab = ZNetScene.instance.GetPrefab("silvervein");
			if ((Object)(object)prefab != (Object)null)
			{
				Beacon componentInChildren = prefab.GetComponentInChildren<Beacon>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Object.Destroy((Object)(object)componentInChildren);
					MiningCavesPlugin.MiningCavesLogger.LogInfo((object)"Done removing silver wishbone ping.");
				}
				else
				{
					MiningCavesPlugin.MiningCavesLogger.LogDebug((object)"Issue finding silvervein beacon, could not remove.");
				}
			}
			else
			{
				MiningCavesPlugin.MiningCavesLogger.LogDebug((object)"Issue finding silvervein. Could not remove beacon.");
			}
		}
	}
}