Decompiled source of Player Modifiers v1.3.1

plugins/PlayerModifiers.dll

Decompiled 4 months 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.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ServerSync;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("PlayerModifiers")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a03cc01f7a06afa33efb41177c52466b49a564a8")]
[assembly: AssemblyProduct("PlayerModifiers")]
[assembly: AssemblyTitle("PlayerModifiers")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PlayerModifiers;

[BepInPlugin("proflupin.playermodifiers", "PlayerModifiers", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class PlayerModifiers : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	private static class ApplyOnSpawn
	{
		private static void Postfix(Player __instance)
		{
			ApplyStats();
		}
	}

	[HarmonyPatch(typeof(Skills), "OnDeath")]
	private static class SkillDecayPatch
	{
		private static void Prefix(Skills __instance)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(Skills), "m_skills");
				if (!(fieldInfo.GetValue(__instance) is IEnumerable<object> enumerable))
				{
					Log.LogWarning((object)"Could not access m_skills; skill decay skipped.");
					return;
				}
				float num = 0f;
				foreach (object item in enumerable)
				{
					FieldInfo fieldInfo2 = AccessTools.Field(item.GetType(), "m_level");
					if (!(fieldInfo2 == null))
					{
						float num2 = (float)fieldInfo2.GetValue(item);
						float num3 = num2 * SkillDecayMultiplier.Value;
						float num4 = Mathf.Max(0f, num2 - num3);
						num += num3;
						fieldInfo2.SetValue(item, num4);
					}
				}
				if (num > 0f && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)Chat.instance != (Object)null)
				{
					string text = $"I JUST LOST {Mathf.Round(num * 100f) / 100f} SKILL LEVELS ON DEATH!!!";
					Chat.instance.SendText((Type)2, text);
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error during skill decay: {arg}");
			}
		}
	}

	public const string PluginGUID = "proflupin.playermodifiers";

	public const string PluginName = "PlayerModifiers";

	public const string PluginVersion = "1.0.0";

	internal static ManualLogSource Log;

	private static readonly ConfigSync configSync = new ConfigSync("proflupin.playermodifiers")
	{
		DisplayName = "PlayerModifiers",
		CurrentVersion = "1.0.0",
		MinimumRequiredVersion = "1.0.0"
	};

	public static ConfigEntry<float> BaseHealth;

	public static ConfigEntry<float> BaseStamina;

	public static ConfigEntry<float> MaxCarryWeight;

	public static ConfigEntry<float> StaminaRegenMultiplier;

	public static ConfigEntry<float> HealthRegenMultiplier;

	public static ConfigEntry<float> SkillDecayMultiplier;

	public static ConfigEntry<float> MovementSpeed;

	public static SyncedConfigEntry<float> sBaseHealth;

	public static SyncedConfigEntry<float> sBaseStamina;

	public static SyncedConfigEntry<float> sMaxCarryWeight;

	public static SyncedConfigEntry<float> sStaminaRegenMultiplier;

	public static SyncedConfigEntry<float> sHealthRegenMultiplier;

	public static SyncedConfigEntry<float> sSkillDecayMultiplier;

	public static SyncedConfigEntry<float> sMovementSpeed;

	private FileSystemWatcher watcher;

	private void Awake()
	{
		Log = ((BaseUnityPlugin)this).Logger;
		CreateConfigEntries();
		SetupServerSync();
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "proflupin.playermodifiers");
		SetupConfigWatcher();
		Log.LogInfo((object)"PlayerModifiers v1.0.0 loaded successfully.");
		ApplyStats();
	}

	private void CreateConfigEntries()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Expected O, but got Unknown
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Expected O, but got Unknown
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Expected O, but got Unknown
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Expected O, but got Unknown
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Expected O, but got Unknown
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		BaseHealth = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "BaseHealth", 25f, new ConfigDescription("Base HP", (AcceptableValueBase)null, new object[1] { val }));
		BaseStamina = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "BaseStamina", 50f, new ConfigDescription("Base Stamina", (AcceptableValueBase)null, new object[1] { val }));
		MaxCarryWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "MaxCarryWeight", 300f, new ConfigDescription("Carry Weight", (AcceptableValueBase)null, new object[1] { val }));
		StaminaRegenMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "StaminaRegenMultiplier", 1f, new ConfigDescription("Stamina Regen Multiplier", (AcceptableValueBase)null, new object[1] { val }));
		HealthRegenMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "HealthRegenMultiplier", 1f, new ConfigDescription("Health Regen Multiplier", (AcceptableValueBase)null, new object[1] { val }));
		SkillDecayMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "SkillDecayMultiplier", 0.33f, new ConfigDescription("Skill Loss On Death Multiplier", (AcceptableValueBase)null, new object[1] { val }));
		MovementSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Player Stats", "MovementSpeed", 5f, new ConfigDescription("Movement Speed", (AcceptableValueBase)null, new object[1] { val }));
		((BaseUnityPlugin)this).Config.Save();
	}

	private void SetupServerSync()
	{
		sBaseHealth = configSync.AddConfigEntry<float>(BaseHealth);
		sBaseStamina = configSync.AddConfigEntry<float>(BaseStamina);
		sMaxCarryWeight = configSync.AddConfigEntry<float>(MaxCarryWeight);
		sStaminaRegenMultiplier = configSync.AddConfigEntry<float>(StaminaRegenMultiplier);
		sHealthRegenMultiplier = configSync.AddConfigEntry<float>(HealthRegenMultiplier);
		sSkillDecayMultiplier = configSync.AddConfigEntry<float>(SkillDecayMultiplier);
		sMovementSpeed = configSync.AddConfigEntry<float>(MovementSpeed);
	}

	private void SetupConfigWatcher()
	{
		string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
		watcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath))
		{
			NotifyFilter = NotifyFilters.LastWrite,
			EnableRaisingEvents = true
		};
		watcher.Changed += delegate
		{
			try
			{
				Thread.Sleep(150);
				((BaseUnityPlugin)this).Config.Reload();
				ApplyStats();
				Log.LogInfo((object)"Config reloaded & stats updated.");
			}
			catch
			{
			}
		};
	}

	public static void ApplyStats()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			localPlayer.m_baseHP = sBaseHealth.Value;
			localPlayer.m_baseStamina = sBaseStamina.Value;
			localPlayer.m_maxCarryWeight = sMaxCarryWeight.Value;
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_staminaRegen");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(Player), "m_healthRegen");
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(Player), "m_speed");
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(localPlayer, (float)fieldInfo.GetValue(localPlayer) * sStaminaRegenMultiplier.Value);
			}
			if (fieldInfo2 != null)
			{
				fieldInfo2.SetValue(localPlayer, (float)fieldInfo2.GetValue(localPlayer) * sHealthRegenMultiplier.Value);
			}
			if (fieldInfo3 != null)
			{
				fieldInfo3.SetValue(localPlayer, sMovementSpeed.Value);
			}
			localPlayer.SetMaxHealth(((Character)localPlayer).GetMaxHealth(), true);
			localPlayer.SetMaxStamina(((Character)localPlayer).GetMaxStamina(), true);
		}
	}

	private void OnDestroy()
	{
		watcher?.Dispose();
	}
}