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 System.Threading.Tasks;
using Assets.Scripts.Actors.Enemies;
using Assets.Scripts.Managers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ShadowFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+dab7a35fdf30a8075f8f7cb326d81bb5945bcf97")]
[assembly: AssemblyProduct("ShadowFix")]
[assembly: AssemblyTitle("ShadowFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ShadowFix
{
[BepInPlugin("ShadowFix", "ShadowFix", "1.1.2")]
public class ShadowFixPlugin : BasePlugin
{
public class ShadowFixComponent : MonoBehaviour
{
private EnemyManager enemyManager;
private int lastScene = -1;
public List<uint> fixedEnemies = new List<uint>();
private bool isFixing;
public static ShadowFixComponent Instance { get; private set; }
private void Start()
{
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Log.LogInfo((object)"Detected duplicate ShadowFixComponent. Destroying the newest one.");
Object.Destroy((Object)(object)this);
}
else
{
Instance = this;
Log.LogInfo((object)"ShadowFixComponent started.");
}
}
private void Update()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
bool flag = default(bool);
try
{
Scene val = SceneManager.GetActiveScene();
int buildIndex = ((Scene)(ref val)).buildIndex;
if (buildIndex != lastScene)
{
ManualLogSource log = Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Detected scene change to ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(buildIndex);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (");
val = SceneManager.GetSceneAt(0);
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Scene)(ref val)).name);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(").");
}
log.LogInfo(val2);
FixShadows();
lastScene = buildIndex;
}
if (EnableNPCShadows && Time.frameCount % 2 >= 1)
{
FixEnemyShadows();
}
}
catch (Exception ex)
{
ManualLogSource log2 = Log;
BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(17, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Error in Update: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
}
log2.LogError(val3);
}
}
private void FixEnemyShadows()
{
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
bool flag = default(bool);
try
{
if ((Object)(object)enemyManager == (Object)null)
{
return;
}
Enumerator<uint, Enemy> enumerator = enemyManager.enemies.Values.GetEnumerator();
while (enumerator.MoveNext())
{
Enemy current = enumerator.Current;
if ((Object)(object)current == (Object)null || fixedEnemies.Contains(current.id))
{
continue;
}
try
{
Renderer renderer = current.renderer;
if (!((Object)(object)renderer == (Object)null))
{
renderer.shadowCastingMode = (ShadowCastingMode)1;
fixedEnemies.Add(current.id);
}
}
catch (Exception ex)
{
ManualLogSource log = Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error fixing shadow for enemy ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(current.id);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
}
catch (Exception ex2)
{
ManualLogSource log2 = Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error in FixEnemyShadows: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
}
log2.LogError(val);
}
}
private async void FadeShadows(Light light, float targetStrength)
{
try
{
int steps = 32;
float duration = 0.15f;
float initialStrength = 0f;
for (int i = 1; i <= steps; i++)
{
if ((Object)(object)light == (Object)null)
{
break;
}
if (((Object)light).Equals((Object)null))
{
break;
}
light.shadowStrength = Mathf.Lerp(initialStrength, targetStrength, (float)i / (float)steps);
await Task.Delay((int)(duration * 1000f / (float)steps));
}
}
catch (Exception ex)
{
ManualLogSource log = Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error in FadeShadows: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
private async void FixShadows()
{
if (isFixing)
{
Log.LogWarning((object)"ShadowFix is already in progress.");
return;
}
bool flag = default(bool);
try
{
Scene activeScene = SceneManager.GetActiveScene();
int buildIndex = ((Scene)(ref activeScene)).buildIndex;
if (buildIndex <= 1 || buildIndex == 3)
{
Log.LogInfo((object)"Non-gameplay scene detected, skipping shadow fix.");
return;
}
Log.LogInfo((object)"Starting ShadowFix...");
isFixing = true;
activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).buildIndex != buildIndex)
{
Log.LogWarning((object)"Scene changed during delay, aborting shadow fix.");
return;
}
await Task.Delay(1000);
float time = Time.time;
fixedEnemies.Clear();
EnableDirectionalShadows();
SetMeshShadowCastingMode();
DestroyBlobShadows();
ConfigurePlayerShadows();
SetupNPCShadows();
float num = Time.time - time;
ManualLogSource log = Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ShadowFix done in ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F2");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s.");
}
log.LogInfo(val);
}
catch (Exception ex)
{
ManualLogSource log2 = Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Error in FixShadows: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log2.LogError(val2);
}
finally
{
isFixing = false;
}
}
private async void EnableDirectionalShadows()
{
int maxRetries = 3;
bool flag2 = default(bool);
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
Il2CppArrayBase<Light> obj = Object.FindObjectsOfType<Light>();
bool flag = false;
foreach (Light item in obj)
{
if ((int)item.type != 1)
{
continue;
}
flag = true;
if ((int)item.shadows == 0)
{
item.shadows = (LightShadows)2;
FadeShadows(item, ShadowDarkness);
item.shadowConstantBias *= 0.8f;
item.shadowBias *= 0.8f;
item.shadowNormalBias *= 0.8f;
ManualLogSource log = Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(23, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Enabled shadows for '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)item).name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
}
log.LogInfo(val);
}
}
if (flag)
{
break;
}
if (attempt < maxRetries)
{
ManualLogSource log2 = Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 2, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Directional light not found, retrying... (Attempt ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(attempt);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(maxRetries);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
}
log2.LogInfo(val);
await Task.Delay(500);
}
else
{
ManualLogSource log3 = Log;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(44, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Directional light not found after ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(maxRetries);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" attempts.");
}
log3.LogWarning(val2);
}
}
}
private void SetMeshShadowCastingMode()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(28, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Must set two-sided shadows? ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(TwoSidedShadows);
}
log.LogInfo(val);
if (!TwoSidedShadows)
{
return;
}
Log.LogInfo((object)"Setting shadow casting mode for all meshes...");
foreach (MeshRenderer item in Object.FindObjectsOfType<MeshRenderer>())
{
((Renderer)item).shadowCastingMode = (ShadowCastingMode)2;
}
Log.LogInfo((object)"Shadow casting mode set!");
}
private async void ConfigurePlayerShadows()
{
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Enable player shadow? ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EnablePlayerShadow);
}
log.LogInfo(val);
int delayMs = (int)(MaxRetryWaitTime * 1000f / (float)MaxRetries);
for (int attempt = 1; attempt <= MaxRetries; attempt++)
{
PlayerRenderer val2 = Object.FindObjectOfType<PlayerRenderer>();
if ((Object)(object)val2 != (Object)null && !((Object)val2).Equals((Object)null))
{
GameObject rendererObject = val2.rendererObject;
if (!((Object)(object)rendererObject == (Object)null) && !((Object)rendererObject).Equals((Object)null))
{
{
foreach (Renderer componentsInChild in rendererObject.GetComponentsInChildren<Renderer>(true))
{
componentsInChild.shadowCastingMode = (ShadowCastingMode)(EnablePlayerShadow ? 1 : 0);
ManualLogSource log2 = Log;
val = new BepInExInfoLogInterpolatedStringHandler(28, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(EnablePlayerShadow ? "Enabled" : "Disabled");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" shadows for player mesh '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)componentsInChild).name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
}
log2.LogInfo(val);
}
break;
}
}
if (attempt >= MaxRetries)
{
Log.LogWarning((object)"Player GameObject not found.");
break;
}
await Task.Delay(delayMs);
}
else if (attempt < MaxRetries)
{
await Task.Delay(delayMs);
}
else
{
ManualLogSource log3 = Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("PlayerRenderer not found after ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(MaxRetries);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" attempts.");
}
log3.LogWarning(val3);
}
}
}
private async void DestroyBlobShadows()
{
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Must destroy blob shadow? ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(DisableBlobShadow);
}
log.LogInfo(val);
int delayMs = (int)(MaxRetryWaitTime * 1000f / (float)MaxRetries);
for (int attempt = 1; attempt <= MaxRetries; attempt++)
{
Il2CppArrayBase<Projector> val2 = Object.FindObjectsOfType<Projector>();
if (val2 != null && val2.Length > 0 && DisableBlobShadow)
{
foreach (Projector item in val2)
{
Object.Destroy((Object)(object)item);
Log.LogInfo((object)"Destroyed BlobShadowProjector.");
}
break;
}
if (DisableBlobShadow && attempt < MaxRetries)
{
await Task.Delay(delayMs);
}
else if (DisableBlobShadow)
{
ManualLogSource log2 = Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("BlobShadowProjector not found after ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(MaxRetries);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" attempts.");
}
log2.LogWarning(val3);
}
}
}
private async void SetupNPCShadows()
{
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Enable NPC shadows? ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EnableNPCShadows);
}
log.LogInfo(val);
if (!EnableNPCShadows)
{
return;
}
int maxRetries = 3;
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
Il2CppArrayBase<EnemyManager> val2 = Object.FindObjectsByType<EnemyManager>((FindObjectsSortMode)0);
if (val2.Length == 0)
{
if (attempt == maxRetries)
{
Log.LogWarning((object)"EnemyManager not found, NPC shadows may not be set up correctly.");
}
await Task.Delay(1000);
continue;
}
enemyManager = val2[0];
Log.LogInfo((object)"EnemyManager found, NPC shadows will be set up.");
break;
}
}
}
[HarmonyPatch(typeof(EnemyDissolve))]
[HarmonyPatch("StartDissolve")]
private class EnemyDissolvePatch
{
private static void Postfix(EnemyDissolve __instance)
{
__instance.enemyRenderer.shadowCastingMode = (ShadowCastingMode)0;
__instance.enemyRenderer.sharedMaterial.renderQueue = 3000;
}
}
internal static ManualLogSource Log;
public static bool DisableBlobShadow = true;
public static bool TwoSidedShadows = true;
public static bool EnablePlayerShadow = false;
public static bool EnableNPCShadows = false;
public static float ShadowDarkness = 0.8f;
public static float MaxRetryWaitTime = 5f;
public static int MaxRetries = 32;
public override void Load()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Expected O, but got Unknown
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Expected O, but got Unknown
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Expected O, but got Unknown
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Expected O, but got Unknown
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Expected O, but got Unknown
Log = ((BasePlugin)this).Log;
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ShadowFix");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded successfully!");
}
log.LogInfo(val);
new Harmony("ShadowFix").PatchAll();
ClassInjector.RegisterTypeInIl2Cpp<ShadowFixComponent>();
ConfigDefinition val2 = new ConfigDefinition("General", "DisableBlobShadow");
DisableBlobShadow = ((BasePlugin)this).Config.Bind<bool>(val2, true, new ConfigDescription("Disable the player circle (blob) shadow.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
ConfigDefinition val3 = new ConfigDefinition("General", "EnablePlayerShadow");
EnablePlayerShadow = ((BasePlugin)this).Config.Bind<bool>(val3, true, new ConfigDescription("Enable realtime shadows for the player.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
ConfigDefinition val4 = new ConfigDefinition("General", "TwoSidedShadows");
TwoSidedShadows = ((BasePlugin)this).Config.Bind<bool>(val4, true, new ConfigDescription("Enable two-sided shadows for mesh renderers. This setting fixes a few visual artifacts at the cost of performance.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
ConfigDefinition val5 = new ConfigDefinition("General", "EnableNPCShadows");
EnableNPCShadows = ((BasePlugin)this).Config.Bind<bool>(val5, true, new ConfigDescription("Enable shadows for NPCs. This setting may impact performance. Has some visual artifacts when killing enemies.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
ConfigDefinition val6 = new ConfigDefinition("General", "ShadowDarkness");
ShadowDarkness = ((BasePlugin)this).Config.Bind<float>(val6, 0.8f, new ConfigDescription("Darkness of the shadows. Set to 1 for maximum contrast.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())).Value;
GameObject val7 = new GameObject("ShadowFixGO");
val7.AddComponent<ShadowFixComponent>();
Object.DontDestroyOnLoad((Object)val7);
}
public override bool Unload()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(11, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unloading ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ShadowFix");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("!");
}
log.LogInfo(val);
return ((BasePlugin)this).Unload();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "ShadowFix";
public const string PLUGIN_NAME = "ShadowFix";
public const string PLUGIN_VERSION = "1.1.2";
}
}