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());
}
}
}
}