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 PaintingCompany v1.0.0
MechaChameleon.dll
Decompiled 4 hours 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.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [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("MechaChameleon")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+67f3cc4d0c9e867227f7474adb201e11df783e76")] [assembly: AssemblyProduct("MechaChameleon")] [assembly: AssemblyTitle("MechaChameleon")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MechaChameleon { public static class AudioSystem { private static AudioSource uiSource; private static AudioSource GetSource() { if ((Object)(object)uiSource == (Object)null && (Object)(object)ChameleonManager.Instance != (Object)null) { uiSource = ((Component)ChameleonManager.Instance).gameObject.AddComponent<AudioSource>(); uiSource.spatialBlend = 0f; uiSource.playOnAwake = false; uiSource.bypassEffects = true; uiSource.bypassListenerEffects = true; } return uiSource; } public static void PlayOpen() { Terminal val = Object.FindObjectOfType<Terminal>(); AudioClip clip = (((Object)(object)val != (Object)null && (Object)(object)val.enterTerminalSFX != (Object)null) ? val.enterTerminalSFX : (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.scanSFX : null)); Play(clip, 0.75f); } public static void PlayClose() { Terminal val = Object.FindObjectOfType<Terminal>(); AudioClip clip = (((Object)(object)val != (Object)null && (Object)(object)val.leaveTerminalSFX != (Object)null) ? val.leaveTerminalSFX : (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.scanSFX : null)); Play(clip, 0.65f); } public static void PlayClick() { Terminal val = Object.FindObjectOfType<Terminal>(); AudioClip clip = null; if ((Object)(object)val != (Object)null && val.keyboardClips != null && val.keyboardClips.Length != 0) { clip = val.keyboardClips[Random.Range(0, val.keyboardClips.Length)]; } else if ((Object)(object)HUDManager.Instance != (Object)null && HUDManager.Instance.dialogueBleeps != null && HUDManager.Instance.dialogueBleeps.Length != 0) { clip = HUDManager.Instance.dialogueBleeps[0]; } Play(clip, 0.5f); } public static void PlaySample() { AudioClip clip = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.scanSFX : null); Play(clip, 0.6f); } public static void PlaySuit() { AudioClip val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.changeSuitSFX : null); if ((Object)(object)val == (Object)null && (Object)(object)HUDManager.Instance != (Object)null) { val = HUDManager.Instance.addToScrapTotalSFX; } Play(val, 0.7f); } public static void PlayError() { AudioClip val = null; if ((Object)(object)HUDManager.Instance != (Object)null) { if (HUDManager.Instance.warningSFX != null && HUDManager.Instance.warningSFX.Length != 0) { val = HUDManager.Instance.warningSFX[Random.Range(0, HUDManager.Instance.warningSFX.Length)]; } else if ((Object)(object)HUDManager.Instance.levelDecreaseSFX != (Object)null) { val = HUDManager.Instance.levelDecreaseSFX; } else if (HUDManager.Instance.tipsSFX != null && HUDManager.Instance.tipsSFX.Length != 0) { val = HUDManager.Instance.tipsSFX[0]; } } if ((Object)(object)val == (Object)null && (Object)(object)StartOfRound.Instance != (Object)null) { val = StartOfRound.Instance.HUDSystemAlertSFX; } if ((Object)(object)val == (Object)null) { Terminal val2 = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val2 != (Object)null && val2.syncedAudios != null && val2.syncedAudios.Length > 1) { val = val2.syncedAudios[1]; } } if ((Object)(object)val != (Object)null) { Play(val, 0.75f); } else { PlayClick(); } } private static void Play(AudioClip clip, float volume = 1f) { if ((Object)(object)clip == (Object)null) { return; } try { AudioSource source = GetSource(); if ((Object)(object)source != (Object)null) { source.PlayOneShot(clip, volume); } else if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.UIAudio != (Object)null) { HUDManager.Instance.UIAudio.PlayOneShot(clip, volume); } } catch { } } } public static class CameraMath { public static Rect DisplayRect(Camera cam) { //IL_0026: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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) Rect val = (Rect)(((Object)(object)cam != (Object)null) ? cam.rect : new Rect(0f, 0f, 1f, 1f)); if (((Rect)(ref val)).x <= 0.001f && ((Rect)(ref val)).y <= 0.001f && ((Rect)(ref val)).width >= 0.999f && ((Rect)(ref val)).height >= 0.999f) { return new Rect(0f, 0f, (float)Screen.width, (float)Screen.height); } return new Rect(((Rect)(ref val)).x * (float)Screen.width, ((Rect)(ref val)).y * (float)Screen.height, ((Rect)(ref val)).width * (float)Screen.width, ((Rect)(ref val)).height * (float)Screen.height); } public static Matrix4x4 ViewMatrix(Camera cam) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)cam).transform; Matrix4x4 val = Matrix4x4.TRS(transform.position, transform.rotation, new Vector3(1f, 1f, -1f)); return ((Matrix4x4)(ref val)).inverse; } public static Ray BuildRay(Camera cam, Vector2 screenPos) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0085: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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) //IL_00c1: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) Rect val = DisplayRect(cam); float num = ((((Rect)(ref val)).width > 0f) ? ((screenPos.x - ((Rect)(ref val)).x) / ((Rect)(ref val)).width * 2f - 1f) : 0f); float num2 = ((((Rect)(ref val)).height > 0f) ? ((screenPos.y - ((Rect)(ref val)).y) / ((Rect)(ref val)).height * 2f - 1f) : 0f); Transform transform = ((Component)cam).transform; Matrix4x4 projectionMatrix = cam.projectionMatrix; Vector4 val2 = ((Matrix4x4)(ref projectionMatrix)).inverse * new Vector4(num, num2, -1f, 1f); if (Mathf.Abs(val2.w) > 1E-06f) { val2 /= val2.w; } Vector3 val3 = transform.TransformDirection(new Vector3(val2.x, val2.y, 0f - val2.z)); if (((Vector3)(ref val3)).sqrMagnitude < 1E-12f) { val3 = transform.forward; } return new Ray(transform.position, ((Vector3)(ref val3)).normalized); } public static bool ProjectToGui(Camera cam, Matrix4x4 viewProjection, Vector3 world, out Vector2 gui) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0024: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) gui = default(Vector2); if ((Object)(object)cam == (Object)null) { return false; } Vector4 val = viewProjection * new Vector4(world.x, world.y, world.z, 1f); if (val.w <= 1E-05f) { return false; } Rect val2 = DisplayRect(cam); float num = ((Rect)(ref val2)).x + (val.x / val.w * 0.5f + 0.5f) * ((Rect)(ref val2)).width; float num2 = ((Rect)(ref val2)).y + (val.y / val.w * 0.5f + 0.5f) * ((Rect)(ref val2)).height; gui = new Vector2(num, (float)Screen.height - num2); return true; } } [DefaultExecutionOrder(30000)] public class ChameleonManager : MonoBehaviour { private PlayerControllerB player; private Camera cam; private PaintTarget target; private PaintUI ui; private static readonly float[] ZoomSteps = new float[11] { 0.3f, 0.45f, 0.65f, 0.9f, 1.25f, 1.7f, 2.3f, 3.1f, 4.2f, 5.5f, 7f }; private Vector3 pivot; private Vector3 panOffset; private float yaw; private float pitch; private int zoomIndex = 5; private float savedAnimatorSpeed = 1f; private bool animatorFrozen; private PaintHit hoverHit; private bool hoverValid; private Vector3 camLocalPos; private Quaternion camLocalRot; private float camNear; private float camFov; private int frameCounter; private bool shouldPickScreen; private float lastScreenRead; private Vector2 pickScreenPos; private bool pickingWithSpace; private Keyboard textDevice; private const float PortraitFov = 34f; internal const float PortraitAspect = 0.75f; public static ChameleonManager Instance { get; private set; } public bool Active { get; private set; } public static bool HasMoreCompany { get { try { if (Chainloader.PluginInfos.ContainsKey("notnotnotswipez-MoreCompany") || Chainloader.PluginInfos.ContainsKey("MoreCompany")) { return true; } return Type.GetType("MoreCompany.MainClass, MoreCompany") != null; } catch { return false; } } } public bool CosmeticsVisible { get; set; } = true; private void Awake() { Instance = this; ui = new PaintUI(); } private void OnDestroy() { UnsubscribeText(); if (Active) { Exit(); } target?.Dispose(); ui?.Dispose(); ChameleonNet.Shutdown(); } private static PlayerControllerB GetLocalPlayer() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return null; } PlayerControllerB localPlayerController = instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled) { return null; } return localPlayerController; } private void Update() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) ChameleonNet.Tick(); Keyboard current = Keyboard.current; PlayerControllerB localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer == (Object)null) { if (Active) { Exit(); } return; } if (target != null && (Object)(object)target.Player != (Object)(object)localPlayer) { if (Active) { Exit(); } target.Dispose(); target = null; } bool flag = Active && ui.CapturingText; if (current != null && !flag && ((ButtonControl)current[Plugin.ToggleKey.Value]).wasPressedThisFrame) { if (Active) { Exit(); } else { Enter(localPlayer); } } else if (!Active) { frameCounter++; if (target == null && localPlayer.isPlayerControlled && ((Object)(object)localPlayer.thisPlayerModel != (Object)null || ((Component)localPlayer).gameObject.activeInHierarchy)) { target = new PaintTarget(localPlayer); if (target.EnsureSetup()) { PublishPaint(); } } if (frameCounter % 15 == 0) { GameObject val = GameObject.Find("ThridPersonCam"); if ((Object)(object)val != (Object)null && val.activeInHierarchy) { LODGroup componentInChildren = ((Component)localPlayer).GetComponentInChildren<LODGroup>(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.enabled && ((Component)componentInChildren).gameObject.activeInHierarchy) { componentInChildren.ForceLOD(0); } } } if (target != null && frameCounter % 30 == 0) { target.ReapplyIfNeeded(); } } else if (current != null && !flag && ((ButtonControl)current.escapeKey).wasPressedThisFrame) { Exit(); } else { if (flag) { HandleTypingInput(current); } else { UnsubscribeText(); } target.PreAnimationTick(); } } private void RunEditor() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_007d: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; Mouse current2 = Mouse.current; if (current2 != null) { Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current2).position).ReadValue(); Vector2 mouse = default(Vector2); ((Vector2)(ref mouse))..ctor(val.x, (float)Screen.height - val.y); bool flag = ui.HandleInput(mouse, current2.leftButton.wasPressedThisFrame, current2.leftButton.isPressed, current2.leftButton.wasReleasedThisFrame); hoverValid = !flag && target.RaycastSurface(BuildRay(val), out hoverHit); HandleCameraInput(current2, current, flag); HandlePaintInput(current2, current, val, flag); ui.SetCursor(cam, hoverValid, hoverHit.Point, hoverHit.Normal, ui.BrushRadius * 0.01f); target.FlushTextures(); } } private void LateUpdate() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Invalid comparison between Unknown and I4 if (Active && !((Object)(object)cam == (Object)null) && target != null) { if ((Object)(object)player != (Object)null) { player.disableLookInput = true; player.disableMoveInput = true; player.disableInteract = true; player.moveInputVector = Vector2.zero; player.isJumping = false; } ApplyCameraPose(); target.AssertTPose(); RunEditor(); target?.TickVisibility(cam); if ((int)Cursor.lockState > 0) { Cursor.lockState = (CursorLockMode)0; } if (!Cursor.visible) { Cursor.visible = true; } } } private void HandleTypingInput(Keyboard kb) { if (kb != null) { SubscribeText(kb); if (((ButtonControl)kb.escapeKey).wasPressedThisFrame) { ui.TypeCancel(); } else if (((ButtonControl)kb.enterKey).wasPressedThisFrame || ((ButtonControl)kb.numpadEnterKey).wasPressedThisFrame) { ui.TypeCommit(); } else if (((ButtonControl)kb.backspaceKey).wasPressedThisFrame) { ui.TypeBackspace(); } } } private void SubscribeText(Keyboard kb) { if (textDevice != kb) { UnsubscribeText(); textDevice = kb; kb.onTextInput += OnTextInput; } } private void UnsubscribeText() { if (textDevice != null) { try { textDevice.onTextInput -= OnTextInput; } catch { } textDevice = null; } } private void OnTextInput(char c) { ui.TypeChar(c); } private Ray BuildRay(Vector2 screenPos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return CameraMath.BuildRay(cam, screenPos); } private int GetEnvironmentMask() { if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.collidersAndRoomMaskAndDefault != 0) { return StartOfRound.Instance.collidersAndRoomMaskAndDefault; } return LayerMask.GetMask(new string[7] { "Room", "Colliders", "Default", "Terrain", "PlaceableShipObject", "Props", "Railing" }); } private void ApplyCameraPose() { //IL_002c: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null || target == null) { return; } Vector3 anchor = target.GetAnchor(); int environmentMask = GetEnvironmentMask(); Vector3 val = anchor + panOffset; Vector3 val2 = val - anchor; float magnitude = ((Vector3)(ref val2)).magnitude; pivot = val; if (magnitude > 0.01f) { Vector3 val3 = val2 / magnitude; RaycastHit val4 = default(RaycastHit); if (Physics.SphereCast(anchor, 0.12f, val3, ref val4, magnitude, environmentMask, (QueryTriggerInteraction)1) && (Object)(object)((RaycastHit)(ref val4)).collider != (Object)null && !((RaycastHit)(ref val4)).collider.isTrigger && ((Object)(object)player == (Object)null || !((Component)((RaycastHit)(ref val4)).collider).transform.IsChildOf(((Component)player).transform))) { float num = Mathf.Max(0f, ((RaycastHit)(ref val4)).distance - 0.06f); pivot = anchor + val3 * num; } } Quaternion val5 = Quaternion.Euler(pitch, yaw, 0f); Vector3 val6 = val5 * Vector3.back; float num2 = ZoomSteps[zoomIndex]; float num3 = num2; float num4 = 0.1f; Ray val7 = default(Ray); ((Ray)(ref val7))..ctor(pivot, val6); RaycastHit[] array = Physics.SphereCastAll(val7, num4, num2, environmentMask, (QueryTriggerInteraction)1); float num5 = num2; for (int i = 0; i < array.Length; i++) { RaycastHit val8 = array[i]; if (!((Object)(object)((RaycastHit)(ref val8)).collider == (Object)null) && !((RaycastHit)(ref val8)).collider.isTrigger && (!((Object)(object)player != (Object)null) || !((Component)((RaycastHit)(ref val8)).collider).transform.IsChildOf(((Component)player).transform)) && ((RaycastHit)(ref val8)).distance < num5) { num5 = ((RaycastHit)(ref val8)).distance; } } RaycastHit val9 = default(RaycastHit); if (Physics.Raycast(val7, ref val9, num2, environmentMask, (QueryTriggerInteraction)1) && (Object)(object)((RaycastHit)(ref val9)).collider != (Object)null && !((RaycastHit)(ref val9)).collider.isTrigger && ((Object)(object)player == (Object)null || !((Component)((RaycastHit)(ref val9)).collider).transform.IsChildOf(((Component)player).transform))) { float num6 = Mathf.Max(0.12f, ((RaycastHit)(ref val9)).distance - 0.06f); if (num6 < num5) { num5 = num6; } } if (num5 < num2) { num3 = Mathf.Max(0.18f, num5); } ((Component)cam).transform.SetPositionAndRotation(pivot + val6 * num3, val5); } private void Enter(PlayerControllerB p) { //IL_0066: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) try { player = p; cam = p.gameplayCamera; if ((Object)(object)cam == (Object)null) { return; } if (target == null) { target = new PaintTarget(p); } if (target.EnsureSetup()) { camLocalPos = ((Component)cam).transform.localPosition; camLocalRot = ((Component)cam).transform.localRotation; camNear = cam.nearClipPlane; camFov = cam.fieldOfView; cam.nearClipPlane = Mathf.Min(camNear, 0.03f); panOffset = Vector3.zero; pivot = target.GetAnchor(); yaw = ((Component)p).transform.eulerAngles.y + 180f; pitch = 6f; zoomIndex = 5; target.SetPerCameraVisibility(Plugin.RecordingCompat.Value); target.SetThirdPerson(on: true, cam); target.SetShadows(ui.ShadowsOn); ui.HasMoreCompany = HasMoreCompany; ui.CosmeticsOn = CosmeticsVisible; target.SetCosmeticsVisible(CosmeticsVisible); LockGameInput(locked: true); Active = true; ApplyCameraPose(); AudioSystem.PlayOpen(); if (Plugin.FreezePose.Value) { ((MonoBehaviour)this).StartCoroutine(FreezePoseSoon()); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to open the paint editor: {arg}"); Exit(); } } public void Exit() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } Active = false; try { AudioSystem.PlayClose(); target?.EndStroke(); target?.SetTPose(on: false); target?.SetFlatView(on: false); ui.TPoseOn = false; ui.FlatViewOn = false; ui.SetPresetsOpen(open: false); UnsubscribeText(); target?.SetThirdPerson(on: false, cam); if (Plugin.AutoSave.Value) { target?.Save(); } PublishPaint(); if ((Object)(object)cam != (Object)null) { ((Component)cam).transform.localPosition = camLocalPos; ((Component)cam).transform.localRotation = camLocalRot; cam.nearClipPlane = camNear; cam.fieldOfView = camFov; } } catch (Exception arg) { Plugin.Log.LogError((object)$"Error while closing the paint editor: {arg}"); } finally { LockGameInput(locked: false); ThawPose(); } } private void PublishPaint() { try { if (target != null && target.TryGetSnapshot(out var albedoPixels, out var maskPixels, out var textureSize)) { ChameleonNet.PublishLocal(albedoPixels, maskPixels, textureSize); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Publishing paint to the lobby failed: {arg}"); } } private IEnumerator FreezePoseSoon() { yield return (object)new WaitForSeconds(0.35f); if (Active && !((Object)(object)player == (Object)null) && !((Object)(object)player.playerBodyAnimator == (Object)null)) { savedAnimatorSpeed = player.playerBodyAnimator.speed; player.playerBodyAnimator.speed = 0f; animatorFrozen = true; } } private void ThawPose() { if (animatorFrozen) { animatorFrozen = false; if ((Object)(object)player != (Object)null && (Object)(object)player.playerBodyAnimator != (Object)null) { player.playerBodyAnimator.speed = ((savedAnimatorSpeed <= 0f) ? 1f : savedAnimatorSpeed); } } } private void LockGameInput(bool locked) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) try { IngamePlayerSettings instance = IngamePlayerSettings.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.playerInput != (Object)null && (Object)(object)instance.playerInput.actions != (Object)null) { if (locked) { instance.playerInput.actions.Disable(); } else { instance.playerInput.actions.Enable(); } } } catch { } if ((Object)(object)player != (Object)null) { try { player.disableLookInput = locked; player.disableMoveInput = locked; player.disableInteract = locked; if (player.playerActions != null) { MovementActions movement; if (locked) { player.playerActions.Disable(); movement = player.playerActions.Movement; ((MovementActions)(ref movement)).Disable(); } else { player.playerActions.Enable(); movement = player.playerActions.Movement; ((MovementActions)(ref movement)).Enable(); } } } catch { } } if (!locked) { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } else { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void HandleCameraInput(Mouse mouse, Keyboard kb, bool uiCaptured) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) if (((InputControl<float>)(object)((Vector2Control)mouse.scroll).y).ReadValue() != 0f) { float num = ((InputControl<float>)(object)((Vector2Control)mouse.scroll).y).ReadValue(); if (kb != null && (((ButtonControl)kb.leftAltKey).isPressed || ((ButtonControl)kb.rightAltKey).isPressed)) { float num2 = ((((ButtonControl)kb.leftShiftKey).isPressed || ((ButtonControl)kb.rightShiftKey).isPressed) ? 0.2f : 1f); ui.BrushRadius = Mathf.Clamp(ui.BrushRadius + ((num > 0f) ? num2 : (0f - num2)), 0.2f, 50f); } else if (!ui.TryScrollPresets(num) && !uiCaptured) { int num3 = zoomIndex; if (num > 0f && zoomIndex > 0) { zoomIndex--; } if (num < 0f && zoomIndex < ZoomSteps.Length - 1) { zoomIndex++; } } } if (mouse.middleButton.isPressed) { Vector2 val = ((InputControl<Vector2>)(object)((Pointer)mouse).delta).ReadValue(); if (kb != null && (((ButtonControl)kb.leftShiftKey).isPressed || ((ButtonControl)kb.rightShiftKey).isPressed)) { float num4 = Plugin.PanSensitivity.Value * ZoomSteps[zoomIndex]; panOffset += ((Component)cam).transform.right * ((0f - val.x) * num4) + ((Component)cam).transform.up * ((0f - val.y) * num4); panOffset = Vector3.ClampMagnitude(panOffset, 3.5f); } else { float value = Plugin.OrbitSensitivity.Value; float num5 = (Plugin.InvertOrbitY.Value ? (-1f) : 1f); yaw = Mathf.Repeat(yaw + val.x * value, 360f); pitch = Mathf.Clamp(pitch - val.y * value * num5, -80f, 85f); } } } private void HandlePaintInput(Mouse mouse, Keyboard kb, Vector2 screenPos, bool uiCaptured) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) if (kb != null && !ui.CapturingText) { if (((ButtonControl)kb[Plugin.PickKey.Value]).isPressed && !uiCaptured) { pickingWithSpace = true; shouldPickScreen = true; pickScreenPos = screenPos; } else if (pickingWithSpace) { pickingWithSpace = false; ui.Remember(ui.Tint, ui.Metallic, ui.Smoothness); AudioSystem.PlaySample(); } bool flag = ((ButtonControl)kb.leftCtrlKey).isPressed || ((ButtonControl)kb.rightCtrlKey).isPressed; if (flag && ((ButtonControl)kb.zKey).wasPressedThisFrame) { RequestUndo(); } if (flag && ((ButtonControl)kb.rKey).wasPressedThisFrame) { RequestReset(); } Key value = Plugin.TPoseKey.Value; if (!flag && (int)value != 0 && ((ButtonControl)kb[value]).wasPressedThisFrame) { SetTPose(!ui.TPoseOn); AudioSystem.PlayClick(); } Key value2 = Plugin.FlatViewKey.Value; if (!flag && (int)value2 != 0 && ((ButtonControl)kb[value2]).wasPressedThisFrame) { SetFlatView(!ui.FlatViewOn); AudioSystem.PlayClick(); } Key value3 = Plugin.PresetsKey.Value; if (!flag && (int)value3 != 0 && ((ButtonControl)kb[value3]).wasPressedThisFrame) { ui.TogglePresets(); AudioSystem.PlayClick(); } } if (uiCaptured || mouse.middleButton.isPressed) { target.EndStroke(); return; } bool isPressed = mouse.rightButton.isPressed; bool isPressed2 = mouse.leftButton.isPressed; if (mouse.leftButton.wasPressedThisFrame || mouse.rightButton.wasReleasedThisFrame) { target.BeginStroke(); ui.Remember(ui.Tint, ui.Metallic, ui.Smoothness); ui.ClearWearing(); } if (isPressed2 || isPressed) { if (hoverValid) { target.StrokeTo(hoverHit, ui.Brush, isPressed && !isPressed2); } else { target.BreakStroke(); } } if ((mouse.leftButton.wasReleasedThisFrame || mouse.rightButton.wasReleasedThisFrame) && !mouse.leftButton.isPressed && !mouse.rightButton.isPressed) { target.EndStroke(); } } private void ExecuteScreenPick(Vector2 screenPos) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)$"[Eyedropper] Pick triggered at screenPos=({screenPos.x:0}, {screenPos.y:0}) [Screen: {Screen.width}x{Screen.height}]"); if (hoverValid) { target.SampleAt(hoverHit.UV, out var color, out var metallic, out var smoothness); Plugin.Log.LogInfo((object)$"[Eyedropper] Sampled own player paint at UV=({hoverHit.UV.x:0.000}, {hoverHit.UV.y:0.000}) -> Color={ToHex(color)} (RGB: {color.r:0.00},{color.g:0.00},{color.b:0.00}), Met={metallic:0.00}, Smooth={smoothness:0.00}"); ui.AdoptSample(color, metallic, smoothness, "own paint"); return; } Ray ray = BuildRay(screenPos); Plugin.Log.LogInfo((object)$"[Eyedropper] Firing MaterialProbe ray from origin=({((Ray)(ref ray)).origin.x:0.00},{((Ray)(ref ray)).origin.y:0.00},{((Ray)(ref ray)).origin.z:0.00}) dir=({((Ray)(ref ray)).direction.x:0.00},{((Ray)(ref ray)).direction.y:0.00},{((Ray)(ref ray)).direction.z:0.00})"); if (MaterialProbe.Sample(ray, ((Object)(object)player != (Object)null) ? ((Component)player).transform : null, out var color2, out var metallic2, out var smoothness2, out var what)) { Plugin.Log.LogInfo((object)$"[Eyedropper] MaterialProbe adopted: {what} -> Color={ToHex(color2)} (RGB: {color2.r:0.00},{color2.g:0.00},{color2.b:0.00}), Met={metallic2:0.00}, Smooth={smoothness2:0.00}"); ui.AdoptSample(color2, metallic2, smoothness2, what); } else { Plugin.Log.LogInfo((object)"[Eyedropper] MaterialProbe did not find readable mesh UV. Starting ReadScreenPixel coroutine..."); if (!(Time.unscaledTime - lastScreenRead < 0.06f)) { lastScreenRead = Time.unscaledTime; ((MonoBehaviour)this).StartCoroutine(ReadScreenPixel(screenPos)); } } } private IEnumerator ReadScreenPixel(Vector2 screenPos) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return (object)new WaitForEndOfFrame(); Texture2D tex = null; RenderTexture prev = RenderTexture.active; RenderTexture tempRt = null; try { int px = Mathf.Clamp(Mathf.RoundToInt(screenPos.x), 0, Screen.width - 1); int py = Mathf.Clamp(Mathf.RoundToInt(screenPos.y), 0, Screen.height - 1); tex = new Texture2D(1, 1, (TextureFormat)4, false, false); _ = Color.black; Color col; if ((Object)(object)cam != (Object)null && (Object)(object)cam.targetTexture != (Object)null) { tempRt = RenderTexture.GetTemporary(1, 1, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); ((Texture)tempRt).filterMode = (FilterMode)0; float normX = Mathf.Clamp01(screenPos.x / (float)Screen.width); float normY = Mathf.Clamp01(screenPos.y / (float)Screen.height); Vector2 scale = new Vector2(1f / (float)Mathf.Max(1, ((Texture)cam.targetTexture).width), 1f / (float)Mathf.Max(1, ((Texture)cam.targetTexture).height)); Vector2 offset = new Vector2(normX - scale.x * 0.5f, normY - scale.y * 0.5f); Graphics.Blit((Texture)(object)cam.targetTexture, tempRt, scale, offset); RenderTexture.active = tempRt; tex.ReadPixels(new Rect(0f, 0f, 1f, 1f), 0, 0); tex.Apply(); col = tex.GetPixel(0, 0); } else { RenderTexture.active = null; tex.ReadPixels(new Rect((float)px, (float)py, 1f, 1f), 0, 0); tex.Apply(); col = tex.GetPixel(0, 0); } col.a = 1f; Plugin.Log.LogInfo((object)$"[Eyedropper ReadScreenPixel] Sampled screen at ({px}, {py}) -> Color={ToHex(col)} (Raw RGBA: {col.r:0.000}, {col.g:0.000}, {col.b:0.000}, {col.a:0.000}), LinearSpace={QualitySettings.activeColorSpace}"); ui.AdoptSample(col, ui.Metallic, ui.Smoothness, "screen"); } catch (Exception ex) { Exception e = ex; Plugin.Log.LogWarning((object)("[Eyedropper ReadScreenPixel FAILED]: " + e.Message + "\n" + e.StackTrace)); } finally { RenderTexture.active = prev; if ((Object)(object)tempRt != (Object)null) { RenderTexture.ReleaseTemporary(tempRt); } if ((Object)(object)tex != (Object)null) { Object.Destroy((Object)(object)tex); } } } private static string ToHex(Color c) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(new Color(Mathf.Clamp01(c.r), Mathf.Clamp01(c.g), Mathf.Clamp01(c.b))); } private void OnGUI() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (Active) { if (shouldPickScreen) { shouldPickScreen = false; ExecuteScreenPick(pickScreenPos); } ui.Draw(this, target); } } internal void RequestFill() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (target != null) { ui.Remember(ui.Tint, ui.Metallic, ui.Smoothness); ui.ClearWearing(); target.FillAll(ui.Brush); AudioSystem.PlaySuit(); } } internal void RequestUndo() { target?.Undo(); AudioSystem.PlayClick(); } internal void RequestReset() { target?.ResetPaint(); ui.ClearWearing(); AudioSystem.PlaySuit(); } internal void RequestSave() { target?.Save(); AudioSystem.PlaySuit(); } internal void RequestLoad() { target?.Load(); AudioSystem.PlaySuit(); } internal void RequestClose() { Exit(); } internal void RequestSavePreset(string name) { if (Active && target != null && target.IsReady) { ((MonoBehaviour)this).StartCoroutine(SavePresetRoutine(name)); } } private IEnumerator SavePresetRoutine(string name) { yield return (object)new WaitForEndOfFrame(); Texture2D shot = CaptureModelShot(384); if (target == null || !target.TryGetSnapshot(out var albedo, out var mask, out var texSize)) { if ((Object)(object)shot != (Object)null) { Object.Destroy((Object)(object)shot); } ui.Announce("Nothing to save yet"); yield break; } SuitPreset saved = SuitPresets.Save(name, albedo, mask, texSize, shot); if (saved != null) { ui.OnPresetSaved(saved); ui.Announce("Saved '" + saved.Name + "'"); AudioSystem.PlaySuit(); yield break; } if ((Object)(object)shot != (Object)null) { Object.Destroy((Object)(object)shot); } ui.Announce("Saving the preset failed - see the log"); } internal void RequestApplyPreset(SuitPreset preset) { if (target != null && preset != null) { if (!SuitPresets.TryRead(preset, out var albedo, out var mask, out var size)) { ui.Announce("'" + preset.Name + "' could not be read"); AudioSystem.PlayClick(); } else if (target.ApplyLayers(albedo, mask, size)) { ui.Announce("Wearing '" + preset.Name + "'" + ((mask == null) ? " (colour only)" : "")); AudioSystem.PlaySuit(); } else { ui.Announce("'" + preset.Name + "' would not apply"); } } } private Texture2D CaptureModelShot(int height) { //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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_007d: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null || target == null) { return null; } if (!target.TryGetPosedBounds(out var bounds)) { return null; } int num = Mathf.RoundToInt((float)height * 0.75f); RenderTexture val = null; RenderTexture active = RenderTexture.active; RenderTexture targetTexture = cam.targetTexture; Vector3 position = ((Component)cam).transform.position; Quaternion rotation = ((Component)cam).transform.rotation; float fieldOfView = cam.fieldOfView; bool flatView = target.FlatView; Texture2D val2 = null; try { target.SetFlatView(on: true); PoseForPortrait(bounds); cam.aspect = 0.75f; val = RenderTexture.GetTemporary(num, height, 24, (RenderTextureFormat)0); cam.targetTexture = val; cam.Render(); RenderTexture.active = val; val2 = new Texture2D(num, height, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; val2.ReadPixels(new Rect(0f, 0f, (float)num, (float)height), 0, 0); val2.Apply(false); if (!CutOutBody(val2)) { Object.Destroy((Object)(object)val2); val2 = null; Plugin.Log.LogInfo((object)"[Presets] Preview came back empty; falling back to the paint's palette."); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Presets] Preview render failed (" + ex.Message + "); falling back to the paint's palette.")); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); val2 = null; } } finally { cam.targetTexture = targetTexture; RenderTexture.active = active; if ((Object)(object)val != (Object)null) { RenderTexture.ReleaseTemporary(val); } cam.fieldOfView = fieldOfView; cam.ResetAspect(); ((Component)cam).transform.SetPositionAndRotation(position, rotation); if (!flatView) { target.SetFlatView(on: false); } } return val2; } private void PoseForPortrait(Bounds body) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0082: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) //IL_00c4: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)player != (Object)null) ? ((Component)player).transform.forward : Vector3.forward); val.y = 0f; val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.forward); cam.fieldOfView = 34f; float num = Mathf.Tan(0.29670596f); float num2 = num * 0.75f; float num3 = Mathf.Max(((Bounds)(ref body)).extents.x, ((Bounds)(ref body)).extents.z); float num4 = Mathf.Max(((Bounds)(ref body)).extents.y / num, num3 / num2) * 1.14f; Vector3 val2 = ((Bounds)(ref body)).center + val * num4; ((Component)cam).transform.SetPositionAndRotation(val2, Quaternion.LookRotation(-val, Vector3.up)); } private bool CutOutBody(Texture2D shot) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_064f: Unknown result type (might be due to invalid IL or missing references) //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_069f: Unknown result type (might be due to invalid IL or missing references) //IL_06ba: Unknown result type (might be due to invalid IL or missing references) //IL_06df: Unknown result type (might be due to invalid IL or missing references) //IL_06e1: Unknown result type (might be due to invalid IL or missing references) if (!target.TryGetPosedGeometry(out var worldVertices, out var triangles)) { return false; } int width = ((Texture)shot).width; int height = ((Texture)shot).height; int num = width * 3; int num2 = height * 3; Matrix4x4 val = cam.projectionMatrix * CameraMath.ViewMatrix(cam); Vector3[] array = (Vector3[])(object)new Vector3[worldVertices.Length]; for (int i = 0; i + 2 < triangles.Length; i += 3) { int num3 = triangles[i]; int num4 = triangles[i + 1]; int num5 = triangles[i + 2]; Vector3 val2 = Vector3.Cross(worldVertices[num4] - worldVertices[num3], worldVertices[num5] - worldVertices[num3]); ref Vector3 reference = ref array[num3]; reference += val2; ref Vector3 reference2 = ref array[num4]; reference2 += val2; ref Vector3 reference3 = ref array[num5]; reference3 += val2; } for (int j = 0; j < array.Length; j++) { array[j] = ((Vector3)(ref array[j])).normalized; } Vector3[] array2 = (Vector3[])(object)new Vector3[worldVertices.Length]; for (int k = 0; k < worldVertices.Length; k++) { Vector4 val3 = val * new Vector4(worldVertices[k].x, worldVertices[k].y, worldVertices[k].z, 1f); if (val3.w <= 1E-05f) { array2[k] = new Vector3(0f, 0f, -1f); continue; } float num6 = 1f / val3.w; array2[k] = new Vector3((val3.x * num6 * 0.5f + 0.5f) * (float)num, (val3.y * num6 * 0.5f + 0.5f) * (float)num2, val3.w); } float[] array3 = new float[num * num2]; float[] array4 = new float[num * num2]; for (int l = 0; l < array3.Length; l++) { array3[l] = float.MaxValue; } Quaternion rotation = ((Component)cam).transform.rotation; Vector3 val4 = new Vector3(-0.45f, 0.62f, -1f); Vector3 key = rotation * ((Vector3)(ref val4)).normalized; Vector3 forward = ((Component)cam).transform.forward; long num7 = 0L; for (int m = 0; m + 2 < triangles.Length; m += 3) { int num8 = triangles[m]; int num9 = triangles[m + 1]; int num10 = triangles[m + 2]; Vector3 val5 = array2[num8]; Vector3 val6 = array2[num9]; Vector3 val7 = array2[num10]; if (!(val5.z < 0f) && !(val6.z < 0f) && !(val7.z < 0f)) { num7 += ShadeTriangle(array3, array4, num, num2, val5, val6, val7, array[num8], array[num9], array[num10], key, forward); } } if (num7 < (long)num * (long)num2 / 900) { Plugin.Log.LogWarning((object)$"[Presets] Silhouette covered almost nothing ({num7} subpixels of {(long)num * (long)num2})."); return false; } double num11 = 0.0; long num12 = 0L; for (int n = 0; n < array4.Length; n++) { if (array3[n] != float.MaxValue) { num11 += (double)array4[n]; num12++; } } float num13 = ((num12 > 0 && num11 > 1E-06) ? ((float)((double)num12 / num11)) : 1f); Color32[] pixels = shot.GetPixels32(); byte[] array5 = new byte[width * height]; float[] array6 = new float[width * height]; int[] array7 = new int[256]; long num14 = 0L; int num15 = 255; int num16 = 0; for (int num17 = 0; num17 < height; num17++) { for (int num18 = 0; num18 < width; num18++) { int num19 = 0; float num20 = 0f; for (int num21 = 0; num21 < 3; num21++) { int num22 = (num17 * 3 + num21) * num + num18 * 3; for (int num23 = 0; num23 < 3; num23++) { if (array3[num22 + num23] != float.MaxValue) { num19++; num20 += array4[num22 + num23]; } } } int num24 = num17 * width + num18; array5[num24] = (byte)(num19 * 255 / 9); array6[num24] = ((num19 > 0) ? (num20 / (float)num19 * num13) : 1f); Color32 val8 = pixels[num24]; int num25 = val8.r * 77 + val8.g * 150 + val8.b * 29 >> 8; if (num25 < num15) { num15 = num25; } if (num25 > num16) { num16 = num25; } if (num19 == 9) { array7[num25]++; num14++; } } } if (num14 == 0L || num16 - num15 < 4) { Plugin.Log.LogWarning((object)$"[Presets] Render came back blank (body px {num14}, frame range {num15}-{num16})."); return false; } byte[] array8 = BuildLevels(array7, num14); if (array8 == null) { return false; } for (int num26 = 0; num26 < pixels.Length; num26++) { Color32 val9 = pixels[num26]; byte b = array5[num26]; if (b == 0) { val9.r = 0; val9.g = 0; val9.b = 0; } else { val9.r = Shaded(array8[val9.r], array6[num26]); val9.g = Shaded(array8[val9.g], array6[num26]); val9.b = Shaded(array8[val9.b], array6[num26]); } val9.a = b; pixels[num26] = val9; } shot.SetPixels32(pixels); shot.Apply(false); return true; } private byte[] BuildLevels(int[] histogram, long inside) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) double num = 0.0; for (int i = 0; i < 256; i++) { if (histogram[i] > 0) { num += (double)((float)histogram[i] * Mathf.Pow((float)i / 255f, 2.2f)); } } num /= (double)inside; if (!target.TryGetSnapshot(out var albedoPixels, out var _, out var _) || albedoPixels == null) { return null; } double num2 = 0.0; long num3 = 0L; int num4 = Mathf.Max(1, albedoPixels.Length / 60000); for (int j = 0; j < albedoPixels.Length; j += num4) { Color32 val = albedoPixels[j]; float num5 = ((float)(int)val.r * 0.299f + (float)(int)val.g * 0.587f + (float)(int)val.b * 0.114f) / 255f; num2 += (double)Mathf.Pow(num5, 2.2f); num3++; } if (num3 == 0) { return null; } num2 /= (double)num3; float num6 = ((num > 1E-06) ? ((float)(num2 / num)) : 1f); num6 = Mathf.Clamp(num6, 0.05f, 64f); float num7 = (float)num * num6; if (num7 < 0.012f && num > 1E-06) { num6 = 0.012f / (float)num; } byte[] array = new byte[256]; for (int k = 0; k < 256; k++) { float num8 = Mathf.Pow((float)k / 255f, 2.2f) * num6; if (num8 > 0.7f) { num8 = 0.7f + (num8 - 0.7f) / (1f + (num8 - 0.7f) * 2.2f); } array[k] = (byte)Mathf.Clamp(Mathf.RoundToInt(Mathf.Pow(Mathf.Min(num8, 1f), 0.45454544f) * 255f), 0, 255); } return array; } private static long ShadeTriangle(float[] depth, float[] shade, int width, int height, Vector3 a, Vector3 b, Vector3 c, Vector3 na, Vector3 nb, Vector3 nc, Vector3 key, Vector3 eye) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, Mathf.FloorToInt(Mathf.Min(a.x, Mathf.Min(b.x, c.x)))); int num2 = Mathf.Min(width - 1, Mathf.CeilToInt(Mathf.Max(a.x, Mathf.Max(b.x, c.x)))); int num3 = Mathf.Max(0, Mathf.FloorToInt(Mathf.Min(a.y, Mathf.Min(b.y, c.y)))); int num4 = Mathf.Min(height - 1, Mathf.CeilToInt(Mathf.Max(a.y, Mathf.Max(b.y, c.y)))); if (num > num2 || num3 > num4) { return 0L; } float num5 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); if (Mathf.Abs(num5) < 1E-06f) { return 0L; } float num6 = 1f / num5; long num7 = 0L; for (int i = num3; i <= num4; i++) { float num8 = (float)i + 0.5f; int num9 = i * width; for (int j = num; j <= num2; j++) { float num10 = (float)j + 0.5f; float num11 = ((b.x - a.x) * (num8 - a.y) - (b.y - a.y) * (num10 - a.x)) * num6; float num12 = ((c.x - b.x) * (num8 - b.y) - (c.y - b.y) * (num10 - b.x)) * num6; float num13 = ((a.x - c.x) * (num8 - c.y) - (a.y - c.y) * (num10 - c.x)) * num6; if (num11 < 0f || num12 < 0f || num13 < 0f) { continue; } int num14 = num9 + j; float num15 = a.z * num12 + b.z * num13 + c.z * num11; if (!(num15 >= depth[num14])) { if (depth[num14] == float.MaxValue) { num7++; } depth[num14] = num15; Vector3 val = na * num12 + nb * num13 + nc * num11; Vector3 val2 = ((Vector3)(ref val)).normalized; if (Vector3.Dot(val2, eye) > 0f) { val2 = -val2; } float num16 = Mathf.Max(0f, Vector3.Dot(val2, key)); float num17 = Mathf.Max(0f, Vector3.Dot(val2, -key)); shade[num14] = 0.37f + 0.84f * num16 + 0.12f * num17; } } } return num7; } private static byte Shaded(byte value, float light) { float num = Mathf.Pow((float)(int)value / 255f, 2.2f) * light; return (byte)Mathf.Clamp(Mathf.RoundToInt(Mathf.Pow(Mathf.Min(num, 1f), 0.45454544f) * 255f), 0, 255); } internal void SetShadows(bool on) { ui.ShadowsOn = on; target?.SetShadows(on); } internal void SetTPose(bool on) { if (target != null) { ui.TPoseOn = target.SetTPose(on); } } internal void SetFlatView(bool on) { if (target != null) { ui.FlatViewOn = target.SetFlatView(on); } } internal void SetCosmeticsVisible(bool on) { CosmeticsVisible = on; ui.CosmeticsOn = on; target?.SetCosmeticsVisible(on); ApplyGlobalCosmeticsVisibility(on); ui.Announce(on ? "Cosmetics: Shown" : "Cosmetics: Hidden"); } internal void ApplyGlobalCosmeticsVisibility(bool on) { try { MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>(true); foreach (MonoBehaviour val in array) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Name != "CosmeticInstance") { continue; } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { val2.enabled = on; } } } } catch { } } } public static class ChameleonNet { private class Incoming { public uint BlobId; public byte[] Buffer; public bool[] Got; public int Received; public int ChunkCount; } private class Outgoing { public ulong Target; public ulong Sender; public uint BlobId; public byte[] Blob; public int NextChunk; public int ChunkCount; } private struct Decoded { public ulong ClientId; public byte[] Planes; public int Size; public byte[] Blob; } private struct Packed { public byte[] Blob; public ulong Hash; } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnHello; public static HandleNamedMessageDelegate <1>__OnData; public static Action<ulong> <2>__OnClientDisconnect; } private const string MsgHello = "MC_Hello"; private const string MsgData = "MC_Data"; private const byte Protocol = 1; private const int ChunkHeader = 22; private const int ChunkPayload = 8192; private const int MaxChunks = 514; private static NetworkManager boundTo; private static bool handlersRegistered; private static bool saidHello; private static byte[] localBlob; private static ulong localHash; private static bool compressing; private static bool blobDirty; private static uint nextBlobId = 1u; private static readonly HashSet<ulong> moddedClients = new HashSet<ulong>(); private static readonly Dictionary<ulong, RemotePaint> remotes = new Dictionary<ulong, RemotePaint>(); private static readonly Dictionary<ulong, byte[]> cache = new Dictionary<ulong, byte[]>(); private static readonly Dictionary<ulong, Incoming> inbox = new Dictionary<ulong, Incoming>(); private static readonly Queue<Outgoing> outbox = new Queue<Outgoing>(); private static float budget; private static float lastTick; private static readonly ConcurrentQueue<Decoded> decoded = new ConcurrentQueue<Decoded>(); private static readonly Dictionary<ulong, Decoded> latest = new Dictionary<ulong, Decoded>(); private static readonly ConcurrentQueue<Packed> compressed = new ConcurrentQueue<Packed>(); private static readonly List<ulong> scratchIds = new List<ulong>(); private static int frame; private static NetworkManager Net { get { NetworkManager singleton = NetworkManager.Singleton; return ((Object)(object)singleton != (Object)null && singleton.IsListening) ? singleton : null; } } private static bool Enabled => Plugin.NetSync != null && Plugin.NetSync.Value; public static void Tick() { if (!Enabled) { if (handlersRegistered) { Unbind(); } return; } DrainCompressed(); NetworkManager net = Net; if ((Object)(object)net == (Object)null) { if (handlersRegistered) { Unbind(); } return; } if (net != boundTo) { Bind(net); } if (handlersRegistered) { Handshake(net); if (blobDirty) { blobDirty = !BroadcastLocal(net); } PumpOutbox(net); ApplyOneDecoded(); if (++frame % 60 == 0) { TickRemotes(); } } } private static void Bind(NetworkManager nm) { //IL_0023: 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_002e: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Unbind(); try { CustomMessagingManager customMessagingManager = nm.CustomMessagingManager; object obj = <>O.<0>__OnHello; if (obj == null) { HandleNamedMessageDelegate val = OnHello; <>O.<0>__OnHello = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("MC_Hello", (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessagingManager2 = nm.CustomMessagingManager; object obj2 = <>O.<1>__OnData; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnData; <>O.<1>__OnData = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("MC_Data", (HandleNamedMessageDelegate)obj2); nm.OnClientDisconnectCallback += OnClientDisconnect; boundTo = nm; handlersRegistered = true; saidHello = false; if (nm.IsServer) { moddedClients.Add(nm.LocalClientId); } if (localBlob != null) { blobDirty = true; } Plugin.Log.LogInfo((object)string.Format("[MC net] Bound as {0}, id {1}.", nm.IsServer ? "host" : "client", nm.LocalClientId)); } catch (Exception arg) { Plugin.Log.LogError((object)$"[MC net] Failed to register handlers: {arg}"); } } private static void Unbind() { if ((Object)(object)boundTo != (Object)null) { try { CustomMessagingManager customMessagingManager = boundTo.CustomMessagingManager; if (customMessagingManager != null) { customMessagingManager.UnregisterNamedMessageHandler("MC_Hello"); } CustomMessagingManager customMessagingManager2 = boundTo.CustomMessagingManager; if (customMessagingManager2 != null) { customMessagingManager2.UnregisterNamedMessageHandler("MC_Data"); } boundTo.OnClientDisconnectCallback -= OnClientDisconnect; } catch { } } foreach (RemotePaint value in remotes.Values) { value.Dispose(); } remotes.Clear(); moddedClients.Clear(); cache.Clear(); inbox.Clear(); outbox.Clear(); latest.Clear(); Decoded result; while (decoded.TryDequeue(out result)) { } boundTo = null; handlersRegistered = false; saidHello = false; } public static void Shutdown() { Unbind(); } private static void Handshake(NetworkManager nm) { if (!saidHello && !nm.IsServer && nm.IsConnectedClient) { SendHello(nm, 0uL); saidHello = true; } } private static void OnClientDisconnect(ulong clientId) { moddedClients.Remove(clientId); inbox.Remove(clientId); cache.Remove(clientId); latest.Remove(clientId); if (remotes.TryGetValue(clientId, out var value)) { value.Dispose(); remotes.Remove(clientId); } DropQueued((Outgoing o) => o.Target == clientId); NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && !singleton.IsServer && clientId == singleton.LocalClientId) { Unbind(); } } private static void DropQueued(Func<Outgoing, bool> drop) { if (outbox.Count == 0) { return; } int count = outbox.Count; for (int i = 0; i < count; i++) { Outgoing outgoing = outbox.Dequeue(); if (!drop(outgoing)) { outbox.Enqueue(outgoing); } } } public static void PublishLocal(Color32[] albedo, Color32[] mask, int srcSize) { if (!Enabled) { return; } if (compressing) { Plugin.Log.LogInfo((object)"[MC net] A publish is already packing; skipping this one."); return; } int num = ((Plugin.NetTextureSize != null) ? Plugin.NetTextureSize.Value : 512); byte[] planes = PaintCodec.ExtractPlanes(albedo, mask, srcSize, num); if (planes == null) { return; } ulong hash = PaintCodec.Hash(planes); if (hash == localHash && localBlob != null) { Plugin.Log.LogInfo((object)"[MC net] Paint unchanged since the last publish; nothing to send."); return; } int size = Mathf.Min(num, srcSize); compressing = true; Task.Run(delegate { try { compressed.Enqueue(new Packed { Blob = PaintCodec.Compress(planes, size), Hash = hash }); } catch (Exception ex) { Plugin.Log.LogError((object)("[MC net] Compression failed: " + ex.Message)); compressed.Enqueue(new Packed { Blob = null, Hash = 0uL }); } }); } private static void DrainCompressed() { Packed result; while (compressed.TryDequeue(out result)) { compressing = false; if (result.Blob != null && result.Blob.Length != 0) { if (result.Blob.Length > 4194304) { Plugin.Log.LogWarning((object)$"[MC net] Packed suit is {result.Blob.Length / 1024} KB, over the limit; not sending."); continue; } localBlob = result.Blob; localHash = result.Hash; blobDirty = true; Plugin.Log.LogInfo((object)$"[MC net] Paint packed to {(float)result.Blob.Length / 1024f:0.0} KB, queued for the lobby."); } } } private static bool BroadcastLocal(NetworkManager nm) { if (localBlob == null) { return true; } if (nm.IsServer) { cache[nm.LocalClientId] = localBlob; foreach (ulong moddedClient in moddedClients) { if (moddedClient != nm.LocalClientId) { Enqueue(moddedClient, nm.LocalClientId, localBlob); } } return true; } if (!saidHello || !nm.IsConnectedClient) { return false; } Enqueue(0uL, nm.LocalClientId, localBlob); return true; } private static void Enqueue(ulong target, ulong sender, byte[] blob) { if (blob == null) { return; } int num = (blob.Length + 8192 - 1) / 8192; if (num > 0 && num <= 514) { DropQueued((Outgoing o) => o.Target == target && o.Sender == sender); outbox.Enqueue(new Outgoing { Target = target, Sender = sender, BlobId = nextBlobId++, Blob = blob, NextChunk = 0, ChunkCount = num }); } } private static void PumpOutbox(NetworkManager nm) { float unscaledTime = Time.unscaledTime; float num = ((lastTick <= 0f) ? 0f : Mathf.Min(unscaledTime - lastTick, 0.5f)); lastTick = unscaledTime; int num2 = ((Plugin.NetUploadKBps != null) ? Plugin.NetUploadKBps.Value : 96); float num3 = (float)num2 * 1024f; budget = Mathf.Min(budget + num * num3, num3); while (outbox.Count > 0) { Outgoing outgoing = outbox.Peek(); int num4 = outgoing.NextChunk * 8192; int num5 = Mathf.Min(8192, outgoing.Blob.Length - num4); if (num5 <= 0) { outbox.Dequeue(); continue; } float num6 = num5 + 22; if (budget < num6) { break; } if (!SendChunk(nm, outgoing, num4, num5)) { outbox.Dequeue(); continue; } budget -= num6; if (++outgoing.NextChunk >= outgoing.ChunkCount) { outbox.Dequeue(); } } } private unsafe static bool SendChunk(NetworkManager nm, Outgoing o, int offset, int len) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00c9: Unknown result type (might be due to invalid IL or missing references) try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(22 + len + 8, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref o.Sender, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<uint>(ref o.BlobId, default(ForPrimitives)); int num = o.Blob.Length; ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ushort num2 = (ushort)o.NextChunk; ((FastBufferWriter)(ref val)).WriteValueSafe<ushort>(ref num2, default(ForPrimitives)); num2 = (ushort)o.ChunkCount; ((FastBufferWriter)(ref val)).WriteValueSafe<ushort>(ref num2, default(ForPrimitives)); num2 = (ushort)len; ((FastBufferWriter)(ref val)).WriteValueSafe<ushort>(ref num2, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(o.Blob, len, offset); nm.CustomMessagingManager.SendNamedMessage("MC_Data", o.Target, val, (NetworkDelivery)4); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[MC net] Dropping transfer to {o.Target}: {ex.Message}"); return false; } } private unsafe static void SendHello(NetworkManager nm, ulong target) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1); try { byte b = 1; ((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives)); nm.CustomMessagingManager.SendNamedMessage("MC_Hello", target, val, (NetworkDelivery)2); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[MC net] Hello to {target} failed: {ex.Message}"); } } private static void OnHello(ulong sender, FastBufferReader reader) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) try { byte b = default(byte); ((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives)); if (b != 1) { Plugin.Log.LogWarning((object)$"[MC net] Client {sender} runs protocol {b}, we run {(byte)1}; not syncing with them."); return; } NetworkManager net = Net; if ((Object)(object)net == (Object)null) { return; } moddedClients.Add(sender); if (net.IsServer) { SendHello(net, sender); int num = 0; foreach (KeyValuePair<ulong, byte[]> item in cache) { if (item.Key != sender) { Enqueue(sender, item.Key, item.Value); num++; } } Plugin.Log.LogInfo((object)$"[MC net] Client {sender} has the mod; sending {num} cached suit(s)."); } else if (localBlob != null) { blobDirty = true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[MC net] Malformed hello from {sender}: {ex.Message}"); } } private static void OnData(ulong sender, FastBufferReader reader) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0089: Unknown result type (might be due to invalid IL or missing references) NetworkManager net = Net; if ((Object)(object)net == (Object)null) { return; } try { ulong num = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives)); uint num2 = default(uint); ((FastBufferReader)(ref reader)).ReadValueSafe<uint>(ref num2, default(ForPrimitives)); int num3 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num3, default(ForPrimitives)); ushort num4 = default(ushort); ((FastBufferReader)(ref reader)).ReadValueSafe<ushort>(ref num4, default(ForPrimitives)); ushort num5 = default(ushort); ((FastBufferReader)(ref reader)).ReadValueSafe<ushort>(ref num5, default(ForPrimitives)); ushort num6 = default(ushort); ((FastBufferReader)(ref reader)).ReadValueSafe<ushort>(ref num6, default(ForPrimitives)); ulong num7 = (net.IsServer ? sender : num); if (num3 <= 0 || num3 > 4194304 || num5 <= 0 || num5 > 514 || num4 >= num5 || num6 <= 0 || num6 > 8192 || num4 * 8192 + num6 > num3) { return; } if (!inbox.TryGetValue(num7, out var value) || value.BlobId != num2 || value.Buffer.Length != num3) { Incoming incoming = new Incoming(); incoming.BlobId = num2; incoming.Buffer = new byte[num3]; incoming.Got = new bool[num5]; incoming.Received = 0; incoming.ChunkCount = num5; value = incoming; inbox[num7] = value; } if (!value.Got[num4]) { byte[] src = new byte[num6]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref src, (int)num6, 0); Buffer.BlockCopy(src, 0, value.Buffer, num4 * 8192, num6); value.Got[num4] = true; if (++value.Received >= value.ChunkCount) { inbox.Remove(num7); OnBlobComplete(num7, value.Buffer); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[MC net] Malformed chunk from {sender}: {ex.Message}"); } } private static void OnBlobComplete(ulong owner, byte[] blob) { Task.Run(delegate { try { if (!PaintCodec.Decompress(blob, out var planes, out var size)) { Plugin.Log.LogWarning((object)$"[MC net] Rejected an undecodable suit from {owner}."); } else { decoded.Enqueue(new Decoded { ClientId = owner, Planes = planes, Size = size, Blob = blob }); } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[MC net] Decode failed for {owner}: {ex.Message}"); } }); } private static void ApplyOneDecoded() { if (!decoded.TryDequeue(out var result)) { return; } NetworkManager net = Net; if ((Object)(object)net == (Object)null) { return; } if (net.IsServer) { cache[result.ClientId] = result.Blob; foreach (ulong moddedClient in moddedClients) { if (moddedClient != result.ClientId && moddedClient != net.LocalClientId) { Enqueue(moddedClient, result.ClientId, result.Blob); } } } if (result.ClientId != net.LocalClientId) { latest[result.ClientId] = result; TryApply(result.ClientId); } } private static void TryApply(ulong clientId) { if (!latest.TryGetValue(clientId, out var value)) { return; } PlayerControllerB val = FindPlayer(clientId); if ((Object)(object)val == (Object)null) { return; } if (!remotes.TryGetValue(clientId, out var value2)) { value2 = (remotes[clientId] = new RemotePaint(clientId)); } try { value2.Apply(val, value.Planes, value.Size); latest.Remove(clientId); Plugin.Log.LogInfo((object)$"[MC net] Applied {val.playerUsername}'s paint ({value.Size}px)."); } catch (Exception ex) { Plugin.Log.LogError((object)("[MC net] Failed to apply " + val.playerUsername + "'s paint: " + ex.Message)); } } private static void TickRemotes() { if (latest.Count > 0) { scratchIds.Clear(); scratchIds.AddRange(latest.Keys); for (int i = 0; i < scratchIds.Count; i++) { TryApply(scratchIds[i]); } } if (remotes.Count == 0) { return; } foreach (KeyValuePair<ulong, RemotePaint> remote in remotes) { PlayerControllerB val = FindPlayer(remote.Key); i