Decompiled source of TameFollow v1.0.0

plugins/TameFollow.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
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;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("TameFollow")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bf2e1b0a01a752b3562806e48708ba2eefcb0a26")]
[assembly: AssemblyProduct("TameFollow")]
[assembly: AssemblyTitle("TameFollow")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 Oddhatter.TameFollow
{
	[HarmonyPatch(typeof(Tameable), "Interact")]
	internal static class Tameable_Interact_Patch
	{
		private static readonly HashSet<string> s_logged = new HashSet<string>();

		private static void Prefix(Tameable __instance, bool alt, out bool? __state)
		{
			__state = null;
			if (!TameFollowPlugin.Enabled.Value || alt || __instance.m_commandable || !__instance.IsTamed())
			{
				return;
			}
			string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
			if ((Object)(object)__instance.m_monsterAI == (Object)null)
			{
				if (s_logged.Add(prefabName))
				{
					TameFollowPlugin.Log.LogInfo((object)(prefabName + " can't follow (no MonsterAI); it is petted as normal."));
				}
				return;
			}
			if (s_logged.Add(prefabName))
			{
				TameFollowPlugin.Log.LogInfo((object)(prefabName + " can now be told to follow / stay."));
			}
			__state = __instance.m_commandable;
			__instance.m_commandable = true;
		}

		private static Exception Finalizer(Tameable __instance, bool? __state, Exception __exception)
		{
			if (__state.HasValue && (Object)(object)__instance != (Object)null)
			{
				__instance.m_commandable = __state.Value;
			}
			return __exception;
		}
	}
	[BepInPlugin("com.oddhatter.tamefollow", "TameFollow", "1.0.0")]
	[BepInProcess("valheim.exe")]
	public sealed class TameFollowPlugin : BaseUnityPlugin
	{
		public const string Guid = "com.oddhatter.tamefollow";

		public const string Name = "TameFollow";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		private const float ConfigReloadDelay = 0.5f;

		private Harmony _harmony;

		private FileSystemWatcher _configWatcher;

		private volatile bool _configFileChanged;

		private float _configReloadAt = -1f;

		private bool _configLockedLogged;

		private void Awake()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "true: pressing Use on any tamed creature that can follow (lox, asksvin, boar, ...) toggles follow / stay, like wolves. false: vanilla, where those creatures are only petted.");
			_harmony = new Harmony("com.oddhatter.tamefollow");
			_harmony.PatchAll(typeof(TameFollowPlugin).Assembly);
			foreach (MethodBase patchedMethod in _harmony.GetPatchedMethods())
			{
				Log.LogInfo((object)("Patched " + patchedMethod.DeclaringType?.Name + "." + patchedMethod.Name));
			}
			WatchConfigFile();
			Log.LogInfo((object)"TameFollow 1.0.0 loaded.");
		}

		private void Update()
		{
			if (_configFileChanged)
			{
				_configFileChanged = false;
				_configReloadAt = Time.realtimeSinceStartup + 0.5f;
			}
			if (_configReloadAt >= 0f && Time.realtimeSinceStartup >= _configReloadAt)
			{
				_configReloadAt = -1f;
				ReloadConfigFromDisk();
			}
		}

		private void OnDestroy()
		{
			_configWatcher?.Dispose();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void WatchConfigFile()
		{
			string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
			_configWatcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath))
			{
				NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
				IncludeSubdirectories = false
			};
			_configWatcher.Changed += OnConfigFileEvent;
			_configWatcher.Created += OnConfigFileEvent;
			_configWatcher.Renamed += OnConfigFileEvent;
			_configWatcher.EnableRaisingEvents = true;
		}

		private void OnConfigFileEvent(object sender, FileSystemEventArgs e)
		{
			_configFileChanged = true;
		}

		private void ReloadConfigFromDisk()
		{
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				return;
			}
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
				_configLockedLogged = false;
				Log.LogInfo((object)"Configuration reloaded from disk.");
			}
			catch (IOException ex)
			{
				if (!_configLockedLogged)
				{
					_configLockedLogged = true;
					Log.LogWarning((object)("Config file busy, will retry: " + ex.Message));
				}
				_configReloadAt = Time.realtimeSinceStartup + 0.5f;
			}
			catch (Exception ex2)
			{
				Log.LogError((object)("Failed to reload configuration: " + ex2.Message));
			}
			finally
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}