Decompiled source of BouncingValheim v1.0.0

Nekonekoo.BouncingValheim.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("BouncingValheim")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BouncingValheim")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4a14432e-4a71-4303-9b44-299be0e5209d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BouncingValheim;

public class BouncingValheim
{
	[HarmonyPatch(typeof(Character), "UpdateMotion")]
	public static class Patch_Character_UpdateMotion
	{
		private static readonly FieldRef<Character, GameObject> VisualField = AccessTools.FieldRefAccess<Character, GameObject>("m_visual");

		public static void Postfix(Character __instance)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				GameObject val = VisualField.Invoke(__instance);
				if (!((Object)(object)val == (Object)null))
				{
					bool flag = __instance.IsPlayer();
					if ((!flag || GetBoolConfig("CE_EnableForPlayer", defaultValue: true)) && (flag || GetBoolConfig("CE_EnableForNPCs", defaultValue: true)))
					{
						float floatConfig = GetFloatConfig("CE_BounceSpeed", 14f);
						float num = Mathf.Sin(Time.time * floatConfig);
						float num2 = Mathf.Abs(num) * 0.4f;
						float num3 = 1f - (1f - Mathf.Abs(num)) * 0.25f;
						float num4 = 1f + (1f - Mathf.Abs(num)) * 0.125f;
						Transform transform = val.transform;
						Vector3 localPosition = transform.localPosition;
						transform.localPosition = new Vector3(localPosition.x, num2, localPosition.z);
						transform.localScale = new Vector3(num4, num3, num4);
					}
				}
			}
			catch
			{
			}
		}
	}

	private static GameObject audioHolder;

	private static AudioSource audioSource;

	private static AudioClip loadedClip;

	private static bool GetBoolConfig(string fieldName, bool defaultValue)
	{
		try
		{
			FieldInfo field = typeof(BouncingValheimPlugin).GetField(fieldName, BindingFlags.Static | BindingFlags.Public);
			if (field != null)
			{
				object value = field.GetValue(null);
				if (value != null)
				{
					PropertyInfo property = value.GetType().GetProperty("Value");
					if (property != null)
					{
						return (bool)property.GetValue(value);
					}
				}
			}
		}
		catch
		{
		}
		return defaultValue;
	}

	private static float GetFloatConfig(string fieldName, float defaultValue)
	{
		try
		{
			FieldInfo field = typeof(BouncingValheimPlugin).GetField(fieldName, BindingFlags.Static | BindingFlags.Public);
			if (field != null)
			{
				object value = field.GetValue(null);
				if (value != null)
				{
					PropertyInfo property = value.GetType().GetProperty("Value");
					if (property != null)
					{
						return (float)property.GetValue(value);
					}
				}
			}
		}
		catch
		{
		}
		return defaultValue;
	}

	public static void InitAudio()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		if (!((Object)(object)audioHolder != (Object)null))
		{
			audioHolder = new GameObject("BouncingValheim_AudioHolder");
			Object.DontDestroyOnLoad((Object)(object)audioHolder);
			AudioRunner audioRunner = audioHolder.AddComponent<AudioRunner>();
			((MonoBehaviour)audioRunner).StartCoroutine(LoadWavRoutine());
		}
	}

	private static IEnumerator LoadWavRoutine()
	{
		string modFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string audioPath = Path.Combine(modFolder, "Audio", "bounce.wav");
		if (!File.Exists(audioPath))
		{
			BouncingValheimPlugin.BouncingLogger.LogWarning((object)("Soundfile 'bounce.wav' not found in path: " + audioPath));
			yield break;
		}
		audioSource = audioHolder.AddComponent<AudioSource>();
		audioSource.loop = true;
		audioSource.volume = GetFloatConfig("CE_AudioVolume", 0.1f);
		UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + audioPath, (AudioType)20);
		try
		{
			yield return www.SendWebRequest();
			if ((int)www.result == 1)
			{
				if ((Object)(object)loadedClip != (Object)null)
				{
					Object.Destroy((Object)(object)loadedClip);
				}
				loadedClip = DownloadHandlerAudioClip.GetContent(www);
				audioSource.clip = loadedClip;
				CheckAudioMute();
				audioSource.Play();
				BouncingValheimPlugin.BouncingLogger.LogInfo((object)"WAV-Sound successfully loaded!");
			}
		}
		finally
		{
			((IDisposable)www)?.Dispose();
		}
	}

	public static void UpdateVolume()
	{
		if ((Object)(object)audioSource != (Object)null)
		{
			audioSource.volume = GetFloatConfig("CE_AudioVolume", 0.5f);
		}
	}

	public static void CheckAudioMute()
	{
		if ((Object)(object)audioSource != (Object)null)
		{
			bool boolConfig = GetBoolConfig("CE_EnableSound", defaultValue: true);
			bool flag = Menu.IsVisible();
			bool flag2 = (Object)(object)Player.m_localPlayer != (Object)null && !((Character)Player.m_localPlayer).IsDead();
			audioSource.mute = !boolConfig || flag || !flag2;
		}
	}

	public static void UnloadAudio()
	{
		if ((Object)(object)audioSource != (Object)null)
		{
			audioSource.Stop();
		}
		if ((Object)(object)loadedClip != (Object)null)
		{
			Object.Destroy((Object)(object)loadedClip);
		}
		if ((Object)(object)audioHolder != (Object)null)
		{
			Object.Destroy((Object)(object)audioHolder);
		}
	}
}
public class AudioRunner : MonoBehaviour
{
	private void Update()
	{
		BouncingValheim.CheckAudioMute();
	}
}
[BepInPlugin("com.nekonekoo.mod.BouncingValheim", "BouncingValheim", "1.0.0")]
public class BouncingValheimPlugin : BaseUnityPlugin
{
	private const string ModName = "BouncingValheim";

	private const string ModVersion = "1.0.0";

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

	private const string ModGUID = "com.nekonekoo.mod.BouncingValheim";

	private static string ConfigFileName = "com.nekonekoo.mod.BouncingValheim.cfg";

	private static string ConfigFileFullPath;

	private readonly Harmony HarmonyInstance = new Harmony("com.nekonekoo.mod.BouncingValheim");

	public static readonly ManualLogSource BouncingLogger;

	public static ConfigEntry<bool> CE_EnableSound;

	public static ConfigEntry<float> CE_AudioVolume;

	public static ConfigEntry<bool> CE_EnableForPlayer;

	public static ConfigEntry<bool> CE_EnableForNPCs;

	public static ConfigEntry<float> CE_BounceSpeed;

	private DateTime _lastReloadTime;

	private const long RELOAD_DELAY = 10000000L;

	private void AddConfig<T>(string key, string section, string description, T value, ref ConfigEntry<T> configEntry)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		configEntry = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
	}

	public void Awake()
	{
		BouncingLogger.LogInfo((object)"BouncingValheim loaded successfully!");
		AddConfig("EnableSound", "Audio", "enables the background bouncing sound.", value: true, ref CE_EnableSound);
		AddConfig("Volume", "Audio", "Volume of the sound (0.0 to 1.0).", 0.1f, ref CE_AudioVolume);
		AddConfig("EnableForPlayer", "Bounce", "enables the bounce effect for the player.", value: true, ref CE_EnableForPlayer);
		AddConfig("EnableForNPCs", "Bounce", "enables the bounce effect for NPCs.", value: true, ref CE_EnableForNPCs);
		AddConfig("BounceSpeed", "Bounce", "speed of the bounce animation.", 14f, ref CE_BounceSpeed);
		Assembly executingAssembly = Assembly.GetExecutingAssembly();
		HarmonyInstance.PatchAll(executingAssembly);
		SetupWatcher();
		BouncingValheim.InitAudio();
	}

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

	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
			{
				BouncingLogger.LogInfo((object)"Attempting to reload configuration...");
				((BaseUnityPlugin)this).Config.Reload();
				BouncingValheim.UpdateVolume();
			}
			catch
			{
				BouncingLogger.LogError((object)("There was an issue loading " + ConfigFileName));
				return;
			}
			_lastReloadTime = now;
		}
	}

	public static bool GetEnableSound()
	{
		return CE_EnableSound != null && CE_EnableSound.Value;
	}

	public static float GetAudioVolume()
	{
		return (CE_AudioVolume == null) ? 0.1f : Mathf.Clamp01(CE_AudioVolume.Value);
	}

	public static bool GetEnableForPlayer()
	{
		return CE_EnableForPlayer == null || CE_EnableForPlayer.Value;
	}

	public static bool GetEnableForNPCs()
	{
		return CE_EnableForNPCs == null || CE_EnableForNPCs.Value;
	}

	public static float GetBounceSpeed()
	{
		return (CE_BounceSpeed == null) ? 14f : CE_BounceSpeed.Value;
	}

	static BouncingValheimPlugin()
	{
		string configPath = Paths.ConfigPath;
		char directorySeparatorChar = Path.DirectorySeparatorChar;
		ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
		BouncingLogger = Logger.CreateLogSource("BouncingValheim");
	}
}