Decompiled source of PeakTweaks v0.2.0

plugins/lm2124.peaktweaks.dll

Decompiled 2 days 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Voice.Unity.UtilityScripts;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("lm2124.peaktweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+84efdc7030bcfe6eb37644fde0f71c44c576d425")]
[assembly: AssemblyProduct("lm2124.peaktweaks")]
[assembly: AssemblyTitle("Peak Tweaks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PeakTweaks
{
	public abstract class ModPatch
	{
		public virtual bool ShouldLoad(ConfigFile config)
		{
			return true;
		}

		public virtual void Init()
		{
		}

		public virtual void DeInit()
		{
		}
	}
	public static class PatchLoader
	{
		public static List<ModPatch> ActivePatches = new List<ModPatch>();

		public static int ApplyPatches(Harmony harmony, ConfigFile config)
		{
			List<Type> list = (from type in AccessTools.AllTypes()
				where !type.IsAbstract && type.IsSubclassOf(typeof(ModPatch))
				select type).ToList();
			Plugin.Log.LogDebug((object)$"Found {list.Count} Patches");
			foreach (Type item in list)
			{
				if (Activator.CreateInstance(item) is ModPatch modPatch && modPatch.ShouldLoad(config))
				{
					Plugin.Log.LogDebug((object)("Applying patch " + item.Name));
					try
					{
						modPatch.Init();
						harmony.PatchAll(item);
					}
					catch (Exception ex)
					{
						Plugin.Log.LogError((object)("Error applying patch " + item.Name + ": " + ex.GetType().FullName + "\r\n" + ex.Message + "\r\n" + ex.StackTrace));
						continue;
					}
					ActivePatches.Add(modPatch);
					Plugin.Log.LogInfo((object)("Initialized patch " + item.Name));
				}
			}
			return ActivePatches.Count;
		}

		public static void ClearPatches(Harmony harmony)
		{
			foreach (ModPatch activePatch in ActivePatches)
			{
				activePatch.DeInit();
			}
			Harmony.UnpatchID(harmony.Id);
		}
	}
	[BepInPlugin("lm2124.peaktweaks", "Peak Tweaks", "0.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Harmony harmony;

		public const string Id = "lm2124.peaktweaks";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "Peak Tweaks";

		public static string Version => "0.2.0";

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony(Name);
			int num = PatchLoader.ApplyPatches(harmony, ((BaseUnityPlugin)this).Config);
			Log.LogInfo((object)$"{Name} has initialized with {num} patches!");
		}

		private void OnDestroy()
		{
			Log.LogInfo((object)"Cleaning up patches");
			PatchLoader.ClearPatches(harmony);
		}
	}
}
namespace PeakTweaks.Patches
{
	public class BananaPeelFix : ModPatch
	{
		public override bool ShouldLoad(ConfigFile config)
		{
			ConfigEntry<bool> val = config.Bind<bool>("Client", "Banana Peel Join Fix", true, "Fix a bug that made it impossible to join a lobby if a banana peel existed anywhere.");
			return val.Value;
		}

		[HarmonyPatch(typeof(BananaPeel), "Update")]
		[HarmonyPrefix]
		public static bool BananaPeel_Update()
		{
			if ((Object)(object)Character.localCharacter == (Object)null)
			{
				Plugin.Log.LogInfo((object)"Preventing Banana Peel join bug ;)");
				return false;
			}
			return true;
		}
	}
	public class CampfireHungerReduction : ModPatch
	{
		public static float CampfireHungerMultiplier;

		public static float CampfireHungerReductionRange;

		public override bool ShouldLoad(ConfigFile config)
		{
			bool value = config.Bind<bool>("Everyone", "Campfire Hunger Reduction", false, "Reduce hunger gain while close to a campfire.\nUseful to avoid starvation while waiting for that *one guy* to catch up. It's always him.\n*Might* work when not everyone has this, but might also cause desyncs. I dunno.").Value;
			CampfireHungerMultiplier = config.Bind<float>("Everyone", "Campfire Hunger Reduction Multiplier", 0.5f, "Multiply hunger gain near campfires by this amount.\nCan be 0 to pause hunger entirely, or a negative value like -1 to regenerate hunger near the campfire.").Value;
			CampfireHungerReductionRange = config.Bind<float>("Everyone", "Campfire Hunger Reduction Range", 15f, "Range of the hunger reduction effect, in in-game meters.").Value / CharacterStats.unitsToMeters;
			if (value && CampfireHungerMultiplier != 1f)
			{
				return CampfireHungerReductionRange > 0f;
			}
			return false;
		}

		[HarmonyPatch(typeof(Campfire), "Awake")]
		[HarmonyPrefix]
		private static void Campfire_Awake(Campfire __instance)
		{
			CampfireProximityTracker.CreateAndAttachToCampfire(__instance, CampfireHungerReductionRange);
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
		[HarmonyPrefix]
		public static bool CharacterAfflictions_AddStatus(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount, bool fromRPC)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if ((int)statusType == 1 && amount > 0f && !fromRPC && CampfireProximityTracker.charactersNearCampfires.Contains(__instance.character) && Mathf.Approximately(amount, Time.deltaTime * __instance.hungerPerSecond * Ascents.hungerRateMultiplier))
			{
				float num = amount * CampfireHungerMultiplier;
				if (!(num < 0f))
				{
					if (num == 0f)
					{
						return false;
					}
					amount = num;
					return true;
				}
				__instance.SubtractStatus(statusType, 0f - num, fromRPC);
				return false;
			}
			return true;
		}

		public override void Init()
		{
			CollectionExtensions.Do<Campfire>((IEnumerable<Campfire>)Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0), (Action<Campfire>)delegate(Campfire c)
			{
				CampfireProximityTracker.CreateAndAttachToCampfire(c, CampfireHungerReductionRange);
			});
		}

		public override void DeInit()
		{
			CollectionExtensions.Do<CampfireProximityTracker>((IEnumerable<CampfireProximityTracker>)Object.FindObjectsByType<CampfireProximityTracker>((FindObjectsSortMode)0), (Action<CampfireProximityTracker>)Object.Destroy);
		}
	}
	public class CampfireProximityTracker : MonoBehaviour
	{
		public static HashSet<Character> charactersNearCampfires = new HashSet<Character>();

		public static void CreateAndAttachToCampfire(Campfire campfire, float range)
		{
			Plugin.Log.LogDebug((object)("Attaching Proximity Tracker to " + ((Object)campfire).name));
			CampfireProximityTracker campfireProximityTracker = ((Component)campfire).gameObject.AddComponent<CampfireProximityTracker>();
			campfireProximityTracker.Initialize(campfire, range);
		}

		public void Initialize(Campfire campfire, float range)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.SetParent(((Component)campfire).transform);
			((Component)this).transform.localPosition = Vector3.zero;
			SphereCollider val = ((Component)this).gameObject.AddComponent<SphereCollider>();
			((Collider)val).isTrigger = true;
			val.radius = range;
		}

		private void OnTriggerEnter(Collider other)
		{
			Character componentInParent = ((Component)other).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null && charactersNearCampfires.Add(componentInParent))
			{
				Plugin.Log.LogDebug((object)("Character entered campfire radius: " + ((Object)componentInParent).name));
			}
		}

		private void OnTriggerExit(Collider other)
		{
			Character componentInParent = ((Component)other).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null && charactersNearCampfires.Remove(componentInParent))
			{
				Plugin.Log.LogDebug((object)("Character exited campfire radius: " + ((Object)componentInParent).name));
			}
		}
	}
	public class ChangeOwnMicVolume : ModPatch
	{
		public static float NewVolume;

		public override bool ShouldLoad(ConfigFile config)
		{
			NewVolume = config.Bind<float>("Client", "Microphone Volume", 100f, "Change your microphone's output volume to your friends.").Value / 100f;
			return !Mathf.Approximately(NewVolume, 1f);
		}

		private static float VolumeMultiplierFromPerceivedVolumeIncrease(float perceivedMultiplier)
		{
			return Mathf.Pow(10f, Mathf.Log(perceivedMultiplier, 2f));
		}

		[HarmonyPatch(typeof(CharacterVoiceHandler), "Start")]
		[HarmonyPrefix]
		public static void CharacterVoiceHandler_Start(CharacterVoiceHandler __instance)
		{
			Character componentInParent = ((Component)__instance).GetComponentInParent<Character>();
			if (!((Object)(object)componentInParent == (Object)null) && componentInParent.IsLocal)
			{
				Plugin.Log.LogInfo((object)$"Boosting your microphone's volume by {NewVolume:F2}x...");
				float num = VolumeMultiplierFromPerceivedVolumeIncrease(NewVolume);
				Plugin.Log.LogDebug((object)$"Adding MicAmplifier component for {((componentInParent != null) ? ((Object)componentInParent).name : null)}; AmplificationFactor = {num}");
				MicAmplifier val = ((Component)__instance).gameObject.AddComponent<MicAmplifier>();
				val.AmplificationFactor = num;
			}
		}

		public override void Init()
		{
			Character localCharacter = Character.localCharacter;
			object obj;
			if (localCharacter == null)
			{
				obj = null;
			}
			else
			{
				CharacterVoiceHandler componentInChildren = ((Component)localCharacter).GetComponentInChildren<CharacterVoiceHandler>();
				if (componentInChildren == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)componentInChildren).gameObject;
					obj = ((gameObject != null) ? gameObject.GetComponent<MicAmplifier>() : null);
				}
			}
			MicAmplifier val = (MicAmplifier)obj;
			if ((Object)(object)val != (Object)null)
			{
				float num = VolumeMultiplierFromPerceivedVolumeIncrease(NewVolume);
				Plugin.Log.LogDebug((object)$"Found MicAmplifier component; setting new AmplificationFactor: {num}");
				val.AmplificationFactor = num;
			}
		}

		public override void DeInit()
		{
			Character localCharacter = Character.localCharacter;
			object obj;
			if (localCharacter == null)
			{
				obj = null;
			}
			else
			{
				CharacterVoiceHandler componentInChildren = ((Component)localCharacter).GetComponentInChildren<CharacterVoiceHandler>();
				if (componentInChildren == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)componentInChildren).gameObject;
					obj = ((gameObject != null) ? gameObject.GetComponent<MicAmplifier>() : null);
				}
			}
			MicAmplifier val = (MicAmplifier)obj;
			if ((Object)(object)val != (Object)null)
			{
				val.AmplificationFactor = 1f;
			}
		}
	}
	public class TweakVoiceVolume : ModPatch
	{
		public static float NewMaxValue;

		public override bool ShouldLoad(ConfigFile config)
		{
			NewMaxValue = config.Bind<float>("Client", "Maximum Voice Volume", 400f, "Increase the maximum volume you can set other players' voice volume to.\nSet to the game's default value of 200 to disable.").Value / 200f;
			return NewMaxValue != 1f;
		}

		[HarmonyPatch(typeof(AudioLevelSlider), "Awake")]
		[HarmonyPostfix]
		public static void AudioLevelSlider_Awake(AudioLevelSlider __instance)
		{
			__instance.slider.maxValue = NewMaxValue;
		}

		[HarmonyPatch(typeof(AudioLevelSlider), "OnSliderChanged")]
		[HarmonyPrefix]
		public static bool AudioLevelSlider_OnSliderChanged(AudioLevelSlider __instance, float newValue)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.player != null)
			{
				AudioLevels.SetPlayerLevel(__instance.player.ActorNumber, newValue);
				float num = newValue / NewMaxValue;
				__instance.icon.sprite = ((newValue == 0f) ? __instance.mutedAudioSprite : __instance.audioSprites[Mathf.Clamp(Mathf.FloorToInt(num * (float)__instance.audioSprites.Length), 0, __instance.audioSprites.Length - 1)]);
				((Graphic)__instance.bar).color = __instance.barGradient.Evaluate(num);
				EventSystem.current.SetSelectedGameObject((GameObject)null);
				((TMP_Text)__instance.percent).text = Mathf.RoundToInt(newValue * 200f) + "%";
			}
			return false;
		}

		public override void Init()
		{
			CollectionExtensions.Do<AudioLevelSlider>((IEnumerable<AudioLevelSlider>)Object.FindObjectsByType<AudioLevelSlider>((FindObjectsSortMode)0), (Action<AudioLevelSlider>)delegate(AudioLevelSlider instance)
			{
				instance.slider.maxValue = NewMaxValue;
			});
		}

		public override void DeInit()
		{
			CollectionExtensions.Do<AudioLevelSlider>((IEnumerable<AudioLevelSlider>)Object.FindObjectsByType<AudioLevelSlider>((FindObjectsSortMode)0), (Action<AudioLevelSlider>)delegate(AudioLevelSlider instance)
			{
				instance.slider.maxValue = 1f;
				instance.slider.value = Mathf.Min(1f, instance.slider.value);
			});
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}