Decompiled source of DimmingFlashlights v0.0.4

BepInEx/Plugins/DimmingFlashlights.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 DimmingFlashlights.NetcodePatcher;
using DimmingFlashlights.Network;
using DimmingFlashlights.Utils;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using LethalNetworkAPI.Utils;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DimmingFlashlights")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.4.0")]
[assembly: AssemblyInformationalVersion("0.0.4")]
[assembly: AssemblyProduct("DimmingFlashlights")]
[assembly: AssemblyTitle("DimmingFlashlights")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 DimmingFlashlights
{
	[BepInPlugin("MrHat.DimmingFlashlights", "DimmingFlashlights", "0.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string modGUID = "MrHat.DimmingFlashlights";

		internal const string modName = "DimmingFlashlights";

		internal const string modVersion = "0.0.4";

		private static Harmony _harmony;

		internal static ManualLogSource mls;

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			mls = Logger.CreateLogSource("MrHat.DimmingFlashlights");
			_harmony = new Harmony("MrHat.DimmingFlashlights");
			ConfigManager.Bind(((BaseUnityPlugin)this).Config);
			DimmingFlashlightsSync.Init();
			mls.LogInfo((object)"[DimmingFlashlights] > Your light...");
			mls.LogWarning((object)"[DimmingFlashlights] > it's fading...");
			mls.LogError((object)"[DimmingFlashlights] > slowly...");
			_harmony.PatchAll();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "DimmingFlashlights";

		public const string PLUGIN_NAME = "DimmingFlashlights";

		public const string PLUGIN_VERSION = "0.0.4";
	}
}
namespace DimmingFlashlights.Utils
{
	internal static class ConfigManager
	{
		internal static ConfigEntry<float> MinimumBrightnessScale { get; private set; }

		internal static ConfigEntry<float> BatteryThreshold { get; private set; }

		internal static ConfigEntry<bool> PerformanceMode { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			MinimumBrightnessScale = config.Bind<float>("Settings", "Minimum brightness scale", 0.15f, "Lowest possible brightness multiplier when the battery is near empty. Default is 15% brightness");
			BatteryThreshold = config.Bind<float>("Settings", "Battery Threshold", 0.6f, "Battery level at which full brightness stops and dimming begins. Default is 60% battery");
			PerformanceMode = config.Bind<bool>("Settings", "Performance Mode", true, "Reduces network update rate to 10 per second to 1 per second. This causes the dimming to be less smooth for other players flashlights, but is far more optimised with 4+ player count. Enabled by default");
		}
	}
	internal static class FlashlightCache
	{
		internal static readonly Dictionary<ulong, float[]> initialHelmetIntensity = new Dictionary<ulong, float[]>();

		private static Dictionary<ulong, float> nextSendTimes = new Dictionary<ulong, float>();

		public static float GetNextSendTime(ulong id)
		{
			if (nextSendTimes.TryGetValue(id, out var value))
			{
				return value;
			}
			return 0f;
		}

		public static void SetNextSendTime(ulong id, float time)
		{
			nextSendTimes[id] = time;
		}

		internal static float GetSendInterval()
		{
			return ConfigManager.PerformanceMode.Value ? 1f : 0.1f;
		}

		internal static void StoreHelmetBaselines(ulong clientId, float[] intensities)
		{
			initialHelmetIntensity[clientId] = intensities;
		}

		internal static float GetHelmetBaseline(ulong clientId, int index)
		{
			if (initialHelmetIntensity.TryGetValue(clientId, out var value) && index >= 0 && index < value.Length)
			{
				return value[index];
			}
			return 0f;
		}

		internal static void ApplyFlashlightIntensity(FlashlightItem item, float charge)
		{
			Light flashlightBulb = item.flashlightBulb;
			if (!((Object)(object)flashlightBulb == (Object)null))
			{
				float num = CalculateBrightnessScale(charge);
				float intensity = item.initialIntensity * num;
				flashlightBulb.intensity = intensity;
			}
		}

		internal static float CalculateBrightnessScale(float charge)
		{
			float num = Mathf.Clamp01(ConfigManager.BatteryThreshold.Value);
			float num2 = Mathf.Clamp01(ConfigManager.MinimumBrightnessScale.Value);
			charge = Mathf.Clamp01(charge);
			if (num <= 0f)
			{
				return 1f;
			}
			if (charge >= num)
			{
				return 1f;
			}
			float num3 = Mathf.Clamp01(charge / num);
			return num2 + (1f - num2) * num3;
		}

		internal static float CalculateHelmetScale(float charge)
		{
			charge = Mathf.Clamp01(charge);
			float num = Mathf.Clamp01(ConfigManager.BatteryThreshold.Value);
			float num2 = Mathf.Clamp01(ConfigManager.MinimumBrightnessScale.Value);
			if (num <= 0f)
			{
				return 1f;
			}
			if (charge >= num)
			{
				return 1f;
			}
			float num3 = Mathf.Clamp01(charge / num);
			float num4 = num2 + (1f - num2) * num3;
			return Mathf.Clamp01(num4);
		}
	}
}
namespace DimmingFlashlights.Patches
{
	[HarmonyPatch(typeof(FlashlightItem))]
	internal static class FlashlightItemPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void PostfixUpdate(FlashlightItem __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			Battery insertedBattery = ((GrabbableObject)__instance).insertedBattery;
			if (insertedBattery == null)
			{
				return;
			}
			float num = Mathf.Clamp01(insertedBattery.charge);
			ulong networkObjectId = ((NetworkBehaviour)__instance).NetworkObject.NetworkObjectId;
			LNetworkVariable<float> val = DimmingFlashlightsSync.EnsureDimmingVar(networkObjectId);
			bool isHostOrServer = LNetworkUtils.IsHostOrServer;
			bool isOwner = ((NetworkBehaviour)__instance).IsOwner;
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				if (isHostOrServer)
				{
					float time = Time.time;
					float nextSendTime = FlashlightCache.GetNextSendTime(networkObjectId);
					if (time >= nextSendTime)
					{
						FlashlightCache.SetNextSendTime(networkObjectId, time + FlashlightCache.GetSendInterval());
						val.Value = num;
						val.MakeDirty();
					}
				}
				else
				{
					float time2 = Time.time;
					float nextSendTime2 = FlashlightCache.GetNextSendTime(networkObjectId);
					if (time2 >= nextSendTime2)
					{
						FlashlightCache.SetNextSendTime(networkObjectId, time2 + FlashlightCache.GetSendInterval());
						DimmingFlashlightsSync.SendFlashlightDimming(networkObjectId, num);
					}
				}
			}
			float value = val.Value;
			FlashlightCache.ApplyFlashlightIntensity(__instance, value);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class HelmetLightPatch
	{
		[HarmonyPatch("LateUpdate")]
		[HarmonyPostfix]
		private static void LateUpdate(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			Light[] allHelmetLights = __instance.allHelmetLights;
			if (allHelmetLights == null || allHelmetLights.Length == 0)
			{
				return;
			}
			ulong ownerClientId = ((NetworkBehaviour)__instance).OwnerClientId;
			if (!FlashlightCache.initialHelmetIntensity.ContainsKey(ownerClientId))
			{
				float[] array = new float[allHelmetLights.Length];
				for (int i = 0; i < allHelmetLights.Length; i++)
				{
					array[i] = (((Object)(object)allHelmetLights[i] != (Object)null) ? allHelmetLights[i].intensity : 0f);
				}
				FlashlightCache.StoreHelmetBaselines(ownerClientId, array);
			}
			LNetworkVariable<float> val = DimmingFlashlightsSync.EnsureDimmingVar(ownerClientId);
			bool isHostOrServer = LNetworkUtils.IsHostOrServer;
			bool isOwner = ((NetworkBehaviour)__instance).IsOwner;
			float num = 1f;
			if (isOwner && __instance.pocketedFlashlight?.insertedBattery != null)
			{
				num = Mathf.Clamp01(__instance.pocketedFlashlight.insertedBattery.charge);
				if (isHostOrServer)
				{
					float time = Time.time;
					float nextSendTime = FlashlightCache.GetNextSendTime(ownerClientId);
					if (time >= nextSendTime)
					{
						FlashlightCache.SetNextSendTime(ownerClientId, time + FlashlightCache.GetSendInterval());
						val.Value = num;
						val.MakeDirty();
					}
				}
				else
				{
					float time2 = Time.time;
					float nextSendTime2 = FlashlightCache.GetNextSendTime(ownerClientId);
					if (time2 >= nextSendTime2)
					{
						FlashlightCache.SetNextSendTime(ownerClientId, time2 + FlashlightCache.GetSendInterval());
						DimmingFlashlightsSync.SendFlashlightDimming(ownerClientId, num);
					}
				}
			}
			float value = val.Value;
			float charge = (isOwner ? num : value);
			float num2 = FlashlightCache.CalculateHelmetScale(charge);
			for (int j = 0; j < allHelmetLights.Length; j++)
			{
				float helmetBaseline = FlashlightCache.GetHelmetBaseline(ownerClientId, j);
				if ((Object)(object)allHelmetLights[j] != (Object)null)
				{
					allHelmetLights[j].intensity = helmetBaseline * num2;
				}
			}
		}
	}
}
namespace DimmingFlashlights.Network
{
	internal struct FlashlightDimmingData
	{
		public ulong netId;

		public float charge;
	}
	internal static class DimmingFlashlightsSync
	{
		internal static readonly Dictionary<ulong, LNetworkVariable<float>> dimmingVars = new Dictionary<ulong, LNetworkVariable<float>>();

		private static LNetworkMessage<FlashlightDimmingData> flashlightDimmingMessage;

		internal static void Init()
		{
			flashlightDimmingMessage = LNetworkMessage<FlashlightDimmingData>.Connect("DimmingFlashlights.FlashlightDimming", (Action<FlashlightDimmingData, ulong>)OnServerReceivedFlashlightDimming, (Action<FlashlightDimmingData>)null, (Action<FlashlightDimmingData, ulong>)null);
		}

		internal static LNetworkVariable<float> EnsureDimmingVar(ulong netId)
		{
			if (dimmingVars.TryGetValue(netId, out var value))
			{
				return value;
			}
			LNetworkVariable<float> val = LNetworkVariable<float>.Connect("DimmingFlashlights.Dimming." + netId, 1f, (LNetworkVariableWritePerms)0, (Action<float, float>)null);
			dimmingVars[netId] = val;
			return val;
		}

		private static void OnServerReceivedFlashlightDimming(FlashlightDimmingData data, ulong senderClientId)
		{
			LNetworkVariable<float> val = EnsureDimmingVar(data.netId);
			val.Value = data.charge;
			val.MakeDirty();
		}

		internal static void SendFlashlightDimming(ulong netId, float charge)
		{
			if (flashlightDimmingMessage != null)
			{
				FlashlightDimmingData flashlightDimmingData = default(FlashlightDimmingData);
				flashlightDimmingData.netId = netId;
				flashlightDimmingData.charge = charge;
				flashlightDimmingMessage.SendServer(flashlightDimmingData);
			}
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace DimmingFlashlights.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}