Decompiled source of Venture Floating Items v0.3.1

Plugins/VentureValheim.FloatingItems.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("VentureValheim.FloatingItems")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VentureValheim.FloatingItems")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("351D4592-2C96-4697-B4AE-AF5FCEBF868B")]
[assembly: AssemblyFileVersion("0.3.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.1.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.FloatingItems
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.orianaventure.mod.VentureFloatingItems", "VentureFloatingItems", "0.3.1")]
	public class FloatingItemsPlugin : BaseUnityPlugin
	{
		private const string ModName = "VentureFloatingItems";

		private const string ModVersion = "0.3.1";

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

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

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

		private static string ConfigFileFullPath;

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

		public static readonly ManualLogSource FloatingItemsLogger;

		internal static ConfigEntry<bool> CE_FloatEverything;

		internal static ConfigEntry<string> CE_FloatingItems;

		internal static ConfigEntry<string> CE_SinkingItems;

		internal static ConfigEntry<bool> CE_FloatTrophies;

		internal static ConfigEntry<bool> CE_FloatMeat;

		internal static ConfigEntry<bool> CE_FloatHides;

		internal static ConfigEntry<bool> CE_FloatGearAndCraftable;

		internal static ConfigEntry<bool> CE_FloatTreasure;

		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 GetFloatEverything()
		{
			return CE_FloatEverything.Value;
		}

		public static string GetFloatingItems()
		{
			return CE_FloatingItems.Value;
		}

		public static string GetSinkingItems()
		{
			return CE_SinkingItems.Value;
		}

		public static bool GetFloatTrophies()
		{
			return CE_FloatTrophies.Value;
		}

		public static bool GetFloatMeat()
		{
			return CE_FloatMeat.Value;
		}

		public static bool GetFloatHides()
		{
			return CE_FloatHides.Value;
		}

		public static bool GetFloatGearAndCraftable()
		{
			return CE_FloatGearAndCraftable.Value;
		}

		public static bool GetFloatTreasure()
		{
			return CE_FloatTreasure.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()
		{
			AddConfig("FloatEverything", "General", "Apply floating to everything!! (boolean).", synced: true, value: false, ref CE_FloatEverything);
			AddConfig("FloatingItems", "General", "Additional prefab names of the items you want to float (comma-separated string).", synced: true, "SerpentScale, BonemawSerpentTooth", ref CE_FloatingItems);
			AddConfig("SinkingItems", "General", "Additional prefab names of the items you want to always sink (comma-separated string).", synced: true, "BronzeNails, IronNails", ref CE_SinkingItems);
			AddConfig("FloatTrophies", "General", "Apply floating to all trophies (boolean).", synced: true, value: true, ref CE_FloatTrophies);
			AddConfig("FloatMeat", "General", "Apply floating to all types of meat (boolean).", synced: true, value: true, ref CE_FloatMeat);
			AddConfig("FloatHides", "General", "Apply floating to all leathers and jute fabrics (boolean).", synced: true, value: true, ref CE_FloatHides);
			AddConfig("FloatGearAndCraftable", "General", "Apply floating to all craftable items and other gear (boolean).", synced: true, value: true, ref CE_FloatGearAndCraftable);
			AddConfig("FloatTreasure", "General", "Apply floating to all treasure (coins, amber, ruby, etc) (boolean).", synced: true, value: true, ref CE_FloatTreasure);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			HarmonyInstance.PatchAll(executingAssembly);
			SetupWatcher();
		}

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

		private void SetupWatcher()
		{
			_lastReloadTime = DateTime.Now;
			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
				{
					FloatingItemsLogger.LogInfo((object)"Attempting to reload configuration...");
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch
				{
					FloatingItemsLogger.LogError((object)("There was an issue loading " + ConfigFileName));
					return;
				}
				_lastReloadTime = now;
				if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated())
				{
					FloatingItems.EnableFloatingItems();
				}
			}
		}

		static FloatingItemsPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			FloatingItemsLogger = Logger.CreateLogSource("VentureFloatingItems");
			CE_FloatEverything = null;
			CE_FloatingItems = null;
			CE_SinkingItems = null;
			CE_FloatTrophies = null;
			CE_FloatMeat = null;
			CE_FloatHides = null;
			CE_FloatGearAndCraftable = null;
			CE_FloatTreasure = null;
		}
	}
	public class FloatingItems
	{
		[HarmonyPriority(200)]
		[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;
					EnableFloatingItems();
				}
				else
				{
					_objectDBReady = false;
				}
			}
		}

		[HarmonyPatch(typeof(Floating), "CustomFixedUpdate")]
		public static class Patch_Floating_CustomFixedUpdate
		{
			private static bool Prefix(Floating __instance)
			{
				if ((Object)(object)__instance.m_body == (Object)null || (Object)(object)__instance.m_collider == (Object)null)
				{
					FloatingItemsPlugin.FloatingItemsLogger.LogDebug((object)("Null found: " + ((Object)__instance).name + ". " + $"{(Object)(object)__instance.m_body == (Object)null}, " + $"{(Object)(object)__instance.m_collider == (Object)null}"));
					return false;
				}
				return true;
			}
		}

		private static readonly FloatingItems _instance = new FloatingItems();

		private static string TrophyPrefab = "trophy";

		private static string MeatPrefab = "meat";

		private static string MeadPrefab = "mead";

		private static string CookedPrefab = "cooked";

		private static string HidePrefab = "hide";

		private static string JutePrefab = "jute";

		private static string LeatherPrefab = "leather";

		private static string PeltPrefab = "pelt";

		private static string PiePrefab = "pie";

		private HashSet<string> FloatingPrefabs = new HashSet<string>();

		private HashSet<string> SinkingPrefabs = new HashSet<string>();

		private HashSet<string> ItemsPrefabs = new HashSet<string> { "helmetdverger", "helmetyule", "beltstrength", "barleywine", "barleyflour", "linenthread" };

		private HashSet<string> TreasurePrefabs = new HashSet<string> { "amber", "amberpearl", "coins", "ruby", "silvernecklace" };

		private static HashSet<string> FloatingAddedPrefabs = new HashSet<string>();

		private static HashSet<string> FloatingDisabledPrefabs = new HashSet<string>();

		private static bool _objectDBReady = false;

		public static FloatingItems Instance => _instance;

		private FloatingItems()
		{
		}

		public static void Update()
		{
			string floatingItems = FloatingItemsPlugin.GetFloatingItems();
			Instance.FloatingPrefabs = new HashSet<string>();
			if (!Utility.IsNullOrWhiteSpace(floatingItems))
			{
				string[] array = floatingItems.Split(new char[1] { ',' });
				for (int i = 0; i < array.Length; i++)
				{
					Instance.FloatingPrefabs.Add(array[i].Trim().ToLower());
				}
			}
			string sinkingItems = FloatingItemsPlugin.GetSinkingItems();
			Instance.SinkingPrefabs = new HashSet<string>();
			if (!Utility.IsNullOrWhiteSpace(sinkingItems))
			{
				string[] array2 = sinkingItems.Split(new char[1] { ',' });
				for (int j = 0; j < array2.Length; j++)
				{
					Instance.SinkingPrefabs.Add(array2[j].Trim().ToLower());
				}
			}
		}

		private static bool IsMeat(string name)
		{
			if (!name.Contains(MeatPrefab) && !name.Contains("necktail") && !name.Contains("morgenheart"))
			{
				return name.Contains("morgensinew");
			}
			return true;
		}

		private static bool IsHide(string name)
		{
			if (!name.Contains(LeatherPrefab) && !name.Contains(JutePrefab) && !name.Contains(HidePrefab) && !name.Contains(PeltPrefab))
			{
				return name.Equals("wolfhairbundle");
			}
			return true;
		}

		private static bool IsTreasure(string name)
		{
			return Instance.TreasurePrefabs.Contains(name);
		}

		private static bool IsPlayerGear(GameObject item)
		{
			string text = ((Object)item).name.ToLower();
			if (Instance.ItemsPrefabs.Contains(text) || text.Contains(MeadPrefab) || text.Contains(CookedPrefab) || text.Contains(PiePrefab))
			{
				return true;
			}
			ItemDrop component = item.GetComponent<ItemDrop>();
			if ((Object)(object)item != (Object)null && (component.m_itemData.m_shared.m_food > 0f || (Object)(object)ObjectDB.instance.GetRecipe(component.m_itemData) != (Object)null))
			{
				return true;
			}
			return false;
		}

		private static bool ShouldFloat(string name, GameObject item)
		{
			if (!FloatingItemsPlugin.GetFloatEverything() && !Instance.FloatingPrefabs.Contains(name) && (!FloatingItemsPlugin.GetFloatTrophies() || !name.Contains(TrophyPrefab)) && (!FloatingItemsPlugin.GetFloatMeat() || !IsMeat(name)) && (!FloatingItemsPlugin.GetFloatHides() || !IsHide(name)) && (!FloatingItemsPlugin.GetFloatGearAndCraftable() || !IsPlayerGear(item)))
			{
				if (FloatingItemsPlugin.GetFloatTreasure())
				{
					return IsTreasure(name);
				}
				return false;
			}
			return true;
		}

		public static void EnableFloatingItems()
		{
			if (!_objectDBReady)
			{
				return;
			}
			Update();
			for (int i = 0; i < ObjectDB.instance.m_items.Count; i++)
			{
				GameObject item = ObjectDB.instance.m_items[i];
				string text = ((Object)item).name.ToLower();
				if (Instance.SinkingPrefabs.Contains(text))
				{
					DisableFloatingComponent(item);
				}
				else if (ShouldFloat(text, item))
				{
					ApplyFloatingComponent(item);
				}
				else
				{
					CleanFloatingItem(text, ref item);
				}
			}
			FloatingItemsPlugin.FloatingItemsLogger.LogInfo((object)"Done applying buoyancy.");
		}

		private static void CleanFloatingItem(string name, ref GameObject item)
		{
			if (FloatingAddedPrefabs.Contains(name))
			{
				Floating component = item.gameObject.GetComponent<Floating>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				FloatingAddedPrefabs.Remove(name);
			}
			else if (FloatingDisabledPrefabs.Contains(name))
			{
				Floating component2 = item.gameObject.GetComponent<Floating>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = true;
				}
				FloatingDisabledPrefabs.Remove(name);
			}
		}

		private static void ApplyFloatingComponent(GameObject item)
		{
			if (!((Object)(object)item.gameObject.GetComponent<Floating>() != (Object)null) && !((Object)(object)item.gameObject.GetComponentInChildren<Collider>() == (Object)null) && !((Object)(object)item.gameObject.GetComponent<Rigidbody>() == (Object)null))
			{
				item.gameObject.AddComponent<Floating>().m_waterLevelOffset = 0.7f;
				FloatingAddedPrefabs.Add(((Object)item.gameObject).name.ToLower());
			}
		}

		private static void DisableFloatingComponent(GameObject item)
		{
			Floating component = item.gameObject.GetComponent<Floating>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
				FloatingDisabledPrefabs.Add(((Object)item.gameObject).name.ToLower());
			}
		}
	}
}