Decompiled source of MultiplayerSettings v1.0.2

MultiplayerSettings.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
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("MultiplayerSettings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("MultiplayerSettings")]
[assembly: AssemblyTitle("MultiplayerSettings")]
[assembly: AssemblyVersion("1.0.2.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 MultiplayerSettings
{
	[BepInPlugin("Iteravio.MultiplayerSettings", "MultiplayerSettings", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "Iteravio.MultiplayerSettings";

		public const string PluginName = "MultiplayerSettings";

		public const string PluginVersion = "1.0.2";

		private const string SettingsSection = "Multiplayer Settings";

		private const float StatusPollSeconds = 1f;

		private const float StatusHeartbeatSeconds = 10f;

		internal static ManualLogSource Log;

		private static ConfigEntry<int> damagePerPlayerPercent;

		private static ConfigEntry<int> healthPerPlayerPercent;

		private static ConfigEntry<float> scaleRange;

		private static ConfigEntry<int> maxPlayers;

		private static ConfigEntry<bool> debugLogging;

		private float nextPoll;

		private float nextHeartbeat;

		private string lastStatus;

		private void Awake()
		{
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			scaleRange = ((BaseUnityPlugin)this).Config.Bind<float>("Multiplayer Settings", "PlayerRange", 100f, Synced("Radius in metres within which players are counted. Vanilla: 100 m.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), 4));
			maxPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("Multiplayer Settings", "MaxCountedPlayers", 5, Synced("Player count is capped at this value. 1 disables all scaling. Vanilla: 5.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), 3));
			healthPerPlayerPercent = ((BaseUnityPlugin)this).Config.Bind<int>("Multiplayer Settings", "PercentEnemyHealthIncreasePerPlayer", 30, Synced("Extra effective enemy health (applied as reduced damage) per additional player in range. Vanilla: 30%.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), 2));
			damagePerPlayerPercent = ((BaseUnityPlugin)this).Config.Bind<int>("Multiplayer Settings", "PercentDamageTakenIncreasePerPlayer", 4, Synced("Extra damage players take from enemies per additional player in range. Vanilla: 4%.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), 1));
			debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogMultipliers", false, "Log a status line (players counted near you + multipliers) when it changes and every 10 s. Local only, not synced.");
			damagePerPlayerPercent.SettingChanged += delegate
			{
				Apply();
			};
			healthPerPlayerPercent.SettingChanged += delegate
			{
				Apply();
			};
			scaleRange.SettingChanged += delegate
			{
				Apply();
			};
			maxPlayers.SettingChanged += delegate
			{
				Apply();
			};
			SynchronizationManager.OnConfigurationSynchronized += delegate
			{
				Apply();
			};
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new StatusCommand());
			new Harmony("Iteravio.MultiplayerSettings").PatchAll();
		}

		private void Update()
		{
			if (debugLogging.Value && !(Time.time < nextPoll))
			{
				nextPoll = Time.time + 1f;
				string liveStatus = GetLiveStatus();
				if (liveStatus == null)
				{
					lastStatus = null;
				}
				else if (!(liveStatus == lastStatus) || !(Time.time < nextHeartbeat))
				{
					lastStatus = liveStatus;
					nextHeartbeat = Time.time + 10f;
					Log.LogInfo((object)liveStatus);
				}
			}
		}

		private static ConfigDescription Synced(string description, AcceptableValueBase range, int order)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			return new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				Order = order
			} });
		}

		internal static void Apply()
		{
			Game instance = Game.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				instance.m_damageScalePerPlayer = (float)damagePerPlayerPercent.Value / 100f;
				instance.m_healthScalePerPlayer = (float)healthPerPlayerPercent.Value / 100f;
				instance.m_difficultyScaleRange = scaleRange.Value;
				instance.m_difficultyScaleMaxPlayers = maxPlayers.Value;
				Log.LogInfo((object)("Applied: " + GetSettingsSummary()));
			}
		}

		internal static string GetSettingsSummary()
		{
			Game instance = Game.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return $"damage +{damagePerPlayerPercent.Value}%/player, enemy health +{healthPerPlayerPercent.Value}%/player, " + $"range {scaleRange.Value} m, max {maxPlayers.Value} players (config; not in a world)";
			}
			return $"damage +{instance.m_damageScalePerPlayer * 100f:0.##}%/player, enemy health +{instance.m_healthScalePerPlayer * 100f:0.##}%/player, " + $"range {instance.m_difficultyScaleRange:0.##} m, max {instance.m_difficultyScaleMaxPlayers} players";
		}

		internal static string GetSettingsSource()
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "local config";
			}
			if (!instance.IsServer())
			{
				return "synced from host";
			}
			return "this machine (host/solo)";
		}

		internal static string GetLiveStatus()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			Game instance = Game.instance;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null)
			{
				return null;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			return $"Status: {instance.GetPlayerDifficulty(position)} player(s) counted near you -> " + $"damage you take x{instance.GetDifficultyDamageScalePlayer(position):0.###}, " + $"enemy damage taken x{instance.GetDifficultyDamageScaleEnemy(position):0.###}";
		}
	}
	internal class StatusCommand : ConsoleCommand
	{
		public override string Name => "mpsettings";

		public override string Help => "Show MultiplayerSettings values in effect and live player-scaling multipliers";

		public override void Run(string[] args, Terminal context)
		{
			if (!((Object)(object)context == (Object)null))
			{
				context.AddString("MultiplayerSettings 1.0.2");
				context.AddString("Settings (" + Plugin.GetSettingsSource() + "): " + Plugin.GetSettingsSummary());
				context.AddString(Plugin.GetLiveStatus() ?? "Status: not in a world");
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Awake")]
	internal static class GameAwakePatch
	{
		private static void Postfix()
		{
			Plugin.Apply();
		}
	}
}