using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JG224.BrighterNights.Core; using JG224.BrighterNights.Runtime; using JG224.ModCore.API; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.PostProcessing; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BrighterNights")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.0.0")] [assembly: AssemblyInformationalVersion("0.5.0")] [assembly: AssemblyProduct("BrighterNights")] [assembly: AssemblyTitle("BrighterNights")] [assembly: AssemblyVersion("0.5.0.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 JG224.BrighterNights { internal sealed class BrighterNightsConfig { private readonly List _entries = new List(); internal ConfigEntry Enabled { get; } internal ConfigEntry NightStrength { get; } internal ConfigEntry SwampStrength { get; } internal ConfigEntry AffectInteriors { get; } internal ConfigEntry InteriorStrength { get; } internal BrighterNightsConfig(ConfigFile file) { Enabled = Add(file.Bind("General", "Enabled", true, "Improve dark-scene visibility on this client. Disable to restore the normal view immediately.")); NightStrength = Add(file.Bind("Visibility", "NightStrength", 0.1f, Strength("Nighttime visibility boost. Fades in from 18:00 to 20:24, stays full until 06:00, then fades out by 08:00. Zero from 08:00 to 18:00."))); SwampStrength = Add(file.Bind("Visibility", "SwampStrength", 0.15f, Strength("Minimum outdoor Swamp visibility boost, including daytime. At night the stronger boost wins; they do not stack."))); AffectInteriors = Add(file.Bind("Visibility", "AffectInteriors", true, "Apply InteriorStrength in the game's dungeon interiors (caves, crypts, chambers and mines). Buildings and shelter do not count. Off leaves interiors unchanged even at night or in the Swamp.")); InteriorStrength = Add(file.Bind("Visibility", "InteriorStrength", 0.15f, Strength("Visibility boost inside dungeon interiors, independent of outdoor time and biome."))); } internal IEnumerable RegisterMetadata(ICoreServices services, ModuleId owner) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) foreach (ConfigEntryBase entry in _entries) { yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, entry.Definition.Section, entry.Definition.Key, (ConfigScope)1, (Func)(() => Convert.ToString(entry.BoxedValue, CultureInfo.InvariantCulture)), 1)); } } private ConfigEntry Add(ConfigEntry entry) { _entries.Add((ConfigEntryBase)(object)entry); return entry; } private static ConfigDescription Strength(string description) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown return new ConfigDescription(description + " Range 0 to 1; 0 disables this boost. This changes the camera's neutral gamma, not light sources or fog.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty()); } } [BepInPlugin("com.jg224.brighternights", "BrighterNights", "0.5.0")] [BepInProcess("valheim.exe")] [BepInDependency("com.jg224.modcore", "0.5.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.jg224.brighternights"; public const string PluginName = "BrighterNights"; public const string PluginVersion = "0.5.0"; public const string ModCoreGuid = "com.jg224.modcore"; public const string ConfigFileName = "com.jg224.brighternights.cfg"; public const int ProtocolVersion = 1; public static readonly ModuleId ModuleId = new ModuleId("brighternights"); private readonly List _registrations = new List(); private Harmony _harmony; private bool _active; private bool _shutDown; private static ModuleRuntimeState _state; private static string _reason; private static bool _registered; internal static ICoreServices Core { get; private set; } internal static BrighterNightsConfig Settings { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { if (!ModCoreApi.IsAvailable) { throw new InvalidOperationException("ModCore did not initialize before BrighterNights."); } Core = ModCoreApi.Services; if (!string.Equals(Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath), "com.jg224.brighternights.cfg", StringComparison.Ordinal)) { throw new InvalidOperationException("Unexpected BrighterNights configuration filename."); } Settings = new BrighterNightsConfig(((BaseUnityPlugin)this).Config); RegisterWithCore(); _harmony = new Harmony("com.jg224.brighternights"); _harmony.PatchAll(typeof(Plugin).Assembly); _active = true; Game.isModded = true; ReportState((ModuleRuntimeState)2, "Client-local visibility adjustment ready."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BrighterNights 0.5.0 loaded; client only."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("BrighterNights failed to initialize safely: " + ex)); if (Core != null) { ReportState((ModuleRuntimeState)5, ex.Message); } Shutdown(); throw; } } private void RegisterWithCore() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) SemanticVersion val = default(SemanticVersion); if (!SemanticVersion.TryParse("0.5.0", ref val)) { throw new InvalidOperationException("Invalid BrighterNights release version."); } _registrations.Add(Core.Modules.Register(new ModuleDescriptor(ModuleId, "com.jg224.brighternights", "BrighterNights", val, 1, (ModuleSide)1, (ModuleRequirement)1, 0uL, 1, 1))); _registered = true; _registrations.AddRange(Settings.RegisterMetadata(Core, ModuleId)); _registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)9, (Action)delegate { VisibilityRuntime.Reset(); }, 0)); _registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)3, (Action)delegate { VisibilityRuntime.Reset(); }, 0)); } private void LateUpdate() { if (!_active) { return; } try { VisibilityRuntime.Tick(); } catch (Exception ex) { _active = false; VisibilityRuntime.Reset(); ReportState((ModuleRuntimeState)5, "Visibility adjustment stopped: " + ex.Message); ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } internal static void ReportState(ModuleRuntimeState state, string reason) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (reason != null && reason.Length > 1024) { reason = reason.Substring(0, 1024); } if (_state == state && _reason == reason) { return; } _state = state; _reason = reason; if (_registered) { ICoreServices core = Core; if (core != null) { core.Modules.SetState(ModuleId, state, reason); } } if ((int)state != 2) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)reason); } } } private void OnDisable() { VisibilityRuntime.Reset(); } private void OnDestroy() { Shutdown(); } private void Shutdown() { if (_shutDown) { return; } _shutDown = true; _active = false; VisibilityRuntime.Reset(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; for (int num = _registrations.Count - 1; num >= 0; num--) { try { _registrations[num].Dispose(); } catch (Exception ex) { ManualLogSource logger = ((BaseUnityPlugin)this).Logger; if (logger != null) { logger.LogWarning((object)("Registration cleanup failed: " + ex.Message)); } } } _registrations.Clear(); _registered = false; Core = null; Settings = null; Log = null; _reason = null; } } } namespace JG224.BrighterNights.Core { public static class VisibilityRules { public const float DefaultNightStrength = 0.1f; public const float DefaultSwampStrength = 0.15f; public const float DefaultInteriorStrength = 0.15f; public const float DefaultTransitionRate = 3f; public static float NightFactor(float dayFraction) { if (!IsFinite(dayFraction) || dayFraction < 0f || dayFraction > 1f || (dayFraction >= 1f / 3f && dayFraction <= 0.75f)) { return 0f; } if (dayFraction <= 0.25f || dayFraction >= 0.85f) { return 1f; } float num = ((dayFraction < 1f / 3f) ? ((1f / 3f - dayFraction) / 0.08333334f) : ((dayFraction - 0.75f) / 0.1f)); return ClampStrength(num * num * (3f - 2f * num)); } public static float GetTargetLift(bool enabled, float nightFactor, bool isSwamp, bool isInterior, bool affectInteriors, float nightStrength, float swampStrength, float interiorStrength) { if (!enabled) { return 0f; } if (isInterior) { if (!affectInteriors) { return 0f; } return ClampStrength(interiorStrength); } float val = ClampStrength(nightFactor) * ClampStrength(nightStrength); float val2 = (isSwamp ? ClampStrength(swampStrength) : 0f); return Math.Max(val, val2); } public static float SmoothLift(float current, float target, float unscaledDeltaTime, float transitionRate) { target = ClampStrength(target); if (target == 0f) { return 0f; } current = ClampStrength(current); if (!IsFinite(unscaledDeltaTime) || unscaledDeltaTime <= 0f || !IsFinite(transitionRate) || transitionRate <= 0f) { return current; } double num = Math.Exp((0.0 - (double)transitionRate) * (double)unscaledDeltaTime); return ClampStrength((float)((double)target + (double)(current - target) * num)); } public static float ClampStrength(float value) { if (!IsFinite(value) || value <= 0f) { return 0f; } if (!(value >= 1f)) { return value; } return 1f; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } } namespace JG224.BrighterNights.Runtime { internal static class VisibilityRuntime { private const float GammaScale = 0.2f; private static GameCamera _gameCamera; private static Camera _camera; private static PostProcessingBehaviour _postProcessing; private static ColorGradingComponent _grading; private static ColorGradingModel _model; private static ColorGradingModel _sourceModel; private static float _strength; private static float _preparedStrength = -1f; private static float _nextRendererLookup; private static bool _preparing; private static bool _renderFaulted; private static bool _sourceChanged; internal static void Tick() { if (_renderFaulted) { return; } GameCamera instance = GameCamera.instance; if ((Object)(object)_gameCamera != (Object)(object)instance) { Reset(); _gameCamera = instance; if (Object.op_Implicit((Object)(object)instance)) { _camera = ((Component)instance).GetComponent(); _postProcessing = ((Component)instance).GetComponent(); _nextRendererLookup = Time.unscaledTime + 1f; } } else if (Object.op_Implicit((Object)(object)instance) && (!Object.op_Implicit((Object)(object)_camera) || !Object.op_Implicit((Object)(object)_postProcessing)) && Time.unscaledTime >= _nextRendererLookup) { _camera = ((Component)instance).GetComponent(); _postProcessing = ((Component)instance).GetComponent(); _nextRendererLookup = Time.unscaledTime + 1f; } float target = GetTarget(); _strength = VisibilityRules.SmoothLift(_strength, target, Time.unscaledDeltaTime, 3f); if (target == 0f) { ReleaseGrading(); Plugin.ReportState((ModuleRuntimeState)2, "Client-local visibility adjustment ready."); } else if (!Object.op_Implicit((Object)(object)_camera) || !Object.op_Implicit((Object)(object)_postProcessing) || !((Behaviour)_postProcessing).isActiveAndEnabled || !Object.op_Implicit((Object)(object)_postProcessing.profile) || _postProcessing.profile.colorGrading == null || !((PostProcessingModel)_postProcessing.profile.colorGrading).enabled) { _strength = 0f; ReleaseGrading(); Plugin.ReportState((ModuleRuntimeState)3, "The game camera's color grading is unavailable or disabled; BrighterNights is inactive. Restore the normal renderer or check graphics mods."); } else { Plugin.ReportState((ModuleRuntimeState)2, "Client-local visibility adjustment ready."); } } private static float GetTarget() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 BrighterNightsConfig settings = Plugin.Settings; Player localPlayer = Player.m_localPlayer; if (settings == null || !settings.Enabled.Value || !Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)EnvMan.instance) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InIntro()) { return 0f; } return VisibilityRules.GetTargetLift(enabled: true, VisibilityRules.NightFactor(EnvMan.instance.GetDayFraction()), (int)localPlayer.GetCurrentBiome() == 2, ((Character)localPlayer).InInterior(), settings.AffectInteriors.Value, settings.NightStrength.Value, settings.SwampStrength.Value, settings.InteriorStrength.Value); } internal static void Prepare(ColorGradingComponent source, Material material, bool sourceDirty) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (_preparing || _renderFaulted) { return; } if (sourceDirty && _sourceModel == ((PostProcessingComponent)(object)source).model) { _sourceChanged = true; } if (_strength <= 0f || ((PostProcessingComponentBase)source).context == null || !Object.op_Implicit((Object)(object)_camera) || (Object)(object)_gameCamera != (Object)(object)GameCamera.instance || (Object)(object)((PostProcessingComponentBase)source).context.camera != (Object)(object)_camera || !Object.op_Implicit((Object)(object)material) || ((PostProcessingComponent)(object)source).model == null || !((PostProcessingComponentBase)source).active || GetTarget() == 0f) { return; } _preparing = true; try { if (_grading == null) { _model = new ColorGradingModel(); _grading = new ColorGradingComponent(); } ((PostProcessingComponent)(object)_grading).Init(((PostProcessingComponentBase)source).context, _model); if (_sourceModel != ((PostProcessingComponent)(object)source).model || _sourceChanged || sourceDirty || Mathf.Abs(_preparedStrength - _strength) >= 0.001f) { Settings settings = ((PostProcessingComponent)(object)source).model.settings; settings.colorWheels.linear.gamma.a += _strength * 0.2f; _model.settings = settings; _sourceModel = ((PostProcessingComponent)(object)source).model; _preparedStrength = _strength; _sourceChanged = false; } ((PostProcessingComponentRenderTexture)(object)_grading).Prepare(material); } catch (Exception ex) { _renderFaulted = true; _strength = 0f; Plugin.ReportState((ModuleRuntimeState)5, "BrighterNights stopped after a rendering failure; see the error log. " + ex.Message); ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)ex); } try { ((PostProcessingComponentRenderTexture)(object)source).Prepare(material); } finally { ReleaseGrading(); } } finally { _preparing = false; } } private static void ReleaseGrading() { if (_grading != null && _model != null) { ((PostProcessingComponentBase)_grading).OnDisable(); } _grading = null; _model = null; _sourceModel = null; _preparedStrength = -1f; _sourceChanged = false; } internal static void Reset() { _strength = 0f; ReleaseGrading(); _gameCamera = null; _camera = null; _postProcessing = null; _nextRendererLookup = 0f; _renderFaulted = false; } } } namespace JG224.BrighterNights.Patches { [HarmonyPatch(typeof(ColorGradingComponent), "Prepare")] internal static class ColorGradingPreparePatch { [HarmonyPrefix] private static void Prefix(ColorGradingComponent __instance, out bool __state) { __state = ((PostProcessingComponent)(object)__instance).model != null && ((PostProcessingComponent)(object)__instance).model.isDirty; } [HarmonyPostfix] private static void Postfix(ColorGradingComponent __instance, Material uberMaterial, bool __state) { VisibilityRuntime.Prepare(__instance, uberMaterial, __state); } } }