using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("NoBloodMoonTint")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0+ac6b2f3da8c5bba8ebbe23e2f064499f301665bf")]
[assembly: AssemblyProduct("NoBloodMoonTint")]
[assembly: AssemblyTitle("NoBloodMoonTint")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 NoBloodMoonTint
{
[BepInPlugin("NoBloodMoonTint", "NoBloodMoonTint", "4.0.0")]
public class Plugin : BasePlugin
{
internal static ManualLogSource PluginLog = null;
internal static Harmony? HarmonyInstance;
private static volatile bool _suppressHueEnabled = false;
internal static KeyCode ToggleKey = (KeyCode)288;
internal static KeyCode ScanKey = (KeyCode)287;
internal static bool IsSuppressionEnabled => _suppressHueEnabled;
internal static void SetSuppression(bool value)
{
_suppressHueEnabled = value;
VolumeSuppress.OnSuppressionChanged(value);
LogInfo($"[KEYBIND] Blood moon tint suppression set to: {value}");
}
public override void Load()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
PluginLog = ((BasePlugin)this).Log;
SessionFileLogger.Initialize("NoBloodMoonTint");
_suppressHueEnabled = false;
HarmonyInstance = new Harmony("NoBloodMoonTint");
ConfigEntry<string> val = ((BasePlugin)this).Config.Bind<string>("Keybinds", "Toggle", "F7", "Key to toggle blood moon tint suppression (Unity KeyCode name)");
ConfigEntry<string> val2 = ((BasePlugin)this).Config.Bind<string>("Keybinds", "ScanVolumes", "F6", "Key to scan and diff current scene volume profiles");
if (Enum.TryParse<KeyCode>(val.Value, ignoreCase: true, out KeyCode result))
{
ToggleKey = result;
}
if (Enum.TryParse<KeyCode>(val2.Value, ignoreCase: true, out KeyCode result2))
{
ScanKey = result2;
}
ShaderColorHook.Install(HarmonyInstance);
ClassInjector.RegisterTypeInIl2Cpp<KeybindListener>();
((BasePlugin)this).AddComponent<KeybindListener>();
LogInfo($"[KEYBIND] Keybinds active — Scan:{ScanKey} Toggle:{ToggleKey}");
LogInfo("[VOLUME] Suppression will reapply on scene load only.");
LogInfo("[VOLUME] Press F6 to scan and diff volume profiles while toggling blood moon on/off.");
}
internal static void LogInfo(string message)
{
PluginLog.LogInfo((object)message);
SessionFileLogger.Info(message);
}
}
public class KeybindListener : MonoBehaviour
{
private GUIStyle? _hudStyle;
public KeybindListener(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if ((int)Plugin.ScanKey != 0 && Input.GetKeyDown(Plugin.ScanKey))
{
VolumeSuppress.ScanAndLog("manual-scan");
}
else if ((int)Plugin.ToggleKey != 0 && Input.GetKeyDown(Plugin.ToggleKey))
{
Plugin.SetSuppression(!Plugin.IsSuppressionEnabled);
}
}
private void OnGUI()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
if (_hudStyle == null)
{
_hudStyle = new GUIStyle();
_hudStyle.fontSize = 11;
_hudStyle.fontStyle = (FontStyle)1;
}
string text = (Plugin.IsSuppressionEnabled ? "NoBloodMoonTint: ON" : "NoBloodMoonTint: OFF");
Color textColor = (Plugin.IsSuppressionEnabled ? new Color(0.2f, 1f, 0.2f, 1f) : new Color(1f, 0.35f, 0.1f, 1f));
float num = (float)Screen.height - 20f - 10f;
_hudStyle.normal.textColor = new Color(0f, 0f, 0f, 0.9f);
GUI.Label(new Rect(11f, num + 1f, 200f, 20f), text, _hudStyle);
_hudStyle.normal.textColor = textColor;
GUI.Label(new Rect(10f, num, 200f, 20f), text, _hudStyle);
}
}
internal static class VolumeSuppress
{
private sealed class VolumeState
{
internal float Weight;
internal bool Enabled;
}
private const float TargetScenePostProcessWeight = 1f;
private const float BrightnessLiftStops = 0.5f;
private static readonly List<Volume> _cached = new List<Volume>();
private static readonly Dictionary<Volume, float> _originalWeights = new Dictionary<Volume, float>();
private static readonly Dictionary<Volume, bool> _originalEnabled = new Dictionary<Volume, bool>();
private static readonly Dictionary<Volume, float> _originalPriorities = new Dictionary<Volume, float>();
private static readonly Dictionary<string, VolumeState> _lastScan = new Dictionary<string, VolumeState>();
private static Color? _originalAmbientLight = null;
private static bool _loggedGenericTargets = false;
private static readonly Dictionary<string, Color> _origColorFilters = new Dictionary<string, Color>();
private static readonly Dictionary<string, float> _origPostExposures = new Dictionary<string, float>();
private static readonly Dictionary<string, Color> _origSplitShadows = new Dictionary<string, Color>();
private static readonly Dictionary<string, Color> _origSplitHighlights = new Dictionary<string, Color>();
private static readonly Dictionary<string, float> _origTemperatures = new Dictionary<string, float>();
private static readonly Dictionary<string, float> _origTints = new Dictionary<string, float>();
private static readonly Dictionary<string, bool> _origBloodMoonFogActive = new Dictionary<string, bool>();
private static readonly Dictionary<Material, Color> _origCustomVignetteTint = new Dictionary<Material, Color>();
private static readonly List<Material> _customVignetteMats = new List<Material>();
private static int _customVignetteScanCooldown = 0;
internal static void OnSuppressionChanged(bool enabled)
{
if (!enabled)
{
RestoreVolumes();
}
else
{
ApplySuppressedStateImmediate();
}
}
private static void ApplySuppressedStateImmediate()
{
RebuildCache();
ZeroBloodMoonVolumes();
}
internal static void ScanAndLog(string reason)
{
Plugin.LogInfo("[VOLUME] Scanning all scene volumes (reason=" + reason + ")...");
try
{
Il2CppArrayBase<Volume> val = Object.FindObjectsOfType<Volume>();
int num = 0;
Dictionary<string, VolumeState> dictionary = new Dictionary<string, VolumeState>();
foreach (Volume item in val)
{
string text = (((Object)(object)item.sharedProfile != (Object)null) ? ((Object)item.sharedProfile).name : "<no profile>");
if (!ShouldSkipVolumeInLogs(text))
{
string value = (((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : "<null go>");
string key = $"{value}|{text}|{item.priority:F3}";
dictionary[key] = new VolumeState
{
Weight = item.weight,
Enabled = ((Behaviour)item).enabled
};
num++;
Plugin.LogInfo($"[VOLUME] '{value}' profile='{text}' enabled={((Behaviour)item).enabled} weight={item.weight:F3} isGlobal={item.isGlobal} priority={item.priority}");
}
}
Plugin.LogInfo($"[VOLUME] Found {num} non-sound volumes total.");
if (_lastScan.Count > 0)
{
int num2 = 0;
foreach (KeyValuePair<string, VolumeState> item2 in dictionary)
{
if (!_lastScan.TryGetValue(item2.Key, out VolumeState value2))
{
Plugin.LogInfo($"[VOLUME_DIFF] Added: {item2.Key} enabled={item2.Value.Enabled} weight={item2.Value.Weight:F3}");
num2++;
}
else if (Math.Abs(value2.Weight - item2.Value.Weight) > 0.0001f || value2.Enabled != item2.Value.Enabled)
{
Plugin.LogInfo($"[VOLUME_DIFF] Changed: {item2.Key} enabled {value2.Enabled}->{item2.Value.Enabled}, weight {value2.Weight:F3}->{item2.Value.Weight:F3}");
num2++;
}
}
foreach (KeyValuePair<string, VolumeState> item3 in _lastScan)
{
if (!dictionary.ContainsKey(item3.Key))
{
Plugin.LogInfo("[VOLUME_DIFF] Removed: " + item3.Key);
num2++;
}
}
if (num2 == 0)
{
Plugin.LogInfo("[VOLUME_DIFF] No differences from previous scan.");
}
}
_lastScan.Clear();
foreach (KeyValuePair<string, VolumeState> item4 in dictionary)
{
_lastScan[item4.Key] = item4.Value;
}
}
catch (Exception ex)
{
Plugin.LogInfo("[VOLUME] ScanAndLog failed: " + ex.GetType().Name + " " + ex.Message);
}
}
private static bool ShouldSkipVolumeInLogs(string profileName)
{
string text = (profileName ?? string.Empty).ToLowerInvariant();
return text.Contains("sound_profile") || text.StartsWith("mus ");
}
internal static void ZeroBloodMoonVolumes()
{
//IL_0506: Unknown result type (might be due to invalid IL or missing references)
//IL_050b: Unknown result type (might be due to invalid IL or missing references)
//IL_052c: Unknown result type (might be due to invalid IL or missing references)
//IL_0520: Unknown result type (might be due to invalid IL or missing references)
//IL_053c: Unknown result type (might be due to invalid IL or missing references)
//IL_0543: Unknown result type (might be due to invalid IL or missing references)
//IL_054a: Unknown result type (might be due to invalid IL or missing references)
//IL_0551: Unknown result type (might be due to invalid IL or missing references)
//IL_055d: Unknown result type (might be due to invalid IL or missing references)
//IL_0354: Unknown result type (might be due to invalid IL or missing references)
//IL_0342: Unknown result type (might be due to invalid IL or missing references)
//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
//IL_040b: Unknown result type (might be due to invalid IL or missing references)
//IL_041a: Unknown result type (might be due to invalid IL or missing references)
//IL_03de: Unknown result type (might be due to invalid IL or missing references)
try
{
foreach (Volume item in _cached)
{
if (!((Object)(object)item == (Object)null))
{
if (!_originalWeights.ContainsKey(item))
{
_originalWeights[item] = item.weight;
}
if (!_originalEnabled.ContainsKey(item))
{
_originalEnabled[item] = ((Behaviour)item).enabled;
}
if (!_originalPriorities.ContainsKey(item))
{
_originalPriorities[item] = item.priority;
}
float value;
float num = (_originalPriorities.TryGetValue(item, out value) ? value : item.priority);
if (Math.Abs(num) < 0.001f)
{
((Behaviour)item).enabled = true;
item.weight = 1f;
ApplyBaselineBrightnessLift(item);
}
else if (item.isGlobal && num >= 9.5f)
{
((Behaviour)item).enabled = false;
item.weight = 0f;
item.priority = 10f;
}
}
}
if (!_loggedGenericTargets)
{
_loggedGenericTargets = true;
Plugin.LogInfo($"[SUPPRESS] Blood moon effect suppression active (brightness +{0.5f:F2} EV).");
}
Color value3 = default(Color);
foreach (Volume item2 in _cached)
{
if ((Object)(object)item2 == (Object)null || (Object)(object)item2.sharedProfile == (Object)null)
{
continue;
}
float value2;
float num2 = (_originalPriorities.TryGetValue(item2, out value2) ? value2 : item2.priority);
if (!item2.isGlobal || !(num2 >= 9.5f))
{
continue;
}
try
{
string name = ((Object)item2.sharedProfile).name;
Enumerator<VolumeComponent> enumerator3 = item2.sharedProfile.components.GetEnumerator();
while (enumerator3.MoveNext())
{
VolumeComponent current3 = enumerator3.Current;
if ((Object)(object)current3 == (Object)null)
{
continue;
}
Type il2CppType = ((Object)current3).GetIl2CppType();
string text = ((il2CppType != null) ? ((MemberInfo)il2CppType).Name : null) ?? ((object)current3).GetType().Name;
if (name.IndexOf("bloodmoon", StringComparison.OrdinalIgnoreCase) >= 0 && text.IndexOf("StunlockFogVolumeComponent", StringComparison.OrdinalIgnoreCase) >= 0)
{
string key = name + "|" + text;
if (!_origBloodMoonFogActive.ContainsKey(key))
{
_origBloodMoonFogActive[key] = current3.active;
}
current3.active = false;
}
ColorAdjustments val = ((Il2CppObjectBase)current3).TryCast<ColorAdjustments>();
if ((Object)(object)val != (Object)null)
{
string key2 = name + "|ColorAdjustments";
if (!_origColorFilters.ContainsKey(key2))
{
_origColorFilters[key2] = ((VolumeParameter<Color>)(object)val.colorFilter).value;
}
((VolumeParameter<Color>)(object)val.colorFilter).value = Color.white;
continue;
}
SplitToning val2 = ((Il2CppObjectBase)current3).TryCast<SplitToning>();
if ((Object)(object)val2 != (Object)null)
{
string key3 = name + "|SplitToning";
if (!_origSplitShadows.ContainsKey(key3))
{
_origSplitShadows[key3] = ((VolumeParameter<Color>)(object)val2.shadows).value;
}
if (!_origSplitHighlights.ContainsKey(key3))
{
_origSplitHighlights[key3] = ((VolumeParameter<Color>)(object)val2.highlights).value;
}
((Color)(ref value3))..ctor(0.5f, 0.5f, 0.5f, 0f);
((VolumeParameter<Color>)(object)val2.shadows).value = value3;
((VolumeParameter<Color>)(object)val2.highlights).value = value3;
continue;
}
WhiteBalance val3 = ((Il2CppObjectBase)current3).TryCast<WhiteBalance>();
if ((Object)(object)val3 != (Object)null)
{
string key4 = name + "|WhiteBalance";
if (!_origTemperatures.ContainsKey(key4))
{
_origTemperatures[key4] = ((VolumeParameter<float>)(object)val3.temperature).value;
}
if (!_origTints.ContainsKey(key4))
{
_origTints[key4] = ((VolumeParameter<float>)(object)val3.tint).value;
}
((VolumeParameter<float>)(object)val3.temperature).value = 0f;
((VolumeParameter<float>)(object)val3.tint).value = 0f;
}
}
}
catch
{
}
}
try
{
Color ambientLight = RenderSettings.ambientLight;
if (!_originalAmbientLight.HasValue)
{
_originalAmbientLight = ambientLight;
}
if (IsWarmColor(ambientLight))
{
Color ambientLight2 = default(Color);
((Color)(ref ambientLight2))..ctor(ambientLight.g, ambientLight.g, ambientLight.g, ambientLight.a);
RenderSettings.ambientLight = ambientLight2;
}
}
catch
{
}
NeutralizeCustomVignetteTint();
}
catch
{
}
}
private static void ApplyBaselineBrightnessLift(Volume v)
{
if ((Object)(object)((v != null) ? v.sharedProfile : null) == (Object)null)
{
return;
}
try
{
string name = ((Object)v.sharedProfile).name;
Enumerator<VolumeComponent> enumerator = v.sharedProfile.components.GetEnumerator();
while (enumerator.MoveNext())
{
VolumeComponent current = enumerator.Current;
if ((Object)(object)current == (Object)null)
{
continue;
}
ColorAdjustments val = ((Il2CppObjectBase)current).TryCast<ColorAdjustments>();
if ((Object)(object)val == (Object)null)
{
continue;
}
string key = name + "|ColorAdjustments.postExposure";
if (!_origPostExposures.ContainsKey(key))
{
_origPostExposures[key] = ((VolumeParameter<float>)(object)val.postExposure).value;
}
((VolumeParameter<float>)(object)val.postExposure).value = _origPostExposures[key] + 0.5f;
break;
}
}
catch
{
}
}
private static void NeutralizeCustomVignetteTint()
{
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
try
{
if (--_customVignetteScanCooldown <= 0)
{
_customVignetteScanCooldown = 120;
_customVignetteMats.Clear();
Il2CppArrayBase<Material> val = Resources.FindObjectsOfTypeAll<Material>();
foreach (Material item in val)
{
if (!((Object)(object)item == (Object)null) && !((Object)(object)item.shader == (Object)null) && ((Object)item.shader).name.Equals("Hidden/Shader/CustomVignette", StringComparison.OrdinalIgnoreCase) && item.HasProperty("_ColorTint"))
{
_customVignetteMats.Add(item);
}
}
}
foreach (Material customVignetteMat in _customVignetteMats)
{
if (!((Object)(object)customVignetteMat == (Object)null) && customVignetteMat.HasProperty("_ColorTint"))
{
if (!_origCustomVignetteTint.ContainsKey(customVignetteMat))
{
_origCustomVignetteTint[customVignetteMat] = customVignetteMat.GetColor("_ColorTint");
}
customVignetteMat.SetColor("_ColorTint", new Color(0f, 0f, 0f, 0f));
}
}
}
catch
{
}
}
private static bool IsWarmColor(Color c)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
return c.r > 0.02f && c.r > c.g * 1.12f;
}
private static void RestoreVolumes()
{
//IL_0478: Unknown result type (might be due to invalid IL or missing references)
//IL_0417: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
foreach (KeyValuePair<Volume, float> originalWeight in _originalWeights)
{
if ((Object)(object)originalWeight.Key != (Object)null)
{
originalWeight.Key.weight = originalWeight.Value;
}
}
foreach (KeyValuePair<Volume, bool> item in _originalEnabled)
{
if ((Object)(object)item.Key != (Object)null)
{
((Behaviour)item.Key).enabled = item.Value;
}
}
foreach (KeyValuePair<Volume, float> originalPriority in _originalPriorities)
{
if ((Object)(object)originalPriority.Key != (Object)null)
{
originalPriority.Key.priority = originalPriority.Value;
}
}
try
{
Il2CppArrayBase<Volume> val = Object.FindObjectsOfType<Volume>();
foreach (Volume item2 in val)
{
if ((Object)(object)((item2 != null) ? item2.sharedProfile : null) == (Object)null)
{
continue;
}
string name = ((Object)item2.sharedProfile).name;
Enumerator<VolumeComponent> enumerator5 = item2.sharedProfile.components.GetEnumerator();
while (enumerator5.MoveNext())
{
VolumeComponent current5 = enumerator5.Current;
if ((Object)(object)current5 == (Object)null)
{
continue;
}
Type il2CppType = ((Object)current5).GetIl2CppType();
string text = ((il2CppType != null) ? ((MemberInfo)il2CppType).Name : null) ?? ((object)current5).GetType().Name;
string key = name + "|" + text;
if (_origBloodMoonFogActive.TryGetValue(key, out var value))
{
current5.active = value;
}
ColorAdjustments val2 = ((Il2CppObjectBase)current5).TryCast<ColorAdjustments>();
if ((Object)(object)val2 != (Object)null)
{
string key2 = name + "|ColorAdjustments";
if (_origColorFilters.TryGetValue(key2, out var value2))
{
((VolumeParameter<Color>)(object)val2.colorFilter).value = value2;
}
string key3 = name + "|ColorAdjustments.postExposure";
if (_origPostExposures.TryGetValue(key3, out var value3))
{
((VolumeParameter<float>)(object)val2.postExposure).value = value3;
}
continue;
}
SplitToning val3 = ((Il2CppObjectBase)current5).TryCast<SplitToning>();
if ((Object)(object)val3 != (Object)null)
{
string key4 = name + "|SplitToning";
if (_origSplitShadows.TryGetValue(key4, out var value4))
{
((VolumeParameter<Color>)(object)val3.shadows).value = value4;
}
if (_origSplitHighlights.TryGetValue(key4, out var value5))
{
((VolumeParameter<Color>)(object)val3.highlights).value = value5;
}
continue;
}
WhiteBalance val4 = ((Il2CppObjectBase)current5).TryCast<WhiteBalance>();
if ((Object)(object)val4 != (Object)null)
{
string key5 = name + "|WhiteBalance";
if (_origTemperatures.TryGetValue(key5, out var value6))
{
((VolumeParameter<float>)(object)val4.temperature).value = value6;
}
if (_origTints.TryGetValue(key5, out var value7))
{
((VolumeParameter<float>)(object)val4.tint).value = value7;
}
}
}
}
}
catch
{
}
_origColorFilters.Clear();
_origPostExposures.Clear();
_origSplitShadows.Clear();
_origSplitHighlights.Clear();
_origTemperatures.Clear();
_origTints.Clear();
_origBloodMoonFogActive.Clear();
foreach (KeyValuePair<Material, Color> item3 in _origCustomVignetteTint)
{
try
{
if ((Object)(object)item3.Key != (Object)null && item3.Key.HasProperty("_ColorTint"))
{
item3.Key.SetColor("_ColorTint", item3.Value);
}
}
catch
{
}
}
_origCustomVignetteTint.Clear();
_customVignetteMats.Clear();
_customVignetteScanCooldown = 0;
if (_originalAmbientLight.HasValue)
{
RenderSettings.ambientLight = _originalAmbientLight.Value;
_originalAmbientLight = null;
}
_originalWeights.Clear();
_originalEnabled.Clear();
_originalPriorities.Clear();
_loggedGenericTargets = false;
}
private static void RebuildCache()
{
_cached.Clear();
Il2CppArrayBase<Volume> val = Object.FindObjectsOfType<Volume>();
foreach (Volume item in val)
{
if (!((Object)(object)item == (Object)null))
{
_cached.Add(item);
}
}
}
}
internal static class ShaderColorHook
{
private static readonly HashSet<string> Logged = new HashSet<string>();
private static readonly HashSet<string> LoggedForcedNeutral = new HashSet<string>();
internal static void Install(Harmony harmony)
{
TryPatch(harmony, typeof(Shader), "SetGlobalColor", new Type[2]
{
typeof(string),
typeof(Color)
}, "SetGlobalColorStringPrefix", "Shader.SetGlobalColor(string,Color)");
TryPatch(harmony, typeof(Shader), "SetGlobalColor", new Type[2]
{
typeof(int),
typeof(Color)
}, "SetGlobalColorIntPrefix", "Shader.SetGlobalColor(int,Color)");
TryPatch(harmony, typeof(Shader), "SetGlobalVector", new Type[2]
{
typeof(string),
typeof(Vector4)
}, "SetGlobalVectorStringPrefix", "Shader.SetGlobalVector(string,Vector4)");
TryPatch(harmony, typeof(Shader), "SetGlobalVector", new Type[2]
{
typeof(int),
typeof(Vector4)
}, "SetGlobalVectorIntPrefix", "Shader.SetGlobalVector(int,Vector4)");
TryPatch(harmony, typeof(Material), "SetColor", new Type[2]
{
typeof(string),
typeof(Color)
}, "SetMaterialColorStringPrefix", "Material.SetColor(string,Color)");
TryPatch(harmony, typeof(Material), "SetColor", new Type[2]
{
typeof(int),
typeof(Color)
}, "SetMaterialColorIntPrefix", "Material.SetColor(int,Color)");
TryPatch(harmony, typeof(Material), "SetVector", new Type[2]
{
typeof(string),
typeof(Vector4)
}, "SetMaterialVectorStringPrefix", "Material.SetVector(string,Vector4)");
TryPatch(harmony, typeof(Material), "SetVector", new Type[2]
{
typeof(int),
typeof(Vector4)
}, "SetMaterialVectorIntPrefix", "Material.SetVector(int,Vector4)");
}
private static void TryPatch(Harmony harmony, Type type, string methodName, Type[] args, string prefixName, string label)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
try
{
MethodInfo method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | ((type == typeof(Shader)) ? BindingFlags.Static : BindingFlags.Instance), null, args, null);
if (method == null)
{
Plugin.LogInfo("[HOOK] Method not found: " + label);
return;
}
HarmonyMethod val = new HarmonyMethod(typeof(ShaderColorHook).GetMethod(prefixName, BindingFlags.Static | BindingFlags.NonPublic));
harmony.Patch((MethodBase)method, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Plugin.LogInfo("[HOOK] Hooked " + label);
}
catch (Exception ex)
{
Plugin.LogInfo($"[HOOK] Failed {label}: {ex.GetType().Name} {ex.Message}");
}
}
private static bool SetGlobalColorStringPrefix(string name, Color value)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
if (Logged.Add("global_color:" + name))
{
Plugin.LogInfo($"[SHADER] SetGlobalColor name='{name}' r={value.r:F3} g={value.g:F3} b={value.b:F3} a={value.a:F3}");
}
if (Plugin.IsSuppressionEnabled && IsBloodMoonColor(value) && IsLikelyMoonContext(name, null, null))
{
Plugin.LogInfo("[SHADER] SUPPRESSED SetGlobalColor '" + name + "'");
return false;
}
return true;
}
private static bool SetGlobalColorIntPrefix(int nameID, Color value)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
if (Logged.Add($"global_color_id:{nameID}"))
{
Plugin.LogInfo($"[SHADER] SetGlobalColor nameID={nameID} r={value.r:F3} g={value.g:F3} b={value.b:F3} a={value.a:F3}");
}
return true;
}
private static bool SetGlobalVectorStringPrefix(string name, Vector4 value)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
if (Logged.Add("global_vector:" + name))
{
Plugin.LogInfo($"[SHADER] SetGlobalVector name='{name}' x={value.x:F3} y={value.y:F3} z={value.z:F3} w={value.w:F3}");
}
return true;
}
private static bool SetGlobalVectorIntPrefix(int nameID, Vector4 value)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
if (Logged.Add($"global_vector_id:{nameID}"))
{
Plugin.LogInfo($"[SHADER] SetGlobalVector nameID={nameID} x={value.x:F3} y={value.y:F3} z={value.z:F3} w={value.w:F3}");
}
return true;
}
private static bool SetMaterialColorStringPrefix(Material __instance, string name, ref Color value)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
string text = SafeName((__instance != null) ? ((Object)__instance).name : null);
string text2 = SafeName(((Object)(object)((__instance != null) ? __instance.shader : null) != (Object)null) ? ((Object)__instance.shader).name : null);
string item = $"mat_color:{text2}:{text}:{name}";
if (Logged.Add(item) && (IsBloodMoonColor(value) || IsLikelyMoonContext(name, text, text2)))
{
Plugin.LogInfo($"[MATERIAL] SetColor name='{name}' shader='{text2}' material='{text}' r={value.r:F3} g={value.g:F3} b={value.b:F3} a={value.a:F3}");
}
if (Plugin.IsSuppressionEnabled && IsDarkForegroundPass(name, text, text2))
{
value = new Color(0f, 0f, 0f, 0f);
string item2 = $"forced_df:{text2}:{text}:{name}";
if (LoggedForcedNeutral.Add(item2))
{
Plugin.LogInfo($"[MATERIAL] FORCED NEUTRAL SetColor name='{name}' shader='{text2}' material='{text}'");
}
return true;
}
if (Plugin.IsSuppressionEnabled && IsBloodMoonColor(value) && IsLikelyMoonContext(name, text, text2))
{
value = new Color(0f, 0f, 0f, 0f);
string item3 = $"forced_generic:{text2}:{text}:{name}";
if (LoggedForcedNeutral.Add(item3))
{
Plugin.LogInfo($"[MATERIAL] FORCED NEUTRAL (generic) SetColor name='{name}' shader='{text2}' material='{text}'");
}
}
return true;
}
private static bool SetMaterialColorIntPrefix(Material __instance, int nameID, ref Color value)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
string text = SafeName((__instance != null) ? ((Object)__instance).name : null);
string text2 = SafeName(((Object)(object)((__instance != null) ? __instance.shader : null) != (Object)null) ? ((Object)__instance.shader).name : null);
string item = $"mat_color_id:{text2}:{text}:{nameID}";
if (Logged.Add(item) && IsBloodMoonColor(value))
{
Plugin.LogInfo($"[MATERIAL] SetColor nameID={nameID} shader='{text2}' material='{text}' r={value.r:F3} g={value.g:F3} b={value.b:F3} a={value.a:F3}");
}
if (Plugin.IsSuppressionEnabled && IsDarkForegroundPass(null, text, text2) && IsBloodMoonColor(value))
{
value = new Color(0f, 0f, 0f, 0f);
string item2 = $"forced_df_id:{text2}:{text}:{nameID}";
if (LoggedForcedNeutral.Add(item2))
{
Plugin.LogInfo($"[MATERIAL] FORCED NEUTRAL SetColor nameID={nameID} shader='{text2}' material='{text}'");
}
}
return true;
}
private static bool SetMaterialVectorStringPrefix(Material __instance, string name, Vector4 value)
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
string text = SafeName((__instance != null) ? ((Object)__instance).name : null);
string text2 = SafeName(((Object)(object)((__instance != null) ? __instance.shader : null) != (Object)null) ? ((Object)__instance.shader).name : null);
string item = $"mat_vector:{text2}:{text}:{name}";
if (Logged.Add(item) && (IsBloodMoonVector(value) || IsLikelyMoonContext(name, text, text2)))
{
Plugin.LogInfo($"[MATERIAL] SetVector name='{name}' shader='{text2}' material='{text}' x={value.x:F3} y={value.y:F3} z={value.z:F3} w={value.w:F3}");
}
return true;
}
private static bool SetMaterialVectorIntPrefix(Material __instance, int nameID, Vector4 value)
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
string value2 = SafeName((__instance != null) ? ((Object)__instance).name : null);
string value3 = SafeName(((Object)(object)((__instance != null) ? __instance.shader : null) != (Object)null) ? ((Object)__instance.shader).name : null);
string item = $"mat_vector_id:{value3}:{value2}:{nameID}";
if (Logged.Add(item) && IsBloodMoonVector(value))
{
Plugin.LogInfo($"[MATERIAL] SetVector nameID={nameID} shader='{value3}' material='{value2}' x={value.x:F3} y={value.y:F3} z={value.z:F3} w={value.w:F3}");
}
return true;
}
private static bool IsBloodMoonColor(Color c)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: 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)
return c.a > 0.02f && c.r > 0.1f && c.r > c.g * 1.4f && c.r > c.b * 1.4f;
}
private static bool IsBloodMoonVector(Vector4 v)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
return v.x > 0.1f && v.x > v.y * 1.4f && v.x > v.z * 1.4f;
}
private static bool IsLikelyMoonContext(string? propertyName, string? materialName, string? shaderName)
{
string text = $"{propertyName} {materialName} {shaderName}".ToLowerInvariant();
return text.Contains("blood") || text.Contains("moon") || text.Contains("tint") || text.Contains("hue") || text.Contains("overlay") || text.Contains("post") || text.Contains("fog") || text.Contains("sky") || text.Contains("atmo") || text.Contains("vignette") || text.Contains("grade");
}
private static bool IsDarkForegroundPass(string? propertyName, string materialName, string shaderName)
{
if (!shaderName.Equals("Hidden/Shader/DarkForeground", StringComparison.OrdinalIgnoreCase) && !materialName.Equals("Hidden/Shader/DarkForeground", StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (propertyName == null)
{
return true;
}
return propertyName.Equals("_ForegroundColor", StringComparison.OrdinalIgnoreCase) || propertyName.Equals("_TintColor", StringComparison.OrdinalIgnoreCase) || propertyName.Equals("_OverlayColor", StringComparison.OrdinalIgnoreCase);
}
private static string SafeName(string? value)
{
return string.IsNullOrWhiteSpace(value) ? "<null>" : value;
}
}
internal static class SessionFileLogger
{
private static readonly object Sync = new object();
private static StreamWriter? _writer;
private static string? _logPath;
internal static void Initialize(string pluginName)
{
string text = Path.Combine(Paths.BepInExRootPath, "logs");
Directory.CreateDirectory(text);
_logPath = Path.Combine(text, pluginName + ".log");
RotateExistingFile(_logPath);
_writer = new StreamWriter(_logPath, append: false)
{
AutoFlush = true
};
Write("INFO", "Session logging started.");
}
internal static void Info(string message)
{
Write("INFO", message);
}
private static void Write(string level, string message)
{
lock (Sync)
{
if (_writer != null)
{
string value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
_writer.WriteLine($"[{value}] [{level}] {message}");
}
}
}
private static void RotateExistingFile(string currentPath)
{
if (File.Exists(currentPath))
{
string directoryName = Path.GetDirectoryName(currentPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(currentPath);
string extension = Path.GetExtension(currentPath);
string text = DateTime.Now.ToString("yyyyMMdd-HHmmss");
string destFileName = Path.Combine(directoryName, fileNameWithoutExtension + "." + text + extension);
File.Move(currentPath, destFileName, overwrite: true);
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "NoBloodMoonTint";
public const string PLUGIN_NAME = "NoBloodMoonTint";
public const string PLUGIN_VERSION = "4.0.0";
}
}