using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AmplifyOcclusion; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using InterprocessLib; using Microsoft.CodeAnalysis; using ReFract.Shared; using Renderite.Shared; using Renderite.Unity; using UnityEngine; using UnityEngine.Rendering.PostProcessing; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Noble")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2+648cb4290b53947c438db453180b9dc0cf4213ff")] [assembly: AssemblyProduct("Re:Fract // Reloaded (for Unity)")] [assembly: AssemblyTitle("ReFract_Unity")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/noblereign/ReFract-ReLoaded")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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.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 ReFract.Shared { public enum ReFractCommandValueType : byte { Int, Float, Bool, Color, Vector2, Vector4, String } public struct ReFractColor { public float r; public float g; public float b; public float a; public override string ToString() { return $"({r}, {g}, {b}, {a})"; } } public struct ReFractVector2 { public float x; public float y; public override string ToString() { return $"({x}, {y})"; } } public struct ReFractVector4 { public float x; public float y; public float z; public float w; public override string ToString() { return $"({x}, {y}, {z}, {w})"; } } public class ReFractCommand : RendererCommand { public int RenderTextureId; public bool IsRemoveAlphaCommand; public string CameraName = ""; public string ComponentName = ""; public string ParameterName = ""; public ReFractCommandValueType ValueType; public int IntValue; public float FloatValue; public bool BoolValue; public ReFractColor ColorValue; public ReFractVector2 Vector2Value; public ReFractVector4 Vector4Value; public string StringValue = ""; public override void Pack(ref MemoryPacker packer) { ((MemoryPacker)(ref packer)).Write(RenderTextureId); ((MemoryPacker)(ref packer)).Write(IsRemoveAlphaCommand); ((MemoryPacker)(ref packer)).Write(CameraName); ((MemoryPacker)(ref packer)).Write(ComponentName); ((MemoryPacker)(ref packer)).Write(ParameterName); ((MemoryPacker)(ref packer)).Write((byte)ValueType); switch (ValueType) { case ReFractCommandValueType.Int: ((MemoryPacker)(ref packer)).Write(IntValue); break; case ReFractCommandValueType.Float: ((MemoryPacker)(ref packer)).Write(FloatValue); break; case ReFractCommandValueType.Bool: ((MemoryPacker)(ref packer)).Write(BoolValue); break; case ReFractCommandValueType.Color: ((MemoryPacker)(ref packer)).Write(ColorValue.r); ((MemoryPacker)(ref packer)).Write(ColorValue.g); ((MemoryPacker)(ref packer)).Write(ColorValue.b); ((MemoryPacker)(ref packer)).Write(ColorValue.a); break; case ReFractCommandValueType.Vector2: ((MemoryPacker)(ref packer)).Write(Vector2Value.x); ((MemoryPacker)(ref packer)).Write(Vector2Value.y); break; case ReFractCommandValueType.Vector4: ((MemoryPacker)(ref packer)).Write(Vector4Value.x); ((MemoryPacker)(ref packer)).Write(Vector4Value.y); ((MemoryPacker)(ref packer)).Write(Vector4Value.z); ((MemoryPacker)(ref packer)).Write(Vector4Value.w); break; case ReFractCommandValueType.String: ((MemoryPacker)(ref packer)).Write(StringValue); break; } } public override void Unpack(ref MemoryUnpacker unpacker) { ((MemoryUnpacker)(ref unpacker)).Read(ref RenderTextureId); ((MemoryUnpacker)(ref unpacker)).Read(ref IsRemoveAlphaCommand); ((MemoryUnpacker)(ref unpacker)).Read(ref CameraName); ((MemoryUnpacker)(ref unpacker)).Read(ref ComponentName); ((MemoryUnpacker)(ref unpacker)).Read(ref ParameterName); ((MemoryUnpacker)(ref unpacker)).Read(ref ValueType); switch (ValueType) { case ReFractCommandValueType.Int: ((MemoryUnpacker)(ref unpacker)).Read(ref IntValue); break; case ReFractCommandValueType.Float: ((MemoryUnpacker)(ref unpacker)).Read(ref FloatValue); break; case ReFractCommandValueType.Bool: ((MemoryUnpacker)(ref unpacker)).Read(ref BoolValue); break; case ReFractCommandValueType.Color: ((MemoryUnpacker)(ref unpacker)).Read(ref ColorValue.r); ((MemoryUnpacker)(ref unpacker)).Read(ref ColorValue.g); ((MemoryUnpacker)(ref unpacker)).Read(ref ColorValue.b); ((MemoryUnpacker)(ref unpacker)).Read(ref ColorValue.a); break; case ReFractCommandValueType.Vector2: ((MemoryUnpacker)(ref unpacker)).Read(ref Vector2Value.x); ((MemoryUnpacker)(ref unpacker)).Read(ref Vector2Value.y); break; case ReFractCommandValueType.Vector4: ((MemoryUnpacker)(ref unpacker)).Read(ref Vector4Value.x); ((MemoryUnpacker)(ref unpacker)).Read(ref Vector4Value.y); ((MemoryUnpacker)(ref unpacker)).Read(ref Vector4Value.z); ((MemoryUnpacker)(ref unpacker)).Read(ref Vector4Value.w); break; case ReFractCommandValueType.String: ((MemoryUnpacker)(ref unpacker)).Read(ref StringValue); break; } } } internal class ReFractConfig { public readonly ConfigEntry debugLogging; public readonly ConfigEntry forceRemoveAlpha; public ReFractConfig(ConfigFile cfg) { cfg.SaveOnConfigSet = false; debugLogging = cfg.Bind("General", "Debug logging", false, "Whether or not to print debug logging. This can make your log files grow incredibly quickly, only enable it if you really need it"); forceRemoveAlpha = cfg.Bind("General", "Always reset alpha channel", false, "By default, Re:Fract embeds the depth data of photos in the alpha channel. If you're using a camera without the option to disable that behavior, you can force it to happen here."); ClearOrphanedEntries(cfg); cfg.Save(); cfg.SaveOnConfigSet = true; } private static void ClearOrphanedEntries(ConfigFile cfg) { ((Dictionary)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(cfg)).Clear(); } } } namespace ReFract.Unity { public static class Introspection { public delegate void RefAction(ref T1 obj, T2 value); public static Dictionary>> _cachedSetters = new Dictionary>>(); public static Dictionary>> _cachedPropSetters = new Dictionary>>(); private static void DoDebugLog(string input) { if (Plugin.BoundConfig.debugLogging.Value) { Debug.Log((object)input); } } public static RefAction? GetFieldSetter(Type obj, string fieldName, Func? ilOverride = null) { try { return _cachedSetters[obj][fieldName]; } catch { if (obj == null || fieldName == null || fieldName.Length == 0) { return null; } DoDebugLog("Introspection : Getting field"); FieldInfo field = obj.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); DoDebugLog("Introspection : Field is " + ((field == null) ? "null" : "not null")); if (field == null) { return null; } DoDebugLog("Introspection : Field is " + field.Name); RefAction dynamicMethod = GetDynamicMethod(obj, field, ilOverride); DoDebugLog("Introspection : Delegate is " + ((dynamicMethod == null) ? "null" : ("not null & " + dynamicMethod.GetType().ToString()))); if (dynamicMethod == null) { return null; } if (!_cachedSetters.ContainsKey(obj)) { _cachedSetters.Add(obj, new Dictionary>()); } _cachedSetters[obj].Add(fieldName, dynamicMethod); DoDebugLog("Introspection : Added delegate to dictionary at " + obj.ToString() + "." + fieldName); return dynamicMethod; } } public static Action? GetPropSetter(Type obj, string propName) { try { return _cachedPropSetters[obj][propName]; } catch { if (obj == null || propName == null || propName.Length == 0) { return null; } DoDebugLog("Introspection : Getting property of " + obj.ToString() + " with name " + propName); PropertyInfo property = obj.GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); DoDebugLog("Introspection : Property is " + ((property == null) ? "null" : "not null")); if (property == null) { return null; } DoDebugLog("Introspection : Property is " + property.Name); Action dynamicPropMethod = GetDynamicPropMethod(obj, property); DoDebugLog("Introspection : Delegate is " + ((dynamicPropMethod == null) ? "null" : ("not null & " + dynamicPropMethod.GetType().ToString()))); if (dynamicPropMethod == null) { return null; } if (!_cachedPropSetters.ContainsKey(obj)) { _cachedPropSetters.Add(obj, new Dictionary>()); } _cachedPropSetters[obj].Add(propName, dynamicPropMethod); DoDebugLog("Introspection : Added delegate to dictionary at " + obj.ToString() + "." + propName); return dynamicPropMethod; } } public static RefAction GetDynamicMethod(Type obj, FieldInfo field, Func? ilOverride = null) { DynamicMethod dynamicMethod = new DynamicMethod("", null, new Type[2] { typeof(object).MakeByRefType(), typeof(object) }, restrictedSkipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(256); Label label = iLGenerator.DefineLabel(); iLGenerator.DefineLabel(); Label label2 = iLGenerator.DefineLabel(); Label label3 = iLGenerator.DefineLabel(); if (ilOverride == null || !ilOverride(obj, field, iLGenerator)) { iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Callvirt, typeof(object).GetMethod("GetType")); iLGenerator.Emit(OpCodes.Ldtoken, typeof(int)); iLGenerator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); iLGenerator.Emit(OpCodes.Ceq); iLGenerator.Emit(OpCodes.Brfalse, label2); iLGenerator.Emit(OpCodes.Ldtoken, field.FieldType); iLGenerator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); iLGenerator.Emit(OpCodes.Call, typeof(Type).GetProperty("IsEnum").GetGetMethod()); iLGenerator.Emit(OpCodes.Brtrue, label3); iLGenerator.MarkLabel(label2); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Callvirt, typeof(object).GetMethod("GetType")); iLGenerator.Emit(OpCodes.Ldtoken, field.FieldType); iLGenerator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); iLGenerator.Emit(OpCodes.Ceq); iLGenerator.Emit(OpCodes.Brfalse, label); iLGenerator.MarkLabel(label3); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldind_Ref); iLGenerator.Emit(OpCodes.Castclass, obj); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Unbox_Any, field.FieldType); iLGenerator.Emit(OpCodes.Stfld, field); iLGenerator.Emit(OpCodes.Ret); iLGenerator.MarkLabel(label); iLGenerator.Emit(OpCodes.Ldstr, $"[Re:Fract] Introspection : Wrong type for field \"{field.Name}\" which takes \"{field.FieldType}\""); iLGenerator.Emit(OpCodes.Call, typeof(Debug).GetMethod("LogWarning", new Type[1] { typeof(string) })); iLGenerator.Emit(OpCodes.Ret); DoDebugLog("Introspection : Generated dynamic method with default IL"); } DoDebugLog("Introspection : Creation of DynamicMethod was successful for " + obj.ToString() + "." + field.Name); return (RefAction)dynamicMethod.CreateDelegate(typeof(RefAction<, >).MakeGenericType(typeof(object), typeof(object))); } public static Action? GetDynamicPropMethod(Type obj, PropertyInfo prop) { if (obj == null || prop == null || !prop.CanWrite) { return null; } MethodInfo setMethod = prop.GetSetMethod(nonPublic: true); if (setMethod == null) { return null; } DynamicMethod dynamicMethod = new DynamicMethod("", null, new Type[2] { typeof(object), typeof(object) }, restrictedSkipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(256); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Castclass, obj); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Unbox_Any, prop.PropertyType); iLGenerator.Emit(OpCodes.Call, setMethod); iLGenerator.Emit(OpCodes.Ret); DoDebugLog("Introspection : Created delegate for property " + prop.Name); return (Action)dynamicMethod.CreateDelegate(typeof(Action)); } } public class ReFractVolumeTracker : MonoBehaviour { public GameObject VolumeObject; private void OnDestroy() { if ((Object)(object)VolumeObject != (Object)null) { Object.Destroy((Object)(object)VolumeObject); return; } Transform val = ((Component)this).transform.Find("ReFract_Volume"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } [BepInPlugin("dog.glacier.ReFractUnity", "Re:Fract // Reloaded (for Unity)", "1.0.2")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(CameraRenderer), "Render")] public static class CameraRenderer_Patch { private static FieldInfo _cameraField; private static FieldInfo _camera360Field; private static Camera FindSourceCamera(CameraRenderTask task) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Invalid comparison between Unknown and I4 //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Invalid comparison between Unknown and I4 //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(task.position.x, task.position.y, task.position.z); Quaternion val2 = default(Quaternion); ((Quaternion)(ref val2))..ctor(task.rotation.x, task.rotation.y, task.rotation.z, task.rotation.w); Camera result = null; float num = float.MaxValue; foreach (List value in _cameraCache.Values) { if (value == null) { continue; } foreach (Camera item in value) { if ((Object)(object)item == (Object)null || !((Behaviour)item).isActiveAndEnabled) { continue; } if (item.orthographic) { if ((int)task.parameters.projection != 1 || Mathf.Abs(item.orthographicSize - task.parameters.orthographicSize) > 0.01f) { continue; } } else if ((int)task.parameters.projection == 1 || (task.parameters.fov < 180f && Mathf.Abs(item.fieldOfView - task.parameters.fov) > 5f)) { continue; } float num2 = Vector3.Distance(((Component)item).transform.position, val); float num3 = Quaternion.Angle(((Component)item).transform.rotation, val2); if (num2 < 2f && num3 < 15f && num2 < num) { num = num2; result = item; } } } return result; } private static Camera GetCaptureCamera(CameraRenderTask task) { if (task.parameters.fov >= 180f) { if (_camera360Field == null) { _camera360Field = AccessTools.Field(typeof(CameraRenderer), "camera360"); } object value = _camera360Field.GetValue(null); if (value == null) { return null; } object? obj = AccessTools.Property(value.GetType(), "Camera")?.GetValue(value); return (Camera)((obj is Camera) ? obj : null); } if (_cameraField == null) { _cameraField = AccessTools.Field(typeof(CameraRenderer), "camera"); } object? value2 = _cameraField.GetValue(null); return (Camera)((value2 is Camera) ? value2 : null); } private static void SetAmplifyOcclusionDefaults(AmplifyOcclusionEffect amplifyOcclusion) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) amplifyOcclusion.ApplyMethod = (ApplicationMethod)0; amplifyOcclusion.SampleCount = (SampleCountLevel)0; amplifyOcclusion.PerPixelNormals = (PerPixelNormalSource)0; amplifyOcclusion.Intensity = 1f; amplifyOcclusion.Tint = new Color(0f, 0f, 0f, 1f); amplifyOcclusion.Radius = 4f; amplifyOcclusion.PowerExponent = 0.6f; amplifyOcclusion.Bias = 0.05f; amplifyOcclusion.Thickness = 1f; amplifyOcclusion.Downsample = true; amplifyOcclusion.CacheAware = true; amplifyOcclusion.BlurEnabled = true; amplifyOcclusion.BlurRadius = 4; amplifyOcclusion.BlurPasses = 4; amplifyOcclusion.BlurSharpness = 3f; amplifyOcclusion.FadeEnabled = true; amplifyOcclusion.FadeStart = 16f; amplifyOcclusion.FadeLength = 128f; amplifyOcclusion.FadeToIntensity = 0f; amplifyOcclusion.FadeToRadius = 2f; amplifyOcclusion.FadeToThickness = 1f; amplifyOcclusion.FadeToTint = new Color(0f, 0f, 0f, 1f); amplifyOcclusion.FadeToPowerExponent = 1f; amplifyOcclusion.FilterEnabled = false; amplifyOcclusion.FilterDownsample = true; amplifyOcclusion.FilterBlending = 0.8f; amplifyOcclusion.FilterResponse = 0.5f; amplifyOcclusion.useMRTBlendingFallback = false; } [HarmonyPrefix] public static void Prefix(CameraRenderTask task, out Camera __state) { //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) __state = null; Camera captureCamera = GetCaptureCamera(task); if ((Object)(object)captureCamera == (Object)null) { return; } AmplifyOcclusionEffect component = ((Component)captureCamera).GetComponent(); Camera val = (__state = FindSourceCamera(task)); PostProcessVolume component2 = ((Component)captureCamera).gameObject.GetComponent(); Transform val2 = ((Component)captureCamera).transform.Find("ReFract_Volume"); PostProcessVolume val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null); if ((Object)(object)val != (Object)null) { Debug.Log((object)$"[Re:Fract] Syncing PostProcess from '{((Object)val).GetInstanceID()}' to Capture Camera."); lastCameraPair.Capture.SetTarget(captureCamera); lastCameraPair.Source.SetTarget(val); PostProcessVolume componentInChildren = ((Component)val).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.profile != (Object)null) { int num = LayerMask.NameToLayer("Ignore Raycast"); if ((Object)(object)val3 == (Object)null) { GameObject val4 = new GameObject("ReFract_Volume"); val4.transform.SetParent(((Component)captureCamera).transform, false); val4.layer = num; val3 = val4.AddComponent(); BoxCollider obj = val4.AddComponent(); ((Collider)obj).isTrigger = true; obj.size = Vector3.one * 0.01f; val3.isGlobal = false; } if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } ((Behaviour)val3).enabled = true; PostProcessProfile val5 = Object.Instantiate(componentInChildren.profile); MotionBlur setting = val5.GetSetting(); if ((Object)(object)setting != (Object)null) { ((ParameterOverride)(object)((PostProcessEffectSettings)setting).enabled).value = false; } val3.profile = val5; val3.weight = componentInChildren.weight; PostProcessLayer component3 = ((Component)captureCamera).GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.volumeLayer = LayerMask.op_Implicit(LayerMask.op_Implicit(component3.volumeLayer) | (1 << num)); component3.volumeTrigger = ((Component)captureCamera).transform; } } AmplifyOcclusionEffect component4 = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { if ((Object)(object)component4 != (Object)null) { Debug.Log((object)$"[Re:Fract] Syncing Amplify Occlusion from '{((Object)val).GetInstanceID()}' to Capture Camera."); ((Behaviour)component).enabled = ((Behaviour)component4).enabled; component.ApplyMethod = component4.ApplyMethod; component.SampleCount = component4.SampleCount; component.PerPixelNormals = component4.PerPixelNormals; component.Intensity = component4.Intensity; component.Tint = component4.Tint; component.Radius = component4.Radius; component.PowerExponent = component4.PowerExponent; component.Bias = component4.Bias; component.Thickness = component4.Thickness; component.Downsample = component4.Downsample; component.CacheAware = component4.CacheAware; component.BlurEnabled = component4.BlurEnabled; component.BlurRadius = component4.BlurRadius; component.BlurPasses = component4.BlurPasses; component.BlurSharpness = component4.BlurSharpness; component.FadeEnabled = component4.FadeEnabled; component.FadeStart = component4.FadeStart; component.FadeLength = component4.FadeLength; component.FadeToIntensity = component4.FadeToIntensity; component.FadeToRadius = component4.FadeToRadius; component.FadeToThickness = component4.FadeToThickness; component.FadeToTint = component4.FadeToTint; component.FadeToPowerExponent = component4.FadeToPowerExponent; component.FilterEnabled = component4.FilterEnabled; component.FilterDownsample = component4.FilterDownsample; component.FilterBlending = component4.FilterBlending; component.FilterResponse = component4.FilterResponse; component.useMRTBlendingFallback = component4.useMRTBlendingFallback; } else { SetAmplifyOcclusionDefaults(component); } } } else { if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } if ((Object)(object)val3 != (Object)null) { ((Behaviour)val3).enabled = false; } if ((Object)(object)component != (Object)null) { SetAmplifyOcclusionDefaults(component); } } } [HarmonyPostfix] public static void Postfix(CameraRenderTask task, Camera __state) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__state == (Object)null || (Object)(object)__state.targetTexture == (Object)null || (!(_removeAlphaCameras.TryGetValue(((Object)__state.targetTexture).GetInstanceID(), out var value) && value) && !BoundConfig.forceRemoveAlpha.Value)) { return; } try { Span span = RenderingManager.Instance.SharedMemory.AccessData(task.resultData); int num = 3; if (((object)(TextureFormat)(ref task.parameters.textureFormat)).ToString().IndexOf("ARGB", StringComparison.OrdinalIgnoreCase) >= 0) { num = 0; } for (int i = num; i < span.Length; i += 4) { span[i] = byte.MaxValue; } } catch (Exception arg) { Debug.LogError((object)$"[Re:Fract] Failed to remove alpha: {arg}"); } } } [HarmonyPatch(typeof(CameraPostprocessingManager), "UpdatePostProcessing", new Type[] { typeof(bool), typeof(bool), typeof(bool) })] public static class CameraPostProcessingManager_UpdatePostProcessing_Patch { [HarmonyPostfix] public static void Postfix(CameraPostprocessingManager __instance, bool enabled, bool motionBlur, bool screenspaceReflections) { lastCameraPair.Capture.TryGetTarget(out Camera target); lastCameraPair.Source.TryGetTarget(out Camera target2); lastCameraPair.Capture.SetTarget(null); lastCameraPair.Source.SetTarget(null); if ((Object)(object)__instance.Camera != (Object)null && (Object)(object)__instance.Camera == (Object)(object)target && (Object)(object)target != (Object)null && (Object)(object)target2 != (Object)null && !((Object)(object)__instance._postProcessing == (Object)null) && (Object)(object)__instance._ao != (Object)null) { AmplifyOcclusionEffect component = ((Component)target2).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)__instance._ao).enabled = ((Behaviour)component).enabled; return; } Debug.LogWarning((object)"Could not find the source camera's AO, so we'll set it like the vanilla game"); ((Behaviour)__instance._ao).enabled = enabled; } } } [CompilerGenerated] private sealed class d__17 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ReFractCommand command; public Plugin <>4__this; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; Plugin plugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; 5__2 = 0; break; case 1: <>1__state = -1; 5__2++; break; } if (5__2 < 5) { <>2__current = null; <>1__state = 1; return true; } RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(command.RenderTextureId); if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null) { return false; } if (command.IsRemoveAlphaCommand) { _removeAlphaCameras[((Object)asset.Texture).GetInstanceID()] = command.BoolValue; } List list = FindCamerasRenderingTo(asset.Texture); if (list.Count > 0) { _cameraCache[command.RenderTextureId] = list; DoDebugLog($"[Re:Fract] Found {list.Count} cameras after waiting."); foreach (Camera item in list) { plugin.EnsurePostProcessVolume(item); if (!command.IsRemoveAlphaCommand) { plugin.ApplyCommand(item, command); } } } else { Debug.LogWarning((object)"[Re:Fract] ...still no camera found after waiting."); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Messenger _msg; private static readonly Dictionary> _cameraCache = new Dictionary>(); private static readonly Dictionary _removeAlphaCameras = new Dictionary(); private readonly ConcurrentQueue _mainThreadQueue = new ConcurrentQueue(); public static Dictionary TypeLookups = new Dictionary { { "AmbientOcclusion", typeof(AmbientOcclusion) }, { "AutoExposure", typeof(AutoExposure) }, { "Bloom", typeof(Bloom) }, { "ChromaticAberration", typeof(ChromaticAberration) }, { "ColorGrading", typeof(ColorGrading) }, { "DepthOfField", typeof(DepthOfField) }, { "Grain", typeof(Grain) }, { "LensDistortion", typeof(LensDistortion) }, { "MotionBlur", typeof(MotionBlur) }, { "ScreenSpaceReflections", typeof(ScreenSpaceReflections) }, { "Vignette", typeof(Vignette) }, { "AmplifyOcclusionBase", typeof(AmplifyOcclusionEffect) }, { "AmplifyOcclusionEffect", typeof(AmplifyOcclusionEffect) } }; private static (WeakReference Capture, WeakReference Source) lastCameraPair = (new WeakReference(null), new WeakReference(null)); internal static ReFractConfig BoundConfig { get; private set; } = null; private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"[Re:Fract] Binding configs"); BoundConfig = new ReFractConfig(((BaseUnityPlugin)this).Config); Debug.Log((object)"[Re:Fract] Setting up interprocess"); _msg = new Messenger("dog.glacier.ReFract", false, "dog.glacier.ReFract", (IMemoryPackerEntityPool)null, 1048576L); _msg.ReceiveObject("SetVariable", (Action)HandleSetVariable); BepInExExtensions.SyncConfigEntry(_msg, BoundConfig.debugLogging); BepInExExtensions.SyncConfigEntry(_msg, BoundConfig.forceRemoveAlpha); Application.quitting += delegate { Debug.Log((object)"[Re:Fract] Shutting down interprocess!"); _msg.Dispose(); }; Debug.Log((object)"[Re:Fract] Running harmony patches!"); new Harmony("dog.glacier.ReFractUnity").PatchAll(); } private void Update() { Action result; while (_mainThreadQueue.TryDequeue(out result)) { result(); } } private static void DoDebugLog(string input) { if (BoundConfig.debugLogging.Value) { Debug.Log((object)input); } } private void HandleSetVariable(ReFractCommand command) { ReFractCommand command2 = command; _mainThreadQueue.Enqueue(delegate { HandleSetVariableInternal(command2); }); } private void HandleSetVariableInternal(ReFractCommand command) { DoDebugLog($"[Re:Fract] Received command for RT ID: {command.RenderTextureId}"); if (command.RenderTextureId == 0) { Debug.LogWarning((object)"[Re:Fract] ERROR: Command has a zero RenderTextureId. Ignoring."); return; } RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(command.RenderTextureId); if ((Object)(object)((asset != null) ? asset.Texture : null) != (Object)null && command.IsRemoveAlphaCommand) { int instanceID = ((Object)asset.Texture).GetInstanceID(); DoDebugLog($"[Re:Fract] Setting RemoveAlpha for Unity Texture {instanceID} (Resonite {command.RenderTextureId}) to {command.BoolValue}"); _removeAlphaCameras[instanceID] = command.BoolValue; } if (!_cameraCache.TryGetValue(command.RenderTextureId, out List value) || value == null) { DoDebugLog($"[Re:Fract] Camera for {command.RenderTextureId} not in cache or is null. Searching..."); if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null) { if (command.IsRemoveAlphaCommand) { ((MonoBehaviour)this).StartCoroutine(WaitForCameraAndApply(command)); } return; } DoDebugLog($"[Re:Fract] Found render texture asset for {command.RenderTextureId}"); value = FindCamerasRenderingTo(asset.Texture); if (value.Count == 0) { Debug.LogWarning((object)"[Re:Fract] ...but no camera was found. Waiting a few frames..."); ((MonoBehaviour)this).StartCoroutine(WaitForCameraAndApply(command)); return; } _cameraCache[command.RenderTextureId] = value; DoDebugLog($"[Re:Fract] Found and cached {value.Count} cameras for ID {command.RenderTextureId}"); } else { DoDebugLog($"[Re:Fract] Using cached cameras for ID {command.RenderTextureId}"); if (command.IsRemoveAlphaCommand && value.Count > 0 && (Object)(object)value[0].targetTexture != (Object)null) { _removeAlphaCameras[((Object)value[0].targetTexture).GetInstanceID()] = command.BoolValue; } } value.RemoveAll((Camera c) => (Object)(object)c == (Object)null); if (value.Count == 0) { Debug.LogWarning((object)$"[Re:Fract] ERROR: All cached cameras for {command.RenderTextureId} were destroyed. Removing from cache."); if ((Object)(object)((asset != null) ? asset.Texture : null) != (Object)null) { _removeAlphaCameras.Remove(((Object)asset.Texture).GetInstanceID()); } _cameraCache.Remove(command.RenderTextureId); return; } foreach (Camera item in value) { EnsurePostProcessVolume(item); if (!command.IsRemoveAlphaCommand) { ApplyCommand(item, command); } } } [IteratorStateMachine(typeof(d__17))] private IEnumerator WaitForCameraAndApply(ReFractCommand command) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__17(0) { <>4__this = this, command = command }; } private void EnsurePostProcessVolume(Camera camera) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_017a: 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_0326: Unknown result type (might be due to invalid IL or missing references) ReFractVolumeTracker reFractVolumeTracker = ((Component)camera).gameObject.GetComponent(); if ((Object)(object)reFractVolumeTracker == (Object)null) { reFractVolumeTracker = ((Component)camera).gameObject.AddComponent(); } int num = LayerMask.NameToLayer("Ignore Raycast"); PostProcessLayer component = ((Component)camera).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { component.volumeTrigger = ((Component)camera).transform; int num2 = 1 << num; if ((LayerMask.op_Implicit(component.volumeLayer) & num2) == 0) { DoDebugLog($"[Re:Fract] PostProcessLayer volumeLayer mask mismatch. Adding layer {num} (Ignore Raycast)."); component.volumeLayer = LayerMask.op_Implicit(LayerMask.op_Implicit(component.volumeLayer) | num2); } } PostProcessVolume component2 = ((Component)camera).GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } BoxCollider component3 = ((Component)camera).GetComponent(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } Transform val = ((Component)camera).transform.Find("ReFract_Volume"); if ((Object)(object)val == (Object)null) { GameObject val2 = new GameObject("ReFract_Volume"); val2.transform.SetParent(((Component)camera).transform, false); val2.layer = num; val = val2.transform; } reFractVolumeTracker.VolumeObject = ((Component)val).gameObject; PostProcessVolume val3 = ((Component)val).GetComponent(); if ((Object)(object)val3 == (Object)null) { DoDebugLog("[Re:Fract] Creating PostProcessVolume on child of '" + ((Object)camera).name + "'."); val3 = ((Component)val).gameObject.AddComponent(); } val3.isGlobal = false; if ((Object)(object)((Component)val).GetComponent() == (Object)null) { BoxCollider obj = ((Component)val).gameObject.AddComponent(); ((Collider)obj).isTrigger = true; obj.size = Vector3.one * 0.01f; } string text = $"ReFract_Profile_{((Object)camera).GetInstanceID()}"; if ((Object)(object)val3.profile == (Object)null) { DoDebugLog("[Re:Fract] PostProcessVolume on '" + ((Object)camera).name + "' has no profile. Creating one and adding all settings."); PostProcessProfile val4 = ScriptableObject.CreateInstance(); ((Object)val4).name = text; val3.profile = val4; foreach (Type value in TypeLookups.Values) { if (typeof(PostProcessEffectSettings).IsAssignableFrom(value)) { DoDebugLog("[Re:Fract] Adding setting '" + value.Name + "' to new profile."); val3.profile.AddSettings(value); } } } else if (((Object)val3.profile).name != text) { DoDebugLog("[Re:Fract] Ensuring unique profile for '" + ((Object)camera).name + "'."); PostProcessProfile val5 = Object.Instantiate(val3.profile); ((Object)val5).name = text; val3.profile = val5; foreach (Type value2 in TypeLookups.Values) { if (typeof(PostProcessEffectSettings).IsAssignableFrom(value2) && !val5.HasSettings(value2)) { val5.AddSettings(value2); } } } ColorGrading val6 = default(ColorGrading); if (val3.profile.TryGetSettings(ref val6)) { ((ParameterOverride)(object)val6.gradingMode).value = (GradingMode)1; ((ParameterOverride)val6.gradingMode).overrideState = true; } } private void ApplyCommand(Camera camera, ReFractCommand command) { DoDebugLog("[Re:Fract] Searching for component '" + command.ComponentName + "' on camera '" + ((Object)camera).name + "'"); object obj = null; if (!TypeLookups.TryGetValue(command.ComponentName, out Type value)) { Debug.LogWarning((object)("[Re:Fract] Unsupported Type " + command.ComponentName)); return; } if (typeof(PostProcessEffectSettings).IsAssignableFrom(value)) { PostProcessVolume componentInChildren = ((Component)camera).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.profile != (Object)null) { foreach (PostProcessEffectSettings setting in componentInChildren.profile.settings) { if (((object)setting).GetType() == value) { obj = setting; break; } } if (obj == null) { obj = componentInChildren.profile.AddSettings(value); } } } else { obj = ((Component)camera).GetComponent(value); } if (obj == null) { Debug.LogWarning((object)("[Re:Fract] ERROR: Camera '" + ((Object)camera).name + "' does not have or could not create component '" + command.ComponentName + "'")); return; } DoDebugLog("[Re:Fract] Found target '" + command.ComponentName + "'"); object valueFromCommand = GetValueFromCommand(command); Type type = obj.GetType(); if (command.ParameterName.EndsWith("!")) { string text = command.ParameterName.Substring(0, command.ParameterName.Length - 1); DoDebugLog($"[Re:Fract] Attempting to set property '{text}' on '{command.ComponentName} ({type.FullName})' to value '{valueFromCommand}'"); Action propSetter = Introspection.GetPropSetter(type, text); if (propSetter != null) { propSetter(obj, valueFromCommand); DoDebugLog("[Re:Fract] SUCCESS: Set property '" + text + "'."); return; } Debug.LogWarning((object)("[Re:Fract] ERROR: Could not find writable property '" + text + "' on component '" + command.ComponentName + "'")); return; } DoDebugLog($"[Re:Fract] Attempting to set '{command.ParameterName}' on '{command.ComponentName} ({type.FullName})' to value '{valueFromCommand}'"); FieldInfo field = type.GetField(command.ParameterName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && typeof(ParameterOverride).IsAssignableFrom(field.FieldType)) { object value2 = field.GetValue(obj); if (value2 != null) { Type type2 = value2.GetType(); bool flag = false; FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.Public); if (field2 != null) { try { field2.SetValue(value2, valueFromCommand); DoDebugLog("[Re:Fract] Set 'value' field on ParameterOverride '" + command.ParameterName + "'."); flag = true; } catch (Exception arg) { Debug.LogWarning((object)$"[Re:Fract] Failed to set ParameterOverride field value: {arg}"); } } if (!flag) { PropertyInfo property = type2.GetProperty("value"); if (property != null && property.CanWrite) { try { property.SetValue(value2, valueFromCommand); DoDebugLog("[Re:Fract] Set 'value' property on ParameterOverride '" + command.ParameterName + "'."); flag = true; } catch (Exception arg2) { Debug.LogWarning((object)$"[Re:Fract] Failed to set ParameterOverride property value: {arg2}"); } } } if (flag) { FieldInfo field3 = type2.GetField("overrideState", BindingFlags.Instance | BindingFlags.Public); if (field3 != null) { field3.SetValue(value2, true); DoDebugLog("[Re:Fract] SUCCESS: Activated override for '" + command.ParameterName + "'."); } else { Debug.LogWarning((object)("[Re:Fract] Could not find 'overrideState' field on '" + type2.Name + "'. The setting may not apply visually.")); } return; } } } Action propSetter2 = Introspection.GetPropSetter(type, command.ParameterName); if (propSetter2 != null) { propSetter2(obj, valueFromCommand); DoDebugLog("[Re:Fract] SUCCESS: Set property '" + command.ParameterName + "'."); return; } Introspection.RefAction fieldSetter = Introspection.GetFieldSetter(type, command.ParameterName); if (fieldSetter != null) { fieldSetter(ref obj, valueFromCommand); DoDebugLog("[Re:Fract] SUCCESS: Set field '" + command.ParameterName + "'."); return; } Debug.LogWarning((object)("[Re:Fract] ERROR: Could not find writable property or field '" + command.ParameterName + "' on component '" + command.ComponentName + "'")); } private static object GetValueFromCommand(ReFractCommand command) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) return command.ValueType switch { ReFractCommandValueType.Int => command.IntValue, ReFractCommandValueType.Float => command.FloatValue, ReFractCommandValueType.Bool => command.BoolValue, ReFractCommandValueType.Color => (object)new Color(command.ColorValue.r, command.ColorValue.g, command.ColorValue.b, command.ColorValue.a), ReFractCommandValueType.Vector2 => (object)new Vector2(command.Vector2Value.x, command.Vector2Value.y), ReFractCommandValueType.Vector4 => (object)new Vector4(command.Vector4Value.x, command.Vector4Value.y, command.Vector4Value.z, command.Vector4Value.w), ReFractCommandValueType.String => command.StringValue, _ => throw new ArgumentOutOfRangeException(), }; } private static List FindCamerasRenderingTo(RenderTexture target) { DoDebugLog(string.Format("[Re:Fract] Searching for RenderTexture {0} @ {1}", Object.op_Implicit((Object)(object)target) ? ((Object)target).name : "NULL TARGET", Object.op_Implicit((Object)(object)target) ? ((object)((Object)target).GetInstanceID()) : "N/A")); Camera[] array = Object.FindObjectsOfType(); List list = new List(); Camera[] array2 = array; foreach (Camera val in array2) { DoDebugLog(string.Format("[Re:Fract] Camera {0} @ {1} --> {2} @ {3}...", ((Object)val).name, ((Object)val).GetInstanceID(), Object.op_Implicit((Object)(object)val.targetTexture) ? ((Object)val.targetTexture).name : "NULL TARGET", Object.op_Implicit((Object)(object)val.targetTexture) ? ((object)((Object)val.targetTexture).GetInstanceID()) : "N/A")); if ((Object)(object)val.targetTexture == (Object)(object)target) { list.Add(val); } } if (list.Count == 0) { Debug.LogWarning((object)"[Re:Fract] No camera found rendering to the specified RenderTexture."); } return list; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }