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 LethalKuchClient v2.5.0
LethalKuchClient.dll
Decompiled 5 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalKuchQOL.Features; using LethalKuchQOL.Lobby; using LethalKuchQOL.UI; using Microsoft.CodeAnalysis; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] [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 LethalKuchQOL { public static class Cfg { public static ConfigEntry<bool> SlotHotkeys; public static ConfigEntry<bool> FlashlightToggle; public static ConfigEntry<string> KeySlot1; public static ConfigEntry<string> KeySlot2; public static ConfigEntry<string> KeySlot3; public static ConfigEntry<string> KeySlot4; public static ConfigEntry<string> KeyFlashlight; public static ConfigEntry<string> KeyMenu; public static ConfigEntry<bool> ControlTips; public static ConfigEntry<bool> HoverTips; public static ConfigEntry<bool> VotingTips; public static ConfigEntry<bool> BuildModeTips; public static ConfigEntry<bool> DisableOutline; public static ConfigEntry<bool> DisableFog; public static ConfigEntry<bool> DisableHelmet; public static ConfigEntry<bool> DisableHud; public static ConfigEntry<bool> GraphicsEnabled; public static ConfigEntry<float> ResolutionScale; public static ConfigEntry<float> LodBias; public static ConfigEntry<int> AntiAliasing; public static ConfigEntry<int> TextureQuality; public static ConfigEntry<int> Anisotropic; public static ConfigEntry<int> FovOffset; public static ConfigEntry<bool> SellCommands; public static ConfigEntry<bool> SellShowItems; public static ConfigEntry<string> DontSellList; public static ConfigEntry<int> AmbientFogMode; public static ConfigEntry<int> InteriorFogMode; public static ConfigEntry<int> WeatherFogMode; public static ConfigEntry<float> AmbientFogDistance; public static ConfigEntry<float> InteriorFogThinness; public static ConfigEntry<float> WeatherFogThinness; public static ConfigEntry<float> InteriorFogAlpha; public static ConfigEntry<bool> InteriorFogCustomDensity; public static ConfigEntry<bool> InteriorFogCustomColor; public static ConfigEntry<bool> WeatherFogCustomDensity; public static ConfigEntry<string> InteriorFogColor; public static ConfigEntry<bool> NightVision; public static ConfigEntry<bool> ClearView; public static ConfigEntry<float> NightVisionStrength; public static void Bind(ConfigFile c) { //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Expected O, but got Unknown //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Expected O, but got Unknown //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Expected O, but got Unknown //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Expected O, but got Unknown //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Expected O, but got Unknown //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Expected O, but got Unknown //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Expected O, but got Unknown //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Expected O, but got Unknown //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Expected O, but got Unknown //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Expected O, but got Unknown //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Expected O, but got Unknown SlotHotkeys = c.Bind<bool>("Controls", "SlotHotkeys", true, "Number keys jump straight to item slots."); FlashlightToggle = c.Bind<bool>("Controls", "FlashlightToggle", true, "Toggle a pocketed flashlight with a key."); KeySlot1 = c.Bind<string>("Keys", "Slot1", "Digit1", "Unity InputSystem Key name. Rebind in the F12 menu."); KeySlot2 = c.Bind<string>("Keys", "Slot2", "Digit2", ""); KeySlot3 = c.Bind<string>("Keys", "Slot3", "Digit3", ""); KeySlot4 = c.Bind<string>("Keys", "Slot4", "Digit4", ""); KeyFlashlight = c.Bind<string>("Keys", "Flashlight", "F", ""); KeyMenu = c.Bind<string>("Keys", "Menu", "F12", "Opens the LethalKuchClient menu."); ControlTips = c.Bind<bool>("ControlTips", "ControlTipLines", true, "Bottom-left control tips show your real binds."); HoverTips = c.Bind<bool>("ControlTips", "HoverPrompts", true, "Crosshair prompts (Grab : [E]) show your real binds."); VotingTips = c.Bind<bool>("ControlTips", "VotingTips", true, "Leave-early / spectator vote prompts show your real binds."); BuildModeTips = c.Bind<bool>("ControlTips", "BuildModeTip", true, "Ship build-mode prompt shows your real binds."); DisableOutline = c.Bind<bool>("Visuals", "DisableOutline", false, "Remove the item/player outline custom pass."); DisableFog = c.Bind<bool>("Visuals", "DisableFog", false, "Disable the main post-processing volume (fog, grain, etc.)."); DisableHelmet = c.Bind<bool>("Visuals", "DisableHelmet", false, "Hide the helmet visor model."); DisableHud = c.Bind<bool>("Visuals", "DisableHud", false, "Hide inventory, sprint meter, battery, weight and quota HUD."); GraphicsEnabled = c.Bind<bool>("Graphics", "Enabled", true, "Apply the graphics settings below."); ResolutionScale = c.Bind<float>("Graphics", "ResolutionScale", 1f, new ConfigDescription("Internal render resolution multiplier. Vanilla is 1 (860x520).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 4f), Array.Empty<object>())); AntiAliasing = c.Bind<int>("Graphics", "AntiAliasing", 0, new ConfigDescription("0 None, 1 FXAA, 2 TAA, 3 SMAA.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>())); TextureQuality = c.Bind<int>("Graphics", "TextureQuality", 0, new ConfigDescription("Mipmap limit. 0 full res, 3 lowest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>())); LodBias = c.Bind<float>("Graphics", "LodBias", 1f, new ConfigDescription("Level-of-detail bias. Higher keeps detail further away.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 4f), Array.Empty<object>())); Anisotropic = c.Bind<int>("Graphics", "Anisotropic", 0, new ConfigDescription("0 game default, 1 disable, 2 force on.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); FovOffset = c.Bind<int>("Graphics", "FovOffset", 0, new ConfigDescription("Added to the camera field of view.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-10, 30), Array.Empty<object>())); SellCommands = c.Bind<bool>("Selling", "Enabled", true, "Terminal commands: sell <amount>, sell quota, sell all."); SellShowItems = c.Bind<bool>("Selling", "ShowFoundItems", true, "List the items that will be sold before confirming."); DontSellList = c.Bind<string>("Selling", "DontSell", "", "Comma-separated item names never to auto-sell."); AmbientFogMode = c.Bind<int>("Fog", "AmbientMode", 0, new ConfigDescription("Moon-wide sky/atmosphere fog on global volumes. 0 vanilla, 1 off, 2 custom distance.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); AmbientFogDistance = c.Bind<float>("Fog", "AmbientDistance", 2f, new ConfigDescription("Custom mode: multiplier on fog view distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>())); InteriorFogMode = c.Bind<int>("Fog", "InteriorMode", 0, new ConfigDescription("Facility fog. 0 vanilla (random chance), 1 off, 2 always on.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); InteriorFogCustomDensity = c.Bind<bool>("Fog", "InteriorCustomDensity", false, "Override interior fog thinness."); InteriorFogThinness = c.Bind<float>("Fog", "InteriorThinness", 5f, new ConfigDescription("Interior fog mean free path. Higher = thinner. Vanilla ~5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); InteriorFogCustomColor = c.Bind<bool>("Fog", "InteriorCustomColor", false, "Override interior fog colour."); InteriorFogColor = c.Bind<string>("Fog", "InteriorColor", "#261710", "Interior fog colour (hex)."); InteriorFogAlpha = c.Bind<float>("Fog", "InteriorAlpha", 1f, new ConfigDescription("Interior fog opacity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); WeatherFogMode = c.Bind<int>("Fog", "WeatherMode", 0, new ConfigDescription("Foggy-weather fog. 0 vanilla, 1 off.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>())); WeatherFogCustomDensity = c.Bind<bool>("Fog", "WeatherCustomDensity", false, "Override foggy-weather thinness."); WeatherFogThinness = c.Bind<float>("Fog", "WeatherThinness", 10f, new ConfigDescription("Foggy weather mean free path. Higher = thinner.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); NightVision = c.Bind<bool>("Visuals", "NightVision", false, "See in the dark: adds a shadowless light that follows your view. Only you see it."); NightVisionStrength = c.Bind<float>("Visuals", "NightVisionLux", 5f, new ConfigDescription("Night vision brightness in lux.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 50f), Array.Empty<object>())); ClearView = c.Bind<bool>("Fog", "ClearView", false, "One switch: removes all fog (sky, interior, weather) and hides rain/storm/dust weather visuals. Overrides the fog modes."); } } [BepInPlugin("ishred.LethalKuchClient", "LethalKuchClient", "2.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "ishred.LethalKuchClient"; public const string NAME = "LethalKuchClient"; public const string VERSION = "2.5.0"; internal static ManualLogSource Log; internal static Plugin Instance; public static void Instance_SaveConfig() { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Config.Save(); } } private void Awake() { //IL_0021: 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_0036: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0095: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Cfg.Bind(((BaseUnityPlugin)this).Config); Harmony val = new Harmony("ishred.LethalKuchClient"); val.PatchAll(typeof(FlashlightToggle)); val.PatchAll(typeof(ControlTips)); val.PatchAll(typeof(GraphicsTweaks)); val.PatchAll(typeof(SellCommands)); val.PatchAll(typeof(FogControl.Patches)); val.PatchAll(typeof(NightVision)); GameObject val2 = new GameObject("LethalKuchClient"); Object.DontDestroyOnLoad((Object)val2); ((Object)val2).hideFlags = (HideFlags)61; val2.AddComponent<SlotHotkeys>(); val2.AddComponent<Visuals>(); val2.AddComponent<FogControl>(); val2.AddComponent<NightVision>(); val2.AddComponent<SettingsPanel>(); Log.LogInfo((object)string.Format("{0} {1} loaded. Press {2} for the menu. Server mod installed: {3}", "LethalKuchClient", "2.5.0", KeyInput.Pretty(Cfg.KeyMenu.Value), LobbyBridge.Installed)); } } } namespace LethalKuchQOL.UI { public class SettingsPanel : MonoBehaviour { private static SettingsPanel inst; private int tab; private static readonly string[] Tabs = new string[6] { "Controls", "Visuals", "Fog", "Graphics", "Selling", "About" }; private GUIStyle panel; private GUIStyle title; private GUIStyle tabOn; private GUIStyle tabOff; private GUIStyle label; private GUIStyle hint; private GUIStyle toggleOn; private GUIStyle toggleOff; private GUIStyle section; private GUIStyle keyOn; private GUIStyle keyOff; private Vector2 scroll; private Texture2D texPanel; private Texture2D texCard; private Texture2D texAccent; private Texture2D texDim; private Texture2D texTabOn; private Texture2D texTabOff; private bool styled; private CursorLockMode prevLock; private bool prevLookDisabled; private ConfigEntry<string> capturing; public static bool Open { get; private set; } public static void Toggle() { if ((Object)(object)inst != (Object)null) { inst.SetOpen(!Open); } } private void Awake() { inst = this; } private unsafe void Update() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 if (capturing != null) { Key val = KeyInput.AnyPressed(); if ((int)val != 0) { if ((int)val != 60) { capturing.Value = (((int)val == 65) ? "None" : ((object)(*(Key*)(&val))/*cast due to .constrained prefix*/).ToString()); } capturing = null; } } else if (KeyInput.Pressed(Cfg.KeyMenu)) { Toggle(); } } private void SetOpen(bool open) { //IL_0025: 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_009a: Unknown result type (might be due to invalid IL or missing references) if (open == Open) { return; } Open = open; PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (open) { prevLock = Cursor.lockState; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; if ((Object)(object)val != (Object)null) { prevLookDisabled = val.disableLookInput; val.disableLookInput = true; } return; } if ((Object)(object)val != (Object)null) { val.disableLookInput = prevLookDisabled; } if ((Object)(object)val != (Object)null && !val.quickMenuManager.isMenuOpen && !val.inTerminalMenu) { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } else { Cursor.lockState = prevLock; } Plugin.Instance_SaveConfig(); } private static Texture2D Solid(Color c) { //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_000a: 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_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, c); val.Apply(); return val; } private void Style() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_0121: Expected O, but got Unknown //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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: 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_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01b7: Expected O, but got Unknown //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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: 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_01fa: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Expected O, but got Unknown //IL_0248: 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_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_028d: 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_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: 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_02dd: Expected O, but got Unknown //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: 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_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Expected O, but got Unknown //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Expected O, but got Unknown //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Expected O, but got Unknown //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Expected O, but got Unknown //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Expected O, but got Unknown if (!styled) { styled = true; texPanel = Solid(new Color(0.07f, 0.08f, 0.1f, 0.96f)); texCard = Solid(new Color(0.12f, 0.13f, 0.16f, 1f)); texAccent = Solid(new Color(1f, 0.47f, 0.16f, 1f)); texDim = Solid(new Color(0.22f, 0.23f, 0.27f, 1f)); texTabOn = Solid(new Color(0.18f, 0.19f, 0.23f, 1f)); texTabOff = Solid(new Color(0.1f, 0.11f, 0.13f, 1f)); GUIStyle val = new GUIStyle(GUI.skin.box); val.normal.background = texPanel; val.padding = new RectOffset(18, 18, 14, 14); panel = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1 }; val2.normal.textColor = new Color(1f, 0.55f, 0.25f); title = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; val3.normal.textColor = new Color(0.6f, 0.65f, 0.75f); val3.margin = new RectOffset(0, 0, 10, 2); section = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = 14 }; val4.normal.textColor = new Color(0.92f, 0.93f, 0.95f); val4.alignment = (TextAnchor)3; label = val4; GUIStyle val5 = new GUIStyle(GUI.skin.label) { fontSize = 11 }; val5.normal.textColor = new Color(0.55f, 0.58f, 0.65f); val5.wordWrap = true; hint = val5; GUIStyle val6 = new GUIStyle(GUI.skin.button) { fontSize = 14, fontStyle = (FontStyle)1, fixedHeight = 32f }; val6.normal.background = texTabOn; val6.normal.textColor = new Color(1f, 0.6f, 0.3f); val6.hover.background = texTabOn; val6.hover.textColor = new Color(1f, 0.6f, 0.3f); val6.active.background = texTabOn; tabOn = val6; GUIStyle val7 = new GUIStyle(tabOn) { fontStyle = (FontStyle)0 }; val7.normal.background = texTabOff; val7.normal.textColor = new Color(0.7f, 0.72f, 0.78f); val7.hover.background = texTabOn; val7.hover.textColor = Color.white; tabOff = val7; GUIStyle val8 = new GUIStyle(GUI.skin.button) { fixedWidth = 54f, fixedHeight = 24f, fontSize = 11, fontStyle = (FontStyle)1 }; val8.normal.background = texAccent; val8.normal.textColor = Color.black; val8.hover.background = texAccent; val8.hover.textColor = Color.black; val8.active.background = texAccent; toggleOn = val8; GUIStyle val9 = new GUIStyle(toggleOn); val9.normal.background = texDim; val9.normal.textColor = new Color(0.8f, 0.8f, 0.85f); val9.hover.background = texDim; val9.hover.textColor = Color.white; val9.active.background = texDim; toggleOff = val9; keyOn = new GUIStyle(toggleOn) { fixedWidth = 130f, fontSize = 12 }; keyOff = new GUIStyle(toggleOff) { fixedWidth = 130f, fontSize = 12 }; } } private void OnGUI() { //IL_003f: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_0138: Unknown result type (might be due to invalid IL or missing references) if (!Open) { return; } Style(); float num = 600f; float num2 = 620f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2); GUI.Box(val, GUIContent.none, panel); GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 14f, num - 36f, num2 - 28f)); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("LethalKuchClient", title, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.Label("v2.5.0 " + KeyInput.Pretty(Cfg.KeyMenu.Value) + " to close", hint, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) }); GUILayout.EndHorizontal(); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); for (int i = 0; i < Tabs.Length; i++) { if (GUILayout.Button(Tabs[i], (i == tab) ? tabOn : tabOff, Array.Empty<GUILayoutOption>())) { if (tab != i) { scroll = Vector2.zero; } tab = i; } } GUILayout.EndHorizontal(); GUILayout.Space(10f); scroll = GUILayout.BeginScrollView(scroll, false, false, Array.Empty<GUILayoutOption>()); switch (tab) { case 0: Controls(); break; case 1: VisualsTab(); break; case 2: FogTab(); break; case 3: GraphicsTab(); break; case 4: Selling(); break; default: About(); break; } GUILayout.EndScrollView(); GUILayout.EndArea(); } private void Controls() { GUILayout.Label("HOTKEYS", section, Array.Empty<GUILayoutOption>()); Toggle(Cfg.SlotHotkeys, "Item slot hotkeys", "Jump straight to a slot."); Toggle(Cfg.FlashlightToggle, "Flashlight toggle key", "Toggle a pocketed flashlight."); GUILayout.Label("KEYBINDS (click, then press a key. Esc cancels, Backspace unbinds)", section, Array.Empty<GUILayoutOption>()); KeyRow(Cfg.KeySlot1, "Item slot 1"); KeyRow(Cfg.KeySlot2, "Item slot 2"); KeyRow(Cfg.KeySlot3, "Item slot 3"); KeyRow(Cfg.KeySlot4, "Item slot 4"); KeyRow(Cfg.KeyFlashlight, "Flashlight"); KeyRow(Cfg.KeyMenu, "This menu"); GUILayout.Label("CONTROL TIPS", section, Array.Empty<GUILayoutOption>()); Toggle(Cfg.ControlTips, "Control tip lines", "Bottom-left tips show your real binds."); Toggle(Cfg.HoverTips, "Hover prompts", "Crosshair prompts like Grab : [E]."); Toggle(Cfg.VotingTips, "Vote prompts", "Leave-early and spectator vote prompts."); Toggle(Cfg.BuildModeTips, "Build mode prompt", "Confirm / Store keys in ship build mode."); } private void VisualsTab() { GUILayout.Label("POST-PROCESSING", section, Array.Empty<GUILayoutOption>()); Toggle(Cfg.DisableOutline, "Disable outline pass", "Removes the item and player outline effect."); Toggle(Cfg.DisableFog, "Disable main post-processing volume", "Kills all VolumeMain effects at once. For fog alone, use the Fog tab."); GUILayout.Label("HUD", section, Array.Empty<GUILayoutOption>()); Toggle(Cfg.DisableHelmet, "Hide helmet visor", "Removes the helmet model overlay."); Toggle(Cfg.DisableHud, "Hide HUD", "Inventory, sprint, battery, weight and quota."); GUILayout.Label("SEE IN THE DARK", section, Array.Empty<GUILayoutOption>()); Toggle(Cfg.NightVision, "Night vision", "Lights up everything you look at, inside and outside. Only you see it."); if (Cfg.NightVision.Value) { SliderF(Cfg.NightVisionStrength, "Brightness", 0.5f, 50f, 0.5f, (float v) => $"{v:0.0} lux"); } } private void FogTab() { Toggle(Cfg.ClearView, "CLEAR VIEW", "Removes all fog and weather visuals in one go. Overrides everything below."); if (Cfg.ClearView.Value) { return; } GUILayout.Label("AMBIENT / SKY FOG", section, Array.Empty<GUILayoutOption>()); SliderI(Cfg.AmbientFogMode, "Mode", 0, 2, (int v) => (new string[3] { "Vanilla", "Off", "Custom" })[v]); if (Cfg.AmbientFogMode.Value == 2) { SliderF(Cfg.AmbientFogDistance, "View distance", 0.25f, 10f, 0.25f, (float v) => $"{v:0.00}x"); } GUILayout.Label("INTERIOR FOG", section, Array.Empty<GUILayoutOption>()); SliderI(Cfg.InteriorFogMode, "Mode", 0, 2, (int v) => (new string[3] { "Vanilla", "Off", "Always" })[v]); if (Cfg.InteriorFogMode.Value != 1) { Toggle(Cfg.InteriorFogCustomDensity, "Custom thinness", "Override how thick the facility fog is."); if (Cfg.InteriorFogCustomDensity.Value) { SliderF(Cfg.InteriorFogThinness, "Thinness", 1f, 40f, 1f, (float v) => $"{v:0} (vanilla 5)"); } Toggle(Cfg.InteriorFogCustomColor, "Custom colour", "Hex colour and opacity for the fog."); if (Cfg.InteriorFogCustomColor.Value) { GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label("Colour", label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); string text = GUILayout.TextField(Cfg.InteriorFogColor.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); if (text != Cfg.InteriorFogColor.Value) { Cfg.InteriorFogColor.Value = text; } GUILayout.EndHorizontal(); SliderF(Cfg.InteriorFogAlpha, "Opacity", 0f, 1f, 0.05f, (float v) => $"{v:0.00}"); } } GUILayout.Label("FOGGY WEATHER", section, Array.Empty<GUILayoutOption>()); SliderI(Cfg.WeatherFogMode, "Mode", 0, 1, (int v) => (new string[2] { "Vanilla", "Off" })[v]); if (Cfg.WeatherFogMode.Value == 0) { Toggle(Cfg.WeatherFogCustomDensity, "Custom thinness", "Override the rolled fog density on foggy days."); if (Cfg.WeatherFogCustomDensity.Value) { SliderF(Cfg.WeatherFogThinness, "Thinness", 1f, 60f, 1f, (float v) => $"{v:0}"); } } GUILayout.Space(4f); GUILayout.Label("Changes apply within a second. Ambient 'Off' skips status-effect volumes (poison, drunk, underwater) so those still work.", hint, Array.Empty<GUILayoutOption>()); } private void GraphicsTab() { Toggle(Cfg.GraphicsEnabled, "Apply graphics tweaks", "Master switch for this tab."); GUILayout.Label("RENDERING", section, Array.Empty<GUILayoutOption>()); int num = (int)(0u | (SliderF(Cfg.ResolutionScale, "Resolution scale", 0.5f, 4f, 0.25f, (float v) => $"{v:0.00}x ({Mathf.RoundToInt(860f * v)}x{Mathf.RoundToInt(520f * v)})") ? 1u : 0u)) | (SliderI(Cfg.AntiAliasing, "Anti-aliasing", 0, 3, (int v) => (new string[4] { "None", "FXAA", "TAA", "SMAA" })[v]) ? 1 : 0); GUILayout.Label("QUALITY", section, Array.Empty<GUILayoutOption>()); int num2 = (int)((uint)num | (SliderI(Cfg.TextureQuality, "Texture quality", 0, 3, (int v) => (new string[4] { "Full", "Half", "Quarter", "Eighth" })[v]) ? 1u : 0u) | (SliderF(Cfg.LodBias, "LOD bias", 0.5f, 4f, 0.25f, (float v) => $"{v:0.00}") ? 1u : 0u)) | (SliderI(Cfg.Anisotropic, "Anisotropic filtering", 0, 2, (int v) => (new string[3] { "Default", "Off", "Force on" })[v]) ? 1 : 0); GUILayout.Label("CAMERA", section, Array.Empty<GUILayoutOption>()); if (((uint)num2 | (SliderI(Cfg.FovOffset, "FOV offset", -10, 30, (int v) => ((v >= 0) ? "+" : "") + v) ? 1u : 0u)) != 0) { GraphicsTweaks.MarkDirty(); } GUILayout.Space(6f); GUILayout.Label("Resolution scale above 1 sharpens the image at a GPU cost. TAA smooths edges but can blur; SMAA is a good middle ground.", hint, Array.Empty<GUILayoutOption>()); } private void Selling() { Toggle(Cfg.SellCommands, "Terminal sell commands", "sell <amount>, sell quota, sell all, sell list. Host only."); Toggle(Cfg.SellShowItems, "Show items before confirming", "Lists what will be sold."); GUILayout.Label("NEVER SELL (comma-separated item names)", section, Array.Empty<GUILayoutOption>()); string text = GUILayout.TextField(Cfg.DontSellList.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }); if (text != Cfg.DontSellList.Value) { Cfg.DontSellList.Value = text; } GUILayout.Space(8f); GUILayout.Label("Type SELL in the ship terminal at The Company for a command list. Only the host can execute sells; anyone can use SELL LIST.", hint, Array.Empty<GUILayoutOption>()); } private void About() { GUILayout.Label("LethalKuchClient combines item slot hotkeys, flashlight toggle, real-key control tips, post-processing and HUD toggles, graphics quality settings, and terminal sell commands into one client-side mod.", hint, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); GUILayout.Label("Keybinds are set on the Controls tab. All options save to BepInEx/config/ishred.LethalKuchClient.cfg when this menu closes.", hint, Array.Empty<GUILayoutOption>()); } private void Toggle(ConfigEntry<bool> e, string name, string desc) { GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Label(name, label, Array.Empty<GUILayoutOption>()); GUILayout.Label(desc, hint, Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); GUILayout.FlexibleSpace(); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); if (GUILayout.Button(e.Value ? "ON" : "OFF", e.Value ? toggleOn : toggleOff, Array.Empty<GUILayoutOption>())) { e.Value = !e.Value; } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private void KeyRow(ConfigEntry<string> e, string name) { GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label(name, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); GUILayout.FlexibleSpace(); bool flag = capturing == e; if (GUILayout.Button(flag ? "press a key..." : KeyInput.Pretty(e.Value), flag ? keyOn : keyOff, Array.Empty<GUILayoutOption>())) { capturing = (flag ? null : e); } GUILayout.EndHorizontal(); } private bool SliderF(ConfigEntry<float> e, string name, float min, float max, float step, Func<float, string> fmt) { GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label(name, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); float num = GUILayout.HorizontalSlider(e.Value, min, max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); num = Mathf.Round(num / step) * step; GUILayout.Label(fmt(num), label, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); if (!Mathf.Approximately(num, e.Value)) { e.Value = num; return true; } return false; } private bool SliderI(ConfigEntry<int> e, string name, int min, int max, Func<int, string> fmt) { GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label(name, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); int num = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)e.Value, (float)min, (float)max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) })); GUILayout.Label(fmt(num), label, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); if (num != e.Value) { e.Value = num; return true; } return false; } } } namespace LethalKuchQOL.Features { [HarmonyPatch] public static class ControlTips { private enum Ctx { Line, Hover, Vote } private class Rule { public string Action; public string Kbm; public string Pad; public Rule(string a, string k, string p) { Action = a; Kbm = k; Pad = p; } } private static readonly Regex Token = new Regex("\\[\\s*([A-Za-z][A-Za-z0-9-]*)\\s*\\]", RegexOptions.Compiled); private static readonly Regex CtrlPath = new Regex("^<([A-Za-z0-9]+)>/([A-Za-z0-9/]+)$", RegexOptions.Compiled); private static readonly Regex BuildConfirm = new Regex("Confirm: \\[\\s*\\w+\\s*\\]", RegexOptions.Compiled); private static readonly Regex BuildStore = new Regex("Store: \\[\\s*\\w+\\s*\\]", RegexOptions.Compiled); private static readonly Rule ConfirmRule = new Rule("ConfirmBuildMode", "<Keyboard>/v", null); private static readonly Rule StoreRule = new Rule("Delete", "<Keyboard>/x", null); private static readonly Dictionary<string, Rule> LineRules = new Dictionary<string, Rule> { ["G"] = new Rule("Discard", "<Keyboard>/g", "<Gamepad>/buttonEast"), ["E"] = new Rule("QEItemInteract", "<Keyboard>/e", "<Gamepad>/dpad/up"), ["Q"] = new Rule("QEItemInteract", "<Keyboard>/q", "<Gamepad>/dpad/down"), ["LMB"] = new Rule("Use", "<Mouse>/leftButton", "<Gamepad>/rightTrigger"), ["RMB"] = new Rule("ActivateItem", "<Mouse>/leftButton", "<Gamepad>/rightTrigger"), ["TAB"] = new Rule("UseUtilitySlot", "<Keyboard>/tab", "<Gamepad>/leftShoulder"), ["START"] = new Rule("OpenMenu", "<Keyboard>/escape", "<Gamepad>/start"), ["R-TRIGGER"] = new Rule("PingScan", "<Mouse>/rightButton", "<Gamepad>/rightShoulder") }; private static readonly Dictionary<string, Rule> HoverRules = new Dictionary<string, Rule> { ["G"] = new Rule("Discard", "<Keyboard>/g", "<Gamepad>/buttonEast"), ["E"] = new Rule("Interact", "<Keyboard>/e", "<Gamepad>/buttonWest"), ["LMB"] = new Rule("Interact", "<Keyboard>/e", "<Gamepad>/buttonWest"), ["RMB"] = new Rule("PingScan", "<Mouse>/rightButton", "<Gamepad>/rightShoulder"), ["Q"] = new Rule("QEItemInteract", "<Keyboard>/q", "<Gamepad>/dpad/down"), ["TAB"] = new Rule("UseUtilitySlot", "<Keyboard>/tab", "<Gamepad>/leftShoulder"), ["START"] = new Rule("OpenMenu", "<Keyboard>/escape", "<Gamepad>/start"), ["R-TRIGGER"] = new Rule("PingScan", "<Mouse>/rightButton", "<Gamepad>/rightShoulder") }; private static readonly Dictionary<string, Rule> VoteRules = new Dictionary<string, Rule> { ["RMB"] = new Rule("PingScan", "<Mouse>/rightButton", "<Gamepad>/rightShoulder"), ["R-TRIGGER"] = new Rule("PingScan", "<Mouse>/rightButton", "<Gamepad>/rightShoulder") }; private static readonly Dictionary<string, string> MouseNames = new Dictionary<string, string> { ["leftButton"] = "LMB", ["rightButton"] = "RMB", ["middleButton"] = "MMB", ["forwardButton"] = "Mouse4", ["backButton"] = "Mouse5", ["scroll/up"] = "Scroll Up", ["scroll/down"] = "Scroll Down", ["scroll/y"] = "Scroll" }; private static readonly Dictionary<string, string> KeyNames = new Dictionary<string, string> { ["tab"] = "TAB", ["space"] = "SPACE", ["escape"] = "ESC", ["enter"] = "ENTER", ["leftShift"] = "LSHIFT", ["rightShift"] = "RSHIFT", ["leftCtrl"] = "LCTRL", ["rightCtrl"] = "RCTRL", ["leftAlt"] = "LALT", ["rightAlt"] = "RALT", ["upArrow"] = "UP", ["downArrow"] = "DOWN", ["leftArrow"] = "LEFT", ["rightArrow"] = "RIGHT", ["slash"] = "/", ["comma"] = ",", ["period"] = ".", ["semicolon"] = ";", ["quote"] = "'", ["backquote"] = "`", ["minus"] = "-", ["equals"] = "=", ["leftBracket"] = "[", ["rightBracket"] = "]", ["backslash"] = "\\", ["backspace"] = "BACKSPACE", ["capsLock"] = "CAPS", ["delete"] = "DEL", ["home"] = "HOME", ["end"] = "END", ["pageUp"] = "PGUP", ["pageDown"] = "PGDN", ["insert"] = "INS" }; private static readonly Dictionary<string, string> PadNames = new Dictionary<string, string> { ["buttonSouth"] = "A", ["buttonEast"] = "B", ["buttonWest"] = "X", ["buttonNorth"] = "Y", ["dpad/up"] = "D-pad up", ["dpad/down"] = "D-pad down", ["dpad/left"] = "D-pad left", ["dpad/right"] = "D-pad right", ["rightTrigger"] = "R-Trigger", ["leftTrigger"] = "L-Trigger", ["rightShoulder"] = "R-shoulder", ["leftShoulder"] = "L-shoulder", ["start"] = "Start", ["select"] = "Select", ["leftStickPress"] = "L-stick", ["rightStickPress"] = "R-stick" }; private static bool Pad { get { if ((Object)(object)StartOfRound.Instance != (Object)null) { return StartOfRound.Instance.localPlayerUsingController; } return false; } } private static string Replace(string text, Ctx ctx) { if (string.IsNullOrEmpty(text) || text.IndexOf('[') < 0) { return text; } Dictionary<string, Rule> rules = ctx switch { Ctx.Vote => VoteRules, Ctx.Hover => HoverRules, _ => LineRules, }; bool pad = Pad; return Token.Replace(text, delegate(Match m) { if (!rules.TryGetValue(m.Groups[1].Value.ToUpperInvariant(), out var value)) { return m.Value; } string text2 = Display(value, pad); return (text2 != null) ? ("[" + text2 + "]") : m.Value; }); } private static string Display(Rule rule, bool pad) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) try { InputActionAsset actions = InputSystem.actions; InputAction val = ((actions != null) ? actions.FindAction(rule.Action, false) : null); if (val == null) { return null; } string text = (pad ? rule.Pad : rule.Kbm); InputBinding? val2 = null; Enumerator<InputBinding> enumerator = val.bindings.GetEnumerator(); try { while (enumerator.MoveNext()) { InputBinding current = enumerator.Current; if (((InputBinding)(ref current)).isComposite) { continue; } string effectivePath = ((InputBinding)(ref current)).effectivePath; if (!string.IsNullOrEmpty(effectivePath) && !(effectivePath == "[Disabled]") && effectivePath.StartsWith("<Gamepad>", StringComparison.OrdinalIgnoreCase) == pad) { if (text != null && string.Equals(((InputBinding)(ref current)).path, text, StringComparison.OrdinalIgnoreCase)) { val2 = current; break; } if (!val2.HasValue) { val2 = current; } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } object result; if (!val2.HasValue) { result = null; } else { InputBinding value = val2.Value; result = Normalize(((InputBinding)(ref value)).effectivePath); } return (string)result; } catch { return null; } } private static string Normalize(string path) { if (string.IsNullOrEmpty(path)) { return null; } Match match = CtrlPath.Match(path); if (match.Success) { string value = match.Groups[1].Value; string value2 = match.Groups[2].Value; switch (value) { case "Mouse": { if (!MouseNames.TryGetValue(value2, out var value5)) { return null; } return value5; } case "Keyboard": { if (!KeyNames.TryGetValue(value2, out var value4)) { if (value2.Length != 1) { return null; } return value2.ToUpperInvariant(); } return value4; } case "Gamepad": { if (!PadNames.TryGetValue(value2, out var value3)) { return null; } return value3; } } } string text = InputControlPath.ToHumanReadableString(path, (HumanReadableStringOptions)2, (InputControl)null); if (!string.IsNullOrWhiteSpace(text)) { return text.Trim(); } return null; } [HarmonyPatch(typeof(HUDManager), "ChangeControlTipMultiple")] [HarmonyPrefix] private static void TipMulti(ref string[] allLines) { if (Cfg.ControlTips.Value && allLines != null) { string[] array = (string[])allLines.Clone(); for (int i = 0; i < array.Length; i++) { array[i] = Replace(array[i], Ctx.Line); } allLines = array; } } [HarmonyPatch(typeof(HUDManager), "ChangeControlTipMultiple")] [HarmonyPostfix] private static void TipMultiPost(bool holdingItem) { if (Cfg.ControlTips.Value && holdingItem) { TextMeshProUGUI[] array = HUDManager.Instance?.controlTipLines; if (array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null) { ((TMP_Text)array[0]).text = Replace(((TMP_Text)array[0]).text, Ctx.Line); } } } [HarmonyPatch(typeof(HUDManager), "ChangeControlTip")] [HarmonyPrefix] private static void Tip(ref string changeTo) { if (Cfg.ControlTips.Value && changeTo != null) { changeTo = Replace(changeTo, Ctx.Line); } } [HarmonyPatch(typeof(PlayerControllerB), "SetHoverTipAndCurrentInteractTrigger")] [HarmonyPostfix] private static void Hover(PlayerControllerB __instance) { if (Cfg.HoverTips.Value) { TextMeshProUGUI cursorTip = __instance.cursorTip; if ((Object)(object)cursorTip != (Object)null && !string.IsNullOrEmpty(((TMP_Text)cursorTip).text) && ((TMP_Text)cursorTip).text.IndexOf('[') >= 0) { ((TMP_Text)cursorTip).text = Replace(((TMP_Text)cursorTip).text, Ctx.Hover); } } } [HarmonyPatch(typeof(HUDManager), "Update")] [HarmonyPostfix] private static void HudUpdate(HUDManager __instance) { if (Cfg.VotingTips.Value) { Fix(__instance.holdButtonToEndGameEarlyText, Ctx.Vote); } } [HarmonyPatch(typeof(HUDManager), "DisplaySpectatorVoteTip")] [HarmonyPostfix] private static void SpectatorTip(HUDManager __instance) { if (Cfg.VotingTips.Value) { Fix(__instance.spectatorTipText, Ctx.Vote); } } private static void Fix(TextMeshProUGUI t, Ctx c) { if (!((Object)(object)t == (Object)null) && !string.IsNullOrEmpty(((TMP_Text)t).text) && ((TMP_Text)t).text.IndexOf('[') >= 0) { string text = Replace(((TMP_Text)t).text, c); if (text != ((TMP_Text)t).text) { ((TMP_Text)t).text = text; } } } [HarmonyPatch(typeof(ShipBuildModeManager), "CreateGhostObjectAndHighlight")] [HarmonyPostfix] private static void BuildTip() { if (!Cfg.BuildModeTips.Value || Pad) { return; } TextMeshProUGUI val = HUDManager.Instance?.buildModeControlTip; if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((TMP_Text)val).text)) { string text = ((TMP_Text)val).text; string text2 = Display(ConfirmRule, pad: false); if (text2 != null) { text = BuildConfirm.Replace(text, "Confirm: [" + text2 + "]"); } string text3 = Display(StoreRule, pad: false); if (text3 != null) { text = BuildStore.Replace(text, "Store: [" + text3 + "]"); } if (text != ((TMP_Text)val).text) { ((TMP_Text)val).text = text; } } } [HarmonyPatch(typeof(IngamePlayerSettings), "UpdateGameToMatchSettings")] [HarmonyPostfix] private static void RefreshAfterRebind() { PlayerControllerB val = StartOfRound.Instance?.localPlayerController; if ((Object)(object)val != (Object)null && (Object)(object)val.currentlyHeldObjectServer != (Object)null) { val.currentlyHeldObjectServer.SetControlTipsForItem(); } } } [HarmonyPatch] public static class FlashlightToggle { [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] [HarmonyPostfix] private static void Clear(PlayerControllerB __instance) { __instance.pocketedFlashlight = null; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void ReadInput(PlayerControllerB __instance) { if (!Cfg.FlashlightToggle.Value || ((!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject)) && !__instance.isTestingPlayer) || __instance.inTerminalMenu || __instance.isTypingChat || !Application.isFocused) { return; } if (__instance.currentlyHeldObjectServer is FlashlightItem && (Object)(object)__instance.currentlyHeldObjectServer != (Object)(object)__instance.pocketedFlashlight) { __instance.pocketedFlashlight = __instance.currentlyHeldObjectServer; } if (SettingsPanel.Open) { return; } GrabbableObject pocketedFlashlight = __instance.pocketedFlashlight; FlashlightItem val = (FlashlightItem)(object)((pocketedFlashlight is FlashlightItem) ? pocketedFlashlight : null); if (val == null || !((GrabbableObject)val).isHeld || !KeyInput.Pressed(Cfg.KeyFlashlight)) { return; } try { ((GrabbableObject)val).UseItemOnClient(true); if (!(__instance.currentlyHeldObjectServer is FlashlightItem)) { ((Behaviour)val.flashlightBulbGlow).enabled = false; ((Behaviour)val.flashlightBulb).enabled = false; bool isBeingUsed = ((GrabbableObject)val).isBeingUsed; ((Behaviour)__instance.helmetLight).enabled = isBeingUsed; val.usingPlayerHelmetLight = isBeingUsed; val.PocketFlashlightServerRpc(isBeingUsed); } } catch { } } } public class FogControl : MonoBehaviour { private class FogOrig { public bool active; public bool enabled; public bool overrideState; public float meanFreePath; } [HarmonyPatch] public static class Patches { [HarmonyPatch(typeof(TimeOfDay), "SetWeatherBasedOnVariables")] [HarmonyPostfix] private static void AfterWeather(TimeOfDay __instance) { //IL_0021: 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_003e: 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) if (!((Object)(object)__instance.foggyWeather == (Object)null) && Cfg.WeatherFogCustomDensity.Value) { LocalVolumetricFogArtistParameters parameters = __instance.foggyWeather.parameters; parameters.meanFreePath = Cfg.WeatherFogThinness.Value; __instance.foggyWeather.parameters = parameters; } } [HarmonyPatch(typeof(RoundManager), "RefreshEnemiesList")] [HarmonyPostfix] private static void AfterLevelLoad(RoundManager __instance) { if (!((Object)(object)__instance.indoorFog == (Object)null)) { if (Cfg.ClearView.Value || Cfg.InteriorFogMode.Value == 1) { ((Component)__instance.indoorFog).gameObject.SetActive(false); } else if (Cfg.InteriorFogMode.Value == 2) { ((Component)__instance.indoorFog).gameObject.SetActive(true); } } } } private static readonly string[] StatusProfiles = new string[7] { "PoisonFilter", "DrunkFilter", "UnderwaterFilter", "FlashbangedFilter", "InsideFactorySkyVolume", "SeeingRedFilter", "InsanityVolume" }; private readonly Dictionary<Fog, FogOrig> ambientOrig = new Dictionary<Fog, FogOrig>(); private float indoorOrigPath = -1f; private float weatherOrigPath = -1f; private Color indoorOrigAlbedo; private Color weatherOrigAlbedo; private LocalVolumetricFog indoorRef; private LocalVolumetricFog weatherRef; private float t; private readonly List<Behaviour> hiddenFog = new List<Behaviour>(); private readonly List<Renderer> hiddenParticles = new List<Renderer>(); private void Update() { t += Time.unscaledDeltaTime; if (t < 1f) { return; } t = 0f; try { Ambient(); Interior(); Weather(); WeatherVisuals(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Fog apply: " + ex.Message)); } } private void WeatherVisuals() { TimeOfDay instance = TimeOfDay.Instance; if (!Cfg.ClearView.Value || (Object)(object)instance == (Object)null || instance.effects == null) { foreach (Behaviour item in hiddenFog) { if ((Object)(object)item != (Object)null) { item.enabled = true; } } foreach (Renderer hiddenParticle in hiddenParticles) { if ((Object)(object)hiddenParticle != (Object)null) { hiddenParticle.enabled = true; } } hiddenFog.Clear(); hiddenParticles.Clear(); return; } WeatherEffect[] effects = instance.effects; foreach (WeatherEffect val in effects) { if ((Object)(object)val?.effectObject == (Object)null) { continue; } ParticleSystemRenderer[] componentsInChildren = val.effectObject.GetComponentsInChildren<ParticleSystemRenderer>(true); foreach (ParticleSystemRenderer val2 in componentsInChildren) { if (((Renderer)val2).enabled) { ((Renderer)val2).enabled = false; hiddenParticles.Add((Renderer)(object)val2); } } LocalVolumetricFog[] componentsInChildren2 = val.effectObject.GetComponentsInChildren<LocalVolumetricFog>(true); foreach (LocalVolumetricFog val3 in componentsInChildren2) { if (((Behaviour)val3).enabled) { ((Behaviour)val3).enabled = false; hiddenFog.Add((Behaviour)(object)val3); } } } } private void Ambient() { int num = (Cfg.ClearView.Value ? 1 : Cfg.AmbientFogMode.Value); Volume[] array = Object.FindObjectsOfType<Volume>(); Fog val2 = default(Fog); foreach (Volume val in array) { if (!val.isGlobal || (Object)(object)val.sharedProfile == (Object)null) { continue; } string text = ((Object)val.sharedProfile).name ?? ""; bool flag = false; string[] statusProfiles = StatusProfiles; foreach (string value in statusProfiles) { if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (!flag && val.sharedProfile.TryGet<Fog>(ref val2)) { if (!ambientOrig.TryGetValue(val2, out var value2)) { Dictionary<Fog, FogOrig> dictionary = ambientOrig; Fog key = val2; FogOrig obj = new FogOrig { active = ((VolumeComponent)val2).active, enabled = ((VolumeParameter<bool>)(object)val2.enabled).value, overrideState = ((VolumeParameter)val2.enabled).overrideState, meanFreePath = ((VolumeParameter<float>)(object)val2.meanFreePath).value }; value2 = obj; dictionary[key] = obj; } if (num == 1) { ((VolumeComponent)val2).active = false; ((VolumeParameter<bool>)(object)val2.enabled).value = false; ((VolumeParameter)val2.enabled).overrideState = false; } else { ((VolumeComponent)val2).active = value2.active; ((VolumeParameter<bool>)(object)val2.enabled).value = value2.enabled; ((VolumeParameter)val2.enabled).overrideState = value2.overrideState; ((VolumeParameter<float>)(object)val2.meanFreePath).value = ((num == 2) ? (value2.meanFreePath * Cfg.AmbientFogDistance.Value) : value2.meanFreePath); } } } } private void Interior() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_0117: Unknown result type (might be due to invalid IL or missing references) RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.indoorFog == (Object)null) { return; } LocalVolumetricFog indoorFog = instance.indoorFog; if ((Object)(object)indoorRef != (Object)(object)indoorFog) { indoorRef = indoorFog; indoorOrigPath = indoorFog.parameters.meanFreePath; indoorOrigAlbedo = indoorFog.parameters.albedo; } int num = (Cfg.ClearView.Value ? 1 : Cfg.InteriorFogMode.Value); switch (num) { case 1: if (((Component)indoorFog).gameObject.activeSelf) { ((Component)indoorFog).gameObject.SetActive(false); } break; case 2: if (!((Component)indoorFog).gameObject.activeSelf) { ((Component)indoorFog).gameObject.SetActive(true); } break; } if (num != 1) { LocalVolumetricFogArtistParameters parameters = indoorFog.parameters; parameters.meanFreePath = (Cfg.InteriorFogCustomDensity.Value ? Cfg.InteriorFogThinness.Value : indoorOrigPath); Color albedo = default(Color); if (Cfg.InteriorFogCustomColor.Value && ColorUtility.TryParseHtmlString(Cfg.InteriorFogColor.Value, ref albedo)) { albedo.a = Cfg.InteriorFogAlpha.Value; parameters.albedo = albedo; } else { parameters.albedo = indoorOrigAlbedo; } indoorFog.parameters = parameters; } } private void Weather() { //IL_0026: 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_004f: 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_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_0073: 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_00d3: Unknown result type (might be due to invalid IL or missing references) TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.foggyWeather == (Object)null) { return; } LocalVolumetricFog foggyWeather = instance.foggyWeather; LocalVolumetricFogArtistParameters parameters = foggyWeather.parameters; if ((Object)(object)weatherRef != (Object)(object)foggyWeather || weatherOrigPath < 0f) { weatherRef = foggyWeather; weatherOrigPath = parameters.meanFreePath; weatherOrigAlbedo = parameters.albedo; } if (!Cfg.WeatherFogCustomDensity.Value) { weatherOrigPath = parameters.meanFreePath; } if ((Cfg.ClearView.Value ? 1 : Cfg.WeatherFogMode.Value) == 1) { if (((Component)foggyWeather).gameObject.activeSelf) { ((Component)foggyWeather).gameObject.SetActive(false); } return; } if (Cfg.WeatherFogCustomDensity.Value) { parameters.meanFreePath = Cfg.WeatherFogThinness.Value; } foggyWeather.parameters = parameters; } } [HarmonyPatch] public static class GraphicsTweaks { private static RenderTexture original; private static RenderTexture scaled; private static bool dirty = true; private static readonly List<Camera> cameras = new List<Camera>(); public static void MarkDirty() { dirty = true; } [HarmonyPatch(typeof(HUDManager), "Start")] [HarmonyPostfix] private static void OnHudStart() { dirty = true; } [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] [HarmonyPostfix] private static void LateUpdate(PlayerControllerB __instance) { if (!Cfg.GraphicsEnabled.Value) { return; } PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance != (Object)(object)val)) { if (Cfg.FovOffset.Value != 0 && !val.inTerminalMenu && (Object)(object)val.gameplayCamera != (Object)null) { val.gameplayCamera.fieldOfView = Mathf.Lerp(val.gameplayCamera.fieldOfView, val.targetFOV + (float)Cfg.FovOffset.Value, 6f * Time.deltaTime); } if (dirty) { ApplyNow(val); } } } private static void ApplyNow(PlayerControllerB local) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) dirty = false; try { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerScreenTexture == (Object)null || (Object)(object)local.gameplayCamera == (Object)null) { return; } if ((Object)(object)original == (Object)null) { original = local.gameplayCamera.targetTexture; } if ((Object)(object)original == (Object)null) { return; } float value = Cfg.ResolutionScale.Value; RenderTexture val; if (Mathf.Approximately(value, 1f)) { val = original; } else { if ((Object)(object)scaled != (Object)null) { scaled.Release(); Object.Destroy((Object)(object)scaled); } RenderTextureDescriptor descriptor = original.descriptor; ((RenderTextureDescriptor)(ref descriptor)).width = Mathf.RoundToInt((float)((Texture)original).width * value); ((RenderTextureDescriptor)(ref descriptor)).height = Mathf.RoundToInt((float)((Texture)original).height * value); scaled = new RenderTexture(descriptor) { name = "KuchQOL_Screen", filterMode = (FilterMode)1 }; scaled.Create(); val = scaled; } cameras.Clear(); Camera[] array = Object.FindObjectsOfType<Camera>(true); foreach (Camera val2 in array) { if ((Object)(object)val2.targetTexture == (Object)(object)original || ((Object)(object)scaled != (Object)null && (Object)(object)val2.targetTexture == (Object)(object)scaled)) { cameras.Add(val2); } } foreach (Camera camera in cameras) { camera.targetTexture = val; HDAdditionalCameraData component = ((Component)camera).GetComponent<HDAdditionalCameraData>(); if ((Object)(object)component != (Object)null) { component.antialiasing = (AntialiasingMode)Cfg.AntiAliasing.Value; } } instance.playerScreenTexture.texture = (Texture)(object)val; QualitySettings.globalTextureMipmapLimit = Cfg.TextureQuality.Value; QualitySettings.lodBias = Cfg.LodBias.Value; if (Cfg.Anisotropic.Value == 1) { QualitySettings.anisotropicFiltering = (AnisotropicFiltering)0; } else if (Cfg.Anisotropic.Value == 2) { QualitySettings.anisotropicFiltering = (AnisotropicFiltering)2; } Plugin.Log.LogInfo((object)$"Graphics applied: {((Texture)val).width}x{((Texture)val).height}, AA {Cfg.AntiAliasing.Value}, tex {Cfg.TextureQuality.Value}, lod {Cfg.LodBias.Value}"); } catch (Exception ex) { Plugin.Log.LogError((object)("Graphics apply failed: " + ex)); } } } public static class KeyInput { private static readonly Dictionary<string, Key> cache = new Dictionary<string, Key>(); public static Key Resolve(string name) { //IL_0026: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(name) || name == "None") { return (Key)0; } if (cache.TryGetValue(name, out var value)) { return value; } value = (Key)(Enum.TryParse<Key>(name, ignoreCase: true, out Key result) ? ((int)result) : 0); cache[name] = value; return value; } public static bool Pressed(ConfigEntry<string> bind) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) Keyboard current = Keyboard.current; if (current == null) { return false; } Key val = Resolve(bind.Value); if ((int)val != 0) { return ((ButtonControl)current[val]).wasPressedThisFrame; } return false; } public static Key AnyPressed() { //IL_0019: 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_0021: 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_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_005e: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.anyKey).wasPressedThisFrame) { Enumerator<KeyControl> enumerator = current.allKeys.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyControl current2 = enumerator.Current; if (((ButtonControl)current2).wasPressedThisFrame) { return current2.keyCode; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return (Key)0; } return (Key)0; } public unsafe static string Pretty(string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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) Key val = Resolve(name); if ((int)val == 0) { return "unbound"; } string text = ((object)(*(Key*)(&val))/*cast due to .constrained prefix*/).ToString(); if (text.StartsWith("Digit")) { return text.Substring(5); } if (text.StartsWith("Numpad")) { return "Num " + text.Substring(6); } return text; } } public static class LobbyBridge { public const string LobbyGuid = "ishred.LethalKuchServer"; public static bool Installed => Chainloader.PluginInfos.ContainsKey("ishred.LethalKuchServer"); public static bool Ready { get { if (Installed) { return ReadyImpl(); } return false; } } public static bool ClientSellAllowed { get { if (Ready) { return ClientSellAllowedImpl(); } return true; } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool ReadyImpl() { return (Object)(object)KuchNet.Instance != (Object)null; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool ClientSellAllowedImpl() { return KuchNet.Instance.AllowClientSell.Value; } [MethodImpl(MethodImplOptions.NoInlining)] public static void RequestSell(List<GrabbableObject> items) { KuchNet.Instance.RequestSell(items); } } public class NightVision : MonoBehaviour { private Light light; private HDAdditionalLightData hd; private void LateUpdate() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) int num; object obj; if (Cfg.NightVision.Value && (Object)(object)StartOfRound.Instance != (Object)null) { num = (((Object)(object)GameNetworkManager.Instance?.localPlayerController != (Object)null) ? 1 : 0); if (num != 0) { obj = StartOfRound.Instance.activeCamera; goto IL_0043; } } else { num = 0; } obj = null; goto IL_0043; IL_0043: Camera val = (Camera)obj; if (num == 0 || (Object)(object)val == (Object)null) { if ((Object)(object)light != (Object)null && ((Behaviour)light).enabled) { ((Behaviour)light).enabled = false; } return; } if ((Object)(object)light == (Object)null) { Create(); } ((Component)light).transform.rotation = ((Component)val).transform.rotation; float value = Cfg.NightVisionStrength.Value; if (!Mathf.Approximately(hd.intensity, value)) { hd.SetIntensity(value, (LightUnit)2); } if (!((Behaviour)light).enabled) { ((Behaviour)light).enabled = true; } } private void Create() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("KuchNightVision"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; light = val.AddComponent<Light>(); light.type = (LightType)1; light.shadows = (LightShadows)0; light.color = new Color(0.92f, 0.97f, 0.92f); hd = val.GetComponent<HDAdditionalLightData>() ?? val.AddComponent<HDAdditionalLightData>(); hd.affectsVolumetric = false; hd.EnableShadows(false); hd.SetIntensity(Cfg.NightVisionStrength.Value, (LightUnit)2); Plugin.Log.LogInfo((object)"Night vision light created."); } [HarmonyPatch(typeof(PlayerControllerB), "SetNightVisionEnabled")] [HarmonyPostfix] private static void After(PlayerControllerB __instance, bool isNotLocalClient) { if (Cfg.NightVision.Value && !((Object)(object)__instance.nightVision == (Object)null)) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val != (Object)null && (isNotLocalClient ? ((Object)(object)val.spectatedPlayerScript == (Object)(object)__instance) : ((Object)(object)__instance == (Object)(object)val))) { ((Behaviour)__instance.nightVision).enabled = true; } } } } [HarmonyPatch] public static class SellCommands { private static List<GrabbableObject> pending; private static float Rate => StartOfRound.Instance.companyBuyingRate; private static string[] DontSell => (from s in Cfg.DontSellList.Value.Split(',') select s.Trim() into s where s.Length > 0 select s).ToArray(); private static TerminalNode Node(string msg) { TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>(); obj.displayText = msg; obj.clearPreviousText = true; obj.maxCharactersToType = 50; return obj; } private static int Real(int v) { return (int)((float)v * Rate); } [HarmonyPatch(typeof(Terminal), "QuitTerminal")] [HarmonyPostfix] private static void OnQuit() { pending = null; } [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] [HarmonyPrefix] [HarmonyPriority(800)] private static bool Parse(Terminal __instance, ref TerminalNode __result) { if (!Cfg.SellCommands.Value) { return true; } string text = __instance.screenText.text; string[] array = text.Substring(Mathf.Max(0, text.Length - __instance.textAdded)).Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return true; } if (pending != null) { string value = array[0].ToLowerInvariant(); if ("confirm".StartsWith(value)) { __result = Confirm(); return false; } if ("deny".StartsWith(value)) { pending = null; __result = Node("Sell request cancelled.\n\n"); return false; } pending = null; return true; } if (!array[0].Equals("sell", StringComparison.OrdinalIgnoreCase)) { return true; } try { __result = Run(array.Skip(1).ToArray()); } catch (Exception ex) { Plugin.Log.LogError((object)ex); __result = Node("Sell command failed: " + ex.Message + "\n\n"); } return false; } private static TerminalNode Run(string[] a) { if (a.Length == 0 || a[0].Equals("help", StringComparison.OrdinalIgnoreCase)) { return Node("LethalKuchClient selling\n\n>SELL <amount>\nSell scrap worth at least <amount>.\n\n>SELL QUOTA\nSell just enough to meet the quota.\n\n>SELL ALL\nSell every scrap item on the ship.\n\n>SELL LIST\nShow sellable scrap on the ship.\n\n"); } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.inShipPhase) { return Node("You must be landed at The Company to sell.\n\n"); } if ((Object)(object)Object.FindObjectOfType<DepositItemsDesk>() == (Object)null) { return Node("You cannot sell on this moon.\n\n"); } List<GrabbableObject> list = ShipScrap(); if (a[0].Equals("list", StringComparison.OrdinalIgnoreCase)) { return Node($"Sellable scrap on ship: {list.Count} items, ${Real(list.Sum((GrabbableObject g) => g.scrapValue))} at {(int)(Rate * 100f)}%\n\n{ItemList(list)}\n\n"); } if (!NetworkManager.Singleton.IsHost && !LobbyBridge.Ready) { return Node(LobbyBridge.Installed ? "Lobby sync is not active (the host needs LethalKuchServer too). Only the host can sell right now.\n\n" : "Only the host can sell. For everyone to sell, host and clients install LethalKuchServer.\n\n"); } if (!NetworkManager.Singleton.IsHost && !LobbyBridge.ClientSellAllowed) { return Node("The host has disabled client selling (Lobby panel, F9).\n\n"); } if (list.Count == 0) { return Node("No sellable scrap found on the ship.\n\n"); } int result; if (a[0].Equals("all", StringComparison.OrdinalIgnoreCase)) { result = int.MaxValue; } else if (a[0].Equals("quota", StringComparison.OrdinalIgnoreCase)) { result = TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled; if (result <= 0) { return Node("Quota already fulfilled.\n\n"); } } else if (!int.TryParse(a[0], out result) || result <= 0) { return Node("Usage: sell <amount> | sell quota | sell all | sell list\n\n"); } List<GrabbableObject> list2 = ((result == int.MaxValue) ? list : Pick(list, result)); int num = Real(list2.Sum((GrabbableObject g) => g.scrapValue)); pending = list2; StringBuilder stringBuilder = new StringBuilder(); string arg = ((result == int.MaxValue || num >= result) ? "green" : "red"); stringBuilder.AppendLine($"Found {list2.Count} items worth <color={arg}>${num}</color>"); if (result != int.MaxValue) { stringBuilder.AppendLine($"Requested: ${result}"); } stringBuilder.AppendLine($"The Company is buying at {(int)(Rate * 100f)}%\n"); if (Cfg.SellShowItems.Value) { stringBuilder.AppendLine(ItemList(list2) + "\n"); } stringBuilder.AppendLine("Please CONFIRM or DENY.\n\n"); return Node(stringBuilder.ToString()); } private static TerminalNode Confirm() { List<GrabbableObject> list = pending; pending = null; DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>(); if ((Object)(object)val == (Object)null || list == null) { return Node("Nothing to sell.\n\n"); } list = list.Where((GrabbableObject g) => (Object)(object)g != (Object)null && !g.isHeld).ToList(); if (list.Count == 0) { return Node("Items are gone.\n\n"); } if (LobbyBridge.Ready) { LobbyBridge.RequestSell(list); } else { if (!NetworkManager.Singleton.IsHost) { return Node("Only the host can sell without LethalKuchServer.\n\n"); } ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(SellRoutine(val, list)); } return Node($"Selling {list.Count} items for ${Real(list.Sum((GrabbableObject g) => g.scrapValue))}...\n\n"); } private static IEnumerator SellRoutine(DepositItemsDesk desk, List<GrabbableObject> items) { foreach (GrabbableObject item in items) { NetworkObject component = ((Component)item).GetComponent<NetworkObject>(); if (!((Object)(object)component == (Object)null)) { item.EnablePhysics(false); item.EnableItemMeshes(false); ((Component)item).transform.SetParent(((Component)desk.deskObjectsContainer).transform); ((Component)item).transform.localPosition = Vector3.zero; desk.AddObjectToDeskServerRpc(NetworkObjectReference.op_Implicit(component)); } } yield return (object)new WaitForSeconds(0.5f); desk.SellItemsOnServer(); } private static List<GrabbableObject> ShipScrap() { List<GrabbableObject> list = new List<GrabbableObject>(((Component)StartOfRound.Instance.elevatorTransform).GetComponentsInChildren<GrabbableObject>()); AutoParentToShip[] array = Object.FindObjectsByType<AutoParentToShip>((FindObjectsSortMode)0); foreach (AutoParentToShip val in array) { if ((Object)(object)((Component)val).transform.parent == (Object)null) { list.AddRange(((Component)val).GetComponentsInChildren<GrabbableObject>()); } } string[] ban = DontSell; return (from g in list.Distinct() where (Object)(object)g != (Object)null && (Object)(object)g.itemProperties != (Object)null && g.itemProperties.isScrap && !g.isHeld && g.grabbable && g.scrapValue > 0 && !ban.Any((string b) => b.Equals(g.itemProperties.itemName, StringComparison.OrdinalIgnoreCase)) select g).ToList(); } private static List<GrabbableObject> Pick(List<GrabbableObject> scrap, int target) { int num = scrap.Sum((GrabbableObject g) => g.scrapValue); if (Real(num) < target) { return scrap; } int[] array = new int[num + 1]; array[0] = -1; for (int num2 = 0; num2 < scrap.Count; num2++) { int scrapValue = scrap[num2].scrapValue; for (int num3 = num; num3 >= scrapValue; num3--) { if (array[num3] == 0 && array[num3 - scrapValue] != 0) { array[num3] = num2 + 1; } } } int num4 = num; for (int num5 = 0; num5 <= num; num5++) { if (array[num5] != 0 && Real(num5) >= target) { num4 = num5; break; } } List<GrabbableObject> list = new List<GrabbableObject>(); int num6 = num4; while (num6 > 0) { int index = array[num6] - 1; list.Add(scrap[index]); num6 -= scrap[index].scrapValue; } return list; } private static string ItemList(List<GrabbableObject> items) { return string.Join("\n", from g in items group g by g.itemProperties.itemName into gr orderby gr.Sum((GrabbableObject x) => x.scrapValue) descending select string.Format("{0}{1}: ${2}", gr.Key, (gr.Count() > 1) ? $" x{gr.Count()}" : "", Real(gr.Sum((GrabbableObject x) => x.scrapValue)))); } } public class SlotHotkeys : MonoBehaviour { private static readonly MethodInfo SwitchToItemSlot = AccessTools.Method(typeof(PlayerControllerB), "SwitchToItemSlot", (Type[])null, (Type[])null); private static readonly MethodInfo SwitchItemSlotsServerRpc = AccessTools.Method(typeof(PlayerControllerB), "SwitchItemSlotsServerRpc", (Type[])null, (Type[])null); private static readonly FieldInfo TimeSinceSwitchingSlots = AccessTools.Field(typeof(PlayerControllerB), "timeSinceSwitchingSlots"); private static readonly FieldInfo ThrowingObject = AccessTools.Field(typeof(PlayerControllerB), "throwingObject"); private void Update() { if (Cfg.SlotHotkeys.Value && !SettingsPanel.Open && Application.isFocused) { if (KeyInput.Pressed(Cfg.KeySlot1)) { Select(0); } else if (KeyInput.Pressed(Cfg.KeySlot2)) { Select(1); } else if (KeyInput.Pressed(Cfg.KeySlot3)) { Select(2); } else if (KeyInput.Pressed(Cfg.KeySlot4)) { Select(3); } } } private static void Select(int target) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null || target < 0 || target >= val.ItemSlots.Length || ((!((NetworkBehaviour)val).IsOwner || !val.isPlayerControlled || (((NetworkBehaviour)val).IsServer && !val.isHostPlayerObject)) && !val.isTestingPlayer) || (float)TimeSinceSwitchingSlots.GetValue(val) < 0.3f || val.isGrabbingObjectAnimation || val.quickMenuManager.isMenuOpen || val.inSpecialInteractAnimation || (bool)ThrowingObject.GetValue(val) || val.isTypingChat || val.twoHanded || val.activatingItem || val.inTerminalMenu || ((val.jetpackControls || val.disablingJetpackControls) && (Object)(object)val.currentlyHeldObjectServer != (Object)null && val.currentlyHeldObjectServer.itemProperties.itemId == 13)) { return; } int currentItemSlot = val.currentItemSlot; int num = val.ItemSlots.Length; if (currentItemSlot != target) { int num2 = ((target - currentItemSlot) % num + num) % num; int num3 = num - num2; bool flag = num2 <= num3; int num4 = (flag ? num2 : num3); ShipBuildModeManager.Instance.CancelBuildMode(true); val.playerBodyAnimator.SetBool("GrabValidated", false); SwitchToItemSlot.Invoke(val, new object[2] { target, null }); for (int i = 0; i < num4; i++) { SwitchItemSlotsServerRpc.Invoke(val, new object[1] { flag }); } if ((Object)(object)val.currentlyHeldObjectServer != (Object)null) { ((Component)val.currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>().PlayOneShot(val.currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f); } TimeSinceSwitchingSlots.SetValue(val, 0f); } } } public class Visuals : MonoBehaviour { private float t; private void Update() { t += Time.unscaledDeltaTime; if (t < 0.5f) { return; } t = 0f; GameObject val = GameObject.Find("Systems"); if ((Object)(object)val == (Object)null) { return; } Transform root = val.transform.Find("Rendering"); Set(root, "CustomPass", !Cfg.DisableOutline.Value); Set(root, "VolumeMain", !Cfg.DisableFog.Value); Set(root, "PlayerHUDHelmetModel", !Cfg.DisableHelmet.Value); Transform val2 = val.transform.Find("UI/Canvas/IngamePlayerHUD"); if (!((Object)(object)val2 == (Object)null)) { bool active = !Cfg.DisableHud.Value; string[] array = new string[7] { "Inventory", "TopLeftCorner/SprintMeter", "TopLeftCorner/Batteries", "TopLeftCorner/WeightUI", "TopLeftCorner/Self", "TopLeftCorner/SelfRed", "BottomLeftCorner" }; foreach (string path in array) { Set(val2, path, active); } } } private static void Set(Transform root, string path, bool active) { Transform val = ((root != null) ? root.Find(path) : null); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf != active) { ((Component)val).gameObject.SetActive(active); } } } }