Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Y4NGZUpgrades v1.0.0
Y4NGZUpgrades.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using DunGen; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using LethalCompanyInputUtils.Config; using LethalCompanyInputUtils.Data; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Animations.Rigging; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.UI; using Y4NGZInteractions.InteractionAnimationApi; using Y4NGZUpgrades; using Y4NGZUpgrades.Config; using Y4NGZUpgrades.Effects; using Y4NGZUpgrades.Gui; using Y4NGZUpgrades.HUD; using Y4NGZUpgrades.Interactive; using Y4NGZUpgrades.Interactive.Feedback; using Y4NGZUpgrades.Interactive.Hud; using Y4NGZUpgrades.Interactive.Patches; using Y4NGZUpgrades.Lucky8; using Y4NGZUpgrades.Patches; using Y4NGZUpgrades.UITheme; using Y4NGZUpgrades.Upgrades; using cakeslice; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Y4NGZUpgrades")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Native Y4NGZ progression and upgrade framework spine")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+aa6e1cd1ef880d5a03be519cbac8a321e9211d53")] [assembly: AssemblyProduct("Y4NGZUpgrades")] [assembly: AssemblyTitle("Y4NGZUpgrades")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 cakeslice { public sealed class LinkedSet<T> : IEnumerable<T>, IEnumerable { private readonly LinkedList<T> _list = new LinkedList<T>(); private readonly Dictionary<T, LinkedListNode<T>> _dictionary = new Dictionary<T, LinkedListNode<T>>(); public int Count => _list.Count; public bool Add(T item) { if (_dictionary.ContainsKey(item)) { return false; } LinkedListNode<T> value = _list.AddLast(item); _dictionary.Add(item, value); return true; } public bool Remove(T item) { if (!_dictionary.TryGetValue(item, out var value)) { return false; } _dictionary.Remove(item); _list.Remove(value); return true; } public bool Contains(T item) { return _dictionary.ContainsKey(item); } public LinkedList<T>.Enumerator GetEnumerator() { return _list.GetEnumerator(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return _list.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [RequireComponent(typeof(Renderer))] public sealed class Outline : MonoBehaviour { private static readonly Material[] EmptyMaterials = (Material[])(object)new Material[0]; private Material[] _sharedMaterials; public int color; public bool eraseRenderer; public Renderer Renderer { get; private set; } public SpriteRenderer SpriteRenderer { get; private set; } public SkinnedMeshRenderer SkinnedMeshRenderer { get; private set; } public MeshFilter MeshFilter { get; private set; } public Material[] SharedMaterials { get { if (_sharedMaterials == null && (Object)(object)Renderer != (Object)null) { _sharedMaterials = Renderer.sharedMaterials; } return _sharedMaterials ?? EmptyMaterials; } } private void Awake() { Renderer = ((Component)this).GetComponent<Renderer>(); SkinnedMeshRenderer = ((Component)this).GetComponent<SkinnedMeshRenderer>(); SpriteRenderer = ((Component)this).GetComponent<SpriteRenderer>(); MeshFilter = ((Component)this).GetComponent<MeshFilter>(); } private void OnEnable() { OutlineEffect.Instance?.AddOutline(this); } private void OnDisable() { OutlineEffect.Instance?.RemoveOutline(this); } } [DisallowMultipleComponent] [RequireComponent(typeof(Camera))] public sealed class OutlineEffect : MonoBehaviour { public sealed class Y4NGZHDRPOutlinePass : CustomPass { internal OutlineEffect Owner; public override void Execute(CustomPassContext ctx) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) OutlineEffect owner = Owner; if ((Object)(object)owner == (Object)null || ctx.cmd == null || ctx.hdCamera == null) { return; } Camera camera = ctx.hdCamera.camera; if ((Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)owner.ResolveSourceCamera()) { return; } if (!owner.HasActiveOutlines(out var activeOutlineCount)) { owner.ResetHdrpCompositeTrace(); return; } int width = Mathf.Max(1, ctx.hdCamera.actualWidth); int height = Mathf.Max(1, ctx.hdCamera.actualHeight); owner.sourceCamera = camera; if (!owner.RenderOutlineBuffer(ctx.cmd)) { owner.ResetHdrpCompositeTrace(); return; } if ((Object)(object)owner.outlineOverlayMaterial == (Object)null || (Object)(object)owner.renderTexture == (Object)null || !owner._outlineTextureValid) { owner.ResetHdrpCompositeTrace(); return; } owner.outlineOverlayMaterial.SetTexture(OutlineSourceId, (Texture)(object)owner.renderTexture); HDUtils.DrawFullScreen(ctx.cmd, owner.outlineOverlayMaterial, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, (MaterialPropertyBlock)null, 0); owner.TraceHdrpComposite(width, height, activeOutlineCount); } } private readonly LinkedSet<Outline> _outlines = new LinkedSet<Outline>(); private readonly List<Material> _materialBuffer = new List<Material>(); [Range(1f, 6f)] public float lineThickness = 1.25f; [Range(0f, 10f)] public float lineIntensity = 0.5f; [Range(0f, 1f)] public float fillAmount = 0.2f; public Color lineColor0 = Color.red; public Color lineColor1 = Color.green; public Color lineColor2 = Color.blue; public bool additiveRendering; public bool backfaceCulling = true; public Color fillColor = Color.blue; public bool useFillColor; public bool cornerOutlines; public bool addLinesBetweenColors; public bool scaleWithScreenSize = true; [Range(0f, 1f)] public float alphaCutoff = 0.5f; public bool flipY; public Camera sourceCamera; public bool autoEnableOutlines; public Camera outlineCamera; public Material outlineShaderMaterial; private Material outlineOverlayMaterial; public RenderTexture renderTexture; public RenderTexture extraRenderTexture; private Material _outline1Material; private Material _outline2Material; private Material _outline3Material; private Material _outlineEraseMaterial; private Material _fallback1Material; private Material _fallback2Material; private Material _fallback3Material; private Shader _outlineShader; private Shader _outlineBufferShader; private Shader _outlineOverlayShader; private Shader _maskShader; private CommandBuffer _immediateCommandBuffer; private GameObject _customPassVolumeObject; private CustomPassVolume _customPassVolume; private Y4NGZHDRPOutlinePass _customPass; private bool _renderNextFrame; private bool _pipelineCallbacksRegistered; private bool _outlineTextureValid; private float _nextFallbackWarningAt; private float _nextHdrpWarningAt; private bool _hdrpTraceActive; private int _lastHdrpTraceActiveCount = int.MinValue; private int _lastHdrpTraceWidth; private int _lastHdrpTraceHeight; private static readonly int CompositeTempId = Shader.PropertyToID("_Y4NGZOutlineCompositeTemp"); private static readonly int OutlineSourceId = Shader.PropertyToID("_OutlineSource"); private static readonly string[] MaskPassNames = new string[4] { "ForwardOnly", "Forward", "SRPDefaultUnlit", "DepthForwardOnly" }; public static OutlineEffect Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)Instance); } Instance = this; } private void Start() { CreateMaterialsIfNeeded(); UpdateMaterialsPublicProperties(); if ((Object)(object)sourceCamera == (Object)null) { sourceCamera = ((Component)this).GetComponent<Camera>() ?? Camera.main; } RecreateRenderTexturesIfNeeded(); EnsureHdrpCustomPass(); } private void OnEnable() { if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null) { EnsureHdrpCustomPass(); } else { RegisterPipelineCallbacks(); } Outline[] array = Object.FindObjectsOfType<Outline>(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && !_outlines.Contains(array[i])) { _outlines.Add(array[i]); } } } private void OnDisable() { UnregisterPipelineCallbacks(); if ((Object)(object)_customPassVolume != (Object)null) { ((Behaviour)_customPassVolume).enabled = false; } ResetHdrpCompositeTrace(); } private void OnPreRender() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (!((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null)) { if (_immediateCommandBuffer == null) { _immediateCommandBuffer = new CommandBuffer { name = "Y4NGZ Outline Buffer" }; } _immediateCommandBuffer.Clear(); if (RenderOutlineBuffer(_immediateCommandBuffer)) { Graphics.ExecuteCommandBuffer(_immediateCommandBuffer); } } } [ImageEffectOpaque] private void OnRenderImage(RenderTexture source, RenderTexture destination) { if ((Object)(object)outlineShaderMaterial == (Object)null || (Object)(object)renderTexture == (Object)null || !_outlineTextureValid) { Graphics.Blit((Texture)(object)source, destination); return; } outlineShaderMaterial.SetTexture("_OutlineSource", (Texture)(object)renderTexture); if (addLinesBetweenColors && (Object)(object)extraRenderTexture != (Object)null) { Graphics.Blit((Texture)(object)source, extraRenderTexture, outlineShaderMaterial, 0); outlineShaderMaterial.SetTexture("_OutlineSource", (Texture)(object)extraRenderTexture); } Graphics.Blit((Texture)(object)source, destination, outlineShaderMaterial, 1); } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } UnregisterPipelineCallbacks(); if ((Object)(object)_customPassVolumeObject != (Object)null) { Object.Destroy((Object)(object)_customPassVolumeObject); _customPassVolumeObject = null; _customPassVolume = null; _customPass = null; } if (_immediateCommandBuffer != null) { _immediateCommandBuffer.Release(); _immediateCommandBuffer = null; } if ((Object)(object)renderTexture != (Object)null) { renderTexture.Release(); } if ((Object)(object)extraRenderTexture != (Object)null) { extraRenderTexture.Release(); } DestroyMaterials(); } public void AddOutline(Outline outline) { if (!((Object)(object)outline == (Object)null)) { _outlines.Add(outline); EnsureHdrpCustomPass(); } } public void RemoveOutline(Outline outline) { if ((Object)(object)outline != (Object)null) { _outlines.Remove(outline); } } private bool HasActiveOutlines(out int activeOutlineCount) { activeOutlineCount = 0; if (_outlines.Count == 0) { return false; } foreach (Outline outline in _outlines) { if ((Object)(object)outline != (Object)null && ((Behaviour)outline).enabled && (Object)(object)outline.Renderer != (Object)null && outline.Renderer.enabled) { activeOutlineCount++; } } return activeOutlineCount > 0; } private void EnsureHdrpCustomPass() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00e3: 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: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GraphicsSettings.currentRenderPipeline == (Object)null) { return; } Camera val = ResolveSourceCamera(); if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)_customPassVolume != (Object)null && _customPass != null) { _customPass.Owner = this; _customPassVolume.targetCamera = val; ((Behaviour)_customPassVolume).enabled = ((Behaviour)this).isActiveAndEnabled; return; } if ((Object)(object)_customPassVolumeObject == (Object)null) { _customPassVolumeObject = new GameObject("Y4NGZ_OutlineCustomPassVolume") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)_customPassVolumeObject); } _customPassVolume = _customPassVolumeObject.GetComponent<CustomPassVolume>(); if ((Object)(object)_customPassVolume == (Object)null) { _customPassVolume = _customPassVolumeObject.AddComponent<CustomPassVolume>(); } _customPassVolume.isGlobal = true; _customPassVolume.priority = 1000f; _customPassVolume.injectionPoint = (CustomPassInjectionPoint)3; _customPassVolume.targetCamera = val; _customPassVolume.customPasses.Clear(); CustomPass val2 = _customPassVolume.AddPassOfType(typeof(Y4NGZHDRPOutlinePass)); _customPass = val2 as Y4NGZHDRPOutlinePass; if (_customPass == null) { if (Time.unscaledTime >= _nextHdrpWarningAt) { _nextHdrpWarningAt = Time.unscaledTime + 10f; ManualLogSource log = Y4NGZUpgrades.Plugin.Log; if (log != null) { log.LogWarning((object)"OutlineEffect: failed to register HDRP custom pass; outlines may be invisible."); } } return; } ((CustomPass)_customPass).name = "Y4NGZ Outline Composite"; ((CustomPass)_customPass).enabled = true; ((CustomPass)_customPass).targetColorBuffer = (TargetBuffer)0; ((CustomPass)_customPass).targetDepthBuffer = (TargetBuffer)0; ((CustomPass)_customPass).clearFlags = (ClearFlag)0; _customPass.Owner = this; ((Behaviour)_customPassVolume).enabled = ((Behaviour)this).isActiveAndEnabled; ManualLogSource log2 = Y4NGZUpgrades.Plugin.Log; if (log2 != null) { log2.LogInfo((object)("OutlineEffect: HDRP custom pass registered on '" + ((Object)val).name + "'.")); } } private void TraceHdrpComposite(int width, int height, int activeOutlineCount) { if (!_hdrpTraceActive || _lastHdrpTraceActiveCount != activeOutlineCount || _lastHdrpTraceWidth != width || _lastHdrpTraceHeight != height) { _hdrpTraceActive = true; _lastHdrpTraceActiveCount = activeOutlineCount; _lastHdrpTraceWidth = width; _lastHdrpTraceHeight = height; ManualLogSource log = Y4NGZUpgrades.Plugin.Log; if (log != null) { log.LogDebug((object)$"OutlineEffect: HDRP custom pass compositing {activeOutlineCount} outline renderer(s) at {width}x{height}."); } } } private void ResetHdrpCompositeTrace() { _hdrpTraceActive = false; _lastHdrpTraceActiveCount = int.MinValue; _lastHdrpTraceWidth = 0; _lastHdrpTraceHeight = 0; } public void UpdateMaterialsPublicProperties() { if (CreateMaterialsIfNeeded() && !((Object)(object)outlineShaderMaterial == (Object)null)) { float num = 1f; if (scaleWithScreenSize) { num = (float)Screen.height / 360f; } float thicknessScale = ((scaleWithScreenSize && num >= 1f) ? num : 1f); ApplyMaterialProperties(outlineShaderMaterial, thicknessScale, legacyComposite: true); if ((Object)(object)outlineOverlayMaterial != (Object)null) { ApplyMaterialProperties(outlineOverlayMaterial, thicknessScale, legacyComposite: false); } Shader.SetGlobalFloat("_OutlineAlphaCutoff", alphaCutoff); } } private void ApplyMaterialProperties(Material material, float thicknessScale, bool legacyComposite) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { material.SetFloat("_LineThicknessX", thicknessScale * (lineThickness / Mathf.Max(1f, (float)Screen.width))); material.SetFloat("_LineThicknessY", thicknessScale * (lineThickness / Mathf.Max(1f, (float)Screen.height))); material.SetFloat("_LineIntensity", lineIntensity); material.SetColor("_LineColor1", legacyComposite ? (lineColor0 * lineColor0) : lineColor0); material.SetColor("_LineColor2", legacyComposite ? (lineColor1 * lineColor1) : lineColor1); material.SetColor("_LineColor3", legacyComposite ? (lineColor2 * lineColor2) : lineColor2); material.SetInt("_CornerOutlines", cornerOutlines ? 1 : 0); if (legacyComposite) { material.SetFloat("_FillAmount", fillAmount); material.SetColor("_FillColor", fillColor); material.SetFloat("_UseFillColor", useFillColor ? 1f : 0f); material.SetInt("_FlipY", flipY ? 1 : 0); material.SetInt("_Dark", (!additiveRendering) ? 1 : 0); } } } private void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) { if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null || (Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)ResolveSourceCamera()) { return; } CommandBuffer val = CommandBufferPool.Get("Y4NGZ Outline Buffer"); try { if (RenderOutlineBuffer(val)) { ((ScriptableRenderContext)(ref context)).ExecuteCommandBuffer(val); } } finally { CommandBufferPool.Release(val); } } private void OnEndCameraRendering(ScriptableRenderContext context, Camera camera) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null || (Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)ResolveSourceCamera() || (Object)(object)outlineShaderMaterial == (Object)null || (Object)(object)renderTexture == (Object)null || !_outlineTextureValid) { return; } int num = Mathf.Max(1, camera.pixelWidth); int num2 = Mathf.Max(1, camera.pixelHeight); CommandBuffer val = CommandBufferPool.Get("Y4NGZ Outline Composite"); try { outlineShaderMaterial.SetTexture("_OutlineSource", (Texture)(object)renderTexture); val.GetTemporaryRT(CompositeTempId, num, num2, 0, (FilterMode)1, (RenderTextureFormat)7); val.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2), RenderTargetIdentifier.op_Implicit(CompositeTempId), outlineShaderMaterial, 1); val.Blit(RenderTargetIdentifier.op_Implicit(CompositeTempId), RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2)); val.ReleaseTemporaryRT(CompositeTempId); ((ScriptableRenderContext)(ref context)).ExecuteCommandBuffer(val); } finally { CommandBufferPool.Release(val); } } private void DrawFallbackSilhouettes(ScriptableRenderContext context, Camera camera) { if ((Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)ResolveSourceCamera()) { return; } CommandBuffer val = CommandBufferPool.Get("Y4NGZ Outline Fallback"); try { DrawFallbackSilhouettes(val); ((ScriptableRenderContext)(ref context)).ExecuteCommandBuffer(val); } finally { CommandBufferPool.Release(val); } } private void DrawImmediateFallback() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (_outlines.Count != 0) { if (_immediateCommandBuffer == null) { _immediateCommandBuffer = new CommandBuffer { name = "Y4NGZ Outline Buffer" }; } _immediateCommandBuffer.Clear(); DrawFallbackSilhouettes(_immediateCommandBuffer); Graphics.ExecuteCommandBuffer(_immediateCommandBuffer); } } private bool RenderOutlineBuffer(CommandBuffer commandBuffer) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (commandBuffer == null) { return false; } if ((Object)(object)ResolveSourceCamera() == (Object)null) { return false; } if (_outlines.Count == 0) { if (!_renderNextFrame) { return false; } _renderNextFrame = false; } else { _renderNextFrame = true; } if (!CreateMaterialsIfNeeded()) { return false; } RecreateRenderTexturesIfNeeded(); UpdateMaterialsPublicProperties(); if ((Object)(object)renderTexture == (Object)null) { return false; } commandBuffer.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)renderTexture)); commandBuffer.SetViewport(new Rect(0f, 0f, (float)((Texture)renderTexture).width, (float)((Texture)renderTexture).height)); commandBuffer.ClearRenderTarget(true, true, Color.clear); commandBuffer.SetViewProjectionMatrices(sourceCamera.worldToCameraMatrix, sourceCamera.projectionMatrix); foreach (Outline outline in _outlines) { DrawOutline(commandBuffer, outline); } _outlineTextureValid = true; return true; } private Camera ResolveSourceCamera() { if ((Object)(object)sourceCamera == (Object)null) { sourceCamera = ((Component)this).GetComponent<Camera>() ?? Camera.main; } return sourceCamera; } private void RegisterPipelineCallbacks() { if (!_pipelineCallbacksRegistered) { RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; RenderPipelineManager.endCameraRendering += OnEndCameraRendering; _pipelineCallbacksRegistered = true; } } private void UnregisterPipelineCallbacks() { if (_pipelineCallbacksRegistered) { RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; RenderPipelineManager.endCameraRendering -= OnEndCameraRendering; _pipelineCallbacksRegistered = false; } } private void DrawOutline(CommandBuffer commandBuffer, Outline outline) { if ((Object)(object)outline == (Object)null || (Object)(object)outline.Renderer == (Object)null || !((Behaviour)outline).enabled) { return; } Material[] sharedMaterials = outline.SharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { Material val = ResolveBufferMaterial(outline, sharedMaterials[i]); if ((Object)(object)val == (Object)null) { continue; } if (val.HasProperty("_Culling")) { val.SetInt("_Culling", backfaceCulling ? 2 : 0); } if (val.HasProperty("_Cull")) { val.SetInt("_Cull", backfaceCulling ? 2 : 0); } MeshFilter meshFilter = outline.MeshFilter; SkinnedMeshRenderer skinnedMeshRenderer = outline.SkinnedMeshRenderer; SpriteRenderer spriteRenderer = outline.SpriteRenderer; int num = ResolveMaskMaterialPass(val); if ((Object)(object)meshFilter != (Object)null && (Object)(object)meshFilter.sharedMesh != (Object)null) { if (i < meshFilter.sharedMesh.subMeshCount) { commandBuffer.DrawRenderer(outline.Renderer, val, i, num); } } else if ((Object)(object)skinnedMeshRenderer != (Object)null && (Object)(object)skinnedMeshRenderer.sharedMesh != (Object)null) { if (i < skinnedMeshRenderer.sharedMesh.subMeshCount) { commandBuffer.DrawRenderer(outline.Renderer, val, i, num); } } else if ((Object)(object)spriteRenderer != (Object)null) { commandBuffer.DrawRenderer(outline.Renderer, val, i, num); } } } private void DrawFallbackSilhouettes(CommandBuffer commandBuffer) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (commandBuffer == null || _outlines.Count == 0 || !CreateFallbackMaterialsIfNeeded()) { return; } commandBuffer.SetRenderTarget(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2)); foreach (Outline outline in _outlines) { DrawFallbackSilhouette(commandBuffer, outline); } } private void DrawFallbackSilhouettes(CommandBuffer commandBuffer, RTHandle colorBuffer, RTHandle depthBuffer) { if (commandBuffer == null || colorBuffer == null || _outlines.Count == 0 || !CreateFallbackMaterialsIfNeeded()) { return; } CoreUtils.SetRenderTarget(commandBuffer, colorBuffer, depthBuffer, (ClearFlag)0, 0, (CubemapFace)(-1), -1); foreach (Outline outline in _outlines) { DrawFallbackSilhouette(commandBuffer, outline); } } private void DrawFallbackSilhouette(CommandBuffer commandBuffer, Outline outline) { if ((Object)(object)outline == (Object)null || (Object)(object)outline.Renderer == (Object)null || !((Behaviour)outline).enabled) { return; } Material fallbackMaterialFromId = GetFallbackMaterialFromId(outline.color); if (!((Object)(object)fallbackMaterialFromId == (Object)null)) { Material[] sharedMaterials = outline.SharedMaterials; int num = ResolveMaskMaterialPass(fallbackMaterialFromId); for (int i = 0; i < sharedMaterials.Length; i++) { commandBuffer.DrawRenderer(outline.Renderer, fallbackMaterialFromId, i, num); } } } private Material ResolveBufferMaterial(Outline outline, Material sourceMaterial) { if ((Object)(object)outline == (Object)null) { return null; } if (!outline.eraseRenderer) { return GetMaterialFromId(outline.color); } return _outlineEraseMaterial; } private Material GetMaterialFromId(int id) { return (Material)(id switch { 1 => _outline2Material, 2 => _outline3Material, _ => _outline1Material, }); } private Material GetFallbackMaterialFromId(int id) { return (Material)(id switch { 1 => _fallback2Material, 2 => _fallback3Material, _ => _fallback1Material, }); } private void EnsureOutlineCamera() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if ((Object)(object)sourceCamera == (Object)null || (Object)(object)outlineCamera != (Object)null) { return; } Camera[] componentsInChildren = ((Component)this).GetComponentsInChildren<Camera>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == "Outline Camera") { outlineCamera = componentsInChildren[i]; ((Behaviour)outlineCamera).enabled = false; return; } } GameObject val = new GameObject("Outline Camera"); val.transform.SetParent(((Component)sourceCamera).transform, false); outlineCamera = val.AddComponent<Camera>(); ((Behaviour)outlineCamera).enabled = false; } private void RecreateRenderTexturesIfNeeded() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown if ((Object)(object)sourceCamera == (Object)null) { return; } int num = Mathf.Max(1, sourceCamera.pixelWidth); int num2 = Mathf.Max(1, sourceCamera.pixelHeight); if ((Object)(object)renderTexture == (Object)null || ((Texture)renderTexture).width != num || ((Texture)renderTexture).height != num2) { if ((Object)(object)renderTexture != (Object)null) { renderTexture.Release(); } if ((Object)(object)extraRenderTexture != (Object)null) { extraRenderTexture.Release(); } _outlineTextureValid = false; renderTexture = new RenderTexture(num, num2, 16, (RenderTextureFormat)0) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; extraRenderTexture = new RenderTexture(num, num2, 16, (RenderTextureFormat)0) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; if ((Object)(object)outlineCamera != (Object)null) { outlineCamera.targetTexture = renderTexture; } } } private bool CreateMaterialsIfNeeded() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) //IL_00e3: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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) if ((Object)(object)_outlineShader == (Object)null) { _outlineShader = OutlineRuntimeAssets.LoadShader("OutlineShader"); } if ((Object)(object)_outlineBufferShader == (Object)null) { _outlineBufferShader = OutlineRuntimeAssets.LoadShader("OutlineBufferShader"); } if ((Object)(object)_outlineOverlayShader == (Object)null) { _outlineOverlayShader = OutlineRuntimeAssets.LoadShader("Y4NGZOutlineOverlayShader"); } if ((Object)(object)_outlineShader == (Object)null) { return false; } if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null && (Object)(object)_outlineOverlayShader == (Object)null) { return false; } if ((Object)(object)outlineShaderMaterial == (Object)null) { outlineShaderMaterial = new Material(_outlineShader) { hideFlags = (HideFlags)61 }; } if ((Object)(object)outlineOverlayMaterial == (Object)null && (Object)(object)_outlineOverlayShader != (Object)null) { outlineOverlayMaterial = new Material(_outlineOverlayShader) { hideFlags = (HideFlags)61 }; } if ((Object)(object)_outlineEraseMaterial == (Object)null) { _outlineEraseMaterial = CreateMaterial(new Color(0f, 0f, 0f, 0f)); } if ((Object)(object)_outline1Material == (Object)null) { _outline1Material = CreateMaterial(new Color(1f, 0f, 0f, 1f)); } if ((Object)(object)_outline2Material == (Object)null) { _outline2Material = CreateMaterial(new Color(0f, 1f, 0f, 1f)); } if ((Object)(object)_outline3Material == (Object)null) { _outline3Material = CreateMaterial(new Color(0f, 0f, 1f, 1f)); } if ((Object)(object)outlineShaderMaterial != (Object)null && ((Object)(object)GraphicsSettings.currentRenderPipeline == (Object)null || (Object)(object)outlineOverlayMaterial != (Object)null) && (Object)(object)_outlineEraseMaterial != (Object)null && (Object)(object)_outline1Material != (Object)null && (Object)(object)_outline2Material != (Object)null) { return (Object)(object)_outline3Material != (Object)null; } return false; } private bool CreateFallbackMaterialsIfNeeded() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_fallback1Material == (Object)null) { _fallback1Material = CreateFallbackMaterial(lineColor0); } if ((Object)(object)_fallback2Material == (Object)null) { _fallback2Material = CreateFallbackMaterial(lineColor1); } if ((Object)(object)_fallback3Material == (Object)null) { _fallback3Material = CreateFallbackMaterial(lineColor2); } if ((Object)(object)_fallback1Material != (Object)null && (Object)(object)_fallback2Material != (Object)null) { return (Object)(object)_fallback3Material != (Object)null; } return false; } private Material CreateMaterial(Color emissionColor) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0033: Expected O, but got Unknown Shader val = ResolveMaskShader(); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { hideFlags = (HideFlags)61, renderQueue = 2500 }; ConfigureMaskMaterial(val2, emissionColor); return val2; } private Shader ResolveMaskShader() { if ((Object)(object)_maskShader != (Object)null) { return _maskShader; } if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null) { _maskShader = Shader.Find("HDRP/Unlit") ?? Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Unlit/Color"); } if ((Object)(object)_maskShader == (Object)null) { _maskShader = _outlineBufferShader; } return _maskShader; } private static void ConfigureMaskMaterial(Material material, Color color) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0034: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { SetColorIfPresent(material, "_Color", color); SetColorIfPresent(material, "_BaseColor", color); SetColorIfPresent(material, "_UnlitColor", color); SetColorIfPresent(material, "_EmissiveColor", color); SetFloatIfPresent(material, "_SurfaceType", 0f); SetFloatIfPresent(material, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(material, "_ZWrite", 0f); SetFloatIfPresent(material, "_ZTestDepthEqualForOpaque", 8f); SetIntIfPresent(material, "_SrcBlend", 1); SetIntIfPresent(material, "_DstBlend", 0); SetIntIfPresent(material, "_Cull", 0); SetIntIfPresent(material, "_Culling", 0); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); } } private static int ResolveMaskMaterialPass(Material material) { if ((Object)(object)material == (Object)null) { return 0; } for (int i = 0; i < MaskPassNames.Length; i++) { int num = material.FindPass(MaskPassNames[i]); if (num >= 0) { return num; } } return 0; } private static void SetColorIfPresent(Material material, string name, Color value) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(name)) { material.SetColor(name, value); } } private static void SetFloatIfPresent(Material material, string name, float value) { if (material.HasProperty(name)) { material.SetFloat(name, value); } } private static void SetIntIfPresent(Material material, string name, int value) { if (material.HasProperty(name)) { material.SetInt(name, value); } } private Material CreateFallbackMaterial(Color color) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ac: Expected O, but got Unknown Shader val = (((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null) ? (Shader.Find("HDRP/Unlit") ?? Shader.Find("Hidden/Internal-Colored")) : Shader.Find("Hidden/Internal-Colored")); if ((Object)(object)val == (Object)null) { if (Time.unscaledTime >= _nextFallbackWarningAt) { _nextFallbackWarningAt = Time.unscaledTime + 10f; ManualLogSource log = Y4NGZUpgrades.Plugin.Log; if (log != null) { log.LogWarning((object)"OutlineEffect: Hidden/Internal-Colored shader unavailable; through-wall fallback silhouettes disabled."); } } return null; } Material val2 = new Material(val) { hideFlags = (HideFlags)61, renderQueue = 5000 }; ConfigureOverlayMaterial(val2, new Color(color.r, color.g, color.b, 0.32f)); return val2; } private static void ConfigureOverlayMaterial(Material material, Color color) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0034: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { SetColorIfPresent(material, "_Color", color); SetColorIfPresent(material, "_BaseColor", color); SetColorIfPresent(material, "_UnlitColor", color); SetColorIfPresent(material, "_EmissiveColor", color); SetFloatIfPresent(material, "_SurfaceType", 1f); SetFloatIfPresent(material, "_BlendMode", 0f); SetFloatIfPresent(material, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(material, "_ZWrite", 0f); SetFloatIfPresent(material, "_TransparentZWrite", 0f); SetFloatIfPresent(material, "_ZTest", 8f); SetFloatIfPresent(material, "_ZTestTransparent", 8f); SetFloatIfPresent(material, "_ZTestDepthEqualForOpaque", 8f); SetIntIfPresent(material, "_SrcBlend", 5); SetIntIfPresent(material, "_DstBlend", 10); SetIntIfPresent(material, "_AlphaSrcBlend", 1); SetIntIfPresent(material, "_AlphaDstBlend", 10); SetIntIfPresent(material, "_Cull", 0); SetIntIfPresent(material, "_CullMode", 0); SetIntIfPresent(material, "_CullModeForward", 0); material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); material.EnableKeyword("_BLENDMODE_ALPHA"); material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); } } private void UpdateOutlineCameraFromSource() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)outlineCamera == (Object)null) && !((Object)(object)sourceCamera == (Object)null)) { outlineCamera.CopyFrom(sourceCamera); outlineCamera.renderingPath = (RenderingPath)1; outlineCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); outlineCamera.clearFlags = (CameraClearFlags)2; outlineCamera.rect = new Rect(0f, 0f, 1f, 1f); outlineCamera.cullingMask = 0; outlineCamera.targetTexture = renderTexture; ((Behaviour)outlineCamera).enabled = false; outlineCamera.allowHDR = false; } } private void DestroyMaterials() { for (int i = 0; i < _materialBuffer.Count; i++) { if ((Object)(object)_materialBuffer[i] != (Object)null) { Object.Destroy((Object)(object)_materialBuffer[i]); } } _materialBuffer.Clear(); if ((Object)(object)outlineShaderMaterial != (Object)null) { Object.Destroy((Object)(object)outlineShaderMaterial); } if ((Object)(object)outlineOverlayMaterial != (Object)null) { Object.Destroy((Object)(object)outlineOverlayMaterial); } if ((Object)(object)_outlineEraseMaterial != (Object)null) { Object.Destroy((Object)(object)_outlineEraseMaterial); } if ((Object)(object)_outline1Material != (Object)null) { Object.Destroy((Object)(object)_outline1Material); } if ((Object)(object)_outline2Material != (Object)null) { Object.Destroy((Object)(object)_outline2Material); } if ((Object)(object)_outline3Material != (Object)null) { Object.Destroy((Object)(object)_outline3Material); } if ((Object)(object)_fallback1Material != (Object)null) { Object.Destroy((Object)(object)_fallback1Material); } if ((Object)(object)_fallback2Material != (Object)null) { Object.Destroy((Object)(object)_fallback2Material); } if ((Object)(object)_fallback3Material != (Object)null) { Object.Destroy((Object)(object)_fallback3Material); } } } } namespace Y4NGZUpgrades { internal static class ArmoryBridge { private const string ArmoryPluginGuid = "com.y4ngz.betterarmory"; private const string PrizeApiTypeName = "Y4NGZUpgrades.Weapons.ArmoryPrizeApi"; private const string AmmoApiTypeName = "Y4NGZUpgrades.Weapons.ArmoryAmmoReserveApi"; private const string PresentationApiTypeName = "Y4NGZUpgrades.Weapons.ArmoryPresentationApi"; private static readonly string[] NoIds = new string[0]; private static readonly Type[] OneString = new Type[1] { typeof(string) }; private static bool _presenceResolved; private static bool _present; private static readonly Lazy<MethodInfo> WeaponPrizeIds = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetWeaponPrizeIds", Type.EmptyTypes); private static readonly Lazy<MethodInfo> WeaponDisplayName = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetWeaponDisplayName", OneString); private static readonly Lazy<MethodInfo> WeaponPrizePrefab = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetWeaponPrizePrefab", OneString); private static readonly Lazy<MethodInfo> WeaponItem = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetWeaponItem", OneString); private static readonly Lazy<MethodInfo> WeaponFingerprint = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetWeaponFingerprintTokens", Type.EmptyTypes); private static readonly Lazy<MethodInfo> WeaponPrizeInit = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "InitializeWeaponPrize", new Type[2] { typeof(GameObject), typeof(string) }); private static readonly Lazy<MethodInfo> AmmoPrizeIds = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetAmmoPrizeIds", Type.EmptyTypes); private static readonly Lazy<MethodInfo> AmmoDisplayName = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetAmmoDisplayName", OneString); private static readonly Lazy<MethodInfo> AmmoPrizePrefab = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetAmmoPrizePrefab", OneString); private static readonly Lazy<MethodInfo> AmmoItem = Method("Y4NGZUpgrades.Weapons.ArmoryPrizeApi", "GetAmmoItem", OneString); private static readonly Lazy<MethodInfo> AmmoFamilyIds = Method("Y4NGZUpgrades.Weapons.ArmoryAmmoReserveApi", "GetAmmoFamilyIds", Type.EmptyTypes); private static readonly Lazy<MethodInfo> AmmoFamilyLabel = Method("Y4NGZUpgrades.Weapons.ArmoryAmmoReserveApi", "GetAmmoFamilyLabel", OneString); private static readonly Lazy<MethodInfo> AmmoFamilyReserve = Method("Y4NGZUpgrades.Weapons.ArmoryAmmoReserveApi", "GetAmmoFamilyReserve", OneString); private static readonly Lazy<MethodInfo> StopPresentation = Method("Y4NGZUpgrades.Weapons.ArmoryPresentationApi", "StopPresentationForHeldItemStow", new Type[1] { typeof(PlayerControllerB) }); private static readonly HashSet<string> Warned = new HashSet<string>(StringComparer.Ordinal); internal static bool IsArmoryPresent { get { if (_presenceResolved) { return _present; } _presenceResolved = true; try { _present = Chainloader.PluginInfos != null && Chainloader.PluginInfos.ContainsKey("com.y4ngz.betterarmory"); } catch { _present = false; } return _present; } } internal static string[] GetWeaponPrizeIds() { return Strings(WeaponPrizeIds); } internal static string GetWeaponDisplayName(string weaponId) { return (Invoke(WeaponDisplayName, weaponId) as string) ?? weaponId; } internal static GameObject GetWeaponPrizePrefab(string weaponId) { object obj = Invoke(WeaponPrizePrefab, weaponId); return (GameObject)((obj is GameObject) ? obj : null); } internal static Item GetWeaponItem(string weaponId) { object obj = Invoke(WeaponItem, weaponId); return (Item)((obj is Item) ? obj : null); } internal static string[] GetWeaponFingerprintTokens() { return Strings(WeaponFingerprint); } internal static void InitializeWeaponPrize(GameObject instance, string weaponId) { MethodInfo methodInfo = Resolve(WeaponPrizeInit); if (methodInfo == null || (Object)(object)instance == (Object)null) { return; } try { methodInfo.Invoke(null, new object[2] { instance, weaponId }); } catch (Exception ex) { Warn("InitializeWeaponPrize", ex); } } internal static string[] GetAmmoPrizeIds() { return Strings(AmmoPrizeIds); } internal static string GetAmmoDisplayName(string pickupId) { return (Invoke(AmmoDisplayName, pickupId) as string) ?? pickupId; } internal static GameObject GetAmmoPrizePrefab(string pickupId) { object obj = Invoke(AmmoPrizePrefab, pickupId); return (GameObject)((obj is GameObject) ? obj : null); } internal static Item GetAmmoItem(string pickupId) { object obj = Invoke(AmmoItem, pickupId); return (Item)((obj is Item) ? obj : null); } internal static string[] GetAmmoFamilyIds() { return Strings(AmmoFamilyIds); } internal static string GetAmmoFamilyLabel(string familyId) { return (Invoke(AmmoFamilyLabel, familyId) as string) ?? familyId; } internal static int GetAmmoFamilyReserve(string familyId) { object obj = Invoke(AmmoFamilyReserve, familyId); if (obj is int) { return (int)obj; } return 0; } internal static void StopPresentationForHeldItemStow(PlayerControllerB player) { MethodInfo methodInfo = Resolve(StopPresentation); if (methodInfo == null || (Object)(object)player == (Object)null) { return; } try { methodInfo.Invoke(null, new object[1] { player }); } catch (Exception ex) { Warn("StopPresentationForHeldItemStow", ex); } } private static Lazy<MethodInfo> Method(string typeName, string methodName, Type[] parameters) { return new Lazy<MethodInfo>(delegate { Type type = FindType(typeName); if (type == null) { return (MethodInfo)null; } MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public, null, parameters, null); if (method == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[ArmoryBridge] " + typeName + "." + methodName + " was not found. That bridge is disabled for this session.")); } } return method; }); } private static MethodInfo Resolve(Lazy<MethodInfo> lazy) { try { return lazy.Value; } catch { return null; } } private static object Invoke(Lazy<MethodInfo> lazy, string argument) { MethodInfo methodInfo = Resolve(lazy); if (methodInfo == null) { return null; } try { return methodInfo.Invoke(null, new object[1] { argument }); } catch (Exception ex) { Warn(methodInfo.Name, ex); return null; } } private static string[] Strings(Lazy<MethodInfo> lazy) { MethodInfo methodInfo = Resolve(lazy); if (methodInfo == null) { return NoIds; } try { return (methodInfo.Invoke(null, null) as string[]) ?? NoIds; } catch (Exception ex) { Warn(methodInfo.Name, ex); return NoIds; } } private static void Warn(string member, Exception ex) { if (Warned.Add(member)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[ArmoryBridge] " + member + " failed safely: " + ex.Message)); } } } private static Type FindType(string fullName) { if (!IsArmoryPresent) { return null; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(fullName, throwOnError: false); if (type != null) { return type; } } catch { } } if (IsArmoryPresent) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[ArmoryBridge] Better Armory is installed but '" + fullName + "' was not found. That bridge is disabled for this session.")); } } return null; } } internal static class ArmoryItemProbe { private const string WeaponNamespacePrefix = "Y4NGZUpgrades.Weapons."; internal static bool IsArmoryWeapon(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return false; } Component[] components = ((Component)item).GetComponents<Component>(); foreach (Component val in components) { if (!((Object)(object)val == (Object)null)) { string fullName = ((object)val).GetType().FullName; if (fullName != null && fullName.StartsWith("Y4NGZUpgrades.Weapons.", StringComparison.Ordinal)) { return true; } } } return false; } } public static class ClutchXpPolicy { public static bool IsEligible(bool localEnteredFacility, bool localExtractedAlive, int otherFacilityEntrants, int deadOtherFacilityEntrants) { if (localEnteredFacility && localExtractedAlive && otherFacilityEntrants > 0) { return deadOtherFacilityEntrants == otherFacilityEntrants; } return false; } } internal static class CompanyQuotaTokenIntegration { [HarmonyPatch(typeof(StartOfRound), "Awake")] private static class StartOfRoundAwakePatch { private static void Postfix() { EnsureRegistered(); } } [HarmonyPatch(typeof(GameNetworkManager), "Disconnect")] private static class DisconnectPatch { private static void Prefix() { Shutdown(); } } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnGrantMessage; } private const string CompanyApiTypeName = "Y4NGZCompany.Core.QuotaProgressionApi"; private const string GrantMessageName = "Y4NGZUpgrades.CompanyQuotaTokenGrant.v1"; private const string CompanyProtocolVersionMember = "TokenGrantProtocolVersion"; private const int MaxActionIdCharacters = 120; private const int LegacyCompanyProtocolVersion = 1; private static NetworkManager _registeredNetworkManager; private static object _companyHandler; private static MethodInfo _companyUnregister; private static bool _loggedRequestShapeError; internal static bool IsCompanyProviderRegistered => _companyHandler != null; internal static void EnsureRegistered() { RegisterNetworkHandler(); RegisterCompanyHandler(); } internal static void Shutdown() { UnregisterCompanyHandler(); UnregisterNetworkHandler(); } private static void RegisterCompanyHandler() { if (_companyHandler != null) { return; } Type type = FindType("Y4NGZCompany.Core.QuotaProgressionApi"); if (type == null || !IsCompanyProtocolCompatible(type)) { return; } MethodInfo method = type.GetMethod("RegisterTokenGrantHandler", BindingFlags.Static | BindingFlags.Public); _companyUnregister = type.GetMethod("UnregisterTokenGrantHandler", BindingFlags.Static | BindingFlags.Public); ParameterInfo[] array = method?.GetParameters(); if (array == null || array.Length != 1) { return; } Type parameterType = array[0].ParameterType; MethodInfo method2 = parameterType.GetMethod("Invoke"); ParameterInfo[] array2 = method2?.GetParameters(); if (method2 == null || method2.ReturnType != typeof(bool) || array2 == null || array2.Length != 1 || !HasRequiredRequestFields(array2[0].ParameterType)) { return; } try { ParameterExpression parameterExpression = Expression.Parameter(array2[0].ParameterType, "request"); MethodInfo method3 = typeof(CompanyQuotaTokenIntegration).GetMethod("HandleCompanyRequest", BindingFlags.Static | BindingFlags.NonPublic); _companyHandler = Expression.Lambda(parameterType, Expression.Call(method3, Expression.Convert(parameterExpression, typeof(object))), parameterExpression).Compile(); method.Invoke(null, new object[1] { _companyHandler }); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[QuotaTokens] Registered Company quota token provider."); } } catch (Exception ex) { _companyHandler = null; _companyUnregister = null; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[QuotaTokens] Company provider registration failed: " + ex.Message)); } } } private static void UnregisterCompanyHandler() { if (_companyHandler == null) { return; } try { _companyUnregister?.Invoke(null, new object[1] { _companyHandler }); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Company provider unregister failed: " + ex.Message)); } } _companyHandler = null; _companyUnregister = null; } private static bool IsCompanyProtocolCompatible(Type apiType) { FieldInfo field = apiType.GetField("TokenGrantProtocolVersion", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); int num; if (field == null) { num = 1; } else { if (!(field.GetValue(null) is int num2)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Not registering: Company TokenGrantProtocolVersion is not an int " + $"(Upgrades protocol {1}). Update Y4NGZUpgrades and Y4NGZCompany together.")); } return false; } num = num2; } if (num == 1) { return true; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[QuotaTokens] Not registering: token-grant protocol mismatch " + $"(Y4NGZUpgrades {1}, Y4NGZCompany {num}). " + "Quota token rewards are disabled until both mods are updated together.")); } return false; } private static bool HasRequiredRequestFields(Type requestType) { string empty = string.Empty; empty = AppendMissing(empty, requestType, "CompletedQuota", typeof(int)); empty = AppendMissing(empty, requestType, "TokensPerPlayer", typeof(int)); empty = AppendMissing(empty, requestType, "ActionId", typeof(string)); if (empty.Length == 0) { return true; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Not registering: Company request type '" + requestType.FullName + "' is missing expected field(s): " + empty + ". Quota token rewards are disabled until both mods are updated together.")); } return false; } private static string AppendMissing(string missing, Type requestType, string name, Type expected) { FieldInfo field = requestType.GetField(name, BindingFlags.Instance | BindingFlags.Public); if (field != null && field.FieldType == expected) { return missing; } string text = ((field == null) ? name : (name + " (expected " + expected.Name + ", found " + field.FieldType.Name + ")")); if (missing.Length != 0) { return missing + ", " + text; } return text; } private static bool HandleCompanyRequest(object request) { NetworkManager singleton = NetworkManager.Singleton; if (request == null || (Object)(object)singleton == (Object)null || !singleton.IsServer) { return false; } try { Type type = request.GetType(); if (!TryReadIntField(type, request, "CompletedQuota", out var value) || !TryReadIntField(type, request, "TokensPerPlayer", out var value2) || !TryReadStringField(type, request, "ActionId", out var value3)) { return false; } bool isReplay = ReadOptionalBoolField(type, request, "IsReplay"); if (value < 1 || value2 < 1 || string.IsNullOrWhiteSpace(value3)) { return false; } return TryGrantConnectedPlayers(new ExternalTokenGrantRequest(value2, "Y4NGZCompany", $"quota:{value}", value3), isReplay); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Company grant failed: " + ex.Message)); } return false; } } internal static bool TryGrantConnectedPlayers(ExternalTokenGrantRequest request) { return TryGrantConnectedPlayers(request, isReplay: false); } internal unsafe static bool TryGrantConnectedPlayers(ExternalTokenGrantRequest request, bool isReplay) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || request.AmountPerPlayer < 1) { return false; } string text = (string.IsNullOrWhiteSpace(request.Source) ? "external" : request.Source.Trim()); string text2 = (string.IsNullOrWhiteSpace(request.ActionId) ? string.Empty : request.ActionId.Trim()); string text3 = text + ":" + text2; int completedQuota = ParseQuota(request.MilestoneId); if (text2.Length == 0) { return false; } try { if (text3.Length > 120) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Rejected " + text + " grant with oversized action ID.")); } return false; } bool result = ApplyLocalGrant(completedQuota, request.AmountPerPlayer, text3, isReplay); CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; if (customMessagingManager == null) { return result; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref completedQuota, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref request.AmountPerPlayer, default(ForPrimitives)); FixedString128Bytes val2 = new FixedString128Bytes(text3); ((FastBufferWriter)(ref val)).WriteValueSafe<FixedString128Bytes>(ref val2, default(ForFixedStrings)); foreach (ulong connectedClientsId in singleton.ConnectedClientsIds) { if (connectedClientsId != singleton.LocalClientId) { customMessagingManager.SendNamedMessage("Y4NGZUpgrades.CompanyQuotaTokenGrant.v1", connectedClientsId, val, (NetworkDelivery)4); } } } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } return true; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[QuotaTokens] " + text + " grant failed: " + ex.Message)); } return false; } } private static bool ApplyLocalGrant(int completedQuota, int tokensPerPlayer, string actionId, bool isReplay = false) { if (!ProgressionManager.TryApplyExternalTokenGrant(actionId, tokensPerPlayer, out var alreadyApplied)) { return false; } if (alreadyApplied) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)string.Format("[QuotaTokens] Quota {0} grant already in this save's ledger ({1}); ignoring{2}.", completedQuota, actionId, isReplay ? " replay" : string.Empty)); } return true; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)string.Format("[QuotaTokens] Quota {0} grant accepted{1}: +{2} tokens ({3}).", completedQuota, isReplay ? " (replay)" : string.Empty, tokensPerPlayer, actionId)); } return true; } private static void RegisterNetworkHandler() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.CustomMessagingManager : null) == null || (Object)(object)_registeredNetworkManager == (Object)(object)singleton) { return; } UnregisterNetworkHandler(); try { CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; object obj = <>O.<0>__OnGrantMessage; if (obj == null) { HandleNamedMessageDelegate val = OnGrantMessage; <>O.<0>__OnGrantMessage = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("Y4NGZUpgrades.CompanyQuotaTokenGrant.v1", (HandleNamedMessageDelegate)obj); _registeredNetworkManager = singleton; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Network handler registration failed: " + ex.Message)); } } } private static void UnregisterNetworkHandler() { NetworkManager registeredNetworkManager = _registeredNetworkManager; if (((registeredNetworkManager != null) ? registeredNetworkManager.CustomMessagingManager : null) != null) { try { _registeredNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler("Y4NGZUpgrades.CompanyQuotaTokenGrant.v1"); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Network handler unregister failed: " + ex.Message)); } } } _registeredNetworkManager = null; } private unsafe static void OnGrantMessage(ulong senderClientId, FastBufferReader reader) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)NetworkManager.Singleton == (Object)null || senderClientId != 0L) { return; } try { int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); int num2 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num2, default(ForPrimitives)); FixedString128Bytes val = default(FixedString128Bytes); ((FastBufferReader)(ref reader)).ReadValueSafe<FixedString128Bytes>(ref val, default(ForFixedStrings)); if (num >= 1 && num2 >= 1 && !((FixedString128Bytes)(ref val)).IsEmpty) { ApplyLocalGrant(num, num2, ((object)(*(FixedString128Bytes*)(&val))/*cast due to .constrained prefix*/).ToString()); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[QuotaTokens] Malformed grant from server: " + ex.Message)); } } } private static Type FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(fullName, throwOnError: false); if (type != null) { return type; } } catch { } } return null; } private static bool TryReadIntField(Type type, object instance, string name, out int value) { value = 0; if (type.GetField(name, BindingFlags.Instance | BindingFlags.Public)?.GetValue(instance) is int num) { value = num; return true; } LogRequestShapeError(type, name, "int"); return false; } private static bool TryReadStringField(Type type, object instance, string name, out string value) { value = string.Empty; FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public); if (field != null && field.FieldType == typeof(string)) { value = (field.GetValue(instance) as string) ?? string.Empty; return true; } LogRequestShapeError(type, name, "string"); return false; } private static bool ReadOptionalBoolField(Type type, object instance, string name) { object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public)?.GetValue(instance); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static void LogRequestShapeError(Type type, string name, string expected) { if (!_loggedRequestShapeError) { _loggedRequestShapeError = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)("[QuotaTokens] Company request type '" + type.FullName + "' has no readable " + expected + " field '" + name + "'. " + $"Quota token grants are being dropped; Y4NGZUpgrades expects token-grant protocol {1}. " + "Update Y4NGZUpgrades and Y4NGZCompany together.")); } } } private static int ParseQuota(string milestoneId) { if (string.IsNullOrWhiteSpace(milestoneId)) { return 0; } int num = milestoneId.LastIndexOf(':'); if (!int.TryParse((num >= 0) ? milestoneId.Substring(num + 1) : milestoneId, out var result)) { return 0; } return Math.Max(0, result); } } internal static class ContractEventAttribution { internal const string CrewFanOutMarker = ".crew."; internal static bool IsIndividuallyAttributed(string eventId, ulong creditedClientId) { if (string.IsNullOrEmpty(eventId)) { return false; } if (!eventId.EndsWith("." + creditedClientId, StringComparison.Ordinal)) { return false; } return eventId.IndexOf(".crew.", StringComparison.Ordinal) < 0; } } internal sealed class CumulativeCountTracker { private readonly Dictionary<int, int> _deltaByTotal = new Dictionary<int, int>(); private int _highWater; internal int Observe(int cumulativeTotal) { if (cumulativeTotal <= 0) { return 1; } if (cumulativeTotal > _highWater) { int num = cumulativeTotal - _highWater; _highWater = cumulativeTotal; _deltaByTotal[cumulativeTotal] = num; return num; } if (!_deltaByTotal.TryGetValue(cumulativeTotal, out var value)) { return 0; } return value; } } internal static class DawnLibCompat { internal const string ItemNamespace = "y4ngz_upgrades"; [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void RegisterNetworkPrefab(GameObject prefab) { DawnLib.RegisterNetworkPrefab(prefab); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void FixMixerGroups(GameObject prefab) { DawnLib.FixMixerGroups(prefab); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static void RegisterItem(string itemKey, Item item) { if (!((Object)(object)item == (Object)null) && !string.IsNullOrWhiteSpace(itemKey)) { DawnLib.DefineItem(NamespacedKey<DawnItemInfo>.From("y4ngz_upgrades", itemKey), item, (Action<ItemInfoBuilder>)delegate { }); } } } internal sealed class DeliveryAttributionLedger { internal const ulong UnattributedHandler = ulong.MaxValue; private readonly Dictionary<ulong, ulong> _lastHandlerByKey = new Dictionary<ulong, ulong>(); private readonly HashSet<ulong> _preexistingInsideKeys = new HashSet<ulong>(); internal int PreexistingInsideCount => _preexistingInsideKeys.Count; internal void Reset() { _lastHandlerByKey.Clear(); _preexistingInsideKeys.Clear(); } internal void MarkPreexistingInside(ulong key) { _preexistingInsideKeys.Add(key); } internal void RecordBoundaryCrossing(ulong key, ulong handlerClientId, bool nowInside) { if (nowInside) { _lastHandlerByKey[key] = handlerClientId; } else { _lastHandlerByKey.Remove(key); } } internal static bool SuppressOutwardTransition(bool nowInside, bool handlerKnown, bool handlerIsDead, bool handlerIsInsideShip) { if (!nowInside && handlerKnown) { return handlerIsDead || handlerIsInsideShip; } return false; } internal static bool ShouldPayBodyRetrieval(bool lastHandlerIsPayee, bool bodyIsInShip, bool bodyDeactivated, bool ownerResolved, bool payeeOwnsBody) { if (lastHandlerIsPayee && bodyIsInShip && !bodyDeactivated && ownerResolved) { return !payeeOwnsBody; } return false; } internal bool TryGetDeliveryHandler(ulong key, out ulong handlerClientId) { return _lastHandlerByKey.TryGetValue(key, out handlerClientId); } internal bool ShouldPayDelivery(ulong key, bool insideAtRoundEnd, ulong localClientId) { if (insideAtRoundEnd && !_preexistingInsideKeys.Contains(key) && _lastHandlerByKey.TryGetValue(key, out var value) && value != ulong.MaxValue) { return value == localClientId; } return false; } } internal static class EffectiveConfigInventory { private readonly struct InventoryRow { internal string FileName { get; } internal ConfigEntryBase Entry { get; } internal InventoryRow(string fileName, ConfigEntryBase entry) { FileName = fileName; Entry = entry; } } internal static string ReportPath => Path.Combine(Paths.ConfigPath, "Y4NGZUpgrades", "effective-config.tsv"); internal static void Write(IEnumerable<ConfigFile> configs) { if (configs == null) { return; } try { List<InventoryRow> list = new List<InventoryRow>(); foreach (ConfigFile config in configs) { if (config == null) { continue; } string fileName = Path.GetFileName(config.ConfigFilePath); foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config) { list.Add(new InventoryRow(fileName, item.Value)); } } list.Sort(delegate(InventoryRow left, InventoryRow right) { int num2 = string.Compare(left.FileName, right.FileName, StringComparison.OrdinalIgnoreCase); if (num2 != 0) { return num2; } int num3 = string.Compare(left.Entry.Definition.Section, right.Entry.Definition.Section, StringComparison.OrdinalIgnoreCase); return (num3 == 0) ? string.Compare(left.Entry.Definition.Key, right.Entry.Definition.Key, StringComparison.OrdinalIgnoreCase) : num3; }); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("file\tsection\tkey\ttype\tdefault\teffective\tdescription"); for (int num = 0; num < list.Count; num++) { InventoryRow inventoryRow = list[num]; ConfigEntryBase entry = inventoryRow.Entry; StringBuilder stringBuilder2 = stringBuilder.Append(Escape(inventoryRow.FileName)).Append('\t').Append(Escape(entry.Definition.Section)) .Append('\t') .Append(Escape(entry.Definition.Key)) .Append('\t') .Append(Escape(entry.SettingType?.FullName)) .Append('\t') .Append(Escape(Format(entry.DefaultValue))) .Append('\t') .Append(Escape(Format(entry.BoxedValue))) .Append('\t'); ConfigDescription description = entry.Description; stringBuilder2.Append(Escape((description != null) ? description.Description : null)).AppendLine(); } Directory.CreateDirectory(Path.GetDirectoryName(ReportPath)); File.WriteAllText(ReportPath, stringBuilder.ToString()); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Effective config inventory written to '{ReportPath}' ({list.Count} definitions)."); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("Failed writing effective config inventory: " + ex.Message)); } } } private static string Format(object value) { if (value == null) { return string.Empty; } if (!(value is IFormattable formattable)) { return value.ToString(); } return formattable.ToString(null, CultureInfo.InvariantCulture); } private static string Escape(string value) { return (value ?? string.Empty).Replace("\t", "\\t").Replace("\r", "\\r").Replace("\n", "\\n"); } } [Serializable] internal sealed class EmployeeStatisticsData { public int monstersKilled; public int stepsTaken; public int scrapValueDelivered; public int timesDied; public int bombsDefused; public float payloadDistancePushedMeters; public int surveyBeaconsPlaced; public int itemsIncinerated; public int whistleblowerDamageDealt; public int pestsTrapped; public int containmentWavesSurvived; public int drillsPlaced; public int breakersRestored; public float timeSpentOnCctvSeconds; public int devicesHacked; public int quotasCompleted; internal EmployeeStatisticsData Clone() { return new EmployeeStatisticsData { monstersKilled = monstersKilled, stepsTaken = stepsTaken, scrapValueDelivered = scrapValueDelivered, timesDied = timesDied, bombsDefused = bombsDefused, payloadDistancePushedMeters = payloadDistancePushedMeters, surveyBeaconsPlaced = surveyBeaconsPlaced, itemsIncinerated = itemsIncinerated, whistleblowerDamageDealt = whistleblowerDamageDealt, pestsTrapped = pestsTrapped, containmentWavesSurvived = containmentWavesSurvived, drillsPlaced = drillsPlaced, breakersRestored = breakersRestored, timeSpentOnCctvSeconds = timeSpentOnCctvSeconds, devicesHacked = devicesHacked, quotasCompleted = quotasCompleted }; } internal void Add(EmployeeStatisticsData other) { if (other != null) { monstersKilled = AddClamped(monstersKilled, other.monstersKilled); stepsTaken = AddClamped(stepsTaken, other.stepsTaken); scrapValueDelivered = AddClamped(scrapValueDelivered, other.scrapValueDelivered); timesDied = AddClamped(timesDied, other.timesDied); bombsDefused = AddClamped(bombsDefused, other.bombsDefused); payloadDistancePushedMeters = AddClamped(payloadDistancePushedMeters, other.payloadDistancePushedMeters); surveyBeaconsPlaced = AddClamped(surveyBeaconsPlaced, other.surveyBeaconsPlaced); itemsIncinerated = AddClamped(itemsIncinerated, other.itemsIncinerated); whistleblowerDamageDealt = AddClamped(whistleblowerDamageDealt, other.whistleblowerDamageDealt); pestsTrapped = AddClamped(pestsTrapped, other.pestsTrapped); containmentWavesSurvived = AddClamped(containmentWavesSurvived, other.containmentWavesSurvived); drillsPlaced = AddClamped(drillsPlaced, other.drillsPlaced); breakersRestored = AddClamped(breakersRestored, other.breakersRestored); timeSpentOnCctvSeconds = AddClamped(timeSpentOnCctvSeconds, other.timeSpentOnCctvSeconds); devicesHacked = AddClamped(devicesHacked, other.devicesHacked); quotasCompleted = AddClamped(quotasCompleted, other.quotasCompleted); } } private static int AddClamped(int left, int right) { long val = (long)Math.Max(0, left) + (long)Math.Max(0, right); return (int)Math.Min(2147483647L, val); } private static float AddClamped(float left, float right) { if (float.IsNaN(left) || float.IsInfinity(left)) { left = 0f; } if (float.IsNaN(right) || float.IsInfinity(right)) { right = 0f; } return Mathf.Clamp(Mathf.Max(0f, left) + Mathf.Max(0f, right), 0f, 1E+09f); } } internal static class EmployeeStatistics { internal readonly struct ReportNoteCandidate { internal readonly int Priority; internal readonly string Text; internal ReportNoteCandidate(int priority, string text) { Priority = priority; Text = text; } } private sealed class RoundState { internal readonly EmployeeStatisticsData Data = new EmployeeStatisticsData(); internal readonly Dictionary<ulong, ulong> LastItemHolderByKey = new Dictionary<ulong, ulong>(); internal readonly Dictionary<ulong, float> LastEnemyHitByLocalPlayer = new Dictionary<ulong, float>(); internal readonly HashSet<ulong> KilledEnemies = new HashSet<ulong>(); internal readonly HashSet<string> UniqueEventKeys = new HashSet<string>(StringComparer.Ordinal); internal Vector3 LastPlayerPosition; internal bool PlayerPositionValid; internal float StepDistance; internal object PayloadCart; internal Vector3 LastPayloadPosition; internal bool PayloadPositionValid; internal readonly CumulativeCountTracker PestCaptureCounts = new CumulativeCountTracker(); } private const string CompanyAssemblyName = "Y4NGZCompany"; private const string CctvAssemblyName = "LethalCCTV"; internal const float StepMeters = 0.76f; private const float MinimumTrackedMovement = 0.02f; private const float MaximumTrackedMovement = 8f; private static readonly string SaveDir = Path.Combine(Paths.ConfigPath, "Y4NGZEmployeeFile"); private static EmployeeStatisticsData _lifetime; private static EmployeeStatisticsData _lastRound; private static RoundState _round = new RoundState(); private static readonly RoundLatch _latch = new RoundLatch(); private static string _key; private static int _lastTimesFulfilledQuota = -1; private static bool _cctvReflectionResolved; private static PropertyInfo _cctvFocusedProperty; private static bool _payloadReflectionResolved; private static PropertyInfo _localPayloadCartProperty; private static PropertyInfo _payloadAttachedToLocalProperty; private static readonly string[] SpelledNumbers = new string[11] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; internal static EmployeeStatisticsData CurrentSnapshot { get { EnsureLoaded(); EmployeeStatisticsData employeeStatisticsData = _lifetime?.Clone() ?? new EmployeeStatisticsData(); if (_latch.Active && !_latch.Finalized) { employeeStatisticsData.Add(_round.Data); } return employeeStatisticsData; } } internal static EmployeeStatisticsData LastRoundSnapshot => _lastRound?.Clone(); internal static void SwitchToCurrentSave() { if (!SaveKey.TryGetCurrent(out var key)) { _key = null; _lifetime = new EmployeeStatisticsData(); ResetRuntimeState(); } else if (_lifetime == null || !string.Equals(_key, key, StringComparison.OrdinalIgnoreCase)) { _key = key; _lifetime = Load(key); _lastRound = null; _round = new RoundState(); _latch.Abandon(); _lastTimesFulfilledQuota = CurrentQuotaCount(); ResetPositionTracking(); } } internal static void BeginRound() { SwitchToCurrentSave(); _round = new RoundState(); _latch.Begin(); _lastRound = null; _lastTimesFulfilledQuota = CurrentQuotaCount(); ResetPositionTracking(); } internal static void AbandonUnfinalizedRound() { if (!_latch.Finalized && _latch.Active) { _latch.Abandon(); _round = new RoundState(); ResetPositionTracking(); } } internal static void ResetCurrentSave() { if (!SaveKey.TryGetCurrentExistingOrSlot(out var key)) { _key = null; _lifetime = new EmployeeStatisticsData(); ResetRuntimeState(); } else { DeleteForKey(key); } } internal static bool DeleteForKey(string key) { bool result = false; try { string path = GetPath(key); if (File.Exists(path)) { File.Delete(path); result = true; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[EmployeeFile] Failed resetting statistics: " + ex.Message)); } } if (string.Equals(_key, key, StringComparison.OrdinalIgnoreCase)) { _key = null; _lifetime = new EmployeeStatisticsData(); } ResetRuntimeState(); return result; } internal static void RecordItemGrabbed(GrabbableObject item) { if (_latch.Active && !_latch.Finalized && !((Object)(object)item == (Object)null)) { PlayerControllerB playerHeldBy = item.playerHeldBy; if ((Object)(object)playerHeldBy != (Object)null) { _round.LastItemHolderByKey[NetworkKey((Component)(object)item)] = playerHeldBy.actualClientId; } } } internal static void RecordEnemyHit(EnemyAI enemy, PlayerControllerB playerWhoHit) { if (_latch.Active && !_latch.Finalized && !((Object)(object)enemy == (Object)null) && IsLocalPlayer(playerWhoHit)) { _round.LastEnemyHitByLocalPlayer[NetworkKey((Component)(object)enemy)] = Time.time; } } internal static void RecordEnemyKilled(EnemyAI enemy) { if (_latch.Active && !_latch.Finalized && !((Object)(object)enemy == (Object)null)) { ulong num = NetworkKey((Component)(object)enemy); if (_round.KilledEnemies.Add(num) && _round.LastEnemyHitByLocalPlayer.TryGetValue(num, out var value) && !(Time.time - value > Mathf.Max(1f, Plugin.ProgressionConfig.KillAttributionWindowSeconds.Value))) { _round.Data.monstersKilled = AddOne(_round.Data.monstersKilled); } } } internal static void RecordDeath() { AddRoundOrLifetime(delegate(EmployeeStatisticsData data) { data.timesDied = AddOne(data.timesDied); }); } internal static void RecordBombDefused(string eventId) { if (TryAddRoundKey("bomb." + (eventId ?? string.Empty))) { _round.Data.bombsDefused = AddOne(_round.Data.bombsDefused); } } internal static void RecordSurveyBeaconPlaced(string eventId) { if (TryAddRoundKey("survey." + (eventId ?? string.Empty))) { _round.Data.surveyBeaconsPlaced = AddOne(_round.Data.surveyBeaconsPlaced); } } internal static void RecordItemIncinerated(int playerId, ulong itemNetworkObjectId) { PlayerControllerB val = LocalPlayer(); if (!((Object)(object)val == (Object)null) && (int)val.playerClientId == playerId && TryAddRoundKey("incinerator.item." + itemNetworkObjectId)) { _round.Data.itemsIncinerated = AddOne(_round.Data.itemsIncinerated); } } internal static void RecordWhistleblowerDamage(EnemyAI enemy, PlayerControllerB playerWhoHit, int damage) { if (!((Object)(object)enemy == (Object)null) && damage > 0 && IsLocalPlayer(playerWhoHit) && _latch.Active && !_latch.Finalized) { _round.Data.whistleblowerDamageDealt = AddClamped(_round.Data.whistleblowerDamageDealt, damage); } } internal static void ObservePestsTrapped(string eventId, ulong creditedClientId, int capturedTotal) { if (_latch.Active && !_latch.Finalized) { int num = _round.PestCaptureCounts.Observe(capturedTotal); PlayerControllerB val = LocalPlayer(); if (num > 0 && !((Object)(object)val == (Object)null) && val.actualClientId == creditedClientId && TryAddRoundKey("pest.trapped." + (eventId ?? string.Empty))) { _round.Data.pestsTrapped = AddClamped(_round.Data.pestsTrapped, num); } } } internal static void RecordContainmentWaveSurvived(string eventId) { if (TryAddRoundKey("containment.wave." + (eventId ?? string.Empty))) { _round.Data.containmentWavesSurvived = AddOne(_round.Data.containmentWavesSurvived); } } internal static void RecordDrillPlaced(string eventId) { if (TryAddRoundKey("shadowraid.drill." + (eventId ?? string.Empty))) { _round.Data.drillsPlaced = AddOne(_round.Data.drillsPlaced); } } internal static void RecordBreakerRestored(int restoredCount, ulong actorClientId) { PlayerControllerB val = LocalPlayer(); if (!((Object)(object)val == (Object)null) && val.actualClientId == actorClientId && TryAddRoundKey("blackout.breaker.count." + Mathf.Max(1, restoredCount))) { _round.Data.breakersRestored = AddOne(_round.Data.breakersRestored); } } internal static void RecordSingleBreakerRestored(string eventId) { if (TryAddRoundKey("blackout.breaker.single." + (eventId ?? string.Empty))) { _round.Data.breakersRestored = AddOne(_round.Data.breakersRestored); } } internal static void RecordDeviceHacked(Object target) { RecordDeviceHacked((target != (Object)null) ? (((object)target).GetType().FullName + "." + target.GetInstanceID()) : ("unknown." + Time.frameCount)); } internal static void RecordDeviceHacked(string targetKey) { if (TryAddRoundKey("hack." + (targetKey ?? string.Empty))) { _round.Data.devicesHacked = AddOne(_round.Data.devicesHacked); } } internal static void UpdateRuntime(PlayerControllerB localPlayer, float deltaTime) { if (_lifetime == null) { SwitchToCurrentSave(); } UpdateQuotaCompletion(); if (_latch.Active && !_latch.Finalized && IsLocalPlayer(localPlayer)) { float num = Mathf.Clamp(deltaTime, 0f, 0.25f); UpdateSteps(localPlayer); if (IsCctvFocused()) { _round.Data.timeSpentOnCctvSeconds += num; } UpdatePayloadDistance(); } } internal static EmployeeStatisticsData FinalizeRound(int scrapCollected) { EnsureLoaded(); if (!_latch.TryBeginFinalize(out var recoveredMissedStart)) { return _lastRound?.Clone() ?? new EmployeeStatisticsData(); } if (recoveredMissedStart) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[EmployeeStatistics] FinalizeRound ran without a round start " + $"(sequence={_latch.Sequence}, scrapCollected={scrapCollected}). " + "Nothing was recorded this round — the RoundLifecycle.RoundStarted hook did not fire for this peer.")); } } _round.Data.scrapValueDelivered = ComputeLocalDeliveredScrapValue(); _lastRound = _round.Data.Clone(); if (_lifetime == null) { _lifetime = new EmployeeStatisticsData(); } _lifetime.Add(_lastRound); _latch.CompleteFinalize(); Save(); return _lastRound.Clone(); } internal static IReadOnlyList<ReportNoteCandidate> BuildReportNoteCandidates() { List<ReportNoteCandidate> list = new List<ReportNoteCandidate>(); EmployeeStatisticsData lastRound = _lastRound; if (lastRound == null) { return list; } if (lastRound.bombsDefused > 0) { list.Add(new ReportNoteCandidate(64, "* Defused " + FormatCount(lastRound.bombsDefused, "live bomb") + " during the operation.")); } if (lastRound.surveyBeaconsPlaced > 0) { list.Add(new ReportNoteCandidate(60, "* Planted " + FormatCount(lastRound.surveyBeaconsPlaced, "survey beacon") + " across the site.")); } if (lastRound.devicesHacked > 0) { list.Add(new ReportNoteCandidate(56, "* Hacked " + FormatCount(lastRound.devicesHacked, "secured device") + " during the operation.")); } if (lastRound.payloadDistancePushedMeters >= 5f) { list.Add(new ReportNoteCandidate(52, $"* Pushed the payload {lastRound.payloadDistancePushedMeters:0}m across the site.")); } if (lastRound.timeSpentOnCctvSeconds >= 20f) { list.Add(new ReportNoteCandidate(48, "* Monitored ship cameras for " + FormatDurationCompact(lastRound.timeSpentOnCctvSeconds) + ".")); } if (lastRound.quotasCompleted > 0) { list.Add(new ReportNoteCandidate(40, "* Closed out the profit quota during this operation.")); } return list; } private static string FormatCount(int count, string singularNoun) { int num = Mathf.Max(0, count); string text = ((num < SpelledNumbers.Length) ? SpelledNumbers[num] : num.ToString("N0")); if (num != 1) { return text + " " + singularNoun + "s"; } return text + " " + singularNoun; } private static string FormatDurationCompact(float seconds) { int num = Mathf.Max(0, Mathf.FloorToInt(seconds)); int num2 = num / 60; int num3 = num % 60; if (num2 <= 0) { return $"{num3}s"; } return $"{num2}m {num3}s"; } internal static string FormatDuration(float seconds) { int num = Mathf.Max(0, Mathf.FloorToInt(seconds)); int num2 = num / 3600; int num3 = num % 3600 / 60; int num4 = num % 60; if (num2 <= 0) { return $"{num3:00}:{num4:00}"; } return $"{num2}:{num3:00}:{num4:00}"; } private static void EnsureLoaded() { if (_lifetime == null) { SwitchToCurrentSave(); } } private static EmployeeStatisticsData Load(string key) { try { string path = GetPath(key); if (File.Exists(path)) { return JsonUtility.FromJson<EmployeeStatisticsData>(File.ReadAllText(path)) ?? new EmployeeStatisticsData(); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[EmployeeFile] Failed reading statistics: " + ex.Message)); } } return new EmployeeStatisticsData(); } private static void Save() { if (_lifetime == null || string.IsNullOrWhiteSpace(_key)) { return; } try { Directory.CreateDirectory(SaveDir); File.WriteAllText(GetPath(_key), JsonUtility.ToJson((object)_lifetime, true)); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[EmployeeFile] Failed writing statistics: " + ex.Message)); } } } private static string GetPath(string key) { char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); char[] array = (key ?? "employee").ToCharArray(); for (int i = 0; i < array.Length; i++) { if (Array.IndexOf(invalidFileNameChars, array[i]) >= 0) { array[i] = '_'; } } return Path.Combine(SaveDir, new string(array) + ".json"); } private static void UpdateSteps(PlayerControllerB player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result t