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
{
}
}