Decompiled source of FollowPlayer v0.1.0

FollowPlayer.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("FollowPlayer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Follow another player in Valheim.")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+5245e59c90d1dc0f13964f9f1146b3bf13f8fb59")]
[assembly: AssemblyProduct("FollowPlayer")]
[assembly: AssemblyTitle("FollowPlayer")]
[assembly: AssemblyVersion("0.1.0.0")]
[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 FollowPlayer
{
	[BepInPlugin("FollowPlayer", "FollowPlayer", "0.1.0")]
	public class FollowPlayerPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__5_0;

			public static ConsoleEvent <>9__5_1;

			public static Func<ConstructorInfo, bool> <>9__9_0;

			public static Predicate<Player> <>9__11_0;

			internal void <Awake>b__5_0(ConsoleEventArgs args)
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					FollowActive = !FollowActive;
					if (FollowActive && string.IsNullOrEmpty(TargetName))
					{
						TargetName = FacingName(localPlayer);
					}
					((Character)localPlayer).Message((MessageType)2, FollowActive ? ("Follow: ON " + (TargetName ?? "(none)")) : "Follow: OFF", 0, (Sprite)null);
				}
			}

			internal void <Awake>b__5_1(ConsoleEventArgs args)
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					CycleTarget(localPlayer);
					((Character)localPlayer).Message((MessageType)2, "Target: " + (TargetName ?? "(none)"), 0, (Sprite)null);
				}
			}

			internal bool <RegisterCommand>b__9_0(ConstructorInfo c)
			{
				ParameterInfo[] parameters = c.GetParameters();
				if (parameters.Length >= 3 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string))
				{
					return parameters[2].ParameterType == typeof(ConsoleEvent);
				}
				return false;
			}

			internal bool <CycleTarget>b__11_0(Player p)
			{
				return p.GetPlayerName() == TargetName;
			}
		}

		internal static ConfigEntry<float> StopDistance;

		internal static ConfigEntry<float> RunDistance;

		internal static bool FollowActive;

		internal static string TargetName;

		private Harmony _harmony;

		private GUIStyle _followLabelStyle;

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00c6: 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_00d1: Expected O, but got Unknown
			StopDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StopDistance", 4f, new ConfigDescription("Stop this many meters short of the target.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			RunDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RunDistance", 8f, new ConfigDescription("Beyond this distance the follower runs.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 60f), Array.Empty<object>()));
			object obj = <>c.<>9__5_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)localPlayer == (Object)null))
					{
						FollowActive = !FollowActive;
						if (FollowActive && string.IsNullOrEmpty(TargetName))
						{
							TargetName = FacingName(localPlayer);
						}
						((Character)localPlayer).Message((MessageType)2, FollowActive ? ("Follow: ON " + (TargetName ?? "(none)")) : "Follow: OFF", 0, (Sprite)null);
					}
				};
				<>c.<>9__5_0 = val;
				obj = (object)val;
			}
			RegisterCommand("follow", "Toggle following the current target on or off.", (ConsoleEvent)obj);
			object obj2 = <>c.<>9__5_1;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)localPlayer == (Object)null))
					{
						CycleTarget(localPlayer);
						((Character)localPlayer).Message((MessageType)2, "Target: " + (TargetName ?? "(none)"), 0, (Sprite)null);
					}
				};
				<>c.<>9__5_1 = val2;
				obj2 = (object)val2;
			}
			RegisterCommand("follownext", "Cycle which nearby player to follow.", (ConsoleEvent)obj2);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "FollowPlayer");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"FollowPlayer 0.1.0 loaded.");
		}

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

		private void OnGUI()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (FollowActive)
			{
				if (_followLabelStyle == null)
				{
					_followLabelStyle = new GUIStyle(GUI.skin.label)
					{
						alignment = (TextAnchor)2,
						fontSize = 16,
						fontStyle = (FontStyle)1
					};
					_followLabelStyle.normal.textColor = Color.white;
				}
				GUI.Label(new Rect((float)(Screen.width - 320), 10f, 300f, 30f), "Following: " + (TargetName ?? "(none)"), _followLabelStyle);
			}
		}

		private static void RegisterCommand(string command, string description, ConsoleEvent action)
		{
			ConstructorInfo constructorInfo = typeof(ConsoleCommand).GetConstructors().FirstOrDefault(delegate(ConstructorInfo c)
			{
				ParameterInfo[] parameters2 = c.GetParameters();
				return parameters2.Length >= 3 && parameters2[0].ParameterType == typeof(string) && parameters2[1].ParameterType == typeof(string) && parameters2[2].ParameterType == typeof(ConsoleEvent);
			});
			if (constructorInfo == null)
			{
				Debug.LogError((object)"FollowPlayer: no matching Terminal.ConsoleCommand constructor found.");
				return;
			}
			ParameterInfo[] parameters = constructorInfo.GetParameters();
			object[] array = new object[parameters.Length];
			array[0] = command;
			array[1] = description;
			array[2] = action;
			for (int num = 3; num < parameters.Length; num++)
			{
				ParameterInfo parameterInfo = parameters[num];
				array[num] = (parameterInfo.HasDefaultValue ? parameterInfo.DefaultValue : (parameterInfo.ParameterType.IsValueType ? Activator.CreateInstance(parameterInfo.ParameterType) : null));
			}
			constructorInfo.Invoke(array);
		}

		private static string FacingName(Player me)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : ((Component)me).transform.forward);
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = ((Component)me).transform.forward;
			}
			((Vector3)(ref val)).Normalize();
			Player val2 = null;
			float num = float.NegativeInfinity;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer == (Object)(object)me)
				{
					continue;
				}
				Vector3 val3 = ((Component)allPlayer).transform.position - ((Component)me).transform.position;
				val3.y = 0f;
				if (!(((Vector3)(ref val3)).sqrMagnitude < 0.0001f))
				{
					float num2 = Vector3.Dot(((Vector3)(ref val3)).normalized, val);
					if (num2 > num)
					{
						num = num2;
						val2 = allPlayer;
					}
				}
			}
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.GetPlayerName();
		}

		private static void CycleTarget(Player me)
		{
			List<Player> list = new List<Player>();
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)(object)me)
				{
					list.Add(allPlayer);
				}
			}
			if (list.Count == 0)
			{
				TargetName = null;
				return;
			}
			int num = list.FindIndex((Player p) => p.GetPlayerName() == TargetName);
			TargetName = list[(num + 1) % list.Count].GetPlayerName();
		}

		internal static Player ResolveTarget(Player me)
		{
			if (string.IsNullOrEmpty(TargetName))
			{
				return null;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)(object)me && allPlayer.GetPlayerName() == TargetName)
				{
					return allPlayer;
				}
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(Player), "SetControls")]
	internal static class Player_SetControls_Patch
	{
		private static readonly FieldRef<Character, Vector3> LookDirRef = AccessTools.FieldRefAccess<Character, Vector3>("m_lookDir");

		private static void Prefix(Player __instance, ref Vector3 movedir, bool attack, bool attackHold, bool secondaryAttack, bool secondaryAttackHold, ref bool run, ref bool autoRun)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!FollowPlayerPlugin.FollowActive || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (((Vector3)(ref movedir)).sqrMagnitude > 0.0001f || attack || attackHold || secondaryAttack || secondaryAttackHold)
			{
				FollowPlayerPlugin.FollowActive = false;
				((Character)__instance).Message((MessageType)2, "Follow: OFF", 0, (Sprite)null);
				return;
			}
			Player val = FollowPlayerPlugin.ResolveTarget(__instance);
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 val2 = ((Component)val).transform.position - ((Component)__instance).transform.position;
				val2.y = 0f;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (magnitude <= FollowPlayerPlugin.StopDistance.Value)
				{
					movedir = Vector3.zero;
					run = false;
					autoRun = false;
					return;
				}
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				Vector3 val3 = LookDirRef.Invoke((Character)(object)__instance);
				val3.y = 0f;
				((Vector3)(ref val3)).Normalize();
				Vector3 val4 = Vector3.Cross(Vector3.up, val3);
				movedir = new Vector3(Vector3.Dot(normalized, val4), 0f, Vector3.Dot(normalized, val3));
				run = magnitude > FollowPlayerPlugin.RunDistance.Value;
				autoRun = false;
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FollowPlayer";

		public const string PLUGIN_NAME = "FollowPlayer";

		public const string PLUGIN_VERSION = "0.1.0";
	}
}