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.6.0")] [assembly: AssemblyInformationalVersion("0.0.6")] [assembly: AssemblyProduct("DimmingFlashlights")] [assembly: AssemblyTitle("DimmingFlashlights")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.6.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.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { internal const string modGUID = "MrHat.DimmingFlashlights"; internal const string modName = "DimmingFlashlights"; internal const string modVersion = "0.0.6"; 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.InitiateBeepBoop(); mls.LogInfo((object)"[DimmingFlashlights] > Your light, it's fading..."); _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.6"; } } namespace DimmingFlashlights.Utils { internal static class ConfigManager { internal static ConfigEntry MinimumBrightnessScale { get; private set; } internal static ConfigEntry BatteryThreshold { get; private set; } internal static void Bind(ConfigFile config) { MinimumBrightnessScale = config.Bind("Settings", "Minimum brightness scale", 0.15f, "Lowest possible brightness multiplier when the battery is near empty. Default is 15% brightness"); BatteryThreshold = config.Bind("Settings", "Battery Threshold", 0.6f, "Battery level at which full brightness stops and dimming begins. Default is 60% battery"); } } internal static class FlashlightCache { internal static readonly Dictionary initialHelmetIntensity = new Dictionary(); private static readonly Dictionary nextItemSendTimes = new Dictionary(); private static readonly Dictionary nextPlayerSendTimes = new Dictionary(); internal static void Clear() { initialHelmetIntensity.Clear(); nextItemSendTimes.Clear(); nextPlayerSendTimes.Clear(); } internal static float GetNextItemSendTime(ulong networkObjectId) { if (nextItemSendTimes.TryGetValue(networkObjectId, out var value)) { return value; } return 0f; } internal static void SetNextItemSendTime(ulong networkObjectId, float time) { nextItemSendTimes[networkObjectId] = time; } internal static float GetNextPlayerSendTime(ulong clientId) { if (nextPlayerSendTimes.TryGetValue(clientId, out var value)) { return value; } return 0f; } internal static void SetNextPlayerSendTime(ulong clientId, float time) { nextPlayerSendTimes[clientId] = time; } internal static float GetSendInterval() { return 1.2f; } 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; } } private 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), "Update")] internal static class FlashlightItemPatch { [HarmonyPostfix] 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 val = DimmingFlashlightsSync.EnsureItemDimmingVar(networkObjectId); bool isHostOrServer = LNetworkUtils.IsHostOrServer; if (((NetworkBehaviour)__instance).IsOwner) { float time = Time.time; float nextItemSendTime = FlashlightCache.GetNextItemSendTime(networkObjectId); if (time >= nextItemSendTime) { FlashlightCache.SetNextItemSendTime(networkObjectId, time + FlashlightCache.GetSendInterval()); if (isHostOrServer) { val.Value = num; val.MakeDirty(); } else { DimmingFlashlightsSync.SendItemDimming(networkObjectId, num); } } } float value = val.Value; FlashlightCache.ApplyFlashlightIntensity(__instance, value); } } [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] internal class PlayerControllerBPatch { [HarmonyPostfix] private static void Postfix(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 val = DimmingFlashlightsSync.EnsurePlayerDimmingVar(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); float time = Time.time; float nextPlayerSendTime = FlashlightCache.GetNextPlayerSendTime(ownerClientId); if (time >= nextPlayerSendTime) { FlashlightCache.SetNextPlayerSendTime(ownerClientId, time + FlashlightCache.GetSendInterval()); if (isHostOrServer) { val.Value = num; val.MakeDirty(); } else { DimmingFlashlightsSync.SendPlayerDimming(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); Light obj = allHelmetLights[j]; if (obj != null) { obj.intensity = helmetBaseline * num2; } } } } [HarmonyPatch(typeof(StartOfRound), "OnDestroy")] internal static class StartOfRoundPatch { [HarmonyPostfix] private static void Postfix() { FlashlightCache.Clear(); DimmingFlashlightsSync.Clear(); } } } namespace DimmingFlashlights.Network { internal struct ItemDimmingData { public ulong networkObjectId; public float charge; } internal struct PlayerDimmingData { public ulong clientId; public float charge; } internal static class DimmingFlashlightsSync { private static readonly Dictionary> itemDimmingVars = new Dictionary>(); private static readonly Dictionary> playerDimmingVars = new Dictionary>(); private static LNetworkMessage itemDimmingMessage; private static LNetworkMessage playerDimmingMessage; internal static void Clear() { itemDimmingVars.Clear(); playerDimmingVars.Clear(); } internal static void InitiateBeepBoop() { itemDimmingMessage = LNetworkMessage.Connect("DimmingFlashlights.ItemDimming", (Action)OnServerReceivedItemDimming, (Action)null, (Action)null); playerDimmingMessage = LNetworkMessage.Connect("DimmingFlashlights.PlayerDimming", (Action)OnServerReceivedPlayerDimming, (Action)null, (Action)null); } internal static LNetworkVariable EnsureItemDimmingVar(ulong networkObjectId) { if (itemDimmingVars.TryGetValue(networkObjectId, out var value)) { return value; } LNetworkVariable val = LNetworkVariable.Connect("DimmingFlashlights.Dimming.Item." + networkObjectId, 1f, (LNetworkVariableWritePerms)0, (Action)null); itemDimmingVars[networkObjectId] = val; return val; } internal static LNetworkVariable EnsurePlayerDimmingVar(ulong clientId) { if (playerDimmingVars.TryGetValue(clientId, out var value)) { return value; } LNetworkVariable val = LNetworkVariable.Connect("DimmingFlashlights.Dimming.Player." + clientId, 1f, (LNetworkVariableWritePerms)0, (Action)null); playerDimmingVars[clientId] = val; return val; } private static void OnServerReceivedItemDimming(ItemDimmingData data, ulong senderClientId) { LNetworkVariable val = EnsureItemDimmingVar(data.networkObjectId); val.Value = data.charge; val.MakeDirty(); } private static void OnServerReceivedPlayerDimming(PlayerDimmingData data, ulong senderClientId) { LNetworkVariable val = EnsurePlayerDimmingVar(data.clientId); val.Value = data.charge; val.MakeDirty(); } internal static void SendItemDimming(ulong networkObjectId, float charge) { if (itemDimmingMessage != null) { ItemDimmingData itemDimmingData = default(ItemDimmingData); itemDimmingData.networkObjectId = networkObjectId; itemDimmingData.charge = charge; itemDimmingMessage.SendServer(itemDimmingData); } } internal static void SendPlayerDimming(ulong clientId, float charge) { if (playerDimmingMessage != null) { PlayerDimmingData playerDimmingData = default(PlayerDimmingData); playerDimmingData.clientId = clientId; playerDimmingData.charge = charge; playerDimmingMessage.SendServer(playerDimmingData); } } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace DimmingFlashlights.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }