using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using AK; using Agents; using AirParticleSystem; using BepInEx.Unity.IL2CPP.Utils.Collections; using BoosterImplants; using CellMenu; using ChainedPuzzles; using Clonesoft.Json; using Clonesoft.Json.Linq; using Enemies; using FX_EffectSystem; using GameData; using Gear; using HarmonyLib; using IRF; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; using StateMachines; using Steamworks; using TMPro; using TheArchive.Core; using TheArchive.Core.Attributes; using TheArchive.Core.Attributes.Feature; using TheArchive.Core.Attributes.Feature.Members; using TheArchive.Core.Attributes.Feature.Patches; using TheArchive.Core.Attributes.Feature.Settings; using TheArchive.Core.FeaturesAPI; using TheArchive.Core.FeaturesAPI.Components; using TheArchive.Core.FeaturesAPI.Groups; using TheArchive.Core.FeaturesAPI.Settings; using TheArchive.Core.Localization; using TheArchive.Core.Managers; using TheArchive.Core.Models; using TheArchive.Features.Accessibility; using TheArchive.Features.Dev; using TheArchive.Interfaces; using TheArchive.Loader; using TheArchive.Utilities; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("2025.2.0")] [assembly: AssemblyInformationalVersion("2025.2.0")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("TheArchive.Essentials")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyProduct("TheArchive.Essentials")] [assembly: AssemblyTitle("TheArchive.Essentials")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2025.2.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } internal class ThisAssembly { public class Git { public class BaseVersion { public const string Major = "0"; public const string Minor = "0"; public const string Patch = "0"; } public class SemVer { public const string Major = "0"; public const string Minor = "0"; public const string Patch = "838"; public const string Label = ""; public const string DashLabel = ""; public const string Source = "Default"; } public const bool IsDirty = false; public const string IsDirtyString = "false"; public const string RepositoryUrl = "https://github.com/Tuesday1028/GTFO_TheArchive"; public const string Branch = "doing-things"; public const string Commit = "a4eb55a"; public const string Sha = "a4eb55a7e97569a44df6831acc6074b0f084b6eb"; public const string CommitDate = "2026-05-07T19:14:52+08:00"; public const string Commits = "838"; public const string Tag = ""; public const string BaseTag = ""; } } internal class ManifestInfo { internal const string TSName = "TheArchive_Essentials"; internal const string TSDescription = "That one massive GTFO Quality of Life mod."; internal const string TSVersion = "2025.2.0"; internal const string TSAuthor = "AuriRex"; internal const string TSWebsite = "https://github.com/AuriRex/GTFO_TheArchive"; } namespace TheArchive { [ArchiveModule("dev.AuriRex.gtfo.TheArchive.Essentials", "TheArchive_Essentials", "2025.2.0")] public class ArchiveEssentialsModule : IArchiveModule { public const string GUID = "dev.AuriRex.gtfo.TheArchive.Essentials"; public const string MOD_NAME = "TheArchive_Essentials"; public const string VERSION = "2025.2.0"; public ILocalizationService LocalizationService { get; set; } public IArchiveLogger Logger { get; set; } public void Init() { } } } namespace TheArchive.Features.Special { [RundownConstraint(/*Could not decode attribute arguments.*/)] public class AdBlock : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageRundown_New_ABC_Patch { public static void Postfix(CM_PageRundown_New __instance) { ToggleDOWImage(__instance); } } public override string Name => "AdBlock"; public override GroupBase Group => (GroupBase)(object)GroupManager.Special; public override string Description => "Removes the Den of Wolves button from the rundown screen."; public static bool IsEnabled { get; set; } public override void OnEnable() { if (Feature.DataBlocksReady) { ToggleDOWImage(MainMenuGuiLayer.Current.PageRundownNew); } } public override void OnDisable() { if (!Feature.IsApplicationQuitting) { ToggleDOWImage(MainMenuGuiLayer.Current.PageRundownNew, setActive: true); } } private static void ToggleDOWImage(CM_PageRundown_New __instance, bool setActive = false) { RectTransform movingContentHolder = ((CM_PageBase)__instance).m_movingContentHolder; object obj; if (movingContentHolder == null) { obj = null; } else { Transform childWithExactName = SharedUtils.GetChildWithExactName((Transform)(object)movingContentHolder, "PasteAndJoinOnLobbyID"); if (childWithExactName == null) { obj = null; } else { Transform childWithExactName2 = SharedUtils.GetChildWithExactName(childWithExactName, "ButtonGIF"); obj = ((childWithExactName2 != null) ? ((Component)childWithExactName2).gameObject : null); } } GameObject val = (GameObject)obj; if (!((Object)(object)val == (Object)null)) { OnEnabledListener component = val.GetComponent(); if ((Object)(object)component != (Object)null && setActive) { Object.Destroy((Object)(object)component); } else if ((Object)(object)component == (Object)null) { component = val.AddComponent(); OnEnabledListener obj2 = component; obj2.OnEnabledSelf = (Action)Delegate.Combine(obj2.OnEnabledSelf, new Action(OnButtonEnabled)); } val.SetActive(setActive); } } private static void OnButtonEnabled(GameObject go) { if (IsEnabled) { go.SetActive(false); } } } [EnableFeatureByDefault] internal class AltTabCounter : Feature { public class AltTabCounterSettings { public class AltTabCounterSettingsForReal { [FSHeader("ALT + TABs <3", true)] [FSReadOnly(true)] [FSDisplayName("Total Count")] [FSDescription("All time total of ALT + TABs")] public int TotalCount { get; set; } [FSReadOnly(true)] [FSDisplayName("This Session Count")] [FSDescription("ALT + TABs accumulated this session")] public int CurrentSessionCount { get; set; } [FSReadOnly(true)] [FSDisplayName("This Level Count")] [FSDescription("ALT + TABs accumulated this level")] public int CurrentWhileInLevelCount { get; set; } } [FSUseDynamicSubmenu] [FSDisplayName("ALT + TAB Counts")] public AltTabCounterSettingsForReal AltTabCounts { get; set; } = new AltTabCounterSettingsForReal(); } public override string Name => "Alt Tab Counter"; public override GroupBase Group => (GroupBase)(object)GroupManager.Special; public override string Description => "Counts the amount of times that the game went out of focus. (ALT + TAB)"; [FeatureConfig] public static AltTabCounterSettings Settings { get; set; } public static bool InLevel { get; private set; } public override void Init() { Settings.AltTabCounts.CurrentSessionCount = 0; } public override void OnApplicationFocusChanged(bool focus) { if (!focus) { Settings.AltTabCounts.TotalCount++; Settings.AltTabCounts.CurrentSessionCount++; if (InLevel) { Settings.AltTabCounts.CurrentWhileInLevelCount++; } Feature.MarkSettingsAsDirty(Settings); } } public void OnGameStateChanged(eGameStateName state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 InLevel = (int)state == 10; if (InLevel) { Settings.AltTabCounts.CurrentWhileInLevelCount = 0; Feature.MarkSettingsAsDirty(Settings); } } } public class HideFirstPersonItem : Feature { public class HideFirstPersonItemSettings { [FSDisplayName("Model Toggle Key")] [FSDescription("Key used to toggle the model.")] public KeyCode Key { get; set; } = (KeyCode)283; } public override string Name => "Weapon Model Toggle"; public override GroupBase Group => (GroupBase)(object)GroupManager.Special; public override string Description => "Forces the held item to be hidden.\nIntended for taking pictures.\n(Warning! This makes you unable to use or switch items until unhidden!)"; [FeatureConfig] public static HideFirstPersonItemSettings Settings { get; set; } public override void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) if ((int)FocusStateManager.CurrentState == 4 && Input.GetKeyDown(Settings.Key)) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent != (Object)null && (Object)(object)localPlayerAgent.FPItemHolder != (Object)null) { localPlayerAgent.FPItemHolder.ForceItemHidden = !localPlayerAgent.FPItemHolder.ForceItemHidden; } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class MuteSpeak : Feature { private static PlayerAgent _localPlayerAgent; public override string Name => "Mute Speak"; public override GroupBase Group => (GroupBase)(object)GroupManager.Special; public override string Description => "Binds a few voice lines to keyboard keys.\n\nArrow keys\n[P, L, K, J, H] toggleable by hitting F8; off by default\nHold [Right Control] for alternate lines"; public static IArchiveLogger FeatureLogger { get; set; } public static bool EnableOtherVoiceBinds { get; set; } public static void IfKeySay(KeyCode key, uint soundId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(key)) { PlayerVoiceManager.WantToSay(_localPlayerAgent.CharacterID, soundId); } } public static void IfKeySay(KeyCode key, uint soundId, int characterID) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(key)) { PlayerVoiceManager.WantToSay(characterID, soundId); } } public override void Update() { if (Input.GetKeyDown((KeyCode)289)) { EnableOtherVoiceBinds = !EnableOtherVoiceBinds; FeatureLogger.Notice($"Voice binds enabled: {EnableOtherVoiceBinds}"); } if (PlayerChatManager.InChatMode || SharedUtils.LocalPlayerIsInTerminal || !PlayerManager.TryGetLocalPlayerAgent(ref _localPlayerAgent) || (Object)(object)_localPlayerAgent == (Object)null) { return; } if (Input.GetKey((KeyCode)305)) { IfKeySay((KeyCode)303, SoundEventCache.Resolve("PLAY_BIGSPACEENTER01", false)); IfKeySay((KeyCode)273, SoundEventCache.Resolve("PLAY_CL_NORTH", false)); IfKeySay((KeyCode)275, SoundEventCache.Resolve("PLAY_CL_EAST", false)); IfKeySay((KeyCode)274, SoundEventCache.Resolve("PLAY_CL_SOUTH", false)); IfKeySay((KeyCode)276, SoundEventCache.Resolve("PLAY_CL_WEST", false)); if (EnableOtherVoiceBinds) { IfKeySay((KeyCode)112, SoundEventCache.Resolve("PLAY_CL_WELLDONE", false)); IfKeySay((KeyCode)108, SoundEventCache.Resolve("PLAY_CL_SHH", false)); IfKeySay((KeyCode)107, SoundEventCache.Resolve("PLAY_CL_WILLDO", false)); IfKeySay((KeyCode)106, SoundEventCache.Resolve("PLAY_CL_YOUTAKE", false)); IfKeySay((KeyCode)104, SoundEventCache.Resolve("PLAY_FALLDAMAGEGRUNT02_5A", false), 2); } } else { IfKeySay((KeyCode)276, SoundEventCache.Resolve("PLAY_CL_LEFT", false)); IfKeySay((KeyCode)275, SoundEventCache.Resolve("PLAY_CL_RIGHT", false)); IfKeySay((KeyCode)273, SoundEventCache.Resolve("PLAY_CL_YES", false)); IfKeySay((KeyCode)274, SoundEventCache.Resolve("PLAY_CL_NO", false)); if (EnableOtherVoiceBinds) { IfKeySay((KeyCode)112, SoundEventCache.Resolve("PLAY_CL_SORRY", false)); IfKeySay((KeyCode)108, SoundEventCache.Resolve("PLAY_CL_HURRY", false)); IfKeySay((KeyCode)106, SoundEventCache.Resolve("PLAY_CL_THREETWOONEGO", false)); IfKeySay((KeyCode)107, SoundEventCache.Resolve("PLAY_CL_SYNCHRONIZE", false)); IfKeySay((KeyCode)104, SoundEventCache.Resolve("PLAY_FALLDAMAGEGRUNT02_5A", false)); } } } } [EnableFeatureByDefault] public class ProcessPriority : Feature { public class ProcessPrioritySettings { [Localized] public enum PriorityClass { High, AboveNormal, Normal, BelowNormal } [FSDisplayName("Priority")] public PriorityClass Priority { get; set; } = PriorityClass.AboveNormal; } private static readonly Dictionary _prioMap = new Dictionary { { ProcessPrioritySettings.PriorityClass.High, ProcessPriorityClass.High }, { ProcessPrioritySettings.PriorityClass.AboveNormal, ProcessPriorityClass.AboveNormal }, { ProcessPrioritySettings.PriorityClass.Normal, ProcessPriorityClass.Normal }, { ProcessPrioritySettings.PriorityClass.BelowNormal, ProcessPriorityClass.BelowNormal } }; public override string Name => "Process Priority"; public override GroupBase Group => (GroupBase)(object)GroupManager.Special; public override string Description => $"Set the games process priority.\n\nThis does the same thing as opening up Taskmanager, going into the 'Details' tab and right clicking on GTFO.exe > [Set Priority]\n\nWarning! Your system might lag / stutter while the game is loading if set to {1} or higher!"; [FeatureConfig] public static ProcessPrioritySettings Settings { get; set; } public override void OnEnable() { SetPriority(Settings.Priority); } public override void OnDisable() { SetPriority(ProcessPrioritySettings.PriorityClass.Normal); } public override void OnFeatureSettingChanged(FeatureSetting setting) { SetPriority(Settings.Priority); } public void SetPriority(ProcessPrioritySettings.PriorityClass settingsPriority) { if (_prioMap.TryGetValue(settingsPriority, out var value)) { using (Process process = Process.GetCurrentProcess()) { process.PriorityClass = value; } ((Feature)this).FeatureLogger.Success($"Set ProcessPriority to {settingsPriority}!"); } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class RemoveChatRestrictions : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerChatManager_SetupPatch { public static void Postfix(ref PlayerChatManager __instance) { try { SetValues(__instance); } catch (Exception ex) { FeatureLogger.Exception(ex); } } } private static PropertyAccessor> A_PlayerChatManager_m_forbiddenChars; private readonly int[] _forbiddenChars = new int[3] { 60, 61, 62 }; public override string Name => "Remove Chat Restrictions"; public override GroupBase Group => (GroupBase)(object)GroupManager.Special; public override string Description => "Allows the usage of '>' and '<' characters in chat.\n\n(Also enables TextMeshPro RichText tags to be used in chat, don't do stupid things!)"; public static IArchiveLogger FeatureLogger { get; set; } public override void OnEnable() { SetValues(PlayerChatManager.Current); } public override void OnDisable() { SetValues(PlayerChatManager.Current, _forbiddenChars); } public override void Init() { A_PlayerChatManager_m_forbiddenChars = PropertyAccessor>.GetAccessor("m_forbiddenChars", false); } public static void SetValues(PlayerChatManager instance, int[] values = null) { if (!((Object)(object)instance == (Object)null)) { A_PlayerChatManager_m_forbiddenChars.Set(instance, Il2CppStructArray.op_Implicit(values ?? Array.Empty())); } } } } namespace TheArchive.Features.Security { [EnableFeatureByDefault] public class AntiBoosterHack : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] private class BoosterImplantManager__OnSyncBoosterImplants__Patch { private static void Postfix(SNet_Player player, pBoosterImplantsWithOwner pBoosterImplantsWithOwner) { SNet_Player player2 = default(SNet_Player); if (SNet.IsMaster && pBoosterImplantsWithOwner != null && (player == null || !player.IsLocal) && SNet.Replication.TryGetLastSender(ref player2, false) && ((pBoosterImplantsWithOwner.BasicImplant.BoosterEffectCount != 0 && !BoosterImplantTemplateManager.TryGetBoosterImplantTemplate(pBoosterImplantsWithOwner.BasicImplant, (BoosterImplantCategory)0)) || (pBoosterImplantsWithOwner.AdvancedImplant.BoosterEffectCount != 0 && !BoosterImplantTemplateManager.TryGetBoosterImplantTemplate(pBoosterImplantsWithOwner.AdvancedImplant, (BoosterImplantCategory)1)) || (pBoosterImplantsWithOwner.SpecializedImplant.BoosterEffectCount != 0 && !BoosterImplantTemplateManager.TryGetBoosterImplantTemplate(pBoosterImplantsWithOwner.SpecializedImplant, (BoosterImplantCategory)2)))) { PunishPlayer(player2); } } } public static class BoosterImplantTemplateManager { public class LocalizedTextJsonConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(string.Empty); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return BoosterImplantTemplateDataBlock.UNKNOWN_BLOCK.PublicName; } public override bool CanConvert(Type objectType) { return objectType == typeof(LocalizedText); } } public class ListOfTConverter : JsonConverter> { public override List ReadJson(JsonReader reader, Type objectType, List existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 JToken val = JToken.Load(reader); if ((int)val.Type == 2) { return SharedUtils.ToIL2CPPListIfNecessary(val.ToObject>(serializer)); } return null; } public override void WriteJson(JsonWriter writer, List value, JsonSerializer serializer) { JToken.FromObject((object)value).WriteTo(writer, Array.Empty()); } public ListOfTConverter() { ((JsonConverter>>)(object)this)..ctor(); } } public class ListOfListOfTConverter : JsonConverter>> { public override List> ReadJson(JsonReader reader, Type objectType, List> existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_0045: 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) JToken val = JToken.Load(reader); List> val2 = (List>)(object)new List>>(); if ((int)val.Type == 2) { foreach (JToken item in val.Children()) { if ((int)item.Type != 2) { continue; } List val3 = new List(); foreach (JToken item2 in item.Children()) { T val4 = item2.ToObject(serializer); val3.Add(val4); } ((List>>)(object)val2).Add((List>)(object)val3); } } return val2; } public override void WriteJson(JsonWriter writer, List> value, JsonSerializer serializer) { JToken.FromObject((object)value).WriteTo(writer, Array.Empty()); } public ListOfListOfTConverter() { ((JsonConverter>>>>)(object)this)..ctor(); } } public class BoosterImplantEffectTemplate { public uint BoosterImplantEffect { get; set; } public float EffectMaxValue { get; set; } public float EffectMinValue { get; set; } public BoosterImplantEffectTemplate(BoosterImplantEffectInstance effect) { EffectMaxValue = effect.MaxValue; EffectMinValue = effect.MinValue; BoosterImplantEffect = effect.BoosterImplantEffect; } } public class BoosterImplantTemplate { public uint BoosterImplantID { get; set; } public BoosterImplantCategory ImplantCategory { get; set; } [JsonIgnore] public List Effects { get; set; } = new List(); [JsonIgnore] public List> RandomEffects { get; set; } = new List>(); [JsonIgnore] public List Conditions { get; set; } = new List(); [JsonIgnore] public List RandomConditions { get; set; } = new List(); [JsonIgnore] public BoosterImplantTemplateDataBlock TemplateDataBlock { get; private set; } public List> EffectGroups { get; set; } = new List>(); public List> ConditionGroups { get; set; } = new List>(); public BoosterImplantTemplate(BoosterImplantTemplateDataBlock block) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) TemplateDataBlock = block; BoosterImplantID = ((GameDataBlockBase)(object)block).persistentID; ImplantCategory = block.ImplantCategory; for (int i = 0; i < block.Effects.Count; i++) { Effects.Add(new BoosterImplantEffectTemplate(block.Effects[i])); } for (int j = 0; j < block.RandomEffects.Count; j++) { List list = new List(); for (int k = 0; k < block.RandomEffects[j].Count; k++) { list.Add(new BoosterImplantEffectTemplate(block.RandomEffects[j][k])); } RandomEffects.Add(list); } Conditions.AddRange((IEnumerable)block.Conditions.ToArray()); RandomConditions.AddRange((IEnumerable)block.RandomConditions.ToArray()); EffectGroups = GenerateEffectGroups(); ConditionGroups = GenerateConditionGroups(); } private List> GenerateEffectGroups() { List> list = new List>(); List> nElementCombinations = GetNElementCombinations(RandomEffects); for (int i = 0; i < nElementCombinations.Count; i++) { List list2 = Effects.ToList(); list2.AddRange(nElementCombinations[i]); list.Add(list2); } return list; } private List> GenerateConditionGroups() { return GetNElementCombinations(new List> { Conditions, RandomConditions }); } } private static string _r5BoosterTemplatesJson; private static List OldBoosterImplantTemplateDataBlocks = new List(); public static List BoosterImplantTemplates { get; } = new List(); private static string R5BoosterTemplatesJson { get { if (!string.IsNullOrWhiteSpace(_r5BoosterTemplatesJson)) { return _r5BoosterTemplatesJson; } byte[] bytes = Utils.LoadFromResource("TheArchive.Resources.RundownFiveBoosterTemplates.json"); _r5BoosterTemplatesJson = Encoding.UTF8.GetString(bytes); return _r5BoosterTemplatesJson; } } public static void LoadTemplateData() { OldBoosterImplantTemplateDataBlocks.Clear(); OldBoosterImplantTemplateDataBlocks.AddRange(JsonConvert.DeserializeObject>(R5BoosterTemplatesJson, (JsonConverter[])(object)new JsonConverter[4] { new LocalizedTextJsonConverter(), (JsonConverter)new ListOfTConverter(), (JsonConverter)new ListOfTConverter(), (JsonConverter)new ListOfListOfTConverter() })); BoosterImplantTemplates.Clear(); Il2CppArrayBase allBlocksForEditor = GameDataBlockBase.GetAllBlocksForEditor(); for (int i = 0; i < allBlocksForEditor.Count; i++) { BoosterImplantTemplates.Add(new BoosterImplantTemplate(allBlocksForEditor[i])); } for (int j = 0; j < OldBoosterImplantTemplateDataBlocks.Count; j++) { BoosterImplantTemplates.Add(new BoosterImplantTemplate(OldBoosterImplantTemplateDataBlocks[j])); } } public static bool TryGetBoosterImplantTemplate(pBoosterImplantData boosterImplant, BoosterImplantCategory category) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) if (boosterImplant == null) { return false; } uint persistenID = boosterImplant.BoosterImplantID; List list = BoosterImplantTemplates.FindAll((BoosterImplantTemplate p) => p.BoosterImplantID == persistenID && p.ImplantCategory == category); for (int k = 0; k < list.Count; k++) { BoosterImplantTemplate boosterImplantTemplate = list[k]; if (boosterImplantTemplate == null || boosterImplantTemplate.TemplateDataBlock == null) { continue; } List> conditionGroups = boosterImplantTemplate.ConditionGroups; int conditionCount = boosterImplant.ConditionCount; bool flag = false; IEnumerable conditions = ((IEnumerable)boosterImplant.Conditions).Take(conditionCount); int j; for (j = 0; j < conditionGroups.Count; j++) { if (conditionCount != conditionGroups[j].Count) { continue; } bool num = conditions.All((uint p) => conditionGroups[j].Any((uint q) => q == p)); bool flag2 = conditionGroups[j].All((uint p) => conditions.Any((uint q) => q == p)); if (num && flag2) { flag = true; break; } } if (!flag) { continue; } int boosterEffectCount = boosterImplant.BoosterEffectCount; bool flag3 = false; List> effectGroups = boosterImplantTemplate.EffectGroups; IEnumerable effects = ((IEnumerable)boosterImplant.BoosterEffectDatas).Take(boosterEffectCount); int i; for (i = 0; i < effectGroups.Count; i++) { if (effectGroups[i].Count != boosterEffectCount) { continue; } for (int l = 0; l < effectGroups[i].Count; l++) { bool num2 = effects.All((pBoosterEffectData p) => effectGroups[i].Any((BoosterImplantEffectTemplate q) => q.BoosterImplantEffect == p.BoosterEffectID && p.EffectValue >= q.EffectMinValue && p.EffectValue <= q.EffectMaxValue)); bool flag4 = effectGroups[i].All((BoosterImplantEffectTemplate p) => effects.Any((pBoosterEffectData q) => q.BoosterEffectID == p.BoosterImplantEffect && q.EffectValue >= p.EffectMinValue && q.EffectValue <= p.EffectMaxValue)); if (num2 && flag4) { flag3 = true; break; } } if (flag3) { break; } } if (flag3) { bool flag5 = boosterImplant.UseCount <= (int)boosterImplantTemplate.TemplateDataBlock.DurationRange.y && boosterImplant.UseCount >= 0; if (flag && flag3 && flag5) { return true; } } } return false; } private static List> GetNElementCombinations(List> lists) { List> list = new List>(); GetNElementCombinationsHelper(lists, new List(), 0, list); return list; } private static void GetNElementCombinationsHelper(List> lists, List currentCombination, int currentIndex, List> combinations) { if (currentIndex == lists.Count) { combinations.Add(new List(currentCombination)); return; } List list = lists[currentIndex]; if (list.Count == 0) { GetNElementCombinationsHelper(lists, currentCombination, currentIndex + 1, combinations); return; } foreach (T item in list) { currentCombination.Add(item); GetNElementCombinationsHelper(lists, currentCombination, currentIndex + 1, combinations); currentCombination.RemoveAt(currentCombination.Count - 1); } } } public override string Name => "Anti Booster Hack"; public override string Description => "Prevents clients from using modified boosters."; public override GroupBase Group => (GroupBase)(object)GroupManager.Security; public override Type[] ExternalLocalizedTypes => new Type[1] { typeof(BasicPunishmentSettings) }; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static BasicPunishmentSettings Settings { get; set; } public override bool ShouldInit() { if (ArchiveMod.IsPlayingModded) { ((Feature)this).RequestDisable("Playing Modded"); return false; } return true; } public override void OnGameDataInitialized() { BoosterImplantTemplateManager.LoadTemplateData(); } public static bool PunishPlayer(SNet_Player player) { if ((Object)(object)player == (Object)null) { return true; } if (SharedUtils.IsFriend(player) && !Settings.PunishFriends) { FeatureLogger.Notice($"Friend \"{player.NickName}\" \"{player.Lookup}\" is using modified boosters!"); return false; } switch (Settings.Punishment) { case BasicPunishmentSettings.PunishmentMode.KickAndBan: PlayerLobbyManagement.BanPlayer(player); break; case BasicPunishmentSettings.PunishmentMode.Kick: PlayerLobbyManagement.KickPlayer(player); break; } FeatureLogger.Notice($"Player \"{player.NickName}\" \"{player.Lookup}\" is using modified boosters! ({Settings.Punishment})"); return true; } } [EnableFeatureByDefault] public class AntiGearHack : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] private class PlayerBackpackManager__ReceiveInventorySync__Patch { private static void Prefix(pInventorySync data) { //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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown if (!SNet.IsMaster) { return; } pPlayer sourcePlayer = data.sourcePlayer; SNet_Player val = default(SNet_Player); SNet_Player val2 = default(SNet_Player); if (!((pPlayer)(ref sourcePlayer)).TryGetPlayer(ref val) || val.IsLocal || val.IsBot || !SNet.Replication.TryGetLastSender(ref val2, false) || val2.IsLocal || val2.IsBot) { return; } foreach (GearIDRange item in new List { new GearIDRange(data.gearStandard), new GearIDRange(data.gearSpecial), new GearIDRange(data.gearMelee), new GearIDRange(data.gearClass), new GearIDRange(data.gearHacking) }) { if (!CheckGearIDRange(item)) { PunishPlayer(val2); break; } } } } private static Dictionary GearCompsHashLookup = new Dictionary(); public override string Name => "Anti Gear Hack"; public override string Description => "Prevents clients from using modified gear."; public override GroupBase Group => (GroupBase)(object)GroupManager.Security; public override Type[] ExternalLocalizedTypes => new Type[1] { typeof(BasicPunishmentSettings) }; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static BasicPunishmentSettings Settings { get; set; } public override bool ShouldInit() { if (ArchiveMod.IsPlayingModded) { ((Feature)this).RequestDisable("Playing Modded"); return false; } return true; } public override void OnGameDataInitialized() { LoadData(); } public static bool PunishPlayer(SNet_Player player) { if ((Object)(object)player == (Object)null) { return true; } if (SharedUtils.IsFriend(player) && !Settings.PunishFriends) { FeatureLogger.Notice($"Friend \"{player.NickName}\" \"{player.Lookup}\" is using modified gears!"); return false; } switch (Settings.Punishment) { case BasicPunishmentSettings.PunishmentMode.KickAndBan: PlayerLobbyManagement.BanPlayer(player); break; case BasicPunishmentSettings.PunishmentMode.Kick: PlayerLobbyManagement.KickPlayer(player); break; } FeatureLogger.Notice($"Player \"{player.NickName}\" \"{player.Lookup}\" is using modified gears! ({Settings.Punishment})"); return true; } public static bool CheckIsValidWeaponGearIDRangeDataForPlayer(SNet_Player player) { if (!player.HasCharacterSlot) { return false; } Enumerator enumerator = ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[player.PlayerSlotIndex()].GetEnumerator(); while (enumerator.MoveNext()) { if (CheckGearIDRange(enumerator.Current)) { return false; } } return true; } public static bool CheckGearIDRange(GearIDRange gearIDRange) { string input = gearIDRange.ToJSON(); string pattern = "(?<=Comps\":)(.*?)(?=,\"MatTrans\")"; string key = Utils.HashString(Regex.Match(input, pattern).Value); return GearCompsHashLookup.ContainsKey(key); } public static void LoadData() { GearCompsHashLookup.Clear(); foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { string gearJSON = allBlock.GearJSON; string pattern = "(?<=Comps\":)(.*?)(?=,\"MatTrans\")"; string key = Utils.HashString(Regex.Match(gearJSON, pattern).Value); GearCompsHashLookup[key] = gearJSON; } } } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] public class AntiSpawn : Feature { public unsafe delegate void Original_InternalSpawnRequestFromSlaveCallback(IntPtr self, IntPtr spawnData, Il2CppMethodInfo* methodInfo); private static bool _hasBeenPatched = false; private static Original_InternalSpawnRequestFromSlaveCallback _originalMethod_InternalSpawnRequestFromSlaveCallback_pEnemySpawnData; private unsafe static Original_InternalSpawnRequestFromSlaveCallback _detourMethod_InternalSpawnRequestFromSlaveCallback_pEnemySpawnData = InternalSpawnRequestFromSlaveCallback_pEnemySpawnData_Replacement; private static Original_InternalSpawnRequestFromSlaveCallback _originalMethod_InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData; private unsafe static Original_InternalSpawnRequestFromSlaveCallback _detourMethod_InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData = InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData_Replacement; public override string Name => "Anti Spawn"; public override string Description => "Prevents clients from spawning in enemies."; public override GroupBase Group => (GroupBase)(object)GroupManager.Security; public override Type[] ExternalLocalizedTypes => new Type[1] { typeof(BasicPunishmentSettings) }; public static IArchiveLogger FeatureLogger { get; set; } public static bool IsEnabled { get; set; } [FeatureConfig] public static BasicPunishmentSettings Settings { get; set; } public override void OnEnable() { OneTimePatch(); } private static void OneTimePatch() { if (!_hasBeenPatched) { LoaderWrapper.ApplyNativeHook, Original_InternalSpawnRequestFromSlaveCallback>("InternalSpawnRequestFromSlaveCallback", typeof(void).FullName, new string[1] { typeof(pEnemySpawnData).FullName }, _detourMethod_InternalSpawnRequestFromSlaveCallback_pEnemySpawnData, ref _originalMethod_InternalSpawnRequestFromSlaveCallback_pEnemySpawnData); LoaderWrapper.ApplyNativeHook>, Original_InternalSpawnRequestFromSlaveCallback>("InternalSpawnRequestFromSlaveCallback", typeof(void).FullName, new string[1] { typeof(pEnemyGroupSpawnData).FullName }, _detourMethod_InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData, ref _originalMethod_InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData); _hasBeenPatched = true; } } public unsafe static void InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData_Replacement(IntPtr self, IntPtr spawnData, Il2CppMethodInfo* methodInfo) { if (IsEnabled && SNet.IsMaster && !SNet.Capture.IsCheckpointRecall) { bool flag = true; SNet_Player player = default(SNet_Player); if (SNet.Replication.TryGetLastSender(ref player, false)) { flag = PunishPlayer(player); } if (flag) { FeatureLogger.Fail("Cancelled enemy spawn!"); return; } } _originalMethod_InternalSpawnRequestFromSlaveCallback_pEnemyGroupSpawnData(self, spawnData, methodInfo); } public unsafe static void InternalSpawnRequestFromSlaveCallback_pEnemySpawnData_Replacement(IntPtr self, IntPtr spawnData, Il2CppMethodInfo* methodInfo) { if (IsEnabled && SNet.IsMaster && !SNet.Capture.IsCheckpointRecall) { bool flag = true; SNet_Player player = default(SNet_Player); if (SNet.Replication.TryGetLastSender(ref player, false)) { flag = PunishPlayer(player); } if (flag) { FeatureLogger.Fail("Cancelled enemy spawn!"); return; } } _originalMethod_InternalSpawnRequestFromSlaveCallback_pEnemySpawnData(self, spawnData, methodInfo); } public static bool PunishPlayer(SNet_Player player) { if ((Object)(object)player == (Object)null) { return true; } if (SharedUtils.IsFriend(player) && !Settings.PunishFriends) { FeatureLogger.Notice("Friend \"" + player.NickName + "\" is spawning something in!"); return false; } switch (Settings.Punishment) { case BasicPunishmentSettings.PunishmentMode.KickAndBan: PlayerLobbyManagement.BanPlayer(player); break; case BasicPunishmentSettings.PunishmentMode.Kick: PlayerLobbyManagement.KickPlayer(player); break; } FeatureLogger.Notice($"Player \"{player.NickName}\" tried to spawn something! ({Settings.Punishment})"); return true; } } public class BasicPunishmentSettings { [Localized] public enum PunishmentMode { NoneAndLog, Kick, KickAndBan } [FSDisplayName("Punish Friends")] [FSDescription("If (Steam) Friends should be affected as well.")] public bool PunishFriends { get; set; } [FSDisplayName("Punishment")] [FSDescription("What to do with griefers.")] public PunishmentMode Punishment { get; set; } = PunishmentMode.Kick; } [EnableFeatureByDefault] public class PlayerLobbyManagement : Feature { public class LobbyManagementSettings { public class LobbyColorSettings { [FSDisplayName("Color the Square")] [FSDescription("Use the colors/settings below to color the square on the loadout screen next to the player names.")] public bool ColorizeLobbyBullet { get; set; } = true; [FSDisplayName("Use Nickname Color for Self")] public bool UseNicknameColorForSelf { get; set; } = true; [FSDisplayName("Random Colors for Self")] public bool RainbowPukeSelf { get; set; } [FSDisplayName("Random Colors for Others")] public bool RainbowPukeFriends { get; set; } [FSHeader("Colors", true)] [FSDisplayName("Default")] public SColor Default { get; set; } = new SColor(1f, 1f, 1f, (float?)null); [FSDisplayName("Friends")] public SColor Friends { get; set; } = new SColor(0.964f, 0.921f, 0.227f, (float?)null); [FSDisplayName("Bots")] public SColor Bots { get; set; } = new SColor(0.949f, 0.58f, 0f, (float?)null); [FSDisplayName("Banned")] public SColor Banned { get; set; } = new SColor(0.545f, 0f, 0f, (float?)null); [FSDisplayName("Self")] public SColor Self { get; set; } = new SColor(1f, 1f, 1f, (float?)null); } public class BanListEntry { [FSSeparator] [FSReadOnly(true)] [FSDisplayName("Name")] public string Name { get; set; } [FSReadOnly(true)] [FSDisplayName("SteamID")] public ulong SteamID { get; set; } [FSReadOnly(true)] [FSTimestamp("U")] [FSDisplayName("Banned on:")] public long Timestamp { get; set; } } public class RecentlyPlayedWithEntry { [FSSeparator] [FSReadOnly(true)] [FSDisplayName("Name")] public string Name { get; set; } [FSReadOnly(true)] [FSDisplayName("SteamID")] public ulong SteamID { get; set; } [FSReadOnly(true)] [FSTimestamp("U")] [FSDisplayName("First time played with:")] public long TimestampFirst { get; set; } [FSReadOnly(true)] [FSTimestamp("U")] [FSDisplayName("Last time played with:")] public long TimestampLast { get; set; } } [FSDisplayName("Names on Map open Steam Profile")] [FSDescription("If clicking a players name on the map screen should open their Steam Profile in your default browser.")] public bool NamesOnMapOpenSteamProfile { get; set; } [FSDisplayName("Open Profiles in Steam Overlay")] [FSDescription("Wheter to open profile links in the overlay or in the default OS browser.")] public bool PreferOpeningProfileLinksInSteamOverlay { get; set; } = true; [FSHeader("Lobby Color Settings", true)] [FSDisplayName("Lobby Colors")] public LobbyColorSettings LobbyColors { get; set; } = new LobbyColorSettings(); [FSHeader("Other", true)] [FSDisplayName("Recently Played With")] public List RecentlyPlayedWith { get; set; } = new List(); [FSDisplayName("Banned Players")] [FSDescription("Players who are on this list will not be able to join any games you host.")] public List BanList { get; set; } = new List(); } [Localized] public enum PlayerRelationShip { None, Self, Friend, Banned, Bot } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class SNet_SessionHub_SlaveWantsToJoin_Patch { public static bool Prefix(SNet_Player player) { if (SNet.IsMaster && IsPlayerBanned(player.Lookup)) { FeatureLogger.Notice("Banned player \"" + player.GetName() + "\" tried to join, their join request has been ignored!"); KickPlayer(player); return false; } return true; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class SNet_OnPlayerJoinedSessionHub_Patch { public static void Postfix(SNet_Player player) { AddRecentlyPlayedWith(player, joined: true); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class SNet_OnPlayerLeftSessionHub_Patch { public static void Prefix(SNet_Player player) { AddRecentlyPlayedWith(player, joined: false); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_UpdatePlayer_Patch { internal static Dictionary colliderMap = new Dictionary(); private static MethodAccessor A_Unregister; private static MethodAccessor A_Start; private static IValueAccessor A_layer; public static void Init() { A_Start = MethodAccessor.GetAccessor("Start", (Type[])null, false); A_Unregister = MethodAccessor.GetAccessor("Unregister", (Type[])null, false); A_layer = AccessorBase.GetValueAccessor("layer", false); } public static void ColorizeNickNameGUIX(GameObject nickNameGuix, PlayerRelationShip rel = PlayerRelationShip.None) { //IL_0051: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)nickNameGuix == (Object)null) { return; } foreach (Transform item in SharedUtils.DirectChildren(nickNameGuix.transform)) { GUIX_ElementSprite component = ((Component)item).GetComponent(); SpriteRenderer component2 = ((Component)item).GetComponent(); if ((Object)(object)component2 != (Object)null) { if (!Settings.LobbyColors.ColorizeLobbyBullet) { component2.color = Color.white; } else if (rel != PlayerRelationShip.Self) { if (rel != PlayerRelationShip.Friend || !Settings.LobbyColors.RainbowPukeFriends) { goto IL_00cf; } component2.color = Random.ColorHSV(); } else if (Settings.LobbyColors.RainbowPukeSelf) { component2.color = Random.ColorHSV(); } else { if (!Settings.LobbyColors.UseNicknameColorForSelf || !FeatureManager.IsFeatureEnabled() || !Nickname.IsNicknameColorEnabled) { goto IL_00cf; } component2.color = Nickname.CurrentNicknameColor; } } goto IL_00db; IL_00cf: component2.color = GetRelationshipColor(rel); goto IL_00db; IL_00db: if (!((Object)(object)A_layer.Get(component) == (Object)null) && ((Component)component).gameObject.activeInHierarchy) { A_Unregister.Invoke(component); component.DynamicIndex = -1; A_layer.Set(component, (GUIX_Layer)null); A_Start.Invoke(component); } } } public static void Postfix(CM_PlayerLobbyBar __instance, SNet_Player player) { //IL_0094: 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) if (player == null) { return; } SNet_Slot characterSlot = player.CharacterSlot; if (characterSlot == null) { return; } _ = characterSlot.index; if (false) { return; } int playerLobbyBarIndex = SharedUtils.GetPlayerLobbyBarIndex(__instance); GameObject gameObject = ((Component)__instance.m_nickText).gameObject; CM_Item CM_Item = gameObject.GetComponent(); if ((Object)(object)CM_Item == (Object)null) { FeatureLogger.Debug($"Setting up player name button for slot index {playerLobbyBarIndex}"); BoxCollider2D val = gameObject.AddComponent(); val.size = new Vector2(447.2f, 52.8f); ((Collider2D)val).offset = new Vector2(160f, 1.6f); if (colliderMap.ContainsKey(playerLobbyBarIndex)) { colliderMap.Remove(playerLobbyBarIndex); } colliderMap.Add(playerLobbyBarIndex, val); CM_Item = gameObject.AddComponent(); CM_Item.ID = playerLobbyBarIndex + 1; SharedUtils.SetCMItemEvents(CM_Item, (Action)delegate(int id) { if (!((RectTransformComp)PopupWindow).IsVisible || ((CM_PopupOverlay)PopupWindow).ID != id) { SetupAndPlaceWindow(id, ((Component)CM_Item).transform); } else { ((RectTransformComp)PopupWindow).SetVisible(false); } }, (Action)null); } ColorizeNickNameGUIX(__instance.m_nickNameGuix, GetRelationship(player)); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_Inventory_UpdateAllSlots_Patch { internal static Dictionary colliderMap = new Dictionary(); public static void Postfix(PUI_Inventory __instance, SNet_Player player) { //IL_008c: 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) if (player == null) { return; } SNet_Slot characterSlot = player.CharacterSlot; if (characterSlot == null) { return; } _ = characterSlot.index; if (false) { return; } int index = player.CharacterSlot.index; GameObject headerRoot = __instance.m_headerRoot; if ((Object)(object)headerRoot.GetComponent() == (Object)null) { FeatureLogger.Debug($"Setting up player name button (map) for index {player.CharacterSlot.index}"); BoxCollider2D val = headerRoot.AddComponent(); val.size = new Vector2(400f, 40f); ((Collider2D)val).offset = new Vector2(-200f, 0f); if (colliderMap.ContainsKey(index)) { colliderMap.Remove(index); } colliderMap.Add(index, val); CM_Item obj = headerRoot.AddComponent(); obj.ID = player.CharacterSlot.index + 1; SharedUtils.SetCMItemEvents(obj, (Action)OnMapNameButtonPressed, (Action)null); } } } private static Dictionary _colorMap = new Dictionary(); private static CM_ScrollWindow _popupWindow = null; public override string Name => "Player Lobby Management"; public override GroupBase Group => (GroupBase)(object)GroupManager.Security; public override string Description => "Allows you to open a players steam profile by clicking on their name as well as kick and ban players as host."; public static ILocalizationService Localization { get; set; } public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static LobbyManagementSettings Settings { get; set; } private static CM_ScrollWindow PopupWindow { get { //IL_0083: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0194: 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_0287: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_popupWindow == (Object)null) { FeatureLogger.Debug("Creating PopupWindow ..."); _popupWindow = Object.Instantiate(PageSettingsData.PopupWindow, (Transform)(object)((CM_PageBase)CM_PageLoadout.Current).m_movingContentHolder); Object.DontDestroyOnLoad((Object)(object)_popupWindow); ((Object)_popupWindow).name = "PlayerLobbyManagement_PopupWindow_PlayerManagement"; ((RectTransformComp)PopupWindow).Setup(); OpenSteamItem = CreatePopupItem(Localization.GetById(1u, (string)null), OnNameButtonPressed); SharedUtils.ChangeColorCMItem(OpenSteamItem, ModSettings.GREEN, (Color?)null); SharedUtils.SetHoldDuration(SharedUtils.TryCastTo((Il2CppObjectBase)(object)OpenSteamItem), 0.5f); IsFriendItem = CreatePopupItem(Localization.GetById(2u, (string)null), delegate { }); SharedUtils.ChangeColorCMItem(IsFriendItem, GetRelationshipColor(PlayerRelationShip.Friend), (Color?)null); SharedUtils.SetHoldDuration(SharedUtils.TryCastTo((Il2CppObjectBase)(object)IsFriendItem), 100f); ((Behaviour)((Component)IsFriendItem).GetComponent()).enabled = false; KickPlayerItem = CreatePopupItem(Localization.GetById(3u, (string)null), KickPlayerButtonPressed); SharedUtils.ChangeColorCMItem(KickPlayerItem, ModSettings.ORANGE, (Color?)null); SharedUtils.SetHoldDuration(SharedUtils.TryCastTo((Il2CppObjectBase)(object)KickPlayerItem), 2f); BanPlayerItem = CreatePopupItem(Localization.GetById(4u, (string)null), BanPlayerButtonPressed); SharedUtils.ChangeColorCMItem(BanPlayerItem, ModSettings.RED, (Color?)null); SharedUtils.SetHoldDuration(SharedUtils.TryCastTo((Il2CppObjectBase)(object)BanPlayerItem), 4f); CM_Item val = CreatePopupItem("Spacer, should not be visible", delegate { }); List val2 = SharedUtils.NewListForGame(); val2.Add(((Component)OpenSteamItem).GetComponentInChildren()); val2.Add(((Component)IsFriendItem).GetComponentInChildren()); val2.Add(((Component)val).GetComponentInChildren()); val2.Add(((Component)KickPlayerItem).GetComponentInChildren()); val2.Add(((Component)BanPlayerItem).GetComponentInChildren()); PopupWindow.SetContentItems(val2, 5f); ((Component)val).gameObject.SetActive(false); ((Component)val).transform.position = new Vector3(-5000f, 0f, 0f); ((RectTransformComp)PopupWindow).SetSize(new Vector2(350f, (float)(58 * val2.Count))); ((RectTransformComp)PopupWindow).SetVisible(false); PopupWindow.SetHeader("Player options"); } return _popupWindow; } } internal static CM_Item OpenSteamItem { get; set; } internal static CM_Item IsFriendItem { get; set; } internal static CM_Item KickPlayerItem { get; set; } internal static CM_Item BanPlayerItem { get; set; } public override void OnEnable() { foreach (BoxCollider2D value in CM_PlayerLobbyBar_UpdatePlayer_Patch.colliderMap.Values) { if ((Object)(object)value != (Object)null) { ((Behaviour)value).enabled = true; } } foreach (BoxCollider2D value2 in PUI_Inventory_UpdateAllSlots_Patch.colliderMap.Values) { if ((Object)(object)value2 != (Object)null) { ((Behaviour)value2).enabled = true; } } SetupColorMap(); } public override void OnDisable() { foreach (BoxCollider2D value in CM_PlayerLobbyBar_UpdatePlayer_Patch.colliderMap.Values) { if ((Object)(object)value != (Object)null) { ((Behaviour)value).enabled = false; } } foreach (BoxCollider2D value2 in PUI_Inventory_UpdateAllSlots_Patch.colliderMap.Values) { if ((Object)(object)value2 != (Object)null) { ((Behaviour)value2).enabled = false; } } } public override void OnFeatureSettingChanged(FeatureSetting setting) { SetupColorMap(); } public static void SetupColorMap() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) _colorMap.Clear(); PlayerRelationShip[] array = Enum.GetValues(typeof(PlayerRelationShip)) as PlayerRelationShip[]; foreach (PlayerRelationShip playerRelationShip in array) { _colorMap.Add(playerRelationShip, GetRelationshipColor(playerRelationShip)); } } public static PlayerRelationShip GetRelationship(PlayerAgent player) { return GetRelationship((player != null) ? player.Owner : null); } public static PlayerRelationShip GetRelationship(SNet_Player player) { if ((Object)(object)player == (Object)null) { return PlayerRelationShip.None; } if (SharedUtils.SafeIsBot(player)) { return PlayerRelationShip.Bot; } if (player.IsLocal) { return PlayerRelationShip.Self; } if (IsPlayerBanned(player.Lookup)) { return PlayerRelationShip.Banned; } if (SharedUtils.IsFriend(player)) { return PlayerRelationShip.Friend; } return PlayerRelationShip.None; } public static Color GetRelationshipColor(PlayerRelationShip rel) { //IL_000f: 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_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_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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (_colorMap.TryGetValue(rel, out var value)) { return value; } return (Color)(rel switch { PlayerRelationShip.Self => SColorExtensions.ToUnityColor(Settings.LobbyColors.Self), PlayerRelationShip.Bot => SColorExtensions.ToUnityColor(Settings.LobbyColors.Bots), PlayerRelationShip.Friend => SColorExtensions.ToUnityColor(Settings.LobbyColors.Friends), PlayerRelationShip.Banned => SColorExtensions.ToUnityColor(Settings.LobbyColors.Banned), _ => SColorExtensions.ToUnityColor(Settings.LobbyColors.Default), }); } public static bool IsPlayerBanned(ulong lookup) { return Settings.BanList.Any((LobbyManagementSettings.BanListEntry bp) => bp.SteamID == lookup); } internal static void OnMapNameButtonPressed(int id) { if (Settings.NamesOnMapOpenSteamProfile) { SNet_Player player = default(SNet_Player); if (!SharedUtils.TryGetPlayerByCharacterIndex(id, ref player)) { FeatureLogger.Debug($"No player found for character index {id - 1}."); } else { OpenSteamProfileFor(player); } } } internal static void OnNameButtonPressed(int id) { ((RectTransformComp)PopupWindow).SetVisible(false); SNet_Player player = default(SNet_Player); if (!SharedUtils.TryGetPlayerByPlayerLobbyBarIndex(id - 1, ref player)) { FeatureLogger.Debug($"No player found for index {id - 1}."); } else { OpenSteamProfileFor(player); } } public static void OpenSteamProfileFor(SNet_Player player) { if ((Object)(object)player == (Object)null) { FeatureLogger.Debug("Player was null!"); return; } if (SharedUtils.SafeIsBot(player)) { FeatureLogger.Notice("The Bot has no steam profile!"); return; } FeatureLogger.Info($"Opening Steam profile for player \"{player.NickName}\" ({player.Lookup})"); string text = $"https://steamcommunity.com/profiles/{player.Lookup}"; if (Settings.PreferOpeningProfileLinksInSteamOverlay && SteamUtils.IsOverlayEnabled()) { SteamFriends.ActivateGameOverlayToWebPage(text, (EActivateGameOverlayToWebPageMode)0); } else { Application.OpenURL(text); } } internal static void KickPlayerButtonPressed(int playerID) { ((RectTransformComp)PopupWindow).SetVisible(false); SNet_Player val = default(SNet_Player); if (SNet.IsMaster && SharedUtils.TryGetPlayerByPlayerLobbyBarIndex(playerID - 1, ref val)) { if (SharedUtils.SafeIsBot(val)) { FeatureLogger.Notice("Use the built in button below to remove bots!"); return; } FeatureLogger.Notice($"Kicking player \"{val.GetName()}\" Nick:\"{val.NickName}\" ..."); KickPlayer(val); } } internal static void BanPlayerButtonPressed(int playerID) { SNet_Player val = default(SNet_Player); if (!SharedUtils.TryGetPlayerByPlayerLobbyBarIndex(playerID - 1, ref val)) { return; } if (val.IsLocal) { BanPlayerItem.SetText(" You can't ban yourself, silly!"); return; } ((RectTransformComp)PopupWindow).SetVisible(false); if (SharedUtils.SafeIsBot(val)) { FeatureLogger.Notice("You can't ban a bot!"); } else if (!IsPlayerBanned(val.Lookup)) { BanPlayer(val); } else { UnbanPlayer(val); } } public static bool BanPlayer(SNet_Player player, bool kickPlayer = true) { if ((Object)(object)player == (Object)null) { return false; } if (!IsPlayerBanned(player.Lookup)) { Settings.BanList.Add(new LobbyManagementSettings.BanListEntry { Name = player.GetName(), SteamID = player.Lookup, Timestamp = DateTime.UtcNow.Ticks }); FeatureLogger.Fail($"Player has been added to list of banned players: Name:\"{player.GetName()}\" SteamID:\"{player.Lookup}\""); Feature.MarkSettingsAsDirty(Settings); if (kickPlayer) { KickPlayer(player); } return true; } return false; } public static bool UnbanPlayer(SNet_Player player) { return UnbanPlayer((player != null) ? player.Lookup : ulong.MaxValue); } public static bool UnbanPlayer(ulong playerID) { if (playerID == ulong.MaxValue) { return false; } LobbyManagementSettings.BanListEntry banListEntry = Settings.BanList.FirstOrDefault((LobbyManagementSettings.BanListEntry entry) => entry.SteamID == playerID); if (banListEntry != null) { Settings.BanList.Remove(banListEntry); FeatureLogger.Success($"Player has been removed from the list of banned players: Name:\"{banListEntry.Name}\" SteamID:\"{banListEntry.SteamID}\""); Feature.MarkSettingsAsDirty(Settings); return true; } return false; } public static void KickPlayer(SNet_Player player) { if (SNet.IsMaster) { SNet.Sync.KickPlayer(player, (SNet_PlayerEventReason)2); } } private static CM_Item CreatePopupItem(string text, Action onClick, int id = 0) { CM_Item val = SharedUtils.TryCastTo((Il2CppObjectBase)(object)GOUtil.SpawnChildAndGetComp(UIHelper.PopupItemPrefab, ((Component)_popupWindow).transform)); val.SetupCMItem(); if (id != 0) { val.ID = id; } val.SetText(text); SharedUtils.SetCMItemEvents(val, onClick, (Action)null); ((RectTransformComp)val).ForcePopupLayer(true, (GameObject)null); return val; } public static void SetupAndPlaceWindow(int playerID, Transform pos) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) SNet_Player val = default(SNet_Player); if (!SharedUtils.TryGetPlayerByPlayerLobbyBarIndex(playerID - 1, ref val)) { return; } string name = val.GetName(); bool flag = SharedUtils.SafeIsBot(val); ((Component)KickPlayerItem).gameObject.SetActive(!flag); ((Component)BanPlayerItem).gameObject.SetActive(!flag); ((Component)OpenSteamItem).gameObject.SetActive(!flag); if (flag) { ((Component)IsFriendItem).gameObject.SetActive(true); IsFriendItem.SetText(Localization.GetById(6u, (string)null)); SharedUtils.ChangeColorCMItem(IsFriendItem, GetRelationshipColor(PlayerRelationShip.Bot), (Color?)null); ShowWindow(name, pos, playerID); return; } ((CM_PopupOverlay)PopupWindow).SetupFromButton(new iCellMenuPopupController(((Il2CppObjectBase)CM_PageLoadout.Current).Pointer), (CM_PageBase)(object)CM_PageLoadout.Current); SNet_Friend val2 = default(SNet_Friend); bool flag2 = SNet.Friends.TryGetFriend(val.Lookup, ref val2); bool flag3 = IsPlayerBanned(val.Lookup); ((Component)IsFriendItem).gameObject.SetActive(flag2 || flag3); if (flag3) { IsFriendItem.SetText(Localization.GetById(5u, (string)null)); SharedUtils.ChangeColorCMItem(IsFriendItem, GetRelationshipColor(PlayerRelationShip.Banned), (Color?)null); } else if (flag2) { IsFriendItem.SetText(Localization.GetById(2u, (string)null)); SharedUtils.ChangeColorCMItem(IsFriendItem, GetRelationshipColor(PlayerRelationShip.Friend), (Color?)null); } KickPlayerItem.SetText(Localization.Format(7u, " Kick {0}", new object[1] { name })); if (val.IsMaster || !SNet.IsMaster) { ((Behaviour)((Component)KickPlayerItem).GetComponent()).enabled = false; SharedUtils.ChangeColorCMItem(KickPlayerItem, ModSettings.DISABLED, (Color?)null); BanPlayerItem.SetText(Localization.Format(8u, " Ban {0}", new object[1] { name })); } else { ((Behaviour)((Component)KickPlayerItem).GetComponent()).enabled = true; SharedUtils.ChangeColorCMItem(KickPlayerItem, ModSettings.ORANGE, (Color?)null); BanPlayerItem.SetText(Localization.Format(9u, " Ban and kick {0}", new object[1] { name })); } if (val.IsLocal) { SharedUtils.ChangeColorCMItem(BanPlayerItem, ModSettings.DISABLED, (Color?)null); } else if (flag3) { BanPlayerItem.SetText(Localization.Format(10u, " Unban {0}", new object[1] { name })); SharedUtils.ChangeColorCMItem(BanPlayerItem, ModSettings.GREEN, (Color?)null); } else { SharedUtils.ChangeColorCMItem(BanPlayerItem, ModSettings.RED, (Color?)null); } ShowWindow(name, pos, playerID); } private static void ShowWindow(string header, Transform pos, int playerID) { //IL_0021: 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) PopupWindow.SetHeader(header); ((CM_PopupOverlay)PopupWindow).ID = playerID; ((Component)PopupWindow).transform.position = pos.position + new Vector3(200f, 0f, 0f); OpenSteamItem.ID = playerID; KickPlayerItem.ID = playerID; BanPlayerItem.ID = playerID; ((RectTransformComp)PopupWindow).SetVisible(true); } private static void AddRecentlyPlayedWith(SNet_Player player, bool joined) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) LobbyManagementSettings.RecentlyPlayedWithEntry recentlyPlayedWithEntry = Settings.RecentlyPlayedWith.FirstOrDefault((LobbyManagementSettings.RecentlyPlayedWithEntry entry) => entry.SteamID == player.Lookup); if (recentlyPlayedWithEntry != null) { if (joined) { if (!player.IsBot) { SteamFriends.SetPlayedWith(new CSteamID(player.Lookup)); } FeatureLogger.Notice($"{player.NickName} joined Session, last time played with them {DateTime.UtcNow - new DateTime(recentlyPlayedWithEntry.TimestampLast):d' day(s) and 'hh':'mm':'ss} ago."); } else { FeatureLogger.Debug(player.NickName + " left Session, saving Timestamp."); } recentlyPlayedWithEntry.TimestampLast = DateTime.UtcNow.Ticks; Feature.MarkSettingsAsDirty(Settings); } else { long ticks = DateTime.UtcNow.Ticks; Settings.RecentlyPlayedWith.Add(new LobbyManagementSettings.RecentlyPlayedWithEntry { Name = player.NickName, SteamID = player.Lookup, TimestampFirst = ticks, TimestampLast = ticks }); Feature.MarkSettingsAsDirty(Settings); } } } } namespace TheArchive.Features.QoL { public class IntroSkip : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageIntro_Update_Patch { private static bool _injectPressed; private static MethodAccessor _onSkip; public static void Init() { _onSkip = MethodAccessor.GetAccessor("OnSkip", (Type[])null, false); } [IsPostfix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PostfixR4OrLater(CM_PageIntro __instance) { CheckAndSkipIfReady(__instance, __instance.m_startupLoaded, __instance.m_enemiesLoaded, __instance.m_sharedLoaded); } public static void CheckAndSkipIfReady(CM_PageIntro __instance, bool ___m_startupLoaded, bool ___m_enemiesLoaded, bool ___m_sharedLoaded) { if (___m_startupLoaded && ___m_enemiesLoaded && ___m_sharedLoaded && ItemSpawnManager.ReadyToSpawnItems && IsProgressionFileReady() && !_injectPressed) { FeatureLogger.Notice("Automatically pressing the Inject button ..."); _onSkip.Invoke(__instance); __instance.EXT_PressInject(-1); _injectPressed = true; } } } public override string Name => "Skip Intro"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Automatically presses inject at the start of the game"; public static IArchiveLogger FeatureLogger { get; set; } public static bool IsProgressionFileReady() { return RundownManager.RundownProgressionReady; } } public class L4DStylePacks : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ResourcePackFirstPerson_UpdateInteraction_Patch { private static MethodAccessor A_UpdateInteractionActionName; private static IValueAccessor A_m_interactionSourceAgent; private static IValueAccessor A_m_interactionTimer; public static void Init() { A_UpdateInteractionActionName = MethodAccessor.GetAccessor("UpdateInteractionActionName", (Type[])null, false); if (!Is.R6OrLater) { A_m_interactionSourceAgent = AccessorBase.GetValueAccessor("m_interactionSourceAgent", false); A_m_interactionTimer = AccessorBase.GetValueAccessor("m_interactionTimer", false); } } public static bool Prefix(ResourcePackFirstPerson __instance) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0031: 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_005c: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) iResourcePackReceiver val = __instance.m_actionReceiver; iResourcePackReceiver lastActionReceiver = __instance.m_lastActionReceiver; eResourceContainerSpawnType packType = __instance.m_packType; Interact_ManualTimedWithCallback interactApplyResource = __instance.m_interactApplyResource; bool flag = false; bool flag2 = false; InputAction input = (InputAction)0; if (InputMapper.GetButtonDown.Invoke((InputAction)8, ((Item)__instance).Owner.InputFilter)) { flag = true; if (!((Interact_Timed)interactApplyResource).TimerIsActive) { val = (__instance.m_actionReceiver = SharedUtils.CastTo((Il2CppObjectBase)(object)((Item)__instance).Owner)); } input = (InputAction)8; } if (InputMapper.GetButton.Invoke((InputAction)7, ((Item)__instance).Owner.InputFilter)) { flag2 = true; flag = true; RaycastHit val3 = default(RaycastHit); if (!((Interact_Timed)interactApplyResource).TimerIsActive && Physics.Raycast(((Item)__instance).Owner.FPSCamera.Position, ((Item)__instance).Owner.FPSCamera.Forward, ref val3, 2.4f, LayerManager.MASK_GIVE_RESOURCE_PACK)) { iResourcePackReceiver componentInParent = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent(); if (componentInParent != null) { val = (__instance.m_actionReceiver = componentInParent); } } input = ((!val.IsLocallyOwned) ? ((InputAction)7) : ((InputAction)8)); } if (val == null || (!((Interact_Timed)interactApplyResource).TimerIsActive && !flag)) { val = (__instance.m_actionReceiver = SharedUtils.CastTo((Il2CppObjectBase)(object)((Item)__instance).Owner)); if (Is.R6OrLater) { OnInteractorStateChangedR6Plus(interactApplyResource, ((Item)__instance).Owner, state: false); } ((Interact_Base)interactApplyResource).PlayerSetSelected(false, ((Item)__instance).Owner); } bool flag3 = NeedsResource(val, packType); if (!((Interact_Timed)interactApplyResource).TimerIsActive && val != lastActionReceiver) { if (val.IsLocallyOwned) { A_UpdateInteractionActionName.Invoke(__instance, new object[2] { Localization.GetById(7u, (string)null), true }); interactApplyResource.m_input = input; } else { A_UpdateInteractionActionName.Invoke(__instance, new object[2] { val.InteractionName, false }); interactApplyResource.m_input = input; if (flag3) { if (Is.R6OrLater) { OnInteractorStateChangedR6Plus(interactApplyResource, ((Item)__instance).Owner, state: true); } else { ActivateTimerR5AndBelow(interactApplyResource, ((Item)__instance).Owner); } } } __instance.m_lastActionReceiver = val; } bool timerIsActive = ((Interact_Timed)interactApplyResource).TimerIsActive; interactApplyResource.ManualUpdateWithCondition(flag3, ((Item)__instance).Owner, flag3 && !val.IsLocallyOwned); bool timerIsActive2 = ((Interact_Timed)interactApplyResource).TimerIsActive; if (!timerIsActive && timerIsActive2 && Is.R6OrLater) { SendGenericInteractR6Plus(__instance, val); } if (timerIsActive && !timerIsActive2) { PlayerAgent owner = ((Item)__instance).Owner; __instance.m_actionReceiver = ((owner != null) ? SharedUtils.CastTo((Il2CppObjectBase)(object)owner) : null); } if (!flag3 && flag && __instance.m_lastButtonDown != flag && (!flag2 || !val.IsLocallyOwned)) { SharedUtils.SafePost(((ItemEquippable)__instance).Sound, EVENTS.BUTTONGENERICBLIPDENIED, true); ShowDoesNotNeedResourcePrompt(val, packType); } __instance.m_lastButtonDown = flag; return false; } private static void ActivateTimerR5AndBelow(Interact_ManualTimedWithCallback timer, PlayerAgent agent) { A_m_interactionSourceAgent.Set((Interact_Timed)(object)timer, agent); ((Interact_Timed)timer).SetTimerActive(true); A_m_interactionTimer.Set((Interact_Timed)(object)timer, Clock.Delta); } [MethodImpl(MethodImplOptions.NoInlining)] private static void SendGenericInteractR6Plus(ResourcePackFirstPerson __instance, iResourcePackReceiver packReceiver) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) TypeEnum val = (TypeEnum)(packReceiver.IsLocallyOwned ? 6 : 5); ((Item)__instance).Owner.Sync.SendGenericInteract(val, false); } [MethodImpl(MethodImplOptions.NoInlining)] private static void OnInteractorStateChangedR6Plus(Interact_ManualTimedWithCallback timer, PlayerAgent sourceAgent, bool state) { ((Interact_Timed)timer).OnInteractorStateChanged(sourceAgent, state); } } private static MethodAccessor A_SetTimedMessage; public override string Name => "L4D Style Resource Packs"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Use left and right mouse buttons to apply resource packs instead of E.\n\nLeft mouse = yourself\nRight mouse = other players\n\n[R4+] You're able to hold down M2 and it will start applying to a receiver under your croshair if in range automatically\n\n<#f00>/!\\ Make sure to disable the vanilla game setting Gameplay > Separate Use Keybinds for this Feature to work!"; public static ILocalizationService Localization { get; set; } public static IArchiveLogger FeatureLogger { get; set; } public override void Init() { if (!Is.R2OrLater) { A_SetTimedMessage = MethodAccessor.GetAccessor("SetTimedMessage", (Type[])null, false); } } public static bool NeedsResource(iResourcePackReceiver receiver, eResourceContainerSpawnType packType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected I4, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (receiver == null) { return false; } switch ((int)packType) { default: if ((int)packType == 9) { if (Is.R2OrLater) { return NeedsDisinfect(receiver); } return false; } return false; case 0: return receiver.NeedHealth(); case 1: return receiver.NeedWeaponAmmo(); case 2: return receiver.NeedToolAmmo(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool NeedsDisinfect(iResourcePackReceiver receiver) { return receiver.NeedDisinfection(); } public static void ShowDoesNotNeedResourcePrompt(iResourcePackReceiver receiver, eResourceContainerSpawnType packType) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected I4, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 string text = (receiver.IsLocallyOwned ? Localization.GetById(1u, (string)null) : Localization.Format(2u, "{0} DOES", new object[1] { receiver.InteractionName })); switch ((int)packType) { default: if ((int)packType == 9) { text += Localization.GetById(6u, (string)null); } break; case 1: text += Localization.GetById(3u, (string)null); break; case 2: text += Localization.GetById(4u, (string)null); break; case 0: text += Localization.GetById(5u, (string)null); break; } SetTimedInteractionPrompt(text, 1.4f); } private static void SetTimedInteractionPrompt(string text, float time) { if (Is.R2OrLater) { TimedInteractionPromptR2Plus(text, time); return; } A_SetTimedMessage.Invoke(GuiManager.InteractionLayer, new object[3] { text, time, (object)(ePUIMessageStyle)1 }); } [MethodImpl(MethodImplOptions.NoInlining)] private static void TimedInteractionPromptR2Plus(string text, float time) { GuiManager.InteractionLayer.SetTimedInteractionPrompt(text, time, (ePUIMessageStyle)0); } } public class LastUsedGearSwitcher : Feature { public class LastUsedGearSwitcherSettings { [FSDisplayName("Quick Swap Key")] [FSDescription("Press this key to switch to the previously wielded gear.")] public KeyCode QuickSwitchKey { get; set; } = (KeyCode)120; [FSHide] [FSDisplayName("Prints Debug Info")] [FSDescription("Prints debug info to the console")] public bool DebugLog { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerSync_WantsToWieldSlot_Patch { public static void Prefix(PlayerSync __instance, InventorySlot slot) { //IL_003f: 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) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) IReplicator replicator = __instance.Replicator; bool? obj; if (replicator == null) { obj = null; } else { SNet_Player owningPlayer = replicator.OwningPlayer; obj = ((owningPlayer != null) ? new bool?(owningPlayer.IsLocal) : null); } bool? flag = obj; if (flag.GetValueOrDefault()) { InventorySlot wieldedSlot = __instance.GetWieldedSlot(); if (Settings.DebugLog) { FeatureLogger.Debug($"PlayerSync.WantsToWieldSlot: currentSlot:{wieldedSlot} -> slot:{slot} | _previousInventorySlot:{_previousInventorySlot}"); } if (wieldedSlot != slot) { _previousInventorySlot = wieldedSlot; } } } } private static readonly eFocusState _eFocusState_FPS = Utils.GetEnumFromName("FPS"); private static eFocusState _eFocusState_FPS_CommunicationDialog; private static InventorySlot _previousInventorySlot = (InventorySlot)10; public override string Name => "Last Used Gear Switcher"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Allows you to swap between the last two used weapons via a keypress"; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static LastUsedGearSwitcherSettings Settings { get; set; } public override void Init() { if (Is.R6OrLater) { Utils.TryGetEnumFromName("FPS_CommunicationDialog", ref _eFocusState_FPS_CommunicationDialog); } } public override void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if ((FocusStateManager.CurrentState == _eFocusState_FPS || (Is.R6OrLater && FocusStateManager.CurrentState == _eFocusState_FPS_CommunicationDialog)) && Input.GetKeyDown(Settings.QuickSwitchKey)) { SwitchToPreviousSlot(); } } public static void SwitchToPreviousSlot() { //IL_0005: 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_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_006b: 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_0054: Unknown result type (might be due to invalid IL or missing references) PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); InventorySlot previousInventorySlot = _previousInventorySlot; InventorySlot wieldedSlot = localPlayerAgent.Inventory.WieldedSlot; if (Settings.DebugLog) { FeatureLogger.Debug($"Switching to previous slot: {wieldedSlot} -> {previousInventorySlot}"); } localPlayerAgent.Sync.WantsToWieldSlot(previousInventorySlot, false); } } public class LoadoutRandomizer : Feature { public class LoadoutRandomizerSettings { [Localized] public enum InventorySlots { Primary, Special, Tool, Melee } [Localized] public enum RandomizerMode { True, NoDuplicate } [FSDisplayName("Do not randomize")] public List ExcludedSlots { get; set; } = new List(); [FSDisplayName("Mode")] public RandomizerMode Mode { get; set; } = RandomizerMode.NoDuplicate; } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_PageLoadout_SetupPatch { public static void Postfix(CM_PageLoadout __instance) { SetupViaInstance(__instance); } } private static CM_TimedButton _loadoutRandomizerButton; private static bool _hasBeenSetup = false; private static eGameStateName _eGameStateName_Lobby; private static readonly Dictionary _invSlotMap = new Dictionary { { Utils.GetEnumFromName("GearMelee"), LoadoutRandomizerSettings.InventorySlots.Melee }, { Utils.GetEnumFromName("GearStandard"), LoadoutRandomizerSettings.InventorySlots.Primary }, { Utils.GetEnumFromName("GearSpecial"), LoadoutRandomizerSettings.InventorySlots.Special }, { Utils.GetEnumFromName("GearClass"), LoadoutRandomizerSettings.InventorySlots.Tool } }; public override string Name => "Loadout Randomizer"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Adds a Loadout Randomizer button onto the loadout screen.\nSelect which gear to randomize via the settings below."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static LoadoutRandomizerSettings Config { get; set; } public static bool IsEnabled { get; set; } public override void Init() { //IL_0005: 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) _eGameStateName_Lobby = Utils.GetEnumFromName("Lobby"); } public override void OnEnable() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between I4 and Unknown if (!_hasBeenSetup) { SetupViaInstance(CM_PageLoadout.Current); } if ((byte)Feature.CurrentGameState == (int)_eGameStateName_Lobby) { SetButtonActive(); } } public override void OnDisable() { CM_TimedButton loadoutRandomizerButton = _loadoutRandomizerButton; if (loadoutRandomizerButton != null) { GameObject gameObject = ((Component)loadoutRandomizerButton).gameObject; if (gameObject != null) { gameObject.SetActive(false); } } } public void OnGameStateChanged(eGameStateName state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (state == _eGameStateName_Lobby) { SetButtonActive(); } else { SetButtonInactive(); } } public static void SetupViaInstance(CM_PageLoadout pageLoadout) { //IL_0012: 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_001a: 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) if (!((Object)(object)pageLoadout == (Object)null)) { CM_TimedButton readyButton = pageLoadout.m_readyButton; CM_Item changeLoadoutButton = null; GameBuildInfo buildInfo = Feature.BuildInfo; if (RundownFlagsExtensions.IsIncludedIn(((GameBuildInfo)(ref buildInfo)).Rundown, RundownFlagsExtensions.ToLatest((RundownFlags)32))) { GetChangeLoadoutButtonR6Plus(pageLoadout, out changeLoadoutButton); } SetupButton(readyButton, changeLoadoutButton); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void GetChangeLoadoutButtonR6Plus(CM_PageLoadout pageLoadout, out CM_Item changeLoadoutButton) { changeLoadoutButton = pageLoadout.m_changeLoadoutButton; } private static void SetupButton(CM_TimedButton readyUpButton, CM_Item changeLoadoutButton = null) { //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_0010: 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) if (_hasBeenSetup) { return; } GameBuildInfo buildInfo = Feature.BuildInfo; if (RundownFlagsExtensions.IsIncludedIn(((GameBuildInfo)(ref buildInfo)).Rundown, RundownFlagsExtensions.ToLatest((RundownFlags)32))) { SharedUtils.AddCMItemEvents((CM_Item)(object)readyUpButton, (Action)SetButtonInactive, (Action)null); if (changeLoadoutButton != null) { SharedUtils.AddCMItemEvents(changeLoadoutButton, (Action)SetButtonActive, (Action)null); } } CreateButton(readyUpButton); _hasBeenSetup = true; } private static CM_TimedButton CreateButton(CM_TimedButton prefab) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) _loadoutRandomizerButton = Object.Instantiate(((Component)prefab).gameObject, ((Component)prefab).transform.parent).GetComponent(); SharedUtils.SetCMItemEvents((CM_Item)(object)_loadoutRandomizerButton, (Action)OnRandomizeLoadoutButtonPressed, (Action)OnButtonHoverChanged); ((Component)_loadoutRandomizerButton).gameObject.transform.Translate(new Vector3(-500f, 0f, 0f)); BoxCollider2D component = ((Component)_loadoutRandomizerButton).GetComponent(); if ((Object)(object)component != (Object)null) { ((Collider2D)component).offset = new Vector2(0f, -40f); } ((CM_Item)_loadoutRandomizerButton).SetText("Randomize Loadout"); SharedUtils.ChangeColorTimedExpeditionButton(_loadoutRandomizerButton, new Color(1f, 1f, 1f, 0.5f)); SetButtonActive(); return _loadoutRandomizerButton; } private static void SetButtonActive(int _ = 0) { CM_TimedButton loadoutRandomizerButton = _loadoutRandomizerButton; if (loadoutRandomizerButton != null) { GameObject gameObject = ((Component)loadoutRandomizerButton).gameObject; if (gameObject != null) { gameObject.SetActive(IsEnabled); } } } public static void SetButtonInactive(int _ = 0) { CM_TimedButton loadoutRandomizerButton = _loadoutRandomizerButton; if (loadoutRandomizerButton != null) { GameObject gameObject = ((Component)loadoutRandomizerButton).gameObject; if (gameObject != null) { gameObject.SetActive(false); } } } public static void OnRandomizeLoadoutButtonPressed(int _) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: 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) FeatureLogger.Notice("Randomizer Button has been pressed!"); CM_PlayerLobbyBar val = null; val = ((IEnumerable)((IEnumerable)CM_PageLoadout.Current.m_playerLobbyBars).ToArray()).FirstOrDefault((Func)delegate(CM_PlayerLobbyBar plb) { SNet_Player player = plb.m_player; int? num = ((player != null) ? new int?(player.CharacterIndex) : null); PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); return num == ((localPlayerAgent != null) ? new int?(localPlayerAgent.CharacterID) : null); }); if ((Object)(object)val == (Object)null) { FeatureLogger.Error("Couldn't find the local players CM_PlayerLobbyBar, aborting randomization of loadout!"); return; } Enumerator enumerator = val.m_inventorySlotItems.GetEnumerator(); BackpackItem val2 = default(BackpackItem); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; InventorySlot key = current.Key; if (!_invSlotMap.TryGetValue(key, out var value) || !Config.ExcludedSlots.Contains(value)) { GearIDRange[] array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)GearManager.GetAllGearForSlot(key)); PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(key, ref val2); GearIDRange currentGearIdForSlot = val2.GearIDRange; LoadoutRandomizerSettings.RandomizerMode mode = Config.Mode; GearIDRange val3 = ((mode == LoadoutRandomizerSettings.RandomizerMode.True || mode != LoadoutRandomizerSettings.RandomizerMode.NoDuplicate) ? Utils.PickRandom(array) : Utils.PickRandomExcept(array, (Func)((GearIDRange random) => !currentGearIdForSlot.GetChecksum().Equals(random.GetChecksum())))); if (val3 == null) { FeatureLogger.Error($"Tried to randomize Gear for slot {key} but received null!"); continue; } FeatureLogger.Notice($"Picked random gear \"{val3.PublicGearName}\" for slot {key}!"); PlayerBackpackManager.ResetLocalAmmoStorage(false); PlayerBackpackManager.EquipLocalGear(val3); GearManager.RegisterGearInSlotAsEquipped(val3.PlayfabItemInstanceId, key); } } } public static void OnButtonHoverChanged(int i, bool b) { } } [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class NoDroppedMagazineSounds : Feature { public override string Name => "No Magazine Drop Sound"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Removes the globally audible sound whenever a magazine drops on the floor after a reload."; public override bool RequiresRestart => true; public override void OnGameDataInitialized() { if (!((Feature)this).Enabled) { return; } foreach (GearMagPartDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { allBlock.DropSoundType = (MagazineDropSoundType)0; } } } [EnableFeatureByDefault] public class NoNavMarkerHideInChat : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GuiManager_OnFocusStateChanged_Patch { private static eFocusState _eFocusState_FPS_TypingInChat; public static void Init() { //IL_0005: 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) _eFocusState_FPS_TypingInChat = Utils.GetEnumFromName("FPS_TypingInChat"); } public static void Postfix(eFocusState state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (state == _eFocusState_FPS_TypingInChat) { ((GuiLayer)GuiManager.NavMarkerLayer).SetVisible(true); } } } public override string Name => "See NavMarkers in Chat"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Prevent enemy pings from hiding whenever the chat is open."; } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class NoStoryDialog : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class WardenObjectiveManager_CheckAndExecuteEventsOnTrigger_Patch { [IsPrefix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PrefixR7(WardenObjectiveEventData eventToTrigger) { if (eventToTrigger.SoundSubtitle.HasValue) { FeatureLogger.Notice($"SoundEvent about to execute was: {eventToTrigger.SoundID} ({SoundEventCache.ReverseResolve(eventToTrigger.SoundID, false)})"); eventToTrigger.SoundID = 0u; } } [IsPrefix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PrefixR6(WardenObjectiveEventData eventToTrigger) { if (eventToTrigger.SoundID != 0) { FeatureLogger.Notice($"SoundEvent about to execute was: {eventToTrigger.SoundID} ({SoundEventCache.ReverseResolve(eventToTrigger.SoundID, false)})"); eventToTrigger.SoundID = 0u; } } } public override string Name => "Remove Story Dialog"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Removes all level-based voice events that come with subtitles.\naka Schaeffer-be-gone"; public static IArchiveLogger FeatureLogger { get; set; } } public class ReloadSoundCue : Feature { public class ReloadSoundCueSettings { [FSDisplayName("Test Sound Event")] [FSDescription("Plays the sound event below,\nit's a little janky and might not work depending on the sound, sorry!")] public FButton TestSoundButton { get; set; } = new FButton("Play Sound", (string)null, (Action)null, false); [FSDisplayName("Sound Event")] [FSDescription("The sound event to play whenever the reload has happened.")] public string SoundEvent { get; set; } = "HACKING_PUZZLE_CORRECT"; [FSDisplayName("Print Sound Events To Console")] [FSDescription("Prints all available sound events to the <#F00>console.\nWarning! This might freeze your game for a few seconds!\n\nSome events might not work because their playback conditions are not met!")] public FButton PrintSoundEventsButton { get; set; } = new FButton("Print To Console", (string)null, (Action)null, false); } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerInventoryLocal_DoReload_Patch { public static void Postfix() { PlaySound(); } } private static bool _hasPrintedEvents; public override string Name => "Reload Sound Cue"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Play a sound cue on reload the moment the bullets have entered your gun."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static ReloadSoundCueSettings Settings { get; set; } public override void OnButtonPressed(ButtonSetting setting) { if (setting.ButtonID == "TestSoundButton") { PlaySound(); } if (setting.ButtonID == "PrintSoundEventsButton") { if (!_hasPrintedEvents) { _hasPrintedEvents = true; SoundEventCache.DebugLog(FeatureLogger); } else { FeatureLogger.Info("Sound events have already been printed once, skipping! :)"); } } } private static void PlaySound() { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent != (Object)null && localPlayerAgent.Sound != null) { uint num = default(uint); if (SoundEventCache.TryResolve(Settings.SoundEvent, ref num)) { SharedUtils.SafePost(localPlayerAgent.Sound, num, true); } else { SharedUtils.SafePost(localPlayerAgent.Sound, SoundEventCache.Resolve("HACKING_PUZZLE_CORRECT", false), true); } } } } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] public class ResourcePrioritizationPings : Feature { [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerAgent_TriggerMarkerPing_R4_R5_Patch { private static PropertyAccessor A_PlayerAgent_CamPos; private static PropertyAccessor A_PlayerAgent_m_pingTargets; private static PropertyAccessor A_PlayerAgent_m_pingPos; public static void Init() { A_PlayerAgent_CamPos = PropertyAccessor.GetAccessor("CamPos", false); A_PlayerAgent_m_pingTargets = PropertyAccessor.GetAccessor("m_pingTarget", false); A_PlayerAgent_m_pingPos = PropertyAccessor.GetAccessor("m_pingPos", false); } public static void Prefix(PlayerAgent __instance, ref iPlayerPingTarget target, ref Vector3 worldPos) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_00cc: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Invalid comparison between Unknown and I4 //IL_0112: 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) //IL_0131: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)__instance == (Object)null || !((Agent)__instance).IsLocallyOwned || target == null) { return; } Il2CppStructArray val = Physics.RaycastAll(A_PlayerAgent_CamPos.Get(__instance), __instance.FPSCamera.Forward, 40f, LayerManager.MASK_PING_TARGET, (QueryTriggerInteraction)1); if (val == null || ((Il2CppArrayBase)(object)val).Length == 0) { return; } float num = -1f; foreach (RaycastHit item in (Il2CppArrayBase)(object)val) { RaycastHit current = item; iPlayerPingTarget componentInChildren = ((Component)((RaycastHit)(ref current)).collider).GetComponentInChildren(); if (componentInChildren != null && ((componentInChildren != null && (int)componentInChildren.PingTargetStyle == 11) || (componentInChildren != null && (int)componentInChildren.PingTargetStyle == 10))) { num = ((RaycastHit)(ref current)).distance; break; } } if (num < 0f) { return; } foreach (RaycastHit item2 in (Il2CppArrayBase)(object)val) { RaycastHit current2 = item2; iPlayerPingTarget componentInChildren2 = ((Component)((RaycastHit)(ref current2)).collider).GetComponentInChildren(); if (componentInChildren2 != null && (int)componentInChildren2.PingTargetStyle != 11 && (int)componentInChildren2.PingTargetStyle != 10 && ((RaycastHit)(ref current2)).distance < num + 1f) { target = componentInChildren2; worldPos = ((RaycastHit)(ref current2)).point; A_PlayerAgent_m_pingTargets.Set(__instance, componentInChildren2); A_PlayerAgent_m_pingPos.Set(__instance, ((RaycastHit)(ref current2)).point); break; } } } catch (Exception ex) { FeatureLogger.Exception(ex); } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerAgent_TriggerMarkerPing_Patch { public static bool Prefix(PlayerAgent __instance, ref iPlayerPingTarget target, ref Vector3 worldPos) { //IL_0024: 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_0069: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Invalid comparison between Unknown and I4 //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Invalid comparison between Unknown and I4 //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_0145: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)__instance == (Object)null || !((Agent)__instance).IsLocallyOwned || target == null) { return true; } LocalPlayerAgent val = SharedUtils.TryCastTo((Il2CppObjectBase)(object)__instance); Il2CppStructArray val2 = Physics.RaycastAll(val.CamPos, __instance.FPSCamera.Forward, 40f, LayerManager.MASK_PING_TARGET, (QueryTriggerInteraction)1); if (val2 == null || ((Il2CppArrayBase)(object)val2).Length == 0) { return true; } float num = -1f; foreach (RaycastHit item in (Il2CppArrayBase)(object)val2) { RaycastHit current = item; iPlayerPingTarget componentInChildren = ((Component)((RaycastHit)(ref current)).collider).GetComponentInChildren(); if (componentInChildren != null && ((componentInChildren != null && (int)componentInChildren.PingTargetStyle == 11) || (componentInChildren != null && (int)componentInChildren.PingTargetStyle == 10))) { num = ((RaycastHit)(ref current)).distance; break; } } if (num < 0f) { return true; } foreach (RaycastHit item2 in (Il2CppArrayBase)(object)val2) { RaycastHit current2 = item2; iPlayerPingTarget componentInChildren2 = ((Component)((RaycastHit)(ref current2)).collider).GetComponentInChildren(); if (componentInChildren2 != null && (int)componentInChildren2.PingTargetStyle != 11 && (int)componentInChildren2.PingTargetStyle != 10 && ((RaycastHit)(ref current2)).distance < num + 1f) { target = componentInChildren2; worldPos = ((RaycastHit)(ref current2)).point; val.m_pingTarget = componentInChildren2; val.m_pingPos = ((RaycastHit)(ref current2)).point; if (OverrideSoundsAndPings(worldPos, ((Component)((RaycastHit)(ref current2)).collider).gameObject)) { return false; } break; } } } catch (Exception ex) { FeatureLogger.Exception(ex); } return true; } } public override string Name => "Prioritize Resource Pings"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Resource Packs will be prioritized and show up with special icons and trigger voice lines when pinged by Middle-Mouse-Pings.\n(Yes, disinfect is ammo apparently)"; public static IArchiveLogger FeatureLogger { get; set; } public static uint Sound_DisinfectHere_ID { get; private set; } public static uint Sound_ToolHere_ID { get; private set; } public override void OnDatablocksReady() { Sound_DisinfectHere_ID = SoundEventCache.Resolve("PLAY_CL_DISINFECTIONHERE", false); Sound_ToolHere_ID = SoundEventCache.Resolve("PLAY_CL_TOOLREFILLHERE", false); } private static bool OverrideSoundsAndPings(Vector3 worldPos, GameObject gameObject) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0068: 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_003a: Unknown result type (might be due to invalid IL or missing references) bool result = false; uint num = 0u; eNavMarkerStyle val = (eNavMarkerStyle)12; ResourcePackPickup componentInChildren = gameObject.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { gameObject = ((Component)componentInChildren).gameObject; eResourceContainerSpawnType packType = componentInChildren.m_packType; if ((int)packType != 2) { if ((int)packType == 9) { num = Sound_DisinfectHere_ID; val = (eNavMarkerStyle)17; result = true; } } else { num = Sound_ToolHere_ID; val = (eNavMarkerStyle)3; result = true; } } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (num != 0) { PlayerVoiceManager.WantToSay(localPlayerAgent.CharacterID, num); } if ((int)val != 12) { GuiManager.AttemptSetPlayerPingStatus(localPlayerAgent, true, worldPos, val); localPlayerAgent.Sync.SendGenericInteract((TypeEnum)4, false); PlayerManager.Current.OnObjectHighlighted(((Agent)localPlayerAgent).CourseNode, gameObject); } return result; } } [EnableFeatureByDefault] public class SituationalAwareWeaponSwitch : Feature { public class SituationalAwareWeaponSwitchSettings { [Localized] public enum DramaState { ElevatorIdle, ElevatorGoingDown, Exploration, Alert, Sneaking, Encounter, Combat, Survival, IntentionalCombat } internal static readonly List defaultOptions = new List { DramaState.ElevatorIdle, DramaState.ElevatorGoingDown, DramaState.Exploration, DramaState.Alert, DramaState.Sneaking }; [FSHide] [FSDisplayName("Is First Time")] public bool IsFirstTime { get; set; } = true; [FSDisplayName("Log Weapon Switches to Console")] [FSDescription("Used to see what this Feature is doing in real time (check console!)")] public bool LogWeaponSwitchesToConsole { get; set; } [FSDisplayName("Prefer Melee")] [FSDescription("The states in which the game should switch to Melee instead of your Primary weapon.")] public List PreferMeleeStates { get; set; } = new List(); } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerBackpackManager_WieldFirstLocalGear_Patch { internal static List preferMeleeStates = new List { Utils.GetEnumFromName("ElevatorIdle"), Utils.GetEnumFromName("ElevatorGoingDown"), Utils.GetEnumFromName("Exploration"), Utils.GetEnumFromName("Sneaking"), Utils.GetEnumFromName("Alert") }; public static bool Prefix(ref bool preferMelee) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (PlayerBackpackManager.LocalBackpack.HasBackpackItem((InventorySlot)8)) { FeatureLogger.Debug($"Player has {8}, re-equipping that!"); PlayerManager.GetLocalPlayerAgent().Sync.WantsToWieldSlot((InventorySlot)8, false); return false; } if (Settings.LogWeaponSwitchesToConsole) { FeatureLogger.Notice($"Current drama state: {DramaManager.CurrentStateEnum}"); } if (preferMeleeStates.Any((DRAMA_State state) => state == DramaManager.CurrentStateEnum)) { preferMelee = true; } else { preferMelee = false; } if (Settings.LogWeaponSwitchesToConsole) { FeatureLogger.Notice($"Prefer melee: {preferMelee}"); } return true; } } public override string Name => "Situation Aware Weapon Switch"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Switch to either your Melee weapon or Primary depending on if you're sneaking around or in combat after depleting all of your throwables, exit a ladder or place down a sentry gun etc."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static SituationalAwareWeaponSwitchSettings Settings { get; set; } public override void OnEnable() { if (Settings.IsFirstTime) { Settings.PreferMeleeStates = new List(SituationalAwareWeaponSwitchSettings.defaultOptions); Settings.IsFirstTime = false; } RecreatePreferMeleeStatesList(); } public override void OnFeatureSettingChanged(FeatureSetting setting) { RecreatePreferMeleeStatesList(); } private void RecreatePreferMeleeStatesList() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) PlayerBackpackManager_WieldFirstLocalGear_Patch.preferMeleeStates = new List(); DRAMA_State item = default(DRAMA_State); foreach (SituationalAwareWeaponSwitchSettings.DramaState preferMeleeState in Settings.PreferMeleeStates) { if (Utils.TryGetEnumFromName(preferMeleeState.ToString(), ref item)) { PlayerBackpackManager_WieldFirstLocalGear_Patch.preferMeleeStates.Add(item); } } if (!Settings.LogWeaponSwitchesToConsole) { return; } FeatureLogger.Debug("DramaStates that prefer melee:"); foreach (DRAMA_State preferMeleeState2 in PlayerBackpackManager_WieldFirstLocalGear_Patch.preferMeleeStates) { FeatureLogger.Debug($"> {preferMeleeState2}"); } } } internal class SkipElevatorAnimation : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ElevatorRide_StartPreReleaseSequence_Patch { public static void Postfix() { ElevatorRide.SkipPreReleaseSequence(); } } public override string Name => "Skip Elevator Animation"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Automatically skips the elevator intro animation sequence without having to hold down a button."; } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class SortBoosters : Feature { private static bool _eventRegistered = false; private static readonly Action _onBoosterImplantInventoryChangedAction = OnBoosterImplantInventoryChanged; public override string Name => "Sort Boosters"; public override GroupBase Group => (GroupBase)(object)GroupManager.QualityOfLife; public override string Description => "Sorts your booster inventory by type and alphabetically"; public static IArchiveLogger FeatureLogger { get; set; } public override bool SkipInitialOnEnable => true; public override void OnGameDataInitialized() { SubscribeToInventoryChangedEvent(subscribe: true); } private static void SubscribeToInventoryChangedEvent(bool subscribe) { if (subscribe) { if (!_eventRegistered) { PersistentInventoryManager current = PersistentInventoryManager.Current; current.OnBoosterImplantInventoryChanged += Action.op_Implicit(_onBoosterImplantInventoryChangedAction); _eventRegistered = true; } } else if (_eventRegistered) { PersistentInventoryManager current2 = PersistentInventoryManager.Current; current2.OnBoosterImplantInventoryChanged -= Action.op_Implicit(_onBoosterImplantInventoryChangedAction); _eventRegistered = false; } } private static void OnBoosterImplantInventoryChanged() { foreach (Category item in (Il2CppArrayBase)(object)PersistentInventoryManager.Current.m_boosterImplantInventory.Categories) { item.Inventory = SharedUtils.ToIL2CPPListIfNecessary(((IEnumerable)item.Inventory.ToArray()).OrderBy(delegate(BoosterImplantInventoryItem b) { //IL_000b: 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_0036: 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) BoosterEffectCategory mainEffectType = b.Implant.Template.MainEffectType; return ((object)(BoosterEffectCategory)(ref mainEffectType)).ToString() + b.Implant.GetCompositPublicName(false) + ((Il2CppArrayBase)(object)b.Implant.Effects)[0].Value; }).ToList()); } FeatureLogger.Notice("Sorted Boosters!"); } public override void OnEnable() { SubscribeToInventoryChangedEvent(subscribe: true); } public override void OnDisable() { if (!Feature.IsApplicationQuitting) { SubscribeToInventoryChangedEvent(subscribe: false); } } } } namespace TheArchive.Features.Hud { internal class BioPingColor : Feature { public class BioPingColorSettings { [FSDisplayName("Bio Ping Color")] [FSDescription("Set the color of bio tracker pings: <#f00>/!\\")] public SColor PingColor { get; set; } = SColor.RED; [FSDisplayName("Separate Blob Color")] [FSDescription("Should blobs on the Bio Tracker Screen be a different color?")] public bool UseSeparateColorForTrackerDisplay { get; set; } [FSDisplayName("Bio Display Blob Color")] [FSDescription("The color of the blobs on the Bio Tracker Screen")] public SColor DisplayColor { get; set; } = SColor.RED; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class EnemyAgent_SyncPlaceNavMarkerTag_Patch { public static void Postfix(EnemyAgent __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) NavMarker obj = A_EnemyAgent_m_tagMarker.Get(__instance); if (obj != null) { obj.SetColor(_pingColor.Value); } SetScannerColor(__instance); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ES_Hibernate_CommonExit_Patch { public static void Postfix(ES_Hibernate __instance) { SetScannerColor(A_ES_Hibernate_m_enemyAgent.Get(__instance)); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ES_PathMove_CommonEnter_Patch { public static void Postfix(ES_PathMove __instance) { SetScannerColor(A_ES_PathMove_m_enemyAgent.Get(__instance)); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ES_PathMoveFlyer_CommonEnter_Patch { public static Type Type() { return typeof(ES_PathMoveFlyer); } public static void Postfix(ES_PathMoveFlyer __instance) { SetScannerColor(((ES_Base)__instance).m_enemyAgent); } } public static IValueAccessor A_EnemyAgent_m_tagMarker; public static IValueAccessor A_ES_Hibernate_m_enemyAgent; public static IValueAccessor A_ES_PathMove_m_enemyAgent; private static Color? _pingColor; private static Color? _displayColor; public override string Name => "Bio Ping Colors"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Customize the color of Bio Tracker Pings as well as the blobs on its display.\n\nSingle color, does not differentiate between enemies."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static BioPingColorSettings Settings { get; set; } public override void Init() { A_EnemyAgent_m_tagMarker = AccessorBase.GetValueAccessor("m_tagMarker", false); A_ES_Hibernate_m_enemyAgent = AccessorBase.GetValueAccessor("m_enemyAgent", false); A_ES_PathMove_m_enemyAgent = AccessorBase.GetValueAccessor("m_enemyAgent", false); } public override void OnEnable() { RefreshColorsIfNeeded(); } public override void OnFeatureSettingChanged(FeatureSetting setting) { if (setting.Type == typeof(SColor)) { _pingColor = null; _displayColor = null; RefreshColorsIfNeeded(); } } private static void RefreshColorsIfNeeded() { //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_0036: 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) if (!_pingColor.HasValue) { _pingColor = SColorExtensions.ToUnityColor(Settings.PingColor); } if (!_displayColor.HasValue) { _displayColor = SColorExtensions.ToUnityColor(Settings.DisplayColor); } } public static void SetScannerColor(EnemyAgent enemy) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)enemy == (Object)null)) { Color value = _pingColor.Value; Color value2 = _displayColor.Value; enemy.ScannerColor = (Settings.UseSeparateColorForTrackerDisplay ? value2 : value); } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class CarryItemMarker : Feature { public class CarryItemMarkerSettings { [FSDisplayName("Colorize Marker")] [FSDescription("Change the marker color.\nturn off for default green color")] public bool ColorizeMarker { get; set; } = true; [FSDisplayName("Show Is-Carrying Marker")] [FSDescription("Adds a \"Carrying\" Marker to players that carry a pickup.")] public bool ShowIsCarryingMarker { get; set; } = true; [FSDisplayName("Display Item Name")] public bool DisplayItemName { get; set; } = true; [FSSlider(/*Could not decode attribute arguments.*/)] [FSDisplayName("Item Name Size")] [FSDescription("Size of the name text.")] public float ItemNameSize { get; set; } = 1f; [FSHeader("Colors", true)] [ItemID(new string[] { "CELL" })] [FSDisplayName("CELL")] public SColor PowerCell { get; set; } = new SColor(0.8f, 0.471f, 0f, (float?)null); [ItemID(new string[] { "FOG_TURBINE" })] [FSDisplayName("FOG_TURBINE")] public SColor FogTurbine { get; set; } = new SColor(0.863f, 1f, 0.98f, (float?)null); [ItemID(new string[] { "NEONATE HSU", "NEONATE_HSU" })] [FSDisplayName("NEONATE_HSU")] public SColor Neonate { get; set; } = new SColor(0.153f, 0.666f, 0.478f, (float?)null); [ItemID(new string[] { "IMPRINTED NEONATE HSU" })] [FSDisplayName("IMPRINTED_NEONATE_HSU")] public SColor ImprintedNeonate { get; set; } = new SColor(0.6f, 0.215f, 0.062f, (float?)null); [ItemID(new string[] { "CRYO" })] [FSDisplayName("CRYO")] public SColor Cryo { get; set; } = new SColor(0f, 0.819f, 1f, (float?)null); [ItemID(new string[] { "Carry_CargoCrate_Generic", "CARGO" })] [FSDisplayName("CARGO")] public SColor Cargo { get; set; } = new SColor(0.01f, 0.514f, 0f, (float?)null); [ItemID(new string[] { "Carry_CargoCrate_Generic_R2A1" })] [FSDisplayName("CARGO (R2A1)")] public SColor CargoAlternate { get; set; } = new SColor(0.71f, 0.71f, 0.71f, (float?)null); [ItemID(new string[] { "HISEC_CARGO" })] [FSDisplayName("HISEC_CARGO")] public SColor CargoHisec { get; set; } = new SColor(0.435f, 0.58f, 0f, (float?)null); [ItemID(new string[] { "HISEC_CARGO_OPEN" })] [FSDisplayName("HISEC_CARGO_OPEN")] public SColor OpenCargo { get; set; } = new SColor(0.419f, 0.455f, 0.314f, (float?)null); [ItemID(new string[] { "DATA_SPHERE" })] [FSDisplayName("DATA_SPHERE")] public SColor DataSphere { get; set; } = new SColor(0.36f, 0.165f, 0.525f, (float?)null); [ItemID(new string[] { "COLLECTION_CASE" })] [FSDisplayName("COLLECTION_CASE")] public SColor CollectionCase { get; set; } = new SColor(0.808f, 0.62f, 0.753f, (float?)null); [ItemID(new string[] { "MATTER_WAVE_PROJECTOR" })] [FSDisplayName("MATTER_WAVE_PROJECTOR")] public SColor MatterWaveProjector { get; set; } = new SColor(0.133f, 0.133f, 0.827f, (float?)null); [FSDisplayName("Fallback Color")] public SColor Fallback { get; set; } = new SColor(0.341f, 0.576f, 0.137f, (float?)null); [FSHeader("Static Colors", true)] [FSDisplayName("Use Static Name Color")] public bool UseStaticColorForName { get; set; } [FSDisplayName("Static Name Color")] [FSDescription("Enable setting above to use this color for every pickup name.")] public SColor StaticNameColor { get; set; } = new SColor(0.8f, 0.8f, 0.8f, (float?)null); [FSDisplayName("Use Static Marker Color")] public bool UseStaticColorForMarker { get; set; } [FSDisplayName("Static Marker Color")] [FSDescription("Enable setting above to use this color for every pickup marker.")] public SColor StaticMarkerColor { get; set; } = new SColor(0.8f, 0.8f, 0.8f, (float?)null); } private class ItemIDAttribute : Attribute { public string[] IDs { get; private set; } public ItemIDAttribute(params string[] id) { IDs = id; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class LG_PickupItem_Sync_Setup_Patch { public static void Postfix(LG_PickupItem_Sync __instance) { SubscribeToOnSyncStateChange(__instance); } } public static readonly Color MARKER_GREEN = new Color(0.341f, 0.576f, 0.137f); private static readonly Dictionary _idToSColorProp = new Dictionary(); public const string MARKER_GO_NAME = "CarryItemMarker_MarkerHolder"; public override string Name => "Carry Item Marker"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Adds a marker for whenever someone carries a big pickup like CELLs or FOG_TURBINEs\n\nAdditionally colorizes the marker based on what item it is."; public static bool IsEnabled { get; set; } public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static CarryItemMarkerSettings Settings { get; set; } public override void Init() { foreach (PropertyInfo item in from pi in typeof(CarryItemMarkerSettings).GetProperties(BindingFlags.Instance | BindingFlags.Public) where pi.GetCustomAttribute() != null select pi) { string[] iDs = item.GetCustomAttribute().IDs; foreach (string key in iDs) { _idToSColorProp.Add(key, item); } } } public static bool GetColor(string id, out SColor col) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!_idToSColorProp.TryGetValue(id, out var value)) { col = SColor.WHITE; return false; } col = (SColor)value.GetValue(Settings); return true; } public static bool TryGetOrAddMarkerPlacer(PlayerAgent playerAgent, out PlaceNavMarkerOnGO markerPlacer) { markerPlacer = GetOrAddMarkerPlacer(playerAgent); return (Object)(object)markerPlacer != (Object)null; } private static PlaceNavMarkerOnGO GetOrAddMarkerPlacer(PlayerAgent playerAgent) { //IL_001f: 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_0045: 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) Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)playerAgent).transform, "CarryItemMarker_MarkerHolder"); PlaceNavMarkerOnGO val; if ((Object)(object)childWithExactName == (Object)null) { childWithExactName = new GameObject("CarryItemMarker_MarkerHolder").transform; Bounds maxBounds = SharedUtils.GetMaxBounds(((Component)playerAgent).gameObject); childWithExactName.SetParent(((Component)playerAgent).transform); childWithExactName.SetPositionAndRotation(((Bounds)(ref maxBounds)).center, Quaternion.identity); val = ((Component)childWithExactName).gameObject.AddComponent(); val.type = (eMarkerType)1; val.PlaceMarker(((Component)childWithExactName).gameObject); val.SetMarkerVisible(false); } else { val = ((Component)childWithExactName).GetComponent(); } return val; } public static void OnSyncStateChanged(LG_PickupItem_Sync sync, ePickupItemStatus status, pPickupPlacement placement, PlayerAgent player, bool isRecall) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0036: 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_0050: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_00c1: 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_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Invalid comparison between Unknown and I4 if (!IsEnabled) { return; } CarryItemPickup_Core component = ((Component)sync).GetComponent(); if ((Object)(object)component == (Object)null) { return; } try { Color val = MARKER_GREEN; if (Settings.UseStaticColorForMarker) { val = SColorExtensions.ToUnityColor(Settings.StaticMarkerColor); } else if (Settings.ColorizeMarker) { val = TryGetColorFor(((Item)component).ItemDataBlock); } Color val2 = (Settings.UseStaticColorForName ? SColorExtensions.ToUnityColor(Settings.StaticNameColor) : val); int num = Mathf.Clamp(Mathf.RoundToInt(60f * Settings.ItemNameSize), 6, 300); string text = (Settings.DisplayItemName ? $"<{SColorExtensions.ToHexString(val2)}>{((Item)component).PublicName}" : string.Empty); component.m_navMarkerPlacer.UpdateName(text, ""); component.m_navMarkerPlacer.UpdatePlayerColor(val); if (!((Object)(object)player == (Object)null) && TryGetOrAddMarkerPlacer(player, out var markerPlacer)) { if (!Settings.ShowIsCarryingMarker) { markerPlacer.SetMarkerVisible(false); return; } markerPlacer.UpdateName(Settings.DisplayItemName ? $"<#FFF>Carrying" : string.Empty, text); markerPlacer.UpdatePlayerColor(val); markerPlacer.SetMarkerVisible((int)status == 1 && !((Agent)player).IsLocallyOwned); } } catch (Exception ex) { FeatureLogger.Exception(ex); } } private static Color TryGetColorFor(ItemDataBlock itemDataBlock) { //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) return SColorExtensions.ToUnityColor(TryGetSColorFor(itemDataBlock)); } private static SColor TryGetSColorFor(ItemDataBlock itemDataBlock) { //IL_000f: 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_0020: Unknown result type (might be due to invalid IL or missing references) if (GetColor(((GameDataBlockBase)(object)itemDataBlock).name, out var col)) { return col; } if (GetColor(itemDataBlock.terminalItemShortName, out col)) { return col; } return Settings.Fallback; } public static void SubscribeToOnSyncStateChange(LG_PickupItem_Sync pickupSync) { LG_PickupItem_Sync obj = pickupSync; obj.OnSyncStateChange += Action.op_Implicit((Action)delegate(ePickupItemStatus status, pPickupPlacement placement, PlayerAgent player, bool recall) { //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) OnSyncStateChanged(pickupSync, status, placement, player, recall); }); } } public class CombatIndicator : Feature { public class CombatIndicatorSettings { [Localized] public enum CombatIndicatorStyle { Simple, Detailed } [FSDisplayName("Style")] public CombatIndicatorStyle Style { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class DramaManager_ChangeState_Patch { public static void Postfix(DRAMA_State state) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasCombatIndicator) { ((TMP_Text)CurrentCombatIndicator).text = GetStateString(state); if (!Is.R6OrLater) { JankTextMeshProUpdaterOnce.Apply(CurrentCombatIndicator); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_LocalPlayerStatus_Start_Patch { public static void Postfix(PUI_LocalPlayerStatus __instance) { if (GetOrSetupCombatIndicator(__instance, out var combatIndicatorTMP)) { CurrentCombatIndicator = combatIndicatorTMP; } } } private static DRAMA_State _DRAMA_State_Encounter; public override string Name => "Combat Indicator"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Displays the current drama state of the game.\n(Above the health bar, right side)\n\nBasically a visual representation of what the music is doing."; public override bool SkipInitialOnEnable => true; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static CombatIndicatorSettings Settings { get; set; } public static TextMeshPro CurrentCombatIndicator { get; private set; } public static bool HasCombatIndicator => (Object)(object)CurrentCombatIndicator != (Object)null; public override void Init() { //IL_0005: 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) _DRAMA_State_Encounter = Utils.GetEnumFromName("Encounter"); } public override void OnEnable() { if (GetOrSetupCombatIndicator(out var combatIndicatorTMP)) { CurrentCombatIndicator = combatIndicatorTMP; } } public override void OnDisable() { if (!Feature.IsApplicationQuitting && (Object)(object)CurrentCombatIndicator != (Object)null) { Object.Destroy((Object)(object)((Component)CurrentCombatIndicator).gameObject); } } public static bool GetOrSetupCombatIndicator(out TextMeshPro combatIndicatorTMP) { PlayerGuiLayer playerLayer = GuiManager.PlayerLayer; return GetOrSetupCombatIndicator((playerLayer != null) ? playerLayer.m_playerStatus : null, out combatIndicatorTMP); } public static bool GetOrSetupCombatIndicator(PUI_LocalPlayerStatus localPlayerStatus, out TextMeshPro combatIndicatorTMP) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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) combatIndicatorTMP = null; if ((Object)(object)localPlayerStatus == (Object)null) { return false; } Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)localPlayerStatus).transform, "CombatIndicator"); if ((Object)(object)childWithExactName != (Object)null) { combatIndicatorTMP = ((Component)childWithExactName).GetComponent(); return true; } combatIndicatorTMP = Object.Instantiate(localPlayerStatus.m_healthText); ((Object)combatIndicatorTMP).name = "CombatIndicator"; combatIndicatorTMP.transform.SetParent(((Component)localPlayerStatus).transform); combatIndicatorTMP.transform.localPosition = new Vector3(245f, 27.5f, 0f); float num = 0.625f; combatIndicatorTMP.transform.localScale = new Vector3(num, num, num); ((Component)combatIndicatorTMP).GetComponent().sizeDelta = new Vector2(300f, 25f); ((TMP_Text)combatIndicatorTMP).alignment = (TextAlignmentOptions)516; ((TMP_Text)combatIndicatorTMP).characterSpacing = -4.5f; ((TMP_Text)combatIndicatorTMP).text = GetStateString(DramaManager.CurrentStateEnum); ((Graphic)combatIndicatorTMP).color = SharedUtils.WithAlpha(Color.white, 0.1961f); ((Component)combatIndicatorTMP).gameObject.SetActive(false); ((Component)combatIndicatorTMP).gameObject.SetActive(true); JankTextMeshProUpdaterOnce.Apply(combatIndicatorTMP); return true; } public static string GetStateString(DRAMA_State state) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) switch (Settings.Style) { case CombatIndicatorSettings.CombatIndicatorStyle.Simple: if (state < _DRAMA_State_Encounter) { return "OutOfCombat"; } return "InCombat"; default: return ((object)(DRAMA_State)(ref state)).ToString(); } } } [EnableFeatureByDefault] public class DetailedExpeditionDisplay : Feature { public class RundownInHeaderSettings { [FSDisplayName("ALT:// and OG:// prefixes")] [FSDescription("Adds ALT:// or OG:// before any mention of the expedition.\n\nOG:// for the original releases\nALT:// for the re-releases")] public bool IncludeALTorOGText { get; set; } = true; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageExpeditionSuccess_OnEnable_Patch { public static void Postfix(CM_PageExpeditionSuccess __instance) { //IL_0038: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected I4, but got Unknown string text = ((TMP_Text)__instance.m_expeditionName).text; if (IsOGBuild && !Is.R2 && !Is.R3) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(1, 2); defaultInterpolatedStringHandler.AppendLiteral("R"); GameBuildInfo buildInfo = Feature.BuildInfo; defaultInterpolatedStringHandler.AppendFormatted((int)((GameBuildInfo)(ref buildInfo)).Rundown); defaultInterpolatedStringHandler.AppendFormatted(text); text = defaultInterpolatedStringHandler.ToStringAndClear(); } if (Settings.IncludeALTorOGText) { text = (IsAlt(text) ? ("ALT://" + text) : ("OG://" + text)); } ((TMP_Text)__instance.m_expeditionName).text = text; } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageMap__SetExpeditionName__Patch { public static void Prefix(ref string name) { //IL_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected I4, but got Unknown if (name.StartsWith("OG://") || name.StartsWith("ALT://")) { return; } if (IsOGBuild) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(1, 2); defaultInterpolatedStringHandler.AppendLiteral("R"); GameBuildInfo buildInfo = Feature.BuildInfo; defaultInterpolatedStringHandler.AppendFormatted((int)((GameBuildInfo)(ref buildInfo)).Rundown); defaultInterpolatedStringHandler.AppendFormatted(name); name = defaultInterpolatedStringHandler.ToStringAndClear(); } if (Settings.IncludeALTorOGText) { if (IsAlt(name)) { name = "ALT://" + name; } else { name = "OG://" + name; } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerGuiLayer__UpdateObjectiveHeader__Patch { [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void Prefix(ref string header) { //IL_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(1, 2); defaultInterpolatedStringHandler.AppendLiteral("R"); GameBuildInfo buildInfo = Feature.BuildInfo; defaultInterpolatedStringHandler.AppendFormatted((int)((GameBuildInfo)(ref buildInfo)).Rundown); defaultInterpolatedStringHandler.AppendFormatted(header); header = defaultInterpolatedStringHandler.ToStringAndClear(); if (Settings.IncludeALTorOGText) { header = "OG://" + header; } } [IsPostfix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PostfixR7(PlayerGuiLayer __instance) { //IL_0033: 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) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected I4, but got Unknown string text = ((TMP_Text)__instance.m_wardenObjective.m_header).text; TextMeshPro header = __instance.m_wardenObjective.m_header; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(1, 2); defaultInterpolatedStringHandler.AppendLiteral("R"); GameBuildInfo buildInfo = Feature.BuildInfo; defaultInterpolatedStringHandler.AppendFormatted((int)((GameBuildInfo)(ref buildInfo)).Rundown); defaultInterpolatedStringHandler.AppendFormatted(text); ((TMP_Text)header).text = defaultInterpolatedStringHandler.ToStringAndClear(); } [IsPostfix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PostfixAlt(PlayerGuiLayer __instance) { string text = ((TMP_Text)__instance.m_wardenObjective.m_header).text; if (Settings.IncludeALTorOGText) { if (text.StartsWith("R7") || text.StartsWith("R8")) { ((TMP_Text)__instance.m_wardenObjective.m_header).text = "OG://" + text; } else { ((TMP_Text)__instance.m_wardenObjective.m_header).text = "ALT://" + text; } } } } public const string ALT_TEXT = "ALT://"; public const string OG_TEXT = "OG://"; public override string Name => "Detailed Expedition Display"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Adds the current Rundown Number into the Header as well as onto the Map, Objectives and Success screens."; public static bool IsOGBuild { get; private set; } [FeatureConfig] public static RundownInHeaderSettings Settings { get; set; } public override bool ShouldInit() { return !Feature.IsPlayingModded; } public override void Init() { IsOGBuild = !Is.A1OrLater; } private static bool IsAlt(string header) { if (IsOGBuild) { return false; } for (int i = 1; i <= 6; i++) { if (header.StartsWith("R" + i)) { return true; } } return false; } } public class DisplaySentryArchetypeName : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_Inventory_UpdateInfoForItem_Patch { private static IValueAccessor> _m_inventorySlots; private static IValueAccessor _Item_ItemDataBlock; public static void Init() { _m_inventorySlots = AccessorBase.GetValueAccessor>("m_inventorySlots", false); _Item_ItemDataBlock = AccessorExtensions.OrAlternative(AccessorBase.GetValueAccessor("ItemDataBlock", false), (Func>)(() => AccessorBase.GetValueAccessor("ItemData", false))); } public static void Postfix(PUI_Inventory __instance, BackpackItem bpItem) { //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_006b: 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) if ((Object)(object)((bpItem != null) ? bpItem.Instance : null) == (Object)null || ((bpItem != null) ? bpItem.GearIDRange : null) == null || bpItem.GearIDRange.GetCompID((eGearComponent)2) != 12) { return; } Item instance = bpItem.Instance; InventorySlot inventorySlot = _Item_ItemDataBlock.Get(instance).inventorySlot; ArchetypeDataBlock archetypeDataForFireMode = SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode((eWeaponFireMode)bpItem.GearIDRange.GetCompID((eGearComponent)1)); if (_m_inventorySlots.Get(__instance).ContainsKey(inventorySlot)) { PUI_InventoryItem obj = _m_inventorySlots.Get(__instance)[inventorySlot]; string text = string.Empty; if (obj.IsDeployed) { text = "" + SharedUtils.GetLocalizedTextSafe(2505980868u, false, "DEPLOYED") + " "; } obj.SetArchetypeName(text + GetPublicName(archetypeDataForFireMode)); } } } private static readonly IValueAccessor _ArchetypeDataBlock_PublicName = AccessorBase.GetValueAccessor("PublicName", false); public override string Name => "Display Sentry Type"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Display the Sentry Type (Sniper, Burst, Auto, Shotgun) for remote players instead of the nondescript \"Sentry Gun\" on the map screen."; public static string GetPublicName(ArchetypeDataBlock archetypeDataBlock) { if (archetypeDataBlock == null) { return string.Empty; } if (Is.R6OrLater) { return GetPublicNameR6(archetypeDataBlock); } return _ArchetypeDataBlock_PublicName.Get(archetypeDataBlock); } [MethodImpl(MethodImplOptions.NoInlining)] private static string GetPublicNameR6(ArchetypeDataBlock archetypeDataBlock) { return LocalizedText.op_Implicit(archetypeDataBlock.PublicName); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class DontHideLoadoutUI : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_UpdatePlayer_Patch { public static void Postfix(CM_PlayerLobbyBar __instance) { CM_PlayerLobbyBar_HideLoadoutUI_Patch.Prefix(__instance, !CollidersEnabled); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_HideLoadoutUI_Patch { public static bool Prefix(CM_PlayerLobbyBar __instance, bool hide) { if (GameStateManager.IsInExpedition) { return false; } CollidersEnabled = !hide; if ((Object)(object)__instance.m_player != (Object)null && (__instance.m_player.IsLocal || (SNet.IsMaster && SharedUtils.SafeIsBot(__instance.m_player)))) { UpdateLobbyBarColliders(__instance); } if (!hide) { return true; } return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageLoadout_UpdateReadyState_Patch { public static void Postfix(CM_PageLoadout __instance) { __instance.m_copyLobbyIdRoot.SetActive(!SNet.IsExternalMatchMakingActive); } } public override string Name => "Don't Hide Loadout UI"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Keep loadout visible after readying up / in expedition"; public static bool CollidersEnabled { get; private set; } = true; public override void OnDisable() { if (Feature.IsApplicationQuitting) { return; } CollidersEnabled = true; foreach (CM_PlayerLobbyBar item in (Il2CppArrayBase)(object)CM_PageLoadout.Current.m_playerLobbyBars) { UpdateLobbyBarColliders(item); } } public static void SetColliderEnabledState(Transform trans) { object obj; if (trans == null) { obj = null; } else { GameObject gameObject = ((Component)trans).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent() : null); } Collider2D val = (Collider2D)obj; if (!((Object)(object)val == (Object)null)) { ((Behaviour)val).enabled = CollidersEnabled; } } public static void UpdateLobbyBarColliders(CM_PlayerLobbyBar playerLobbyBar) { SharedUtils.ForEachChildDo(playerLobbyBar.m_pillarRoot.transform, (Action)SetColliderEnabledState, true); SharedUtils.ForEachChildDo(playerLobbyBar.m_boosterImplantAlign, (Action)SetColliderEnabledState, true); SetColliderEnabledState(((Component)playerLobbyBar.m_clothesButton).transform); } } [EnableFeatureByDefault] public class EnhancedExpeditionTimer : Feature { [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageObjectives__Setup__Patch { public static void Postfix(CM_PageObjectives __instance) { MoveTimer(moveToEnhanced: true, __instance); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class SNet_Capture__OnReceiveBufferCompletion__Patch { private static void Postfix(pBufferCompletion completion) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)completion.type == 1) { _stagedLateJoinTimePassed = new TimeSpan((long)(completion.data.progressionTime * 1000f) * 10000); IsTimerAccurate = true; } } } public static IStaticValueAccessor A_MainMenuGuiLayer_Current; private static readonly eGameStateName _eGameStateName_InLevel = Utils.GetEnumFromName("InLevel"); private static readonly eGameStateName _eGameStateName_ExpeditionSuccess = Utils.GetEnumFromName("ExpeditionSuccess"); private static readonly eGameStateName _eGameStateName_ExpeditionFail = Utils.GetEnumFromName("ExpeditionFail"); private static readonly Stopwatch _expeditionTimer = new Stopwatch(); private static TimeSpan? _stagedLateJoinTimePassed; private static TimeSpan? _lateJoinTimePassed; public override string Name => "Enhanced Expedition Timer"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "A more accurate mission timer."; public static IArchiveLogger FeatureLogger { get; set; } public static bool IsTimerActive => _expeditionTimer.IsRunning; public static TimeSpan ElapsedMissionTime { get { if (_lateJoinTimePassed.HasValue) { return _expeditionTimer.Elapsed.Add(_lateJoinTimePassed.Value); } return _expeditionTimer.Elapsed; } } public static string TotalElapsedMissionTimeFormatted => $"{ElapsedMissionTime:hh\\:mm\\:ss\\.ffffff}"; public static bool IsTimerAccurate { get; private set; } public static bool TimerHasBeenMoved { get; private set; } = false; public override void Init() { A_MainMenuGuiLayer_Current = AccessorBase.GetValueAccessor("Current", false) as IStaticValueAccessor; } public override void OnEnable() { //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) //IL_0008: 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_0010: 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_0018: Unknown result type (might be due to invalid IL or missing references) eGameStateName val = (eGameStateName)(byte)Feature.CurrentGameState; if (val == _eGameStateName_InLevel || val == _eGameStateName_ExpeditionFail || val == _eGameStateName_ExpeditionSuccess) { IsTimerAccurate = false; if (!_expeditionTimer.IsRunning) { _expeditionTimer.Start(); } } MoveTimer(moveToEnhanced: true); } public override void OnDisable() { if (_expeditionTimer.IsRunning) { _expeditionTimer.Stop(); } MoveTimer(moveToEnhanced: false); } public void OnGameStateChanged(eGameStateName state) { //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) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_000f: 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_00a5: 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_0083: Unknown result type (might be due to invalid IL or missing references) eGameStateName val = (eGameStateName)(byte)Feature.PreviousGameState; if (state == _eGameStateName_InLevel) { if (val == _eGameStateName_ExpeditionFail) { FeatureLogger.Debug("Checkpoint has been loaded, total current time spent in expedition: " + TotalElapsedMissionTimeFormatted); _expeditionTimer.Start(); return; } FeatureLogger.Debug("New expedition has begun, timer started!"); _lateJoinTimePassed = _stagedLateJoinTimePassed; _stagedLateJoinTimePassed = null; IsTimerAccurate = true; _expeditionTimer.Reset(); _expeditionTimer.Start(); } else if (state == _eGameStateName_ExpeditionSuccess || state == _eGameStateName_ExpeditionFail) { _expeditionTimer.Stop(); FeatureLogger.Debug($"{state}, timer stopped."); FeatureLogger.Notice("Total mission time: " + TotalElapsedMissionTimeFormatted + " " + ((!IsTimerAccurate) ? "(Timer not accurate due to late start!)" : string.Empty)); } } public static void MoveTimer(bool moveToEnhanced, CM_PageObjectives objectives = null) { //IL_007a: 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_0093: 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_0051: 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) object obj = objectives; if (obj == null) { MainMenuGuiLayer current = MainMenuGuiLayer.Current; obj = ((current != null) ? current.PageObjectives : null); } CM_PageObjectives val = (CM_PageObjectives)obj; if ((Object)(object)val == (Object)null) { return; } if (moveToEnhanced) { if (!TimerHasBeenMoved) { TimerHasBeenMoved = true; Transform transform = val.m_expeditionTime.transform; transform.position += new Vector3(140f, 0f, 0f); } } else if (TimerHasBeenMoved) { TimerHasBeenMoved = false; Transform transform2 = val.m_expeditionTime.transform; transform2.position -= new Vector3(140f, 0f, 0f); } } public override void LateUpdate() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between I4 and Unknown if ((byte)Feature.CurrentGameState == (int)_eGameStateName_InLevel) { CM_PageObjectives pageObjectives = MainMenuGuiLayer.Current.PageObjectives; ((TMP_Text)pageObjectives.m_expeditionTime).text = TotalElapsedMissionTimeFormatted; JankTextMeshProUpdaterOnce.UpdateMesh(pageObjectives.m_expeditionTime); } } } public class ExpeditionResultsScreenTweaks : Feature { public class ExpeditionResultsScreenTweaksSettings { [FSDisplayName("Add Failed Expedition Timer")] [FSDescription("Adds an expedition timer to the fail screen that displayes total time spent in the level.\n\n(Requires Enhanced Expedition Timer to be enabled!)")] public bool ShowTimerOnFailScreen { get; set; } = true; [FSDisplayName("Success Expedition Timer")] [FSDescription("Replaces the default timer with the enhanced version.\n(Adds a timer to R1-R3)\n\n(Requires Enhanced Expedition Timer to be enabled!)")] public bool OverrideEnhancedTimerOnSuccessScreen { get; set; } = true; [FSDisplayName("Show Level Seed")] [FSDescription("Adds the 'session seed' to the fail and success screens.\n\n(This is the seed used for boxes, enemy count and alarm scan locations.")] public bool ShowSessionSeed { get; set; } = true; [FSDisplayName("Disable Success Background")] [FSDescription("Removes the background image on the Expedition Success Screen.\n(background turns black instead)")] [FSRundownHint(/*Could not decode attribute arguments.*/)] [FSIdentifier("DisableSuccessMask")] public bool DisableSuccessMask { get; set; } [FSDisplayName("Disable Fail Background")] [FSDescription("Removes the background image on the Expedition Fail Screen.\n(background turns black instead)")] [FSRundownHint(/*Could not decode attribute arguments.*/)] [FSIdentifier("DisableFailSkull")] public bool DisableFailSkull { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageExpeditionFail_OnEnable_Patch { public static void Postfix(CM_PageExpeditionFail __instance) { ShowExtraUIOnExpdFailScreen(show: true, __instance); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageExpeditionSuccess_OnEnable_Patch { public static void Postfix(CM_PageExpeditionSuccess __instance) { ShowExtraUIOnExpdSuccessScreen(show: true, __instance); if (!Settings.OverrideEnhancedTimerOnSuccessScreen) { return; } try { string[] array = ((TMP_Text)__instance.m_expeditionName).text.Split('-'); string value = ((array.Length > 1) ? string.Join("-", array.Take(array.Length - 1)) : array[0]); string text; if (FeatureManager.IsFeatureEnabled("EnhancedExpeditionTimer", false)) { text = EnhancedExpeditionTimer.TotalElapsedMissionTimeFormatted; if (!EnhancedExpeditionTimer.IsTimerAccurate) { text += " <#aaa>(Unverified)"; } } else { text = GetFallbackExpeditionTime(); if (string.IsNullOrWhiteSpace(text)) { text = "No timer available, enable 'EnhancedExpeditionTimer' or disable 'ResultsScreenTweaks > Success Expedition Timer' in mod settings."; } } string value2 = string.Empty; if (Is.R1OrLater && !Is.R4OrLater) { value2 = " "; } string text2 = $"{value}{value2}- {text}"; ((TMP_Text)__instance.m_expeditionName).text = text2; } catch (Exception ex) { FeatureLogger.Exception(ex); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageExpeditionSuccess_Setup_Patch { public static void Postfix(CM_PageExpeditionSuccess __instance) { if (Settings.DisableSuccessMask) { SetMaskBackgroundActive(((Component)__instance).transform, active: false); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageExpeditionFail_Setup_Patch { public static void Postfix(CM_PageExpeditionFail __instance) { if (Settings.DisableFailSkull) { SetMaskBackgroundActive(((Component)__instance).transform, active: false); } } } [CompilerGenerated] private sealed class d__29 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public bool isFail; public TextMeshPro tmp; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; int value = (isFail ? 30 : (Is.R4OrLater ? 70 : 30)); ((TMP_Text)tmp).text = $"SessionSeed: {RundownManager.GetActiveExpeditionData().sessionSeed}"; JankTextMeshProUpdaterOnce.UpdateMesh(tmp); <>2__current = CoroutineManager.BlinkIn(((Component)tmp).gameObject, 1.25f); <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__30 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TextMeshPro tmp; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__30(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: { <>1__state = -1; string text; if (FeatureManager.IsFeatureEnabled("EnhancedExpeditionTimer", false)) { text = EnhancedExpeditionTimer.TotalElapsedMissionTimeFormatted; if (!EnhancedExpeditionTimer.IsTimerAccurate) { text += " <#aaa>(Unverified)"; } } else { text = GetFallbackExpeditionTime(); if (string.IsNullOrWhiteSpace(text)) { text = "No timer available, enable 'EnhancedExpeditionTimer' or disable 'ResultsScreenTweaks > Add Failed Expedition Timer' in mod settings."; } } ((TMP_Text)tmp).text = "" + text + ""; JankTextMeshProUpdaterOnce.UpdateMesh(tmp); <>2__current = CoroutineManager.BlinkIn(((Component)tmp).gameObject, 0f); <>1__state = 2; return true; } case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IStaticValueAccessor A_MainMenuGuiLayer_Current; public const string SESSION_SEED_GO_NAME = "SessionSeed"; public const string EXPEDITION_TIMER_GO_NAME = "ExpeditionTimer"; public const string EXPEDITION_TIMER_UNVERIFIED = "<#aaa>(Unverified)"; public override string Name => "Results Screen Tweaks"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Tweak the Expedition Fail/Success screens!"; public override bool SkipInitialOnEnable => true; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static ExpeditionResultsScreenTweaksSettings Settings { get; set; } public override void OnFeatureSettingChanged(FeatureSetting setting) { if (setting.Identifier == "DisableSuccessMask") { SetSuccessMaskActive(!Settings.DisableSuccessMask); } if (setting.Identifier == "DisableFailSkull") { SetFailMaskActive(!Settings.DisableFailSkull); } } public override void OnEnable() { if (Settings.DisableSuccessMask) { SetSuccessMaskActive(active: false); } if (Settings.DisableFailSkull) { SetFailMaskActive(active: false); } ShowExtraUIOnExpdFailScreen(show: true); ShowExtraUIOnExpdSuccessScreen(show: true); } public override void OnDisable() { SetSuccessMaskActive(active: true); SetFailMaskActive(active: true); ShowExtraUIOnExpdFailScreen(show: false); ShowExtraUIOnExpdSuccessScreen(show: false); } public override void Init() { A_MainMenuGuiLayer_Current = AccessorBase.GetStaticValueAccessor("Current", false); } private static TextMeshPro GetOrCreateNewTextFromFailedTextPrefab(string goName, Vector3 offset, CM_PageExpeditionFail fail = null) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) object obj = fail; if (obj == null) { MainMenuGuiLayer staticValue = A_MainMenuGuiLayer_Current.GetStaticValue(); obj = ((staticValue != null) ? staticValue.PageExpeditionFail : null); } CM_PageExpeditionFail val = (CM_PageExpeditionFail)obj; Transform childWithExactName = SharedUtils.GetChildWithExactName(val.m_missionFailed_text.transform.parent, goName); TextMeshPro val2 = ((childWithExactName != null) ? ((Component)childWithExactName).GetComponent() : null); if ((Object)(object)childWithExactName == (Object)null) { val2 = Object.Instantiate(val.m_missionFailed_text, val.m_missionFailed_text.transform.parent); ((Object)val2).name = goName; Transform transform = val2.transform; transform.position += offset; } return val2; } private static TextMeshPro GetOrCreateNewTextFromSuccessTextPrefab(string goName, Vector3 offset, CM_PageExpeditionSuccess success = null) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) object obj = success; if (obj == null) { MainMenuGuiLayer staticValue = A_MainMenuGuiLayer_Current.GetStaticValue(); obj = ((staticValue != null) ? staticValue.PageExpeditionSuccess : null); } CM_PageExpeditionSuccess val = (CM_PageExpeditionSuccess)obj; Transform childWithExactName = SharedUtils.GetChildWithExactName(val.m_expeditionName.transform.parent, goName); TextMeshPro val2 = ((childWithExactName != null) ? ((Component)childWithExactName).GetComponent() : null); if ((Object)(object)childWithExactName == (Object)null) { val2 = Object.Instantiate(val.m_expeditionName, val.m_expeditionName.transform.parent); ((Object)val2).name = goName; Transform transform = val2.transform; transform.position += offset; } return val2; } private static void ShowExtraUIOnExpdFailScreen(bool show, CM_PageExpeditionFail fail = null) { //IL_003a: 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) object obj = fail; if (obj == null) { MainMenuGuiLayer staticValue = A_MainMenuGuiLayer_Current.GetStaticValue(); obj = ((staticValue != null) ? staticValue.PageExpeditionFail : null); } CM_PageExpeditionFail val = (CM_PageExpeditionFail)obj; if (!((Object)(object)val == (Object)null)) { TextMeshPro orCreateNewTextFromFailedTextPrefab = GetOrCreateNewTextFromFailedTextPrefab("ExpeditionTimer", new Vector3(0f, 130f, 0f), val); ((Component)orCreateNewTextFromFailedTextPrefab).gameObject.SetActive(false); if (show && Settings.ShowTimerOnFailScreen) { LoaderWrapper.StartCoroutine(ShowTimerDelayed(orCreateNewTextFromFailedTextPrefab)); } TextMeshPro orCreateNewTextFromFailedTextPrefab2 = GetOrCreateNewTextFromFailedTextPrefab("SessionSeed", new Vector3(0f, 200f, 0f), val); ((Component)orCreateNewTextFromFailedTextPrefab2).gameObject.SetActive(false); if (show && Settings.ShowSessionSeed) { LoaderWrapper.StartCoroutine(ShowSessionSeedCoroutine(orCreateNewTextFromFailedTextPrefab2, isFail: true)); } } } private static void ShowExtraUIOnExpdSuccessScreen(bool show, CM_PageExpeditionSuccess success = null) { //IL_0057: 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) object obj = success; if (obj == null) { MainMenuGuiLayer staticValue = A_MainMenuGuiLayer_Current.GetStaticValue(); obj = ((staticValue != null) ? staticValue.PageExpeditionSuccess : null); } CM_PageExpeditionSuccess val = (CM_PageExpeditionSuccess)obj; if (!((Object)(object)val == (Object)null)) { TextMeshPro orCreateNewTextFromSuccessTextPrefab = GetOrCreateNewTextFromSuccessTextPrefab("SessionSeed", Is.R4OrLater ? new Vector3(1240f, 0f, 0f) : new Vector3(0f, -100f, 0f), val); ((Component)orCreateNewTextFromSuccessTextPrefab).gameObject.SetActive(false); if (show && Settings.ShowSessionSeed) { LoaderWrapper.StartCoroutine(ShowSessionSeedCoroutine(orCreateNewTextFromSuccessTextPrefab)); } } } [IteratorStateMachine(typeof(d__29))] private static IEnumerator ShowSessionSeedCoroutine(TextMeshPro tmp, bool isFail = false) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0) { tmp = tmp, isFail = isFail }; } [IteratorStateMachine(typeof(d__30))] private static IEnumerator ShowTimerDelayed(TextMeshPro tmp) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__30(0) { tmp = tmp }; } [MethodImpl(MethodImplOptions.NoInlining)] private static string GetFallbackExpeditionTime() { float num = (Is.R6OrLater ? CheckpointWastedTimeR6Plus() : 0f); return TimeSpan.FromSeconds(Clock.ExpeditionProgressionTime + num).ToString("hh':'mm':'ss"); } [MethodImpl(MethodImplOptions.NoInlining)] private static float CheckpointWastedTimeR6Plus() { return Clock.ExpeditionCheckpointWastedTime; } public static void SetSuccessMaskActive(bool active) { MainMenuGuiLayer obj = ((IValueAccessor)(object)A_MainMenuGuiLayer_Current).Get((MainMenuGuiLayer)null); object trans; if (obj == null) { trans = null; } else { CM_PageExpeditionSuccess pageExpeditionSuccess = obj.PageExpeditionSuccess; trans = ((pageExpeditionSuccess != null) ? ((Component)pageExpeditionSuccess).transform : null); } SetMaskBackgroundActive((Transform)trans, active); } public static void SetFailMaskActive(bool active) { MainMenuGuiLayer obj = ((IValueAccessor)(object)A_MainMenuGuiLayer_Current).Get((MainMenuGuiLayer)null); object trans; if (obj == null) { trans = null; } else { CM_PageExpeditionFail pageExpeditionFail = obj.PageExpeditionFail; trans = ((pageExpeditionFail != null) ? ((Component)pageExpeditionFail).transform : null); } SetMaskBackgroundActive((Transform)trans, active); } public static void SetMaskBackgroundActive(Transform trans, bool active) { if (trans == null) { return; } Transform childWithExactName = SharedUtils.GetChildWithExactName(trans, "Backgrounds"); if (childWithExactName == null) { return; } Transform childWithExactName2 = SharedUtils.GetChildWithExactName(childWithExactName, "Middle"); if (childWithExactName2 != null) { GameObject gameObject = ((Component)childWithExactName2).gameObject; if (gameObject != null) { gameObject.SetActive(active); } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class FlashlightIconColors : Feature { public class FlashlightIconColorsSettings { [FSDisplayName("Color Flashlight On")] public SColor ColorEnabled { get; set; } = new SColor(1f, 0.9206f, 0.7206f, (float?)0.6137f); [FSDisplayName("Color Flashlight Off")] public SColor ColorDisabled { get; set; } = new SColor(0.7216f, 0.7216f, 0.7216f, (float?)0.3137f); } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_Inventory_Setup_Patch { public static void Postfix(PUI_Inventory __instance) { SetCustomColors(__instance); } } private static bool _defaultsSet; private static Color _default_Enabled; private static Color _default_Disabled; public override string Name => "Flashlight Icon Colors"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Customize the flashlight on/off indicator colors."; public override bool SkipInitialOnEnable => true; [FeatureConfig] public static FlashlightIconColorsSettings Settings { get; set; } public override void OnEnable() { PlayerGuiLayer playerLayer = GuiManager.PlayerLayer; SetCustomColors((playerLayer != null) ? playerLayer.Inventory : null); SetMapFlashlightIcons(defaultColors: false); } public override void OnFeatureSettingChanged(FeatureSetting setting) { ((Feature)this).OnEnable(); } public override void OnDisable() { //IL_0018: 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) if (_defaultsSet) { PlayerGuiLayer playerLayer = GuiManager.PlayerLayer; SetFlashlightIconColors((playerLayer != null) ? playerLayer.Inventory : null, _default_Enabled, _default_Disabled); SetMapFlashlightIcons(defaultColors: true); } } private void SetMapFlashlightIcons(bool defaultColors) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CM_PageMap.Current == (Object)null) { return; } foreach (PUI_Inventory item in (Il2CppArrayBase)(object)CM_PageMap.Current.m_inventory) { if (defaultColors) { SetFlashlightIconColors(item, _default_Enabled, _default_Disabled); } else { SetCustomColors(item); } } } public static void SetCustomColors(PUI_Inventory inventory) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) SetFlashlightIconColors(inventory, SColorExtensions.ToUnityColor(Settings.ColorEnabled), SColorExtensions.ToUnityColor(Settings.ColorDisabled)); } public static void SetFlashlightIconColors(PUI_Inventory inventory, Color colorEnabled, Color colorDisabled) { //IL_0050: 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_002a: 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_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) object obj; if (inventory == null) { obj = null; } else { PUI_InventoryIconDisplay iconDisplay = inventory.m_iconDisplay; obj = ((iconDisplay != null) ? iconDisplay.FlashLightIcon : null); } SpriteStatusIcon val = (SpriteStatusIcon)obj; if (val != null) { if (!_defaultsSet) { _default_Enabled = val.Enabled.color; _default_Disabled = val.Disabled.color; _defaultsSet = true; } val.Enabled.color = colorEnabled; val.Disabled.color = colorDisabled; } } } [EnableFeatureByDefault] public class HudToggle : Feature { public class HudToggleSettings { [FSDisplayName("HUD Toggle Key")] [FSDescription("Key used to toggle the HUD.")] public KeyCode Key { get; set; } = (KeyCode)282; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerGuiLayer__SetVisible__Patch { public static void Postfix(bool visible) { _hudIsVisible = visible; } } private static bool _hudIsVisible = true; public override string Name => "Hud Toggle"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Keybind to toggle parts of the HUD"; [FeatureConfig] public static HudToggleSettings Settings { get; set; } public override void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) if ((int)FocusStateManager.CurrentState == 4 && Input.GetKeyDown(Settings.Key)) { _hudIsVisible = !_hudIsVisible; ((GuiLayer)GuiManager.PlayerLayer).SetVisible(_hudIsVisible); ((GuiLayer)GuiManager.WatermarkLayer).SetVisible(_hudIsVisible); ((GuiLayer)GuiManager.CrosshairLayer).SetVisible(_hudIsVisible); } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class InteractReviveFix : Feature { public class InteractReviveFixSettings { [FSDisplayName("Add Multi-Res Warning")] [FSDescription("Display a warning whenever multiple people are trying to revive the same person.")] public bool AddMultiResWarning { get; set; } = true; [FSDisplayName("Multi-Res Warning Text")] [FSDescription("The warning text to display.\nDefault is: <#F00>/!\\ Double")] public string MultiResWarning { get; set; } = "<#F00>/!\\ Double"; [FSHeader("Advanced Multi-Res HUD Text", true)] [FSDisplayName("Ignore Localization")] [FSDescription("If the revive text should not be translated using the game and instead be replaced completely by the settings below whenever multiple people are reviving the same person.\n\n(Enable this to use the settings below!)")] public bool ForceOverrideStringsUsage { get; set; } [FSDisplayName("Multi-Res Others Text")] [FSDescription("Displayed whenever you're reviving with multiple people.\n\nUse \"{0}\" to insert the name of the person you're reviving.\nUse \"{1}\" to insert the names of all the people reviving (excluding you)")] public string MultiReviveOthersOverride { get; set; } = "Reviving {0} together with {1}."; [FSDisplayName("Multi-Res Yourself Text")] [FSDescription("Displayed whenever you're getting revived by multiple people.\n\nUse \"{0}\" to insert the name of all the people reviving you.\nUse \"{1}\" to insert your name.")] public string GettingMultiRevivedOverride { get; set; } = "{0} are reviving you."; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Interact_Revive_SetUIState_Patch { private static readonly List _interactorsTemp = new List(); public static bool Prefix(Interact_Revive __instance) { if (((Agent)((Interact_Timed)__instance).m_interactTargetAgent).IsLocallyOwned) { return true; } Enumerator enumerator = ((Interact_Timed)__instance).m_interactors.GetEnumerator(); while (enumerator.MoveNext()) { if (((Agent)enumerator.Current.Agent).IsLocallyOwned) { return true; } } return false; } public static void Postfix(Interact_Revive __instance, bool state) { if (!state || ((Interact_Timed)__instance).m_interactors.Count <= 1) { return; } _interactorsTemp.Clear(); Enumerator enumerator = ((Interact_Timed)__instance).m_interactors.GetEnumerator(); while (enumerator.MoveNext()) { InteractorInfo current = enumerator.Current; _interactorsTemp.Add(current.Agent.InteractionName); } if (((Agent)((Interact_Timed)__instance).m_interactTargetAgent).IsLocallyOwned) { string text = string.Join(", ", _interactorsTemp); string localizedTextSafeAndFormat = SharedUtils.GetLocalizedTextSafeAndFormat(3655755863u, Settings.ForceOverrideStringsUsage, Settings.GettingMultiRevivedOverride, new string[2] { text, ((Interact_Timed)__instance).m_interactTargetAgent.InteractionName }); GuiManager.InteractionLayer.SetInteractPrompt(localizedTextSafeAndFormat, "", (ePUIMessageStyle)0); return; } _interactorsTemp.Remove(PlayerManager.GetLocalPlayerAgent().InteractionName); string text2 = SharedUtils.GetLocalizedTextSafeAndFormat(852u, Settings.ForceOverrideStringsUsage, Settings.MultiReviveOthersOverride, new string[2] { ((Interact_Timed)__instance).m_interactTargetAgent.InteractionName, string.Join(", ", _interactorsTemp) }); if (Settings.AddMultiResWarning) { text2 = Settings.MultiResWarning + " " + text2; } GuiManager.InteractionLayer.SetInteractPrompt(text2, "", (ePUIMessageStyle)0); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Interact_Timed_OnTimerUpdate_Patch { public static bool Prefix(Interact_Timed __instance, float timeRel) { if ((Object)(object)SharedUtils.TryCastTo((Il2CppObjectBase)(object)__instance) == (Object)null) { return true; } if (((Agent)__instance.m_interactTargetAgent).IsLocallyOwned) { return true; } Enumerator enumerator = __instance.m_interactors.GetEnumerator(); while (enumerator.MoveNext()) { if (((Agent)enumerator.Current.Agent).IsLocallyOwned) { return true; } } return false; } } public override string Name => "Fix Multi-Revive UI"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Fix revive progress visually resetting whenever multiple revives are going on at the same time."; [FeatureConfig] public static InteractReviveFixSettings Settings { get; set; } } public class LoadingIndicator : Feature { public class LoadTimerInfo : MonoBehaviour { private readonly Stopwatch _stopwatch = new Stopwatch(); public LoadTimerInfo(IntPtr ptr) : base(ptr) { } public void StartTimer() { _stopwatch.Restart(); } public TimeSpan StopTimer() { _stopwatch.Stop(); return _stopwatch.Elapsed; } public static LoadTimerInfo GetOrAdd(GameObject go) { return go.GetComponent() ?? go.AddComponent(); } } public enum LoadMarkerState { Cutscene, Loading, Ready, Hide } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GameStateManager_OnPlayerGameStateChange_Patch { public static void Postfix(SNet_Player player, pGameState data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references) if (data.gameState == _eGameStateName_ReadyToStopElevatorRide) { LoaderWrapper.StartCoroutine(RemoveMarkerCoroutine(SetMarkerState(player, LoadMarkerState.Ready), 5f)); } if (data.gameState == _eGameStateName_Generating) { SetMarkerState(player, LoadMarkerState.Loading); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GuiManager_OnFocusStateChanged_Patch { private static eFocusState _eFocusState_InElevator; public static void Init() { //IL_0005: 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) _eFocusState_InElevator = Utils.GetEnumFromName("InElevator"); } public static void Postfix(eFocusState state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (state == _eFocusState_InElevator) { ((GuiLayer)GuiManager.NavMarkerLayer).SetVisible(true); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ElevatorRide_StartPreReleaseSequence_Patch { public static void Postfix() { SNet_Lobby lobby = SNet.Lobby; List val = ((lobby != null) ? lobby.Players : null); if (val == null) { return; } ((GuiLayer)GuiManager.NavMarkerLayer).SetVisible(true); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !current.IsLocal && current.HasPlayerAgent) { SetMarkerState(current, LoadMarkerState.Cutscene); } } } } [CompilerGenerated] private sealed class d__26 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float secondsDelay; public PlaceNavMarkerOnGO navMarker; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (secondsDelay > 0f) { <>2__current = (object)new WaitForSeconds(secondsDelay); <>1__state = 1; return true; } goto IL_0050; case 1: <>1__state = -1; goto IL_0050; case 2: { <>1__state = -1; 5__2++; break; } IL_0050: 5__2 = 0; break; } if (5__2 < BlinkAmount * 2) { PlaceNavMarkerOnGO obj = navMarker; if (obj != null) { obj.SetMarkerVisible(5__2 % 2 != 0); } <>2__current = (object)new WaitForSeconds(BlinkIntervalSeconds); <>1__state = 2; return true; } PlaceNavMarkerOnGO obj2 = navMarker; if (obj2 != null) { obj2.SetMarkerVisible(false); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Color Cutscene = new Color(0.2f, 0.2f, 1f); public static Color Loading = new Color(1f, 0f, 0f); public static Color Ready = new Color(0f, 1f, 0f); public static IValueAccessor A_NavMarker; public const string LOADING_MARKER_GO_NAME = "LoadingIndicator"; private static readonly eGameStateName _eGameStateName_InLevel = Utils.GetEnumFromName("InLevel"); private static readonly eGameStateName _eGameStateName_ReadyToStopElevatorRide = Utils.GetEnumFromName("ReadyToStopElevatorRide"); private static readonly eGameStateName _eGameStateName_Generating = Utils.GetEnumFromName("Generating"); public static uint BlinkAmount = 3u; public static float BlinkIntervalSeconds = 0.2f; public override string Name => "Loading Indicator"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Displays a little indicator that shows if other players have finished loading yet."; public static IArchiveLogger FeatureLogger { get; set; } public override void Init() { A_NavMarker = AccessorBase.GetValueAccessor("m_marker", false); ClassInjector.RegisterTypeInIl2Cpp(false); } public static PlaceNavMarkerOnGO GetOrCreateMarker(SNet_Player player) { //IL_0040: 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_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return null; } if (!player.HasPlayerAgent) { return null; } PlayerAgent val = SharedUtils.CastTo((Il2CppObjectBase)(object)player.PlayerAgent); Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)val).transform, "LoadingIndicator"); PlaceNavMarkerOnGO val2; if ((Object)(object)childWithExactName == (Object)null) { childWithExactName = new GameObject("LoadingIndicator").transform; childWithExactName.SetParent(((Component)val).transform); childWithExactName.localPosition = Vector3.up; childWithExactName.rotation = Quaternion.identity; val2 = ((Component)childWithExactName).gameObject.AddComponent(); val2.type = (eMarkerType)1; val2.PlaceMarker(((Component)childWithExactName).gameObject); val2.SetMarkerVisible(false); } else { val2 = ((Component)childWithExactName).GetComponent(); } return val2; } public static PlaceNavMarkerOnGO SetMarkerState(SNet_Player player, LoadMarkerState state) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) PlaceNavMarkerOnGO orCreateMarker = GetOrCreateMarker(player); if ((Object)(object)orCreateMarker == (Object)null) { FeatureLogger.Warning("NavMarker is null!!"); return null; } if (state == LoadMarkerState.Hide) { orCreateMarker.SetMarkerVisible(false); return orCreateMarker; } string text = string.Empty; Color val; switch (state) { case LoadMarkerState.Hide: orCreateMarker.SetMarkerVisible(false); return orCreateMarker; case LoadMarkerState.Cutscene: if (A_NavMarker.Get(orCreateMarker).IsVisible) { return orCreateMarker; } val = Cutscene; break; default: val = Loading; LoadTimerInfo.GetOrAdd(((Component)orCreateMarker).gameObject).StartTimer(); break; case LoadMarkerState.Ready: { val = Ready; TimeSpan value = LoadTimerInfo.GetOrAdd(((Component)orCreateMarker).gameObject).StopTimer(); text = $"{value:mm\\:ss\\.fff}"; break; } } orCreateMarker.UpdateName($"<#{ColorUtility.ToHtmlStringRGB(player.PlayerColor)}>{player.NickName}", $"<#{ColorUtility.ToHtmlStringRGB(val)}>{state}{(string.IsNullOrWhiteSpace(text) ? string.Empty : ("\n" + text))}"); orCreateMarker.UpdatePlayerColor(val); orCreateMarker.SetMarkerVisible(true); return orCreateMarker; } public void OnGameStateChanged(eGameStateName state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0058: Unknown result type (might be due to invalid IL or missing references) if (state == _eGameStateName_InLevel) { SNet_Lobby lobby = SNet.Lobby; List val = ((lobby != null) ? lobby.Players : null); if (val == null) { return; } Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !current.IsLocal && current.HasPlayerAgent) { SetMarkerState(current, LoadMarkerState.Hide); } } } if (state == _eGameStateName_Generating) { ((GuiLayer)GuiManager.NavMarkerLayer).SetVisible(true); } } [IteratorStateMachine(typeof(d__26))] public static IEnumerator RemoveMarkerCoroutine(PlaceNavMarkerOnGO navMarker, float secondsDelay = 0f) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__26(0) { navMarker = navMarker, secondsDelay = secondsDelay }; } } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] public class LogVisualizer : Feature { public class LogVisualizerSettings { [Localized] public enum SpoilerMode { Never, OnceDiscovered, Always } [FSHide] public bool DebugPrint { get; set; } [FSDisplayName("Show Total Log Count")] [FSDescription("Shows overall log count and per rundown count under the title at the top after selecting one.")] public bool ShowTotalCount { get; set; } = true; [FSDisplayName("Show Log Count for Rundowns")] [FSDescription("Shows the total count for each rundown on the rundown selection menu.")] public bool ShowCountPerRundownSelectionButton { get; set; } = true; [FSDisplayName("Show Log Count on Expeditions")] [FSDescription("Shows the total count of logs in each expedition.")] public bool ShowCountPerExpedition { get; set; } = true; [FSHeader(":// In Expedition Display", true)] [FSDisplayName("Enable")] [FSDescription("Shows you the logs available in the current expedition on the Objectives screen.")] public bool ShowInExpeditionDisplay { get; set; } = true; [FSDisplayName("Show Zone Spoiler")] [FSDescription("Displays the Zone a log is in.")] public SpoilerMode Spoilers { get; set; } [FSHeader(":// Colors", true)] [FSDisplayName("Color: Logs Incomplete")] public SColor ColorNormal { get; set; } = SColor.WHITE; [FSDisplayName("Color: All Logs Gotten")] public SColor ColorAllGotten { get; set; } = SColor.ORANGE; [FSDisplayName("Color: No Logs Available")] public SColor ColorNoLogs { get; set; } = new SColor(0.5f, 0.5f, 0.5f, (float?)null); } public record LogInExpedition { public uint Rundown { get; set; } public uint ExpeditionTier { get; set; } public uint ExpeditionNumber { get; set; } public uint ExpeditionIndex { get; set; } public string LogFileName { get; set; } public uint LogId { get; set; } public bool IsAudioLog { get; set; } public int DimensionIndex { get; internal set; } public int Zone { get; internal set; } public int ZoneOverride { get; internal set; } public override string ToString() { RundownDataBlock block = GameDataBlockBase.GetBlock(Rundown); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(32, 8); object value; if (block == null) { value = null; } else { RundownStorytellingData storytellingData = block.StorytellingData; if (storytellingData == null) { value = null; } else { LocalizedText title = storytellingData.Title; value = ((title != null) ? ((Object)title).ToString().Split('\n')[1].Replace("TITLE: ", string.Empty) : null); } } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(": "); defaultInterpolatedStringHandler.AppendFormatted(char.ConvertFromUtf32((int)(65 + ExpeditionTier))); defaultInterpolatedStringHandler.AppendFormatted(ExpeditionNumber + 1); defaultInterpolatedStringHandler.AppendLiteral(": "); defaultInterpolatedStringHandler.AppendFormatted(LogFileName); defaultInterpolatedStringHandler.AppendLiteral(" | ID: "); defaultInterpolatedStringHandler.AppendFormatted(LogId); defaultInterpolatedStringHandler.AppendLiteral(" | Audio: "); defaultInterpolatedStringHandler.AppendFormatted(IsAudioLog); defaultInterpolatedStringHandler.AppendLiteral(" | "); defaultInterpolatedStringHandler.AppendFormatted((eDimensionIndex)DimensionIndex); defaultInterpolatedStringHandler.AppendLiteral(" | ZONE_"); defaultInterpolatedStringHandler.AppendFormatted((ZoneOverride >= 0) ? ZoneOverride : Zone); return defaultInterpolatedStringHandler.ToStringAndClear(); } } private static class DataBlockTraversal { public static void IterateTier(List tiers, uint rundownID, uint expTier) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_0191: Invalid comparison between Unknown and I4 //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected I4, but got Unknown if (tiers == null) { return; } uint num = 0u; uint num2 = 0u; Enumerator enumerator = tiers.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionInTierData current = enumerator.Current; if (current == null) { break; } IterateLayer(current.LevelLayoutData, rundownID, expTier, num, num2, (eDimensionIndex)0); IterateLayer(current.SecondaryLayout, rundownID, expTier, num, num2, (eDimensionIndex)0); IterateLayer(current.ThirdLayout, rundownID, expTier, num, num2, (eDimensionIndex)0); Enumerator enumerator2 = current.DimensionDatas.GetEnumerator(); while (enumerator2.MoveNext()) { DimensionInExpeditionData current2 = enumerator2.Current; DimensionDataBlock block = GameDataBlockBase.GetBlock(current2.DimensionData); eDimensionIndex dimensionIndex = current2.DimensionIndex; if (block.DimensionData.StaticTerminalPlacements != null) { Enumerator enumerator3 = block.DimensionData.StaticTerminalPlacements.GetEnumerator(); while (enumerator3.MoveNext()) { TerminalPlacementData current3 = enumerator3.Current; if (current3.LocalLogFiles == null) { continue; } Enumerator enumerator4 = current3.LocalLogFiles.GetEnumerator(); while (enumerator4.MoveNext()) { TerminalLogFileData current4 = enumerator4.Current; if (current4.FileContent.Id != 0) { AddLog(new LogInExpedition { Rundown = rundownID, ExpeditionTier = expTier, ExpeditionNumber = num, ExpeditionIndex = num2, LogFileName = current4.FileName, LogId = current4.FileContent.Id, IsAudioLog = (current4.AttachedAudioFile != 0), DimensionIndex = (int)dimensionIndex, Zone = 0, ZoneOverride = 0 }); } } } } IterateLayer(block.DimensionData.LevelLayoutData, rundownID, expTier, num, num2, dimensionIndex); } if ((int)current.Accessibility != 1) { num++; } num2++; } } private static void IterateLayer(uint layoutDataId, uint rundown, uint tier, uint expeditionNum, uint expeditionIndex, eDimensionIndex dimensionIndex) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (layoutDataId == 0) { return; } LevelLayoutDataBlock block = GameDataBlockBase.GetBlock(layoutDataId); if (block == null) { return; } Enumerator enumerator = block.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; if (current.SpecificTerminalSpawnDatas != null) { Enumerator enumerator2 = current.SpecificTerminalSpawnDatas.GetEnumerator(); while (enumerator2.MoveNext()) { SpecificTerminalSpawnData current2 = enumerator2.Current; TerminalToLogs(block, current, SpecificTerminalSpawnData.op_Implicit(current2), rundown, tier, expeditionNum, expeditionIndex, dimensionIndex); } } if (current.TerminalPlacements != null) { Enumerator enumerator3 = current.TerminalPlacements.GetEnumerator(); while (enumerator3.MoveNext()) { TerminalPlacementData current3 = enumerator3.Current; TerminalToLogs(block, current, current3, rundown, tier, expeditionNum, expeditionIndex, dimensionIndex); } } } } private static void TerminalToLogs(LevelLayoutDataBlock level, ExpeditionZoneData zone, TerminalPlacementData term, uint rundown, uint tier, uint expeditionNum, uint expeditionIndex, eDimensionIndex dimensionIndex) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected I4, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected I4, but got O //IL_00be: Expected O, but got I4 //IL_00c3: Expected O, but got I4 //IL_00ad->IL00ad: Incompatible stack types: O vs I4 //IL_00a0->IL00ad: Incompatible stack types: I4 vs O //IL_00a0->IL00ad: Incompatible stack types: O vs I4 if (((term != null) ? term.LocalLogFiles : null) == null) { return; } Enumerator enumerator = term.LocalLogFiles.GetEnumerator(); while (enumerator.MoveNext()) { TerminalLogFileData current = enumerator.Current; if (current.FileContent.Id != 0) { object obj = new LogInExpedition { Rundown = rundown, ExpeditionTier = tier, ExpeditionNumber = expeditionNum, ExpeditionIndex = expeditionIndex, LogFileName = current.FileName, LogId = current.FileContent.Id, IsAudioLog = (current.AttachedAudioFile != 0), DimensionIndex = (int)dimensionIndex }; object obj2 = obj; int num; if (zone.Alias == 0) { obj = level.ZoneAliasStart + zone.LocalIndex; num = (int)obj; } else { num = zone.Alias; obj = num; num = (int)obj; } ((LogInExpedition)obj2).Zone = (int)obj; ((LogInExpedition)num).ZoneOverride = zone.AliasOverride; AddLog((LogInExpedition)num); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Achievement_ReadAllLogs_OnPlayFabLoginSuccess_Patch { public static void Postfix(Achievement_ReadAllLogs __instance) { if (__instance.m_allLogs == null) { FeatureLogger.Notice("Achievements are likely disabled, disabling LogVisualizer!"); LogVisualizer instance = Instance; if (instance != null) { ((Feature)instance).RequestDisable("Achievements likely disabled"); } return; } List source = _allLogs.Where((LogInExpedition log) => __instance.m_allLogs.Contains(log.LogId)).ToList(); uint[] array = source.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); IEnumerable enumerable = source.Where((LogInExpedition log) => __instance.m_readLogsOnStart.Contains(log.LogId)); uint[] array2 = enumerable.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); FeatureLogger.Notice($"{array2.Length}/{array.Length} Logs found!"); if (!Settings.DebugPrint) { return; } FeatureLogger.Notice("Printing all obtained logs:"); foreach (LogInExpedition item in enumerable) { FeatureLogger.Info($"{item}"); } FeatureLogger.Success("---"); FeatureLogger.Fail("Logs not required for Achievement:"); foreach (LogInExpedition item2 in _allLogs.Where((LogInExpedition log) => !__instance.m_allLogs.Contains(log.LogId)).ToList()) { FeatureLogger.Success(item2.ToString()); } IEnumerable enumerable2 = from id in SharedUtils.ToSystemList(__instance.m_allLogs) where !_allLogs.Any((LogInExpedition log) => log.LogId == id) select id; FeatureLogger.Fail("Logs that weren't found in any level?:"); foreach (uint item3 in enumerable2) { FeatureLogger.Notice($"Missing Log: {item3}"); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageRundown_New_UpdateHeaderText_Patch { public static void Postfix(CM_PageRundown_New __instance) { if (!Settings.ShowTotalCount) { return; } TextMeshPro textRundownHeader = __instance.m_textRundownHeader; uint num = ((GameDataBlockBase)(object)__instance.m_currentRundownData)?.persistentID ?? 0; string value = (((TMP_Text)textRundownHeader).text.Contains("
") ? ((TMP_Text)textRundownHeader).text.Split(_br, StringSplitOptions.None)[0] : ((TMP_Text)textRundownHeader).text); if (string.IsNullOrWhiteSpace(value)) { value = __instance.m_customHeader; } Achievement_ReadAllLogs rel = GetReadAllLogsAchievementInstance(); if (rel == null || rel.m_allLogs == null || rel.m_readLogsOnStart == null) { return; } int num2 = 0; int num3 = 0; if (num == 0) { num2 = rel.m_allLogs.Count; num3 = rel.m_readLogsOnStart.Count; } else { IEnumerable source = from log in GetAllLogsFromRundown(num) where rel.m_allLogs.Contains(log.LogId) select log; IEnumerable source2 = source.Where((LogInExpedition log) => rel.m_readLogsOnStart.Contains(log.LogId)); uint[] array = source.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); uint[] array2 = source2.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); num2 = array.Length; num3 = array2.Length; } ((TMP_Text)__instance.m_textRundownHeader).SetText($"{value}
{Localization.GetById(5u, "Total Logs")}: ({num3} / {num2})", true); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageRundown_New_UpdateRundownSelectionButton_Patch { public static readonly Vector3 _og_friendsHostingTextPos = new Vector3(0f, 16.4f, 0f); public static readonly Vector3 _new_friendsHostingTextPos = new Vector3(0f, 76.4f, 0f); public static void Postfix(CM_RundownSelection rundownSelection, int rundownId) { //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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ShowCountPerRundownSelectionButton) { return; } TextMeshPro rundownText = rundownSelection.m_rundownText; if ((Object)(object)rundownText == (Object)null) { return; } string text = (((TMP_Text)rundownText).text.Contains("
") ? ((TMP_Text)rundownText).text.Split(_br, StringSplitOptions.None)[0] : ((TMP_Text)rundownText).text); Achievement_ReadAllLogs ral = GetReadAllLogsAchievementInstance(); if (ral != null && ral.m_allLogs != null && ral.m_readLogsOnStart != null) { IEnumerable source = from log in GetAllLogsFromRundown((uint)rundownId) where ral.m_allLogs.Contains(log.LogId) select log; IEnumerable source2 = source.Where((LogInExpedition log) => ral.m_readLogsOnStart.Contains(log.LogId)); uint[] array = source.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); uint[] array2 = source2.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); SColor val = Settings.ColorNormal; string value = $"{array2.Length} / {array.Length}"; if (array.Length == 0) { val = Settings.ColorNoLogs; value = Localization.GetById(1u, (string)null); } else if (array2.Length == array.Length) { val = Settings.ColorAllGotten; } string text2 = $"
<{SColorExtensions.ToHexString(val)}>{Localization.GetById(2u, (string)null)}: ({value})"; ((TMP_Text)rundownSelection.m_rundownText).SetText(text + text2, true); rundownSelection.m_hostingFriendsCountText.transform.localPosition = _new_friendsHostingTextPos; if ((Object)(object)rundownSelection.m_altText != (Object)null && !((TMP_Text)rundownSelection.m_altText).text.Contains("
")) { ((TMP_Text)rundownSelection.m_altText).SetText(((TMP_Text)rundownSelection.m_altText).text + "

.", true); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_ExpeditionIcon_New_SetStatus_Patch { public static readonly Vector3 _og_friendsHostingTextPos = new Vector3(-156.3781f, -99.4f, -1.3656f); public static readonly Vector3 _new_friendsHostingTextPos = new Vector3(-156.3781f, -124.4f, -1.3656f); public static void Postfix(CM_ExpeditionIcon_New __instance) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected I4, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ShowCountPerExpedition) { return; } string value = (((TMP_Text)__instance.m_statusText).text.Contains("
") ? ((TMP_Text)__instance.m_statusText).text.Split(_br, StringSplitOptions.None)[0] : ((TMP_Text)__instance.m_statusText).text); Achievement_ReadAllLogs ral = GetReadAllLogsAchievementInstance(); if (ral == null || ral.m_allLogs == null || ral.m_readLogsOnStart == null) { return; } uint expIndex = (uint)__instance.ExpIndex; uint expTier = (uint)(__instance.Tier - 1); uint rundownID = default(uint); if (!Utils.TryParseRundownKey(__instance.RundownKey, ref rundownID)) { FeatureLogger.Warning($"Failed to parse Rundown ID from \"{__instance.RundownKey}\" ({__instance.FullName})"); return; } __instance.m_hostingFriendsCountText.transform.localPosition = _new_friendsHostingTextPos; IEnumerable source = from log in GetAllLogsFromExpedition(rundownID, expTier, expIndex) where ral.m_allLogs.Contains(log.LogId) select log; IEnumerable source2 = source.Where((LogInExpedition log) => ral.m_readLogsOnStart.Contains(log.LogId)); uint[] array = source.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); uint[] array2 = source2.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); SColor val = Settings.ColorNormal; string value2 = $"{array2.Length} / {array.Length}"; if (array.Length == 0) { value2 = Localization.GetById(1u, (string)null); val = Settings.ColorNoLogs; } else if (array2.Length == array.Length) { val = Settings.ColorAllGotten; } ((TMP_Text)__instance.m_statusText).SetText($"{value}
<{SColorExtensions.ToHexString(val)}>{Localization.GetById(2u, (string)null)}: ({value2})", true); } } public class LogEntry { public readonly uint logId; public readonly string logName; public readonly bool collected; public readonly LogInExpedition details; public LogEntry(uint id, string logFileName, bool collected, LogInExpedition details) { logId = id; logName = logFileName; this.collected = collected; this.details = details; } } public class CM_LogDisplayRoot : MonoBehaviour { private readonly List _items = new List(); public Vector3 LocalItemRootPos { get; internal set; } public static Vector3 ItemDistance { get; private set; } = new Vector3(0f, -45f, 0f); public TextMeshPro HeaderText { get; internal set; } public static string PrefabGOName { get; internal set; } public CM_LogDisplayRoot(IntPtr ptr) : base(ptr) { } public void EnableDisplay() { ((Component)this).gameObject.SetActive(true); } public void DisableDisplay() { ((Component)this).gameObject.SetActive(false); } public void SetLogCollected(uint logId) { foreach (CM_LogDisplayItem item in _items) { if (item.LogID == logId) { item.SetCollected(collected: true); } } UpdateHeaderText(); } [HideFromIl2Cpp] public void Initialize(ISet logs) { Cleanup(); if (logs.Count > 0) { foreach (LogEntry log in logs) { string text; if (log.details.Zone == 0 && log.details.ZoneOverride == 0) { text = $"DIM_{log.details.DimensionIndex}"; } else { text = $"ZONE_{((log.details.ZoneOverride > 0) ? log.details.ZoneOverride : log.details.Zone)}"; if (log.details.DimensionIndex != 0) { text = $"{text}, DIM_{log.details.DimensionIndex}"; } } CreateItem(log.logId, log.logName, log.collected, text); } } UpdateHeaderText(); } private void UpdateHeaderText() { if (_items.Count == 0) { ((TMP_Text)HeaderText).SetText(Localization.GetById(3u, (string)null), true); return; } int value = _items.Where((CM_LogDisplayItem item) => item.Collected).Count(); ((TMP_Text)HeaderText).SetText($"{Localization.GetById(2u, (string)null)}: ({value} / {_items.Count})", true); } public void UpdateItemVisuals() { foreach (CM_LogDisplayItem item in _items) { item.UpdateVisuals(); } } private void CreateItem(uint logid, string logName, bool collected, string spoiler) { //IL_000c: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (float)_items.Count * ItemDistance; GameObject val2 = Object.Instantiate(((Component)SharedUtils.GetChildWithExactName(((Component)this).transform, PrefabGOName)).gameObject); val2.transform.SetParent(((Component)this).transform, false); val2.transform.localPosition = LocalItemRootPos + val; CM_LogDisplayItem component = val2.GetComponent(); CM_LogDisplayItem cM_LogDisplayItem = component; if (cM_LogDisplayItem.Text == null) { cM_LogDisplayItem.Text = ((Component)SharedUtils.GetChildWithExactName(val2.transform, "CategoryHeader")).GetComponent(); } cM_LogDisplayItem = component; if (cM_LogDisplayItem.Divider == null) { cM_LogDisplayItem.Divider = ((Component)SharedUtils.GetChildWithExactName(val2.transform, "DividerLine")).GetComponent(); } cM_LogDisplayItem = component; if (cM_LogDisplayItem.Gradient == null) { cM_LogDisplayItem.Gradient = ((Component)SharedUtils.GetChildWithExactName(val2.transform, "Gradient")).GetComponent(); } component.LogID = logid; component.LogName = logName; component.Spoiler = spoiler; component.SetCollected(collected, alreadyCollectedOnLevelStart: true); val2.gameObject.SetActive(true); _items.Add(component); } public void Cleanup() { foreach (CM_LogDisplayItem item in _items) { SharedUtils.SafeDestroyGO((Component)(object)item); } _items.Clear(); } } public class CM_LogDisplayItem : MonoBehaviour { public TextMeshPro Text; public SpriteRenderer Divider; public SpriteRenderer Gradient; public bool Collected { get; private set; } public bool CollectedOnStart { get; private set; } public uint LogID { get; internal set; } public string LogName { get; internal set; } = string.Empty; public string Spoiler { get; internal set; } public CM_LogDisplayItem(IntPtr ptr) : base(ptr) { } public void SetCollected(bool collected, bool alreadyCollectedOnLevelStart = false) { Collected = collected; CollectedOnStart = alreadyCollectedOnLevelStart; UpdateVisuals(); } public void UpdateVisuals() { //IL_00e0: 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_0100: 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_0064: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) string text = string.Empty; if (Settings.Spoilers == LogVisualizerSettings.SpoilerMode.Always || (Settings.Spoilers == LogVisualizerSettings.SpoilerMode.OnceDiscovered && Collected)) { text = " <#999>[" + Spoiler + "]"; } if (Collected) { ((TMP_Text)Text).SetText(LogName + text, true); ((Graphic)Text).color = Color.white; Divider.color = Color.green; if (CollectedOnStart) { Gradient.color = SharedUtils.WithAlpha(Color.white, 0.025f); } else { Gradient.color = SharedUtils.WithAlpha(Color.green, 0.025f); } } else { ((TMP_Text)Text).SetText(Localization.GetById(4u, (string)null) + text, true); ((Graphic)Text).color = Color.gray; Divider.color = Color.red; Gradient.color = SharedUtils.WithAlpha(Color.red, 0.025f); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Achievement_ReadAllLogs_OnReadLog_Patch { public static void Postfix(pLogRead data) { //IL_001d: 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) FeatureLogger.Info($"Log with ID \"{data.ID}\" read."); _logDisplayRoot?.SetLogCollected(data.ID); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_ArtifactInventoryDisplay_Setup_Patch { public static void Postfix(CM_ArtifactInventoryDisplay __instance) { GetOrCreateLogDisplayRoot(__instance, out var _, isFromStartup: true); } } private static readonly eGameStateName _eGameStateName_InLevel = Utils.GetEnumFromName("InLevel"); private static bool _logsDiscovered = false; private static List _allLogs = new List(); private static readonly Dictionary> _rundownLogLookup = new Dictionary>(); private static readonly Dictionary>>> _logLookup = new Dictionary>>>(); private static readonly IReadOnlyList _emptyList = new List(); private static readonly ISet _emptyLogSet = new HashSet(); private static readonly string[] _br = new string[1] { "
" }; private static CM_LogDisplayRoot _logDisplayRoot = null; public override string Name => "Log Visualizer"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Missing some logs for that Achievement, huh?"; public static ILocalizationService Localization { get; set; } private static LogVisualizer Instance { get; set; } [FeatureConfig] public static LogVisualizerSettings Settings { get; set; } public static IArchiveLogger FeatureLogger { get; set; } public override bool ShouldInit() { return !Feature.IsPlayingModded; } public override void Init() { ClassInjector.RegisterTypeInIl2Cpp(false); ClassInjector.RegisterTypeInIl2Cpp(false); } public override void OnFeatureSettingChanged(FeatureSetting setting) { if (setting.Identifier.EndsWith("ShowInExpeditionDisplay") || setting.Identifier.EndsWith("Spoilers")) { OnLogDisplaySettingChanged(); } } private void OnLogDisplaySettingChanged() { MainMenuGuiLayer current = MainMenuGuiLayer.Current; object artifactInvDisplay; if (current == null) { artifactInvDisplay = null; } else { CM_PageObjectives pageObjectives = current.PageObjectives; artifactInvDisplay = ((pageObjectives != null) ? pageObjectives.m_artifactInventoryDisplay : null); } CM_LogDisplayRoot logDisplayRoot; bool orCreateLogDisplayRoot = GetOrCreateLogDisplayRoot((CM_ArtifactInventoryDisplay)artifactInvDisplay, out logDisplayRoot); if (Settings.ShowInExpeditionDisplay) { InitializeAndEnableLogDisplayForActiveExpedition(logDisplayRoot, orCreateLogDisplayRoot); } else { logDisplayRoot.DisableDisplay(); } } public override void OnEnable() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Invalid comparison between I4 and Unknown if (!Feature.DataBlocksReady) { return; } TryDiscoverAllLogsFromDataBlocks(); if (Settings.ShowInExpeditionDisplay) { MainMenuGuiLayer current = MainMenuGuiLayer.Current; object artifactInvDisplay; if (current == null) { artifactInvDisplay = null; } else { CM_PageObjectives pageObjectives = current.PageObjectives; artifactInvDisplay = ((pageObjectives != null) ? pageObjectives.m_artifactInventoryDisplay : null); } CM_LogDisplayRoot logDisplayRoot; bool orCreateLogDisplayRoot = GetOrCreateLogDisplayRoot((CM_ArtifactInventoryDisplay)artifactInvDisplay, out logDisplayRoot); if ((Object)(object)logDisplayRoot == (Object)null) { FeatureLogger.Warning("Log Display is null! (This shouldn't happen!)"); } if ((byte)Feature.CurrentGameState == (int)_eGameStateName_InLevel) { InitializeAndEnableLogDisplayForActiveExpedition(logDisplayRoot, orCreateLogDisplayRoot); } } } public void OnGameStateChanged(eGameStateName state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (state == _eGameStateName_InLevel && Settings.ShowInExpeditionDisplay) { MainMenuGuiLayer current = MainMenuGuiLayer.Current; object artifactInvDisplay; if (current == null) { artifactInvDisplay = null; } else { CM_PageObjectives pageObjectives = current.PageObjectives; artifactInvDisplay = ((pageObjectives != null) ? pageObjectives.m_artifactInventoryDisplay : null); } CM_LogDisplayRoot logDisplayRoot; bool orCreateLogDisplayRoot = GetOrCreateLogDisplayRoot((CM_ArtifactInventoryDisplay)artifactInvDisplay, out logDisplayRoot); InitializeAndEnableLogDisplayForActiveExpedition(logDisplayRoot, orCreateLogDisplayRoot); } } public override void OnDisable() { DisableLogDisplayRoot(); } private void InitializeAndEnableLogDisplayForActiveExpedition(CM_LogDisplayRoot logDisplay, bool createdThisFrame) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0085: Unknown result type (might be due to invalid IL or missing references) pActiveExpedition activeExpeditionData = RundownManager.GetActiveExpeditionData(); int expeditionIndex = activeExpeditionData.expeditionIndex; eRundownTier tier = activeExpeditionData.tier; string data = activeExpeditionData.rundownKey.data; FeatureLogger.Debug($"Initializing LogDisplay for expedition: Rundown: {data}, Tier: {tier}, Index: {expeditionIndex}"); ISet logs = GetLogsForExpedition(data, tier, expeditionIndex); if (!createdThisFrame) { logDisplay.Initialize(logs); logDisplay.EnableDisplay(); return; } LoaderWrapper.StartCoroutine(Utils.NextFrame((Action)delegate { logDisplay.Initialize(logs); logDisplay.EnableDisplay(); })); } public override void OnDatablocksReady() { TryDiscoverAllLogsFromDataBlocks(); } private void TryDiscoverAllLogsFromDataBlocks() { if (_logsDiscovered) { return; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Enumerator enumerator = GameDataBlockBase.GetAllBlocks()[0].RundownIdsToLoad.GetEnumerator(); while (enumerator.MoveNext()) { RundownDataBlock block = GameDataBlockBase.GetBlock(enumerator.Current); if (block == null) { return; } uint persistentID = ((GameDataBlockBase)(object)block).persistentID; DataBlockTraversal.IterateTier(block.TierA, persistentID, 0u); DataBlockTraversal.IterateTier(block.TierB, persistentID, 1u); DataBlockTraversal.IterateTier(block.TierC, persistentID, 2u); DataBlockTraversal.IterateTier(block.TierD, persistentID, 3u); DataBlockTraversal.IterateTier(block.TierE, persistentID, 4u); } _allLogs = _allLogs.Distinct().ToList(); _logsDiscovered = true; stopwatch.Stop(); FeatureLogger.Success($"Discovered {_allLogs.Count} total log files in DataBlocks in {stopwatch.Elapsed}"); } private static void AddLog(LogInExpedition log) { _allLogs.Add(log); if (!_rundownLogLookup.TryGetValue(log.Rundown, out var value)) { value = new List(); _rundownLogLookup.Add(log.Rundown, value); } value.Add(log); if (!_logLookup.TryGetValue(log.Rundown, out var value2)) { value2 = new Dictionary>>(); _logLookup.Add(log.Rundown, value2); } if (!value2.TryGetValue(log.ExpeditionTier, out var value3)) { value3 = new Dictionary>(); value2.Add(log.ExpeditionTier, value3); } if (!value3.TryGetValue(log.ExpeditionIndex, out var value4)) { value4 = new List(); value3.Add(log.ExpeditionIndex, value4); } value4.Add(log); } public static IReadOnlyList GetAllLogsFromExpedition(uint rundownID, uint expTier, uint expIndex) { if (_logLookup.TryGetValue(rundownID, out var value) && value.TryGetValue(expTier, out var value2) && value2.TryGetValue(expIndex, out var value3)) { return value3; } return _emptyList; } public static IReadOnlyList GetAllLogsFromRundown(uint rundownID) { if (_rundownLogLookup.TryGetValue(rundownID, out var value)) { return value; } return _emptyList; } public ISet GetLogsForExpedition(string rundownKey, eRundownTier eExpTier, int expIndex) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected I4, but got Unknown uint num = (uint)(eExpTier - 1); uint rundownID = default(uint); if (!Utils.TryParseRundownKey(rundownKey, ref rundownID)) { FeatureLogger.Warning($"Failed to parse Rundown ID from \"{rundownKey}\" (Tier: {num}, Index: {expIndex})"); return _emptyLogSet; } Achievement_ReadAllLogs ral = GetReadAllLogsAchievementInstance(); if (ral == null || ral.m_allLogs == null || ral.m_readLogsOnStart == null) { return _emptyLogSet; } IReadOnlyList allLogsFromExpedition = GetAllLogsFromExpedition(rundownID, num, (uint)expIndex); IEnumerable source = allLogsFromExpedition.Where((LogInExpedition log) => ral.m_readLogsOnStart.Contains(log.LogId)); uint[] array = allLogsFromExpedition.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); uint[] source2 = source.Select((LogInExpedition log) => log.LogId).Distinct().ToArray(); HashSet hashSet = new HashSet(); uint[] array2 = array; foreach (uint id in array2) { LogInExpedition logInExpedition = allLogsFromExpedition.FirstOrDefault((LogInExpedition log) => log.LogId == id); if (!(logInExpedition == null)) { hashSet.Add(new LogEntry(id, logInExpedition.LogFileName, source2.Any((uint lih) => lih == id), logInExpedition)); } } return hashSet; } public static Achievement_ReadAllLogs GetReadAllLogsAchievementInstance() { AchievementManager current = AchievementManager.Current; if (((current != null) ? current.m_allAchievements : null) == null) { return null; } Enumerator enumerator = AchievementManager.Current.m_allAchievements.GetEnumerator(); while (enumerator.MoveNext()) { AchievementTask current2 = enumerator.Current; if (((MemberInfo)((Object)current2).GetIl2CppType()).Name == "Achievement_ReadAllLogs") { return SharedUtils.TryCastTo((Il2CppObjectBase)(object)current2); } } return null; } private static void DisableLogDisplayRoot() { _logDisplayRoot?.DisableDisplay(); } public static bool GetOrCreateLogDisplayRoot(CM_ArtifactInventoryDisplay artifactInvDisplay, out CM_LogDisplayRoot logDisplayRoot, bool isFromStartup = false) { //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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)artifactInvDisplay == (Object)null || (Object)(object)_logDisplayRoot != (Object)null) { logDisplayRoot = _logDisplayRoot; return false; } GameObject val = Object.Instantiate(((Component)artifactInvDisplay).gameObject); val.transform.SetParent(((Component)artifactInvDisplay).transform.parent, false); Vector3 localPosition = val.transform.localPosition; float num = (isFromStartup ? (localPosition.x - 100f) : localPosition.x); val.transform.localPosition = new Vector3(num, -50f, localPosition.z); CM_ArtifactInventoryDisplay component = val.GetComponent(); ((Object)val).name = "LogDisplayRoot"; CM_ArtifactCounter basicCounter = component.m_basicCounter; SharedUtils.SafeDestroyGO((Component)(object)basicCounter.m_artifactsTitle); SharedUtils.SafeDestroyGO((Component)(object)basicCounter.m_artifactValue); SharedUtils.SafeDestroyGO((Component)(object)basicCounter.m_boosterValueTitle); SharedUtils.SafeDestroyGO((Component)(object)basicCounter.m_boosterValue); TextMeshPro categoryHeader = basicCounter.m_categoryHeader; SpriteRenderer dividerLine = basicCounter.DividerLine; SpriteRenderer gradient = basicCounter.Gradient; SharedUtils.SafeDestroy((Component)(object)component.m_basicCounter); SharedUtils.SafeDestroyGO((Component)(object)component.m_specializedCounter); SharedUtils.SafeDestroyGO((Component)(object)component.m_advancedCounter); SharedUtils.SafeDestroy((Component)(object)component); ((Component)dividerLine).transform.localScale = new Vector3(1f, 1f / 3f, 1f); ((Component)dividerLine).transform.localPosition = ((Component)dividerLine).transform.localPosition + new Vector3(0f, 30f, 0f); ((Component)gradient).transform.localScale = new Vector3(1f, 1f / 3f, 1f); ((Component)gradient).transform.localPosition = ((Component)gradient).transform.localPosition + new Vector3(0f, 30f, 0f); ((Component)gradient).gameObject.SetActive(true); ((Object)basicCounter).name = "LogDisplayItem"; logDisplayRoot = val.AddComponent(); ((TMP_Text)categoryHeader).SetText("COO-LXL-OGS", true); ((Component)basicCounter).gameObject.SetActive(false); CM_LogDisplayItem cM_LogDisplayItem = ((Component)basicCounter).gameObject.AddComponent(); cM_LogDisplayItem.Text = categoryHeader; cM_LogDisplayItem.Divider = dividerLine; cM_LogDisplayItem.Gradient = gradient; TextMeshPro component2 = ((Component)SharedUtils.GetChildWithExactName(val.transform, "HeaderText")).GetComponent(); SharedUtils.SafeDestroy((Component)(object)((Component)component2).GetComponent()); ((TMP_Text)component2).SetText(Localization.GetById(2u, (string)null), true); logDisplayRoot.HeaderText = component2; logDisplayRoot.LocalItemRootPos = ((Component)cM_LogDisplayItem).transform.localPosition; CM_LogDisplayRoot.PrefabGOName = ((Object)((Component)cM_LogDisplayItem).gameObject).name; _logDisplayRoot = logDisplayRoot; val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)((Component)_logDisplayRoot).gameObject); ((Object)((Component)_logDisplayRoot).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)_logDisplayRoot); ((Object)_logDisplayRoot).hideFlags = (HideFlags)61; return true; } } public class ProMode : Feature { public class ProModeSettings { [FSDisplayName("Show Navmarkers")] [FSDescription("If Player Names, Bio Pings and Player Pings should be shown.")] public bool EnableNavmarkers { get; set; } [FSDisplayName("Show Warden Intel")] [FSDescription("If Objective Info / Reminders should be shown.")] public bool EnableWardenIntel { get; set; } [FSDisplayName("Show Coms-Menu")] [FSDescription("Enable the Communication Menu in order to communicate / command bots.")] [FSRundownHint(/*Could not decode attribute arguments.*/)] public bool EnableComsMenu { get; set; } [FSDisplayName("Show Crosshair")] [FSDescription("If the crosshair in the center of the screen should be shown.")] public bool EnableCrosshair { get; set; } [FSDisplayName("Show Interactions")] [FSDescription("If Interactions like picking up resource packs/consumables or reviving players should be shown.")] public bool EnableInteractions { get; set; } [FSDisplayName("Show Chat")] [FSDescription("If the chat should be shown.")] public bool EnableChat { get; set; } [FSDisplayName("Hide Inactive Chat")] [FSDescription("Hide the chat completely after a few seconds of inactivity instead of only dimming it.")] public bool HideInactiveChat { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GuiManager_OnFocusStateChanged_Patch { private static MethodAccessor _UpdateGUIElementsVisibility; public static void Init() { if (!Is.R5OrLater) { _UpdateGUIElementsVisibility = MethodAccessor.GetAccessor("UpdateGUIElementsVisibility", new Type[1] { typeof(bool) }, false); } } public static bool Prefix(eFocusState state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0034: 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_0075: 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_007d: Unknown result type (might be due to invalid IL or missing references) if (state == _eFocusState_MainMenu || state == _eFocusState_Map || state == _eFocusState_InActive || state == _eFocusState_GlobalPopupMessage || (Is.R6OrLater && Settings.EnableComsMenu && state == _eFocusState_FPS_CommunicationsMenu)) { return true; } foreach (GuiLayer allLayer in GetAllLayers()) { if (allLayer.IsVisible()) { allLayer.SetVisible(false); } } if (state == _eFocusState_FPS || state == _eFocusState_FPS_TypingInChat) { if (Settings.EnableNavmarkers) { ((GuiLayer)GuiManager.NavMarkerLayer).SetVisible(true); } if (Settings.EnableInteractions) { ((GuiLayer)GuiManager.InteractionLayer).SetVisible(true); } if (Settings.EnableCrosshair) { ((GuiLayer)GuiManager.CrosshairLayer).SetVisible(true); } if (Settings.EnableChat) { DoChatVisibilityJank(); } } return false; } internal static void DoChatVisibilityJank() { ((GuiLayer)GuiManager.PlayerLayer).SetVisible(true); if (Is.R5OrLater) { UpdateGUIElementsVisibility_IL2CPP(); return; } _UpdateGUIElementsVisibility.Invoke(GuiManager.PlayerLayer, new object[1] { true }); } [MethodImpl(MethodImplOptions.NoInlining)] private static void UpdateGUIElementsVisibility_IL2CPP() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) GuiManager.PlayerLayer.UpdateGUIElementsVisibility(_eFocusState_InElevator); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_GameEventLog_Update_Patch { private static IValueAccessor A_m_logHidden; public static void Init() { A_m_logHidden = AccessorBase.GetValueAccessor("m_logHidden", false); } public static void Postfix(PUI_GameEventLog __instance) { if (((GuiLayer)GuiManager.PlayerLayer).IsVisible() && Settings.HideInactiveChat) { SetChatVisible(!A_m_logHidden.Get(__instance)); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_WardenIntel_SetVisible_Patch { public static bool Prefix(PUI_WardenIntel __instance) { if (Settings.EnableWardenIntel) { return true; } ((Component)__instance).gameObject.SetActive(false); return false; } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_GameEventLog_UpdateHelpText_Patch { public static bool Prefix(PUI_GameEventLog __instance, SNet_Player speaker) { if ((Object)(object)speaker != (Object)null || (__instance.m_checkPushToTalk && __instance.m_lastPushToTalkStatus)) { ((Behaviour)__instance.m_txtHelp).enabled = true; return true; } ((Behaviour)__instance.m_txtHelp).enabled = false; return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerGuiLayer_UpdateGUIElementsVisibility_Patch { [IsPrefix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PrefixNew(ref eFocusState currentState) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown if (Settings.EnableChat) { currentState = (eFocusState)(int)_eFocusState_InElevator; } } [IsPrefix] [RundownConstraint(/*Could not decode attribute arguments.*/)] public static void PrefixOld(ref bool inElevator) { if (Settings.EnableChat) { inElevator = true; } } public static void Postfix() { if (Settings.EnableChat) { SetChatVisible(visible: true); } } } private static eFocusState _eFocusState_MainMenu; private static eFocusState _eFocusState_Map; private static eFocusState _eFocusState_InActive; private static eFocusState _eFocusState_GlobalPopupMessage; private static eFocusState _eFocusState_InElevator; private static eFocusState _eFocusState_FPS; private static eFocusState _eFocusState_FPS_TypingInChat; private static eFocusState _eFocusState_FPS_CommunicationsMenu; internal static IValueAccessor A_PlayerGuiLayer_m_gameEventLog; private static string _originalText; public override string Name => "Hud Pro Mode (Disable HUD)"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Force disable ALL HUD layers unless re-enabled via the submenu.\n\nMain purpose is for video production"; public override bool SkipInitialOnEnable => true; [FeatureConfig] public static ProModeSettings Settings { get; set; } public override void Init() { //IL_0005: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_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_003f: Unknown result type (might be due to invalid IL or missing references) _eFocusState_MainMenu = Utils.GetEnumFromName("MainMenu"); _eFocusState_Map = Utils.GetEnumFromName("Map"); _eFocusState_InActive = Utils.GetEnumFromName("InActive"); if (!Utils.TryGetEnumFromName("GlobalPopupMessage", ref _eFocusState_GlobalPopupMessage)) { _eFocusState_GlobalPopupMessage = (eFocusState)(-1); } _eFocusState_InElevator = Utils.GetEnumFromName("InElevator"); _eFocusState_FPS = Utils.GetEnumFromName("FPS"); _eFocusState_FPS_TypingInChat = Utils.GetEnumFromName("FPS_TypingInChat"); Utils.TryGetEnumFromName("FPS_CommunicationDialog", ref _eFocusState_FPS_CommunicationsMenu); A_PlayerGuiLayer_m_gameEventLog = AccessorBase.GetValueAccessor("m_gameEventLog", false); } public override void OnEnable() { if (Is.R4OrLater || GuiManager.PlayerLayer == null) { return; } PUI_GameEventLog obj = A_PlayerGuiLayer_m_gameEventLog.Get(GuiManager.PlayerLayer); TextMeshPro val = ((obj != null) ? obj.m_txtHelp : null); if ((Object)(object)val != (Object)null) { if (string.IsNullOrWhiteSpace(_originalText)) { _originalText = ((TMP_Text)val).text; } ((Behaviour)val).enabled = false; ((TMP_Text)val).text = string.Empty; } } public override void OnDisable() { if (Feature.IsApplicationQuitting || GuiManager.PlayerLayer == null) { return; } PUI_GameEventLog obj = A_PlayerGuiLayer_m_gameEventLog.Get(GuiManager.PlayerLayer); TextMeshPro val = ((obj != null) ? obj.m_txtHelp : null); if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = true; if (!Is.R4OrLater && !string.IsNullOrWhiteSpace(_originalText)) { ((TMP_Text)val).text = _originalText; } } } public static void SetChatVisible(bool visible) { ((RectTransformComp)A_PlayerGuiLayer_m_gameEventLog.Get(GuiManager.PlayerLayer)).SetVisible(visible); } public static IEnumerable GetAllLayers() { return (IEnumerable)GuiManager.GetAllLayers(); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class PuzzleHUDTweaks : Feature { public class PuzzleHUDTweaksSettings { [FSDisplayName("Use Roman Numerals")] [FSDescription("If Roman Numerals should be used instead of numbers:\nI, II, III, IV, V, VI, ...")] public bool UseRomanNumerals { get; set; } = true; [FSDisplayName("Ignore Single Scans")] [FSDescription("If alarms with only a single scan should hide the (I/I) text")] public bool IgnoreSingleScans { get; set; } = true; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CP_Bioscan_Hud_SetVisible_Patch { private static string _ogAtText; private static string _ogEnterScanText; public static void Postfix(CP_Bioscan_Hud __instance, int puzzleIndex, bool visible) { if (!__instance.m_atText.Contains("(")) { _ogAtText = __instance.m_atText; _ogEnterScanText = __instance.m_enterSecurityScanText; } if (!visible) { return; } CP_Bioscan_Hud obj = __instance; object obj2; if (obj == null) { obj2 = null; } else { Transform transform = ((Component)obj).transform; if (transform == null) { obj2 = null; } else { Transform parent = transform.parent; obj2 = ((parent != null) ? ((Component)parent).GetComponentsInChildren() : null); } } Il2CppArrayBase val = (Il2CppArrayBase)obj2; ChainedPuzzleInstance val2 = ((val.Count <= 1) ? ((IEnumerable)val).FirstOrDefault() : ((IEnumerable)val).Where((ChainedPuzzleInstance cpi) => ((IEnumerable)cpi.m_chainedPuzzleCores).FirstOrDefault((Func)delegate(iChainedPuzzleCore core) { iChainedPuzzleHUD hudFromCore = GetHudFromCore(core); return ((hudFromCore != null) ? new IntPtr?(((Il2CppObjectBase)hudFromCore).Pointer) : null) == ((Il2CppObjectBase)__instance).Pointer; }) != null).FirstOrDefault()); if (!((Object)(object)val2 == (Object)null)) { int num = puzzleIndex + 1; int count = ((Il2CppArrayBase)(object)val2.m_chainedPuzzleCores).Count; if (count != 1 || !Settings.IgnoreSingleScans) { string text = ((!Settings.UseRomanNumerals) ? $" ({num}/{count})" : $" ({Utils.ToRoman(num)}/{Utils.ToRoman(count)})"); __instance.m_atText = text + _ogAtText; __instance.m_enterSecurityScanText = _ogEnterScanText + text; } } } public static iChainedPuzzleHUD GetHudFromCore(iChainedPuzzleCore core) { CP_Bioscan_Core val = default(CP_Bioscan_Core); if (SharedUtils.TryCastTo((Il2CppObjectBase)(object)core, ref val)) { return val.m_hud; } CP_Cluster_Core val2 = default(CP_Cluster_Core); if (SharedUtils.TryCastTo((Il2CppObjectBase)(object)core, ref val2)) { iChainedPuzzleHUD hud = val2.m_hud; if (hud == null) { return null; } CP_Cluster_Hud obj = SharedUtils.TryCastTo((Il2CppObjectBase)(object)hud); if (obj == null) { return null; } return obj.m_hud; } return null; } } public override string Name => "Scan HUD Tweaks"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Adds an overall alarm class counter to the HUD message for door alarms etc"; [FeatureConfig] public static PuzzleHUDTweaksSettings Settings { get; set; } } public class RemoveDownedMessage : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public class PLOC_Downed_Enter_Patch { public static bool IsMethodExecuting { get; private set; } public static void Prefix() { IsMethodExecuting = true; } public static void Postfix() { IsMethodExecuting = false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public class PLOC_Downed_Exit_Patch { public static bool IsMethodExecuting { get; private set; } public static void Prefix() { IsMethodExecuting = true; } public static void Postfix() { IsMethodExecuting = false; } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] public class InteractionGuiLayer_SetMessage_Patch_R2Plus { public static bool Prefix() { return !ShouldSkipSetMessage(); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] public class InteractionGuiLayer_SetMessage_Patch_R1 { public static bool Prefix() { return !ShouldSkipSetMessage(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public class InteractionGuiLayer_MessageVisible_Patch { public static bool Prefix() { return !ShouldSkipSetMessage(); } } public override string Name => "Remove Downed Message"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Completely removes the 'You are dead, use TAB to check map' message."; public static bool ShouldSkipSetMessage() { if (!PLOC_Downed_Enter_Patch.IsMethodExecuting) { return PLOC_Downed_Exit_Patch.IsMethodExecuting; } return true; } } public class Watermark : Feature { public class WatermarkSettings { [Localized] public enum DecimalPrecision { None, One, Two } [Localized] public enum WatermarkMode { Mod, Positional, Timer } [FSDisplayName("Watermark Mode")] [FSDescription("Mod: Shows currently installed mod version\nPositional: Shows your current position / XYZ coordinates")] public WatermarkMode Mode { get; set; } = WatermarkMode.Timer; [FSSlider(/*Could not decode attribute arguments.*/)] [FSDisplayName("XYZ Saturation")] [FSDescription("How much color to apply to the XYZ coords.")] public float XYZSaturation { get; set; } = 0.5f; [FSDisplayName("XYZ Decimals")] [FSDescription("Decimal precision to show on the XYZ coords.")] public DecimalPrecision Precision { get; set; } = DecimalPrecision.One; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PUI_Watermark_UpdateWatermarkPatch { public static void Postfix(PUI_Watermark __instance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) _ = __instance.m_rundownKey; _ = __instance.m_revision; string watermark = __instance.m_watermark; try { Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)__instance).transform, "TheArchive_WatermarkTopLine"); if ((Object)(object)((childWithExactName != null) ? ((Component)childWithExactName).gameObject : null) == (Object)null) { GameObject obj = Object.Instantiate(((Component)__instance.m_watermarkText).gameObject); ((Object)obj).name = "TheArchive_WatermarkTopLine"; obj.transform.parent = ((Component)__instance).transform; obj.transform.position = __instance.m_watermarkText.transform.position + new Vector3(0f, 18f, 0f); WatermarkTopLine = obj.GetComponent(); ((TMP_Text)WatermarkTopLine).text = string.Empty; obj.GetComponent().sizeDelta = Vector2.zero; } if (Settings.Mode == WatermarkSettings.WatermarkMode.Mod) { ((TMP_Text)WatermarkTopLine).text = "<#FBF3FF>TheArchive v0.0.838"; ((Graphic)WatermarkTopLine).Rebuild((CanvasUpdate)3); } if (!Is.R6OrLater) { string text2 = (__instance.m_watermark = watermark.Split(new string[1] { "\n" }, 2, StringSplitOptions.None)[1]); ((TMP_Text)__instance.m_watermarkText).text = text2; } } catch (Exception ex) { FeatureLogger.Error($"Watermark broke! Please fix~ {ex}: {ex.Message}"); FeatureLogger.Exception(ex); } } } public const string ColorHex = "FBF3FF"; private static string _format = "0.00"; private Color _cRed = Color.red; private Color _cGreen = Color.green; private Color _cBlue = Color.blue; private string _cRedString; private string _cGreenString; private string _cBlueString; private static readonly eGameStateName _eGameStateName_InLevel = Utils.GetEnumFromName("InLevel"); private bool _hideElement = true; public const string TOPLINE_GO_NAME = "TheArchive_WatermarkTopLine"; public override string Name => "Watermark Tweaks"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; [IgnoreLocalization] public override string Description => Localization.Format(1u, "Configurable to either show your current position, a timer or the mod version in the bottom right:\n - X:24 Y:2 Z:-46\n - Timer showing elapsed mission time\n - <#{0}>{1} v{2}", new object[3] { "FBF3FF", "TheArchive", "0.0.838" }); public override bool SkipInitialOnEnable => true; public static ILocalizationService Localization { get; set; } public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static WatermarkSettings Settings { get; set; } public static TextMeshPro WatermarkTopLine { get; private set; } public override void Init() { Setup(); } public override void OnEnable() { CallUpdateWatermark(); TextMeshPro watermarkTopLine = WatermarkTopLine; if (watermarkTopLine != null) { GameObject gameObject = ((Component)watermarkTopLine).gameObject; if (gameObject != null) { gameObject.SetActive(true); } } } public override void OnDisable() { CallUpdateWatermark(); TextMeshPro watermarkTopLine = WatermarkTopLine; if (watermarkTopLine != null) { GameObject gameObject = ((Component)watermarkTopLine).gameObject; if (gameObject != null) { gameObject.SetActive(false); } } } private static void CallUpdateWatermark() { WatermarkGuiLayer watermarkLayer = GuiManager.WatermarkLayer; if (watermarkLayer != null) { PUI_Watermark watermark = watermarkLayer.m_watermark; if (watermark != null) { watermark.UpdateWatermark(); } } } public override void OnFeatureSettingChanged(FeatureSetting setting) { Setup(); CallUpdateWatermark(); } public void Setup() { SetupColors(Settings.XYZSaturation); switch (Settings.Precision) { case WatermarkSettings.DecimalPrecision.None: _format = "0"; break; case WatermarkSettings.DecimalPrecision.One: _format = "0.0"; break; case WatermarkSettings.DecimalPrecision.Two: _format = "0.00"; break; } } public Color SaturateColor(Color color, float saturation) { //IL_0000: 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) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(color, ref num, ref num2, ref num3); return Color.HSVToRGB(num, saturation, num3); } public void SetupColors(float saturation) { //IL_0003: 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_001b: 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_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) _cRedString = SColorExtensions.ToHexString(SaturateColor(_cRed, saturation)); _cGreenString = SColorExtensions.ToHexString(SaturateColor(_cGreen, saturation)); _cBlueString = SColorExtensions.ToHexString(SaturateColor(_cBlue, saturation)); } public override void Update() { //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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Invalid comparison between I4 and Unknown if ((Object)(object)WatermarkTopLine == (Object)null) { return; } _hideElement = true; switch (Settings.Mode) { default: return; case WatermarkSettings.WatermarkMode.Positional: { PlayerAgent val = default(PlayerAgent); if (PlayerManager.TryGetLocalPlayerAgent(ref val)) { Vector3 position = ((Component)val).transform.position; ((TMP_Text)WatermarkTopLine).text = $"<{_cRedString}>X:{position.x.ToString(_format)} <{_cGreenString}>Y:{position.y.ToString(_format)} <{_cBlueString}>Z:{position.z.ToString(_format)}"; ((Graphic)WatermarkTopLine).Rebuild((CanvasUpdate)3); _hideElement = false; } break; } case WatermarkSettings.WatermarkMode.Timer: if ((byte)Feature.CurrentGameState == (int)_eGameStateName_InLevel) { ((TMP_Text)WatermarkTopLine).text = EnhancedExpeditionTimer.TotalElapsedMissionTimeFormatted; ((Graphic)WatermarkTopLine).Rebuild((CanvasUpdate)3); _hideElement = false; } break; } if (_hideElement && ((TMP_Text)WatermarkTopLine).text != string.Empty) { ((TMP_Text)WatermarkTopLine).text = string.Empty; ((Graphic)WatermarkTopLine).Rebuild((CanvasUpdate)3); } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class WeaponPickerTweaks : Feature { public class WeaponPickerTweaksSettings { [Localized] public enum SortMode { Default, Archetype, Name } public class ItemColors { public enum ColorOptions { Indicator, Icon, Name } [FSHeader("Colors", true)] [FSDisplayName("Only color Indicator")] [FSDescription("Only colorizes the indicator bar on the left side")] public bool IndicatorLeftOnly { get; set; } [FSDisplayName("Favorites Color")] public SColor ColorFavorite { get; set; } = new SColor(0.92f, 0.76f, 0f, (float?)null); [FSDisplayName("Hidden Color")] public SColor ColorHidden { get; set; } = new SColor(0.2f, 0.2f, 0.2f, (float?)null); } public class WeaponPickerEntry { [FSHeader("--------------------------------", true)] [FSReadOnly(true)] public string Name { get; set; } [FSReadOnly(true)] [FSDescription("The items unique identifier*\n\n*usually unique")] public uint Checksum { get; set; } public ItemFavState Category { get; set; } = ItemFavState.Normal; public uint Index { get; set; } } [Localized] public enum ItemFavState { Favorite, Normal, Hidden } [FSDisplayName("Favorite Gear Modifier")] [FSDescription("Hold this key and select the Gear in the weapon picker to mark is as Favorite.")] public KeyCode FavoriteToggleKey { get; set; } = (KeyCode)308; [FSHide] [FSDisplayName("Sort Gear Up Modifier")] public KeyCode SortOrderUpKey { get; set; } = (KeyCode)119; [FSHide] [FSDisplayName("Sort Gear Down Modifier")] public KeyCode SortOrderDownKey { get; set; } = (KeyCode)115; [FSDisplayName("Hide Gear Modifier")] [FSDescription("Hold this key and select the Gear in the weapon picker to mark is as Hidden.")] public KeyCode HideToggleKey { get; set; } = (KeyCode)305; [FSHeader(":// Other", true)] [FSDisplayName("Colors")] public ItemColors Colors { get; set; } = new ItemColors(); [FSDisplayName("Sort Gear by ...")] [FSDescription("Default: Default Gear order\nArchetype: Sort by Archetype Name (the bottom one)\nName: Sort by Gear name")] public SortMode Mode { get; set; } [FSDisplayName("Remove Hidden Completely")] [FSDescription("Gear marked as Hidden will be removed from the weapon picker.")] public bool HideRemovesFromMenu { get; set; } [FSDisplayName("Disable with MTFO installed")] [FSDescription("Disables this feature if MTFO is installed.")] public bool DisableOnModded { get; set; } [FSHide] [FSDisplayName("Favorites (Vanilla)")] public List Entries { get; set; } = new List(); [FSHide] [FSDisplayName("Favorites (Modded)")] public List EntriesModded { get; set; } = new List(); public void SortUpwards(WeaponPickerEntry entry) { } public void SortDownwards(WeaponPickerEntry entry) { } public List GetEntries() { if (Feature.IsPlayingModded) { return EntriesModded; } return Entries; } public WeaponPickerEntry GetOrCreateEntry(GearIDRange gid, ItemFavState initialState = ItemFavState.Normal) { uint checksum = gid.GetChecksum(); List entries = GetEntries(); WeaponPickerEntry weaponPickerEntry = entries.FirstOrDefault((WeaponPickerEntry e) => e.Checksum == checksum); if (weaponPickerEntry == null) { weaponPickerEntry = new WeaponPickerEntry { Name = gid.PublicGearName, Checksum = checksum, Category = initialState }; entries.Add(weaponPickerEntry); } return weaponPickerEntry; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_InventorySlotItem_SetupAsWeaponPicker_Patch { public static void Postfix(CM_InventorySlotItem __instance) { //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_0036: 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) //IL_003f: 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_0067: 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_007a: 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_009e: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0148: 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) switch (Settings.GetOrCreateEntry(__instance.m_gearID).Category) { case WeaponPickerTweaksSettings.ItemFavState.Favorite: { Color val8 = (((CM_LobbyScrollItem)__instance).m_colHover = (((CM_LobbyScrollItem)__instance).m_colPassive = (((CM_LobbyScrollItem)__instance).m_colSeleced = SColorExtensions.ToUnityColor(Settings.Colors.ColorFavorite)))); if (!Settings.Colors.IndicatorLeftOnly) { ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOut)[1] = val8; ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOut)[1] = SharedUtils.WithAlpha(val8, 0.5f); ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOver)[1] = val8; ((Graphic)((CM_LobbyScrollItem)__instance).m_nameText).color = ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOut)[1]; ((CM_LobbyScrollItem)__instance).m_icon.color = SharedUtils.WithAlpha(val8, 0.6176f); } break; } case WeaponPickerTweaksSettings.ItemFavState.Hidden: { Color val4 = (((CM_LobbyScrollItem)__instance).m_colHover = (((CM_LobbyScrollItem)__instance).m_colPassive = (((CM_LobbyScrollItem)__instance).m_colSeleced = SColorExtensions.ToUnityColor(Settings.Colors.ColorHidden)))); if (!Settings.Colors.IndicatorLeftOnly) { ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOut)[1] = val4; ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOut)[1] = SharedUtils.WithAlpha(val4, 0.5f); ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOver)[1] = val4; ((Graphic)((CM_LobbyScrollItem)__instance).m_nameText).color = ((Il2CppArrayBase)(object)((CM_Item)__instance).m_textColorOut)[1]; ((CM_LobbyScrollItem)__instance).m_icon.color = SharedUtils.WithAlpha(val4, 0.6176f); } break; } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_OnWeaponSlotItemSelected_Patch { private static bool _itsMeee; public static void Postfix(CM_PlayerLobbyBar __instance, CM_InventorySlotItem slotItem) { //IL_0069: 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) if (!_itsMeee) { GearIDRange gearID = slotItem.m_gearID; if (HandleInput(Settings.GetOrCreateEntry(gearID))) { Feature.MarkSettingsAsDirty(Settings); __instance.UnSelect(); __instance.m_popupVisible = false; ((Component)__instance.m_popupHolder).gameObject.SetActive(false); __instance.m_popupScrollWindow.ResetInfoBox(); ((RectTransformComp)__instance.m_popupScrollWindow).SetVisible(false); CM_InventorySlotItem val = __instance.m_inventorySlotItems[slotItem.m_slot]; _itsMeee = true; __instance.ShowWeaponSelectionPopup(slotItem.m_slot, ((CM_LobbyScrollItem)val).m_guiAlign); _itsMeee = false; } } } private static bool HandleInput(WeaponPickerTweaksSettings.WeaponPickerEntry entry) { //IL_0005: 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) if (Input.GetKey(Settings.FavoriteToggleKey)) { if (entry.Category == WeaponPickerTweaksSettings.ItemFavState.Favorite) { entry.Category = WeaponPickerTweaksSettings.ItemFavState.Normal; return true; } entry.Category = WeaponPickerTweaksSettings.ItemFavState.Favorite; return true; } if (Input.GetKey(Settings.HideToggleKey)) { if (entry.Category == WeaponPickerTweaksSettings.ItemFavState.Hidden) { entry.Category = WeaponPickerTweaksSettings.ItemFavState.Normal; return true; } entry.Category = WeaponPickerTweaksSettings.ItemFavState.Hidden; return true; } return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_PlayerLobbyBar_UpdateWeaponWindowInfo_Patch { public static bool InMethod { get; private set; } public static void Prefix() { InMethod = true; } public static void Postfix() { InMethod = false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class GearManager_GetAllGearForSlot_Patch { public static void Postfix(GearManager __instance, ref Il2CppReferenceArray __result) { if (CM_PlayerLobbyBar_UpdateWeaponWindowInfo_Patch.InMethod) { FeatureLogger.Notice("Returning sorted Gear!"); GearIDRange[] array = ((IEnumerable)__result).ToArray(); Dictionary dictionary = new Dictionary(); for (int i = 0; i < array.Length; i++) { dictionary.Add(i, array[i]); } IEnumerable gearIDs = from kvp in dictionary orderby GetOrderString(kvp) select kvp.Value; __result = Il2CppReferenceArray.op_Implicit(FilterDisabled(gearIDs).ToArray()); } } } [CompilerGenerated] private sealed class d__20 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private GearIDRange <>2__current; private int <>l__initialThreadId; private IEnumerable gearIDs; public IEnumerable <>3__gearIDs; private IEnumerator <>7__wrap1; GearIDRange IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; } <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!Settings.HideRemovesFromMenu) { <>7__wrap1 = gearIDs.GetEnumerator(); <>1__state = -3; goto IL_0077; } <>7__wrap1 = gearIDs.GetEnumerator(); <>1__state = -4; break; case 1: <>1__state = -3; goto IL_0077; case 2: { <>1__state = -4; break; } IL_0077: if (<>7__wrap1.MoveNext()) { GearIDRange current = <>7__wrap1.Current; <>2__current = current; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = null; return false; } while (<>7__wrap1.MoveNext()) { GearIDRange current2 = <>7__wrap1.Current; if (Settings.GetOrCreateEntry(current2).Category != WeaponPickerTweaksSettings.ItemFavState.Hidden) { <>2__current = current2; <>1__state = 2; return true; } } <>m__Finally2(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__20 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__20(0); } d__.gearIDs = <>3__gearIDs; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public override string Name => "Weapon Picker Tweaks"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Allows you to Favorite and Hide Gear in the weapon picker."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static WeaponPickerTweaksSettings Settings { get; set; } public override bool LateShouldInit() { if (Feature.IsPlayingModded) { return !Settings.DisableOnModded; } return true; } [IteratorStateMachine(typeof(d__20))] public static IEnumerable FilterDisabled(IEnumerable gearIDs) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(-2) { <>3__gearIDs = gearIDs }; } public static string GetOrderString(KeyValuePair kvp) { int key = kvp.Key; GearIDRange value = kvp.Value; StringBuilder stringBuilder = new StringBuilder(); WeaponPickerTweaksSettings.WeaponPickerEntry orCreateEntry = Settings.GetOrCreateEntry(value); stringBuilder.Append((int)orCreateEntry.Category); if (orCreateEntry.Index > 999) { orCreateEntry.Index = 999u; } StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral("_"); handler.AppendFormatted(orCreateEntry.Index.ToString("D3")); stringBuilder3.Append(ref handler); switch (Settings.Mode) { default: { stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral("_"); handler.AppendFormatted(key); stringBuilder6.Append(ref handler); break; } case WeaponPickerTweaksSettings.SortMode.Archetype: { stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral("_"); handler.AppendFormatted(GetArchetypeName(value)); stringBuilder5.Append(ref handler); break; } case WeaponPickerTweaksSettings.SortMode.Name: { stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral("_"); handler.AppendFormatted(orCreateEntry.Name); stringBuilder4.Append(ref handler); break; } } stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral("_"); handler.AppendFormatted(orCreateEntry.Name); stringBuilder7.Append(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendLiteral("_"); handler.AppendFormatted(key); stringBuilder8.Append(ref handler); return stringBuilder.ToString(); } public static string GetArchetypeName(GearIDRange idRange) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) uint compID = idRange.GetCompID((eGearComponent)2); GearCategoryDataBlock block = GameDataBlockBase.GetBlock(compID); if ((int)GameDataBlockBase.GetBlock(block.BaseItem).inventorySlot == 10) { if (Is.R6OrLater) { GetMeleeArchetypeName(block); } } else { eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1); ArchetypeDataBlock val2 = ((compID == 12) ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase.GetBlock(GearBuilder.GetArchetypeID(block, val))); if (val2 != null) { return LocalizedText.op_Implicit(val2.PublicName); } } return "zError"; } [MethodImpl(MethodImplOptions.NoInlining)] public static string GetMeleeArchetypeName(GearCategoryDataBlock gearCatDB) { return GameDataBlockBase.GetBlock(GearBuilder.GetMeleeArchetypeID(gearCatDB)).PublicName; } } public class WeaponStats : Feature { public class WeaponStatsSettings { [Localized] public enum Stats { Damage, Clip, MaxAmmo, Reload, Stagger, Precision, Pierce, Burst, ShotgunPellets, ShotgunSpread, FalloffStart, FalloffEnd, ChargeupTime, FiringRate } [Localized] public enum MeleeStats { Damage, DamageCharged, Stagger, StaggerCharged, Precision, PrecisionCharged, SleepingBonus, SleepingBonusCharged, Environment, EnvironmentCharged, CanRun, MaxDamageChargeTime } [FSDisplayName("Weapon Stats To Display")] [FSDescription("The stats to display for Bullet weapons.")] public List StatsToDisplay { get; set; } = new List(); [FSDisplayName("Melee Stats To Display")] [FSDescription("The stats to display for Melee weapons.")] public List MeleeStatsToDisplay { get; set; } = new List(); [FSHeader("Misc", true)] [FSDisplayName("Hide Default Descriptions")] [FSDescription("Remove the games built in vague weapon descriptions\n\nCan make stats on some weapons easier to read.")] public bool HideDefaultDescriptions { get; set; } [FSDisplayName("Rounding")] [FSDescription("Amount of digits to round excessively long numbers up to.\n\nSome values might not be 100% accurate with this on!")] public RoundTo Rounding { get; set; } = (RoundTo)2; [FSDisplayName("Strikethrough Pierce Stat")] [FSDescription("If the Prc stat should be shown with strikethrough text")] public bool StrikethroughPierce { get; set; } [FSHide] public bool IsFirstTime { get; set; } = true; public bool IsStatEnabled(Stats stat) { return StatsToDisplay.Contains(stat); } public bool IsMeleeStatEnabled(MeleeStats stat) { return MeleeStatsToDisplay.Contains(stat); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_InventorySlotItem_LoadData_Patch { public static Type Type() { return typeof(CM_InventorySlotItem); } public static void Postfix(CM_InventorySlotItem __instance, GearIDRange idRange) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0050: 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_002a: 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_0034: 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_005e: Unknown result type (might be due to invalid IL or missing references) uint compID = idRange.GetCompID((eGearComponent)2); GearCategoryDataBlock block = GameDataBlockBase.GetBlock(compID); ItemDataBlock block2 = GameDataBlockBase.GetBlock(block.BaseItem); if ((int)block2.inventorySlot == 10) { GameBuildInfo buildInfo = Feature.BuildInfo; if (RundownFlagsExtensions.IsIncludedIn(((GameBuildInfo)(ref buildInfo)).Rundown, RundownFlagsExtensions.ToLatest((RundownFlags)32))) { R6PlusOnly(__instance, block, block2); } return; } eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1); bool flag = compID == 12; ArchetypeDataBlock archeTypeDataBlock = (flag ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase.GetBlock(GearBuilder.GetArchetypeID(block, val))); string text = string.Empty; if (!Settings.HideDefaultDescriptions) { text = __instance.GearDescription + "\n\n"; } __instance.GearDescription = text + GetFormatedWeaponStats(archeTypeDataBlock, block2, flag); } [MethodImpl(MethodImplOptions.NoInlining)] private static void R6PlusOnly(CM_InventorySlotItem __instance, GearCategoryDataBlock gearCatBlock, ItemDataBlock itemDataBlock) { MeleeArchetypeDataBlock block = GameDataBlockBase.GetBlock(GearBuilder.GetMeleeArchetypeID(gearCatBlock)); string text = string.Empty; if (!Settings.HideDefaultDescriptions) { text = __instance.GearDescription + "\n\n"; } __instance.GearDescription = text + OnlyTouchInR6OrHigher.GetFormatedWeaponStats(block, itemDataBlock); } } private static class OnlyTouchInR6OrHigher { public static string GetFormatedWeaponStats(MeleeArchetypeDataBlock archeTypeDataBlock, ItemDataBlock itemDataBlock) { if (archeTypeDataBlock == null) { return string.Empty; } uint meleeAnimationSetID = GearBuilder.GetMeleeAnimationSetID(archeTypeDataBlock); MeleeAnimationSetDataBlock val = ((meleeAnimationSetID != 0) ? GameDataBlockBase.GetBlock(meleeAnimationSetID) : null); StringBuilder stringBuilder = new StringBuilder(); int count = 0; if (Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.Damage)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#9D2929>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Damage); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder3.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.LightAttackDamage)); stringBuilder.Append(""); } if (Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.DamageCharged)) { Divider(ref count, stringBuilder); stringBuilder.Append(""); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Damage); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder4.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ChargedAttackDamage)); stringBuilder.Append(""); } if (!archeTypeDataBlock.AllowRunningWhenCharging && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.CanRun)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#FFD306>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_MeleeCanRunWhileCharging); handler.AppendLiteral(" "); stringBuilder5.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.AllowRunningWhenCharging); stringBuilder.Append(""); count++; } if (archeTypeDataBlock.LightStaggerMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.Stagger)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#C0FF00>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Stagger); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder6.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.LightStaggerMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.ChargedStaggerMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.StaggerCharged)) { Divider(ref count, stringBuilder); stringBuilder.Append(""); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Stagger); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder7.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ChargedStaggerMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.LightPrecisionMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.Precision)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#004E2C>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Precision); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder8.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.LightPrecisionMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.ChargedPrecisionMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.PrecisionCharged)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#55022B>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_Precision); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder9.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ChargedPrecisionMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.LightSleeperMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.SleepingBonus)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#A918A7>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder10 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_MeleeSleepingEnemiesMultiplier); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder10.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.LightSleeperMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.ChargedSleeperMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.SleepingBonusCharged)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#025531>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder11 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_MeleeSleepingEnemiesMultiplier); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder11.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ChargedSleeperMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.LightEnvironmentMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.Environment)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#18A4A9>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder12 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_EnvironmentMultiplier); handler.AppendFormatted(Short_MeleeLight); handler.AppendLiteral(" "); stringBuilder12.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.LightEnvironmentMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.ChargedEnvironmentMulti != 1f && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.EnvironmentCharged)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#75A2AA>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder13 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2); handler.AppendFormatted(Short_EnvironmentMultiplier); handler.AppendFormatted(Short_MeleeCharged); handler.AppendLiteral(" "); stringBuilder13.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ChargedEnvironmentMulti)); stringBuilder.Append(""); } if (val != null && Settings.IsMeleeStatEnabled(WeaponStatsSettings.MeleeStats.MaxDamageChargeTime)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#C0FF00>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder14 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_MeleeMaxDamageChargeTime); handler.AppendLiteral(" "); stringBuilder14.Append(ref handler); stringBuilder.Append(Round(val.MaxDamageChargeTime)); stringBuilder.Append(" s"); stringBuilder.Append(""); } string text = stringBuilder.ToString(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return Localization.GetById(21u, (string)null); } } private static PlayerDataBlock _playerDataBlock; public const string DIVIDER = " | "; public const string CLOSE_COLOR_TAG = ""; public override string Name => "Show Weapon Stats"; public override GroupBase Group => (GroupBase)(object)GroupManager.Hud; public override string Description => "Adds weapon statistics such as damage, clip size and reload speed (and more if applicable) on the weapon select screen."; public static ILocalizationService Localization { get; set; } public override Type[] ExternalLocalizedTypes => new Type[1] { typeof(RoundTo) }; [FeatureConfig] public static WeaponStatsSettings Settings { get; set; } public static string Short_MeleeLight => Localization.GetById(1u, (string)null); public static string Short_MeleeCharged => Localization.GetById(2u, (string)null); public static string Short_MeleeCanRunWhileCharging => Localization.GetById(3u, (string)null); public static string Short_MeleeSleepingEnemiesMultiplier => Localization.GetById(4u, (string)null); public static string Short_EnvironmentMultiplier => Localization.GetById(5u, (string)null); public static string Short_MeleeMaxDamageChargeTime => Localization.GetById(19u, (string)null); public static string Short_Damage => Localization.GetById(6u, (string)null); public static string Short_Clip => Localization.GetById(7u, (string)null); public static string Short_MaxAmmo => Localization.GetById(8u, (string)null); public static string Short_Reload => Localization.GetById(9u, (string)null); public static string Short_Stagger => Localization.GetById(10u, (string)null); public static string Short_Precision => Localization.GetById(11u, (string)null); public static string Short_PierceCount => Localization.GetById(12u, (string)null); public static string Short_ShotgunPelletCount => Localization.GetById(13u, (string)null); public static string Short_ShotgunSpread => Localization.GetById(14u, (string)null); public static string Short_BurstShotCount => Localization.GetById(15u, (string)null); public static string Short_FiringRate => Localization.GetById(16u, (string)null); public static string Short_FalloffDistanceClose => Localization.GetById(17u, (string)null); public static string Short_FalloffDistanceFar => Localization.GetById(18u, (string)null); public static string Short_SpecialChargeupTime => Localization.GetById(20u, (string)null); public static float Round(float val) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown if ((int)Settings.Rounding == -1) { return val; } return (float)Math.Round(val, (int)Settings.Rounding); } public override void Init() { if (Settings.IsFirstTime) { Settings.StatsToDisplay = new List { WeaponStatsSettings.Stats.Damage, WeaponStatsSettings.Stats.Clip, WeaponStatsSettings.Stats.MaxAmmo, WeaponStatsSettings.Stats.Reload, WeaponStatsSettings.Stats.Stagger, WeaponStatsSettings.Stats.Pierce, WeaponStatsSettings.Stats.Burst, WeaponStatsSettings.Stats.ShotgunPellets, WeaponStatsSettings.Stats.FalloffStart, WeaponStatsSettings.Stats.FiringRate }; Settings.MeleeStatsToDisplay = new List { WeaponStatsSettings.MeleeStats.Damage, WeaponStatsSettings.MeleeStats.DamageCharged, WeaponStatsSettings.MeleeStats.StaggerCharged, WeaponStatsSettings.MeleeStats.PrecisionCharged, WeaponStatsSettings.MeleeStats.EnvironmentCharged, WeaponStatsSettings.MeleeStats.SleepingBonusCharged, WeaponStatsSettings.MeleeStats.CanRun, WeaponStatsSettings.MeleeStats.MaxDamageChargeTime }; Settings.IsFirstTime = false; } } public override void OnDatablocksReady() { _playerDataBlock = GameDataBlockBase.GetBlock(1u); } public static int GetAmmoMax(ItemDataBlock itemDataBlock) { //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown AmmoType ammoTypeFromSlot = PlayerAmmoStorage.GetAmmoTypeFromSlot(itemDataBlock.inventorySlot); return (int)ammoTypeFromSlot switch { 0 => _playerDataBlock.AmmoStandardMaxCap, 1 => _playerDataBlock.AmmoSpecialMaxCap, 2 => _playerDataBlock.AmmoClassMaxCap, 5 => itemDataBlock.ConsumableAmmoMax, _ => -1, }; } public static int GetTotalAmmo(ArchetypeDataBlock archetypeDataBlock, ItemDataBlock itemDataBlock, bool isSentryGun = false) { int ammoMax = GetAmmoMax(itemDataBlock); float num = archetypeDataBlock.CostOfBullet; if (isSentryGun) { num *= itemDataBlock.ClassAmmoCostFactor; if ((float)archetypeDataBlock.ShotgunBulletCount > 0f) { num *= (float)archetypeDataBlock.ShotgunBulletCount; } } int num2 = (int)((float)ammoMax / num); if (isSentryGun) { return num2; } return num2 + archetypeDataBlock.DefaultClipSize; } private static void Divider(ref int count, StringBuilder builder, int maxPerLine = 3) { if (count >= maxPerLine) { builder.Append("\n"); count = 0; } else if (count > 0) { builder.Append(" | "); } count++; } public static string GetFormatedWeaponStats(ArchetypeDataBlock archeTypeDataBlock, ItemDataBlock itemDataBlock, bool isSentryGun = false) { //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Invalid comparison between Unknown and I4 //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Invalid comparison between Unknown and I4 //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_070b: Unknown result type (might be due to invalid IL or missing references) if (archeTypeDataBlock == null) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); int count = 0; if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.Damage)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#9D2929>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Damage); handler.AppendLiteral(" "); stringBuilder3.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.Damage)); stringBuilder.Append(""); } if (!isSentryGun && Settings.IsStatEnabled(WeaponStatsSettings.Stats.Clip)) { Divider(ref count, stringBuilder, 4); stringBuilder.Append(""); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Clip); handler.AppendLiteral(" "); stringBuilder4.Append(ref handler); stringBuilder.Append(archeTypeDataBlock.DefaultClipSize); stringBuilder.Append(""); } if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.MaxAmmo)) { Divider(ref count, stringBuilder, 4); stringBuilder.Append("<#FFD306>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_MaxAmmo); handler.AppendLiteral(" "); stringBuilder5.Append(ref handler); stringBuilder.Append(GetTotalAmmo(archeTypeDataBlock, itemDataBlock, isSentryGun)); stringBuilder.Append(""); } if (!isSentryGun && Settings.IsStatEnabled(WeaponStatsSettings.Stats.Reload)) { Divider(ref count, stringBuilder, 4); stringBuilder.Append("<#C0FF00>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Reload); handler.AppendLiteral(" "); stringBuilder6.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.DefaultReloadTime)); stringBuilder.Append(""); } if (archeTypeDataBlock.StaggerDamageMulti != 1f && Settings.IsStatEnabled(WeaponStatsSettings.Stats.Stagger)) { Divider(ref count, stringBuilder); stringBuilder.Append(""); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Stagger); handler.AppendLiteral(" "); stringBuilder7.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.StaggerDamageMulti)); stringBuilder.Append(""); } if (archeTypeDataBlock.PrecisionDamageMulti != 1f && Settings.IsStatEnabled(WeaponStatsSettings.Stats.Precision)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#888888>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_Precision); handler.AppendLiteral(" "); stringBuilder8.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.PrecisionDamageMulti)); stringBuilder.Append(""); count++; } if (archeTypeDataBlock.PiercingBullets && Settings.IsStatEnabled(WeaponStatsSettings.Stats.Pierce)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#004E2C>"); if (Settings.StrikethroughPierce) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder9 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 1, stringBuilder2); handler.AppendLiteral(""); handler.AppendFormatted(Short_PierceCount); handler.AppendLiteral(" "); stringBuilder9.Append(ref handler); } else { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder10 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_PierceCount); handler.AppendLiteral(" "); stringBuilder10.Append(ref handler); } stringBuilder.Append(Round(archeTypeDataBlock.PiercingDamageCountLimit)); stringBuilder.Append(""); } if (archeTypeDataBlock.ShotgunBulletCount > 0) { if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.ShotgunPellets)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#55022B>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder11 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_ShotgunPelletCount); handler.AppendLiteral(" "); stringBuilder11.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ShotgunBulletCount)); stringBuilder.Append(""); } if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.ShotgunSpread)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#A918A7>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder12 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_ShotgunSpread); handler.AppendLiteral(" "); stringBuilder12.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.ShotgunBulletSpread)); stringBuilder.Append(""); } } if (archeTypeDataBlock.SpecialChargetupTime > 0f && Settings.IsStatEnabled(WeaponStatsSettings.Stats.ChargeupTime)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#CC9347>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder13 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_SpecialChargeupTime); handler.AppendLiteral(" "); stringBuilder13.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.SpecialChargetupTime)); stringBuilder.Append(" s"); stringBuilder.Append(""); } if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.FiringRate)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#18A4A9>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder14 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_FiringRate); handler.AppendLiteral(" "); stringBuilder14.Append(ref handler); float num = (((int)archeTypeDataBlock.FireMode == 1) ? Mathf.Max(archeTypeDataBlock.BurstDelay, archeTypeDataBlock.ShotDelay) : archeTypeDataBlock.ShotDelay); stringBuilder.Append((num <= 0f) ? Localization.GetById(22u, (string)null) : ((object)Round(60f / num))); if (num > 0f) { stringBuilder.Append(" RPM"); } stringBuilder.Append(""); } if (archeTypeDataBlock.BurstShotCount > 1 && (int)archeTypeDataBlock.FireMode == 1 && Settings.IsStatEnabled(WeaponStatsSettings.Stats.Burst)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#025531>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder15 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_BurstShotCount); handler.AppendLiteral(" "); stringBuilder15.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.BurstShotCount)); stringBuilder.Append(""); } if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.FalloffStart)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#00FFA2>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder16 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_FalloffDistanceClose); handler.AppendLiteral(" "); stringBuilder16.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.DamageFalloff.x)); stringBuilder.Append(" m"); stringBuilder.Append(""); } if (Settings.IsStatEnabled(WeaponStatsSettings.Stats.FalloffEnd)) { Divider(ref count, stringBuilder); stringBuilder.Append("<#1D82FF>"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder17 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(Short_FalloffDistanceFar); handler.AppendLiteral(" "); stringBuilder17.Append(ref handler); stringBuilder.Append(Round(archeTypeDataBlock.DamageFalloff.y)); stringBuilder.Append(" m"); stringBuilder.Append(""); } string text = stringBuilder.ToString(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return Localization.GetById(21u, (string)null); } } } namespace TheArchive.Features.Fixes { [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class BioTrackerSmallRedDotFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class EnemyAgent_ScannerData_Patch { public static void Postfix(EnemyAgent __instance) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 __instance.m_hasDirtyScannerColor = true; EnemyScannerDataObject scannerData = __instance.ScannerData; if ((int)__instance.Locomotion.CurrentStateEnum != 14) { scannerData.m_soundIndex = 0; } } } public override string Name => "Bio Tracker Small Red Dots"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Fixes tiny red dots on the bio tracker."; } [EnableFeatureByDefault] internal class BioTrackerStuckSoundFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class EnemyScanner_OnUnWield_Patch { public static void Prefix(EnemyScanner __instance) { if (BIOTRACKER_TAGGING_CHARGE_FINISHED_ID != 0) { SharedUtils.SafePost(((ItemEquippable)__instance).Sound, BIOTRACKER_TAGGING_CHARGE_FINISHED_ID, true); ((ItemEquippable)__instance).Sound.Stop(); } } } private static uint? _BIOTRACKER_TAGGING_CHARGE_FINISHED_ID; public override string Name => "Bio Stuck Sound Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Stops the tagging progress sound after unwielding the tracker, just in case the sound gets stuck."; private static uint BIOTRACKER_TAGGING_CHARGE_FINISHED_ID { get { uint valueOrDefault = _BIOTRACKER_TAGGING_CHARGE_FINISHED_ID.GetValueOrDefault(); if (!_BIOTRACKER_TAGGING_CHARGE_FINISHED_ID.HasValue) { valueOrDefault = SoundEventCache.Resolve("BIOTRACKER_TAGGING_CHARGE_FINISHED", false); _BIOTRACKER_TAGGING_CHARGE_FINISHED_ID = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } } [EnableFeatureByDefault] public class DecayIRFNREFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class EnemyPrefabManager__BuildEnemyPrefab__Patch { public static void Postfix(EnemyDataBlock data, ref GameObject __result) { foreach (InstancedRenderFeature componentsInChild in __result.GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild.Descriptor != (Object)null)) { FeatureLogger.Debug($"Found invalid IRF on enemy '{((GameDataBlockBase)(object)data).name}' (pID: {((GameDataBlockBase)(object)data).persistentID}), removing ..."); Object.Destroy((Object)(object)componentsInChild); } } } } public override string Name => "Decay IRF NRE Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Fixes enemies with invalid IRFs spamming the console on death.\n\nSpecifically 'tank_boss'"; public static IArchiveLogger FeatureLogger { get; set; } } [EnableFeatureByDefault] public class FlickShotFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] private static class BulletWeapon__Fire__Patch { private static void Prefix(BulletWeapon __instance) { if (((Agent)((Item)__instance).Owner).IsLocallyOwned) { ((Item)__instance).Owner.FPSCamera.UpdateCameraRay(); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private static class Shotgun__Fire__Patch { private static void Prefix(Shotgun __instance) { if (((Agent)((Item)__instance).Owner).IsLocallyOwned) { ((Item)__instance).Owner.FPSCamera.UpdateCameraRay(); } } } public const int PatchPriority = 10000; public override string Name => "Flick Shot Fix"; public override string Description => "Before each single shot of the firearm, update the shooting direction to ensure it aligns with the camera's orientation, avoiding discrepancies between the actual firing direction and the crosshair."; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; } [EnableFeatureByDefault] public class GhostEnemyFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] private static class EnemyAgent__set_Alive__Patch { private static void Postfix(EnemyAgent __instance, bool value) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (value && (int)__instance.UpdateMode == 0) { EnemyUpdateManager.Current.Register(__instance, ((Agent)__instance).CourseNode.m_enemyUpdateMode); } } } public override string Name => "Ghost Enemy Fix"; public override string Description => "Preventing the issue where enemies are killed immediately after spawning, causing their corpses to not be properly disposed of."; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; } [EnableFeatureByDefault] public class InteractionFix : Feature { [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerInteraction_UpdateWorldInteractions_Patch { [CompilerGenerated] private sealed class d__3 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private bool 5__2; private bool 5__3; private Label 5__4; private IEnumerator <>7__wrap4; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__3(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 3u) { try { } finally { <>m__Finally1(); } } <>7__wrap4 = null; <>1__state = -2; } private bool MoveNext() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = true; 5__3 = false; <>7__wrap4 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)_mi_get_CameraRayInteractionEnabled); <>1__state = 2; return true; case 2: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Brfalse, (object)5__4); <>1__state = 3; return true; case 3: <>1__state = -3; 5__2 = false; break; case 4: <>1__state = -3; break; } if (<>7__wrap4.MoveNext()) { CodeInstruction current = <>7__wrap4.Current; if (5__2) { if (CodeInstructionExtensions.LoadsField(current, _fi_FPSCamera, false)) { 5__3 = true; } if (5__3 && current.opcode == OpCodes.Brfalse) { 5__4 = (Label)current.operand; <>2__current = current; <>1__state = 1; return true; } } <>2__current = current; <>1__state = 4; return true; } <>m__Finally1(); <>7__wrap4 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap4 != null) { <>7__wrap4.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__3 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__3(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static MethodInfo _mi_get_CameraRayInteractionEnabled; private static FieldInfo _fi_FPSCamera; public static void Init() { _mi_get_CameraRayInteractionEnabled = typeof(InteractionFix).GetProperty("CameraRayInteractionEnabled", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod(); _fi_FPSCamera = typeof(PlayerAgent).GetField("FPSCamera", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } [IteratorStateMachine(typeof(d__3))] public static IEnumerable Transpiler(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__3(-2) { <>3__instructions = instructions }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ResourcePackFirstPerson_OnUnWield_Patch { public static void Postfix() { CameraRayInteractionEnabled = true; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ResourcePackFirstPerson_Update_Patch { public static void Prefix(ResourcePackFirstPerson __instance) { PlayerInteraction interaction = ((Item)__instance).Owner.Interaction; Interact_ManualTimedWithCallback interactApplyResource = __instance.m_interactApplyResource; if (((Interact_Timed)interactApplyResource).TimerIsActive || ((ItemEquippable)__instance).FireButton || ((ItemEquippable)__instance).AimButtonHeld) { if (interaction.HasWorldInteraction) { A_UnSelectCurrentBestInteraction.Invoke(interaction); ((Interact_Base)interactApplyResource).OnSelectedChange(true, ((Item)__instance).Owner, true); ((Interact_Timed)interactApplyResource).OnTimerUpdate(((Interact_Timed)interactApplyResource).InteractionTimerRel); } CameraRayInteractionEnabled = false; } else { CameraRayInteractionEnabled = true; } } } private static MethodAccessor A_UnSelectCurrentBestInteraction; private static bool _cameraRayInteractionEnabled = true; public override string Name => "Interaction Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Prevents resource packs from getting interrupted from other interacts.\nMost notably: running past lockers etc\n\n(Text might sometimes disappear)"; public static bool CameraRayInteractionEnabled { get { if (Is.R2OrLater) { return GetR2PCameraRayInteractionEnabled(); } return _cameraRayInteractionEnabled; } set { if (Is.R2OrLater) { SetR2PCameraRayInteractionEnabled(value); } else { _cameraRayInteractionEnabled = value; } } } public override void Init() { A_UnSelectCurrentBestInteraction = MethodAccessor.GetAccessor("UnSelectCurrentBestInteraction", (Type[])null, false); } public override void OnDisable() { CameraRayInteractionEnabled = true; } [MethodImpl(MethodImplOptions.NoInlining)] private static void SetR2PCameraRayInteractionEnabled(bool enabled) { PlayerInteraction.CameraRayInteractionEnabled = enabled; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool GetR2PCameraRayInteractionEnabled() { return PlayerInteraction.CameraRayInteractionEnabled; } } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class KillIndicatorFix : Feature { public class KillIndicatorFixSettings { [FSDisplayName("Tag Buffer Period")] [FSDescription("Determines how long (in ms) an enemy is tracked for after getting shot at.")] public int TagBufferPeriod { get; set; } = 1000; [FSHide] [FSDescription("Prints debug info to console.")] public bool DebugLog { get; set; } } private class Tag { public float health; public long timestamp; public Vector3 localHitPosition; public Tag(float health) { this.health = health; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class EnemyBehaviour_ChangeState_Patch { public static void Prefix(EnemyBehaviour __instance, EB_States state) { //IL_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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) if (SNet.IsMaster || __instance.m_currentStateName == state || (int)state != 19) { return; } try { EnemyAgent enemyAgent = __instance.m_ai.m_enemyAgent; ushort globalID = ((Agent)enemyAgent).GlobalID; long num = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds(); if (!taggedEnemies.ContainsKey(globalID)) { return; } Tag tag = taggedEnemies[globalID]; if (Settings.DebugLog) { if (tag.timestamp <= num) { FeatureLogger.Info($"Received kill update {num - tag.timestamp} milliseconds after tag."); } else { FeatureLogger.Info("Received kill update for enemy that was tagged in the future? Possibly long overflow..."); } } if (tag.timestamp <= num && num - tag.timestamp < Settings.TagBufferPeriod) { if (!enemyAgent.Damage.DeathIndicatorShown) { FeatureLogger.Info("Client side marker was not shown, showing server side one."); CrosshairGuiLayer crosshairLayer = GuiManager.CrosshairLayer; if (crosshairLayer != null) { crosshairLayer.ShowDeathIndicator(((Component)enemyAgent).transform.position + tag.localHitPosition); } enemyAgent.Damage.DeathIndicatorShown = true; } else if (Settings.DebugLog) { FeatureLogger.Info("Client side marker was shown, not showing server side one."); } } else if (Settings.DebugLog) { FeatureLogger.Info("Client was no longer interested in this enemy, marker will not be shown."); } taggedEnemies.Remove(globalID); } catch (Exception value) { FeatureLogger.Error($"Something went wrong:\n{value}"); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Dam_EnemyDamageBase_BulletDamage_Patch { public static void Prefix(Dam_EnemyDamageBase __instance, float dam, Agent sourceAgent, Vector3 position) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster) { return; } PlayerAgent val = ((sourceAgent != null) ? ((Il2CppObjectBase)sourceAgent).TryCast() : null); if ((Object)(object)val == (Object)null) { if (Settings.DebugLog) { FeatureLogger.Notice("Could not find PlayerAgent."); } } else { if (val.Owner.IsBot || ((Dam_SyncedDamageBase)__instance).Health <= 0f) { return; } EnemyAgent owner = __instance.Owner; ushort globalID = ((Agent)owner).GlobalID; long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds(); if (!taggedEnemies.ContainsKey(globalID)) { taggedEnemies.Add(globalID, new Tag(((Dam_SyncedDamageBase)__instance).Health)); } Tag tag = taggedEnemies[globalID]; tag.localHitPosition = position - ((Component)owner).transform.position; tag.timestamp = timestamp; ((UFloat16)(ref fullDamageData.damage)).Set(dam, ((Dam_SyncedDamageBase)__instance).HealthMax); float num = AgentModifierManager.ApplyModifier((Agent)(object)owner, (AgentModifier)7, ((UFloat16)(ref fullDamageData.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax)); tag.health -= num; if (tag.health <= 0f && !__instance.DeathIndicatorShown) { CrosshairGuiLayer crosshairLayer = GuiManager.CrosshairLayer; if (crosshairLayer != null) { crosshairLayer.ShowDeathIndicator(position); } __instance.DeathIndicatorShown = true; disableHitIndicator = true; } if (Settings.DebugLog) { FeatureLogger.Info($"{num} Bullet Damage done by {val.PlayerName}. IsBot: {val.Owner.IsBot}"); FeatureLogger.Info($"Tracked current HP: {tag.health}, [{globalID}]"); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Dam_EnemyDamageBase_MeleeDamage_Patch { public static void Prefix(Dam_EnemyDamageBase __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, int limbID, float staggerMulti, float precisionMulti, float backstabberMulti, float sleeperMulti, bool skipLimbDestruction, DamageNoiseLevel damageNoiseLevel) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster) { return; } PlayerAgent val = ((sourceAgent != null) ? ((Il2CppObjectBase)sourceAgent).TryCast() : null); if ((Object)(object)val == (Object)null) { if (Settings.DebugLog) { FeatureLogger.Notice("Could not find PlayerAgent."); } } else { if (val.Owner.IsBot) { return; } EnemyAgent owner = __instance.Owner; ushort globalID = ((Agent)owner).GlobalID; long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds(); if (!taggedEnemies.ContainsKey(globalID)) { taggedEnemies.Add(globalID, new Tag(((Dam_SyncedDamageBase)__instance).Health)); } Tag tag = taggedEnemies[globalID]; tag.localHitPosition = position - ((Component)owner).transform.position; tag.timestamp = timestamp; ((UFloat16)(ref fullDamageData.damage)).Set(dam, ((Dam_SyncedDamageBase)__instance).DamageMax); float num = AgentModifierManager.ApplyModifier((Agent)(object)owner, (AgentModifier)6, Dam_EnemyDamageBase.RoundDamage(((UFloat16)(ref fullDamageData.damage)).Get(((Dam_SyncedDamageBase)__instance).DamageMax))); tag.health -= num; if (tag.health <= 0f && !__instance.DeathIndicatorShown) { CrosshairGuiLayer crosshairLayer = GuiManager.CrosshairLayer; if (crosshairLayer != null) { crosshairLayer.ShowDeathIndicator(position); } __instance.DeathIndicatorShown = true; disableHitIndicator = true; } if (Settings.DebugLog) { FeatureLogger.Info($"Melee Damage: {num}"); FeatureLogger.Info($"Tracked current HP: {((Dam_SyncedDamageBase)__instance).Health}, [{globalID}]"); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class Dam_EnemyDamageLimb_ShowHitIndicator_Patch { public static bool Prefix(Dam_EnemyDamageLimb __instance, bool hitWeakspot, bool willDie, Vector3 position, bool hitArmor) { if (disableHitIndicator) { disableHitIndicator = false; return false; } return true; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class Dam_EnemyDamageBase_ReceiveSetHealth_Patch { private static void Postfix(Dam_EnemyDamageBase __instance, pSetHealthData data) { if (!SNet.IsMaster) { ushort globalID = ((Agent)__instance.Owner).GlobalID; if (taggedEnemies.ContainsKey(globalID)) { taggedEnemies[globalID].health = ((SFloat16)(ref data.health)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); } } } } public const string KILL_INDICATOR_FIX_GUID = "randomuserhi.KillIndicatorFix"; private static Dictionary taggedEnemies = new Dictionary(); private static pFullDamageData fullDamageData = default(pFullDamageData); private static bool disableHitIndicator = false; public override string Name => "Kill Indicator Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Fixes orange kill indicators not being consistent for clients."; public override bool InlineSettingsIntoParentMenu => true; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static KillIndicatorFixSettings Settings { get; set; } public override bool ShouldInit() { if (LoaderWrapper.IsModInstalled("randomuserhi.KillIndicatorFix")) { ((Feature)this).RequestDisable("Kill Indicator Fix is installed, disabling this copy."); return false; } return true; } public override void Init() { RundownManager.OnExpeditionGameplayStarted += Action.op_Implicit((Action)OnRundownStart); } private void OnRundownStart() { taggedEnemies.Clear(); } } [EnableFeatureByDefault] public class MapPanFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageMap_UpdatePanning_Patch { public static bool Prefix(CM_PageMap __instance) { //IL_002a: 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_003a: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0096: Unknown result type (might be due to invalid IL or missing references) if (InputMapper.GetButton.Invoke((InputAction)59, (eFocusState)13)) { ((CM_PageBase)__instance).m_cursor.SetDragging(true); Vector3 localPosition = __instance.m_mapMover.transform.localPosition; localPosition.x += ((CM_PageBase)__instance).m_mouseInput.x / __instance.m_scaleCurrent; localPosition.y += ((CM_PageBase)__instance).m_mouseInput.y / __instance.m_scaleCurrent; __instance.m_lastMove = Vector2.op_Implicit(localPosition - __instance.m_mapMover.transform.localPosition); __instance.m_mapMover.transform.localPosition = localPosition; return false; } return true; } } public override string Name => "Map Pan Unclamp"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Remove the MMB Map panning restrictions.\nMakes you able to zoom in on far out zones."; } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] public class MapToObjectivesSwitchFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class MainMenuGuiLayer_ChangePagePatch { [CompilerGenerated] private sealed class d__2 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; PlayerAgent val = default(PlayerAgent); if (PlayerManager.TryGetLocalPlayerAgent(ref val)) { CellSoundPlayer sound = val.Sound; if (sound != null) { sound.Stop(); } } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static readonly eCM_MenuPage eCM_MenuPage_CMP_OBJECTIVES = Utils.GetEnumFromName("CMP_OBJECTIVES"); public static bool Prefix(eCM_MenuPage pageEnum) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (pageEnum == eCM_MenuPage_CMP_OBJECTIVES && PlayerChatManager.InChatMode) { LoaderWrapper.StartCoroutine(CancelSoundButJank()); return false; } return true; } [IteratorStateMachine(typeof(d__2))] private static IEnumerator CancelSoundButJank() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0); } } public override string Name => "Map Chat Abduction Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Prevent a switch to the Objectives Screen whenever the chat is open and the 'o' key is pressed.\n\n(Thanks for fixing this in A6 Alex! <3)"; } [EnableFeatureByDefault] public class NoDeadPings : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class EnemyAgent_SyncPlaceNavMarkerTag_Patch { private static IValueAccessor _A_m_alive; public static void Init() { _A_m_alive = AccessorBase.GetValueAccessor("m_alive", false); } public static bool Prefix(EnemyAgent __instance) { if (!_A_m_alive.Get(__instance)) { return false; } if (!Is.R6OrLater) { __instance.RemoveNavMarker(); } return true; } } public override string Name => "No Dead Pings"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Prevents bio pings (<#F00>/\\) on dead enemies."; } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] public class PouncerFXFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PouncerBehaviour_OnConsumeRequestReceived_Patch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public eDimensionIndex pouncerDimension; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //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) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1.2f); <>1__state = 1; return true; case 1: { <>1__state = -1; PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (((Agent)localPlayerAgent).DimensionIndex == pouncerDimension) { return false; } FeatureLogger.Notice($"Player Dimension: {((Agent)localPlayerAgent).DimensionIndex} - Pouncer Dimension: {pouncerDimension}"); localPlayerAgent.FPSCamera.PouncerScreenFX.SetCovered(false); FeatureLogger.Success("Removing PouncerFX from screen in an attempt to prevent PouncerFX glitch."); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void Postfix(PouncerBehaviour __instance, pEB_PouncerTargetInfoPacket data) { //IL_0000: 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_00a2: Unknown result type (might be due to invalid IL or missing references) int playerSlot = data.PlayerSlot; PlayerAgent val = default(PlayerAgent); PlayerManager.TryGetPlayerAgent(ref playerSlot, ref val); Dimension val2 = default(Dimension); if (((Agent)val).IsLocallyOwned && !SharedUtils.SafeIsBot(val.Owner) && ((EnemyBehaviour)__instance).m_ai.m_enemyAgent.GetArenaDimension((uint)playerSlot, ref val2)) { LoaderWrapper.StartCoroutine(CheckForPouncerFXGlitch(val2.DimensionIndex)); IArchiveLogger featureLogger = FeatureLogger; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(24, 3); defaultInterpolatedStringHandler.AppendFormatted("PouncerBehaviour_OnConsumeRequestReceived_Patch"); defaultInterpolatedStringHandler.AppendLiteral(" called! Target: "); object value; if (val == null) { value = null; } else { SNet_Player owner = val.Owner; value = ((owner != null) ? owner.NickName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(", Dim: "); defaultInterpolatedStringHandler.AppendFormatted(val2.DimensionIndex); featureLogger.Notice(defaultInterpolatedStringHandler.ToStringAndClear()); } } [IteratorStateMachine(typeof(d__1))] public static IEnumerator CheckForPouncerFXGlitch(eDimensionIndex pouncerDimension) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { pouncerDimension = pouncerDimension }; } } public override string Name => "Pouncer ScreenFX Stuck Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "(WIP) Prevents the pouncer tentacles from getting stuck on screen."; public static IArchiveLogger FeatureLogger { get; set; } } [EnableFeatureByDefault] internal class ReloadMinusOneBugFix : Feature { public class ReloadMinusOneBugFixSettings { [FSHide] [FSDisplayName("Reload Debug Log")] [FSDescription("Logs expected values from PlayerAmmoStorage.GetClipBulletsFromPack")] public bool DebugLog { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerAmmoStorage_GetClipBulletsFromPack_Patch { public static int BulletClipSize; public static int CurrentClip; public static float CostOfBullet; public static float AmmoInPack; public static float NewAmmoInPack; public static int NewCurrentClip; public static int BulletsNeeded; public static float NeededBulletCost; public static int BulletsToRefill; public static bool IsWrongAmmoType(AmmoType ammoType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 if ((int)ammoType != 0) { return (int)ammoType != 1; } return false; } public static void Prefix(PlayerAmmoStorage __instance, int currentClip, AmmoType ammoType) { //IL_0000: 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_0015: Expected I4, but got Unknown if (!IsWrongAmmoType(ammoType)) { InventorySlotAmmo obj = ((Il2CppArrayBase)(object)__instance.m_ammoStorage)[(int)ammoType]; BulletClipSize = obj.BulletClipSize; CostOfBullet = obj.CostOfBullet; AmmoInPack = obj.AmmoInPack; CurrentClip = currentClip; BulletsNeeded = BulletClipSize - CurrentClip; NeededBulletCost = (float)BulletsNeeded * CostOfBullet; BulletsToRefill = (int)Math.Floor(0.0001 + (double)(Mathf.Min(NeededBulletCost, AmmoInPack) / CostOfBullet)); NewAmmoInPack = AmmoInPack - (float)BulletsToRefill * CostOfBullet; NewCurrentClip = CurrentClip + BulletsToRefill; if (Settings.DebugLog) { FeatureLogger.Notice($"BulletClipSize: {BulletClipSize}, CostOfBullet: {CostOfBullet}, AmmoInPack: {AmmoInPack}, CurrentClip: {CurrentClip}"); FeatureLogger.Info($"BulletsNeeded = BulletClipSize - CurrentClip; => {BulletsNeeded}"); FeatureLogger.Info($"NeededBulletCost = BulletsNeeded * CostOfBullet; => {NeededBulletCost}"); FeatureLogger.Info($"BulletsToRefill = Mathf.FloorToInt(Mathf.Min(NeededBulletCost, AmmoInPack) / CostOfBullet); => {BulletsToRefill}"); FeatureLogger.Notice($"NewAmmoInPack = AmmoInPack - BulletsToRefill * CostOfBullet; => {NewAmmoInPack}"); FeatureLogger.Notice($"NewCurrentClip = CurrentClip + BulletsToRefill; => {NewCurrentClip}"); } } } public static void Postfix(PlayerAmmoStorage __instance, AmmoType ammoType, ref int __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected I4, but got Unknown if (IsWrongAmmoType(ammoType)) { return; } if (Settings.DebugLog) { FeatureLogger.Notice($"(result) returned currentClip: {__result}"); } if (__result + 1 == NewCurrentClip) { if (Settings.DebugLog) { FeatureLogger.Fail("Reload is wrong! Correcting ..."); } __result++; InventorySlotAmmo val = ((Il2CppArrayBase)(object)__instance.m_ammoStorage)[(int)ammoType]; val.AmmoInPack -= val.CostOfBullet; __instance.UpdateSlotAmmoUI(val, __result); } } } public override string Name => "99% Reload Fix"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Fixes the bug that leaves you with one bullet short in the mag.\n(Currently only for IL2CPP builds)"; public override bool InlineSettingsIntoParentMenu => true; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static ReloadMinusOneBugFixSettings Settings { get; set; } } [EnableFeatureByDefault] public class ResourceInheritanceFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] private static class PlayerBackpackManager__MasterAddAllItemsForDropin__Prefix { private static void Prefix(SNet_Player sendToPlayer) { PlayerBackpack val = default(PlayerBackpack); if (!SNet.IsMaster || sendToPlayer.IsLocal || Feature.CurrentGameState != 10 || PlayerManager.Current.m_leaverBackpacks.Count == 0 || !PlayerBackpackManager.TryGetBackpack(sendToPlayer, ref val)) { return; } bool flag = false; bool flag2 = false; Enumerator enumerator = PlayerManager.Current.m_leaverBackpacks.GetEnumerator(); BackpackItem val2 = default(BackpackItem); BackpackItem val3 = default(BackpackItem); BackpackItem val4 = default(BackpackItem); BackpackItem val5 = default(BackpackItem); while (enumerator.MoveNext()) { PlayerBackpack current = enumerator.Current; if (flag && flag2) { break; } if (!flag && !val.TryGetBackpackItem((InventorySlot)4, ref val2) && current.TryGetBackpackItem((InventorySlot)4, ref val3)) { PlayerBackpackManager.MasterAddItem(val3.Instance, val); current.BackpackItems.Remove(val3); flag = true; } if (!flag2 && !val.TryGetBackpackItem((InventorySlot)5, ref val4) && current.TryGetBackpackItem((InventorySlot)5, ref val5)) { PlayerBackpackManager.MasterAddItem(val5.Instance, val); current.BackpackItems.Remove(val5); flag2 = true; } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private static class PlayerManager__OnPlayerSpawned__Prefix { private static PlayerBackpack _tempBackpack; private static void Prefix(PlayerManager __instance, pPlayerSpawnData spawnData) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster && Feature.CurrentGameState == 10) { pPlayer snetPlayer = spawnData.snetPlayer; SNet_Player val = default(SNet_Player); ((pPlayer)(ref snetPlayer)).GetPlayer(ref val); if (val.IsBot && __instance.m_leaverBackpacks.Count != 0) { _tempBackpack = __instance.m_leaverBackpacks[__instance.m_leaverBackpacks.Count - 1]; } } } private static void Postfix(PlayerManager __instance, pPlayerSpawnData spawnData) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster && Feature.CurrentGameState == 10) { pPlayer snetPlayer = spawnData.snetPlayer; SNet_Player val = default(SNet_Player); ((pPlayer)(ref snetPlayer)).GetPlayer(ref val); if (val.IsBot && _tempBackpack != null && !__instance.m_leaverBackpacks.Contains(_tempBackpack)) { __instance.m_leaverBackpacks.Add(_tempBackpack); } } } } public override string Name => "Resource Inheritance Fix"; public override string Description => "Transfers resources from players who leave the game to new players who join, preventing resource loss for the team.\nWhen a player exits during gameplay, their resource pack and consumables will be inherited by the next player who joins."; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; } [EnableFeatureByDefault] public class WeaponAudioSyncFix : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] private class BulletWeapon__Update__Patch { private static void Postfix(BulletWeapon __instance) { if (((Agent)((Item)__instance).Owner).IsLocallyOwned) { s_weaponSyncedUpdaters[((Object)__instance).GetInstanceID()].UpdateLocal(); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class BulletWeaponSynced__OnGearSpawnComplete__Patch { private static void Postfix(BulletWeaponSynced __instance) { if (((ItemEquippable)__instance).AudioData != null) { ((BulletWeapon)__instance).m_audioChargeup = BulletWeapon.GetRandomAudioEvents(((ItemEquippable)__instance).AudioData.eventOnChargeup2D); ((BulletWeapon)__instance).m_audioCooldown = BulletWeapon.GetRandomAudioEvents(((ItemEquippable)__instance).AudioData.eventOnCooldown2D); ((BulletWeapon)__instance).m_audioChargeupEnd = ((ItemEquippable)__instance).AudioData.eventOnChargeupEnd2D; ((BulletWeapon)__instance).m_audioCooldownEnd = ((ItemEquippable)__instance).AudioData.eventOnCooldownEnd2D; } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class PlayerInventoryBase__ReceiveSimpleItemStatus__Patch { private static void Postfix(PlayerInventoryBase __instance, pSimpleItemSyncData data) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!((Agent)__instance.Owner).IsLocallyOwned && !((Object)(object)__instance.m_wieldedItem == (Object)null) && s_weaponSyncedUpdaters.TryGetValue(((Object)__instance.m_wieldedItem).GetInstanceID(), out var value)) { value.ReceiveItemSync(data); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class BulletWeapon__Setup__Patch { private static void Postfix(BulletWeapon __instance) { s_weaponSyncedUpdaters[((Object)__instance).GetInstanceID()] = new BulletWeaponSyncedDataUpdater(__instance); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class BulletWeaponSynced__Setup__Patch { private static void Postfix(BulletWeaponSynced __instance) { s_weaponSyncedUpdaters[((Object)__instance).GetInstanceID()] = new BulletWeaponSyncedDataUpdater((BulletWeapon)(object)__instance); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class ItemEquippable__OnDestroy__Patch { private static void Prefix(ItemEquippable __instance) { s_weaponSyncedUpdaters.Remove(((Object)__instance).GetInstanceID()); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private class BulletWeaponSynced__UpdateRegular__Patch { private static void Prefix(BulletWeaponSynced __instance) { s_weaponSyncedUpdaters[((Object)__instance).GetInstanceID()].UpdateSync(); } } private class BulletWeaponSyncedDataUpdater { private readonly BulletWeapon _weapon; private pSimpleItemSyncData _lastSyncData; private float _lastSyncTime; private const float _syncTimeout = 0.5f; private const float _syncInterval = 0.25f; private bool _syncCharging; private bool _syncCooldown; public BulletWeaponSyncedDataUpdater(BulletWeapon weapon) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) _weapon = weapon; _lastSyncData = default(pSimpleItemSyncData); } public void ReceiveItemSync(pSimpleItemSyncData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _lastSyncData = data; _lastSyncTime = Clock.Time; } public void UpdateLocal() { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (((ItemEquippable)_weapon).IsEnabled) { bool inCooldown = _lastSyncData.inCooldown; bool inFireMode = _lastSyncData.inFireMode; bool inAimMode = _lastSyncData.inAimMode; _lastSyncData.inCooldown = _weapon.m_archeType.HasCooldown && _weapon.m_archeType.m_nextBurstTimer > Clock.Time; _lastSyncData.inFireMode = _weapon.m_archeType.m_inChargeup; _lastSyncData.inAimMode = ((ItemEquippable)_weapon).AimButtonHeld; if (inCooldown != _lastSyncData.inCooldown || inFireMode != _lastSyncData.inFireMode || inAimMode != _lastSyncData.inAimMode || Clock.Time - _lastSyncTime > 0.25f) { ((Item)_weapon).Owner.Inventory.SendSimpleItemStatus(_lastSyncData, false); _lastSyncTime = Clock.Time; } } } public void UpdateSync() { if (Clock.Time - _lastSyncTime > 0.5f) { _lastSyncData.inAimMode = false; _lastSyncData.inFireMode = false; } if (_lastSyncData.inFireMode) { if (!_syncCharging) { _weapon.TriggerAudioChargeup(); _syncCharging = true; } } else if (_syncCharging) { _weapon.TriggerAudioChargeupEnd(); _syncCharging = false; } if (_lastSyncData.inCooldown) { if (!_syncCooldown) { _syncCooldown = true; _weapon.TriggerAudioCooldown(); } } else if (_syncCooldown) { _weapon.TriggerAudioCooldownEnd(0f); _syncCooldown = false; } } } private static Dictionary s_weaponSyncedUpdaters = new Dictionary(); public override string Name => "Weapon Audio Sync Fix"; public override string Description => "Synchronize the charging and cooling sounds of firearms with other players who have also enabled this feature."; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override void OnEnable() { if (Feature.CurrentGameState < 5) { return; } foreach (BulletWeapon item in Object.FindObjectsOfType()) { s_weaponSyncedUpdaters[((Object)item).GetInstanceID()] = new BulletWeaponSyncedDataUpdater(item); } } public override void OnDisable() { s_weaponSyncedUpdaters.Clear(); } } [EnableFeatureByDefault] [RundownConstraint(/*Could not decode attribute arguments.*/)] public class WeaponShootForward : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class Shotgun_Fire_Patch { public static void Prefix(Shotgun __instance) { //IL_000b: 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_0020: 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) Direction = ((Item)__instance).Owner.FPSCamera.CameraRayPos - ((Item)__instance).Owner.FPSCamera.Position; Frame = Time.frameCount; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class BulletWeapon_Fire_Patch { public static void Prefix(BulletWeapon __instance) { //IL_000b: 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_0020: 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) Direction = ((Item)__instance).Owner.FPSCamera.CameraRayPos - ((Item)__instance).Owner.FPSCamera.Position; Frame = Time.frameCount; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class Weapon_CastWeaponRay_Patch { public static Type[] ParameterTypes() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) GameBuildInfo buildInfo = Feature.BuildInfo; if (!RundownFlagsExtensions.IsIncludedIn(((GameBuildInfo)(ref buildInfo)).Rundown, (RundownFlags)1)) { return new Type[4] { typeof(Transform), typeof(WeaponHitData).MakeByRefType(), typeof(Vector3), typeof(int) }; } return new Type[3] { typeof(Transform), typeof(WeaponHitData).MakeByRefType(), typeof(Vector3) }; } public static void Prefix(ref WeaponHitData weaponRayData) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (Frame == Time.frameCount) { weaponRayData.fireDir = Direction; } } } public static Vector3 Direction = Vector3.zero; public static int Frame = 0; public override string Name => "Weapons shoot forward"; public override GroupBase Group => (GroupBase)(object)GroupManager.Fixes; public override string Description => "Patches weapons to always shoot into the center of your crosshair.\nMakes shotgun draw & insta-shoot not shoot the floor"; public static IArchiveLogger FeatureLogger { get; set; } } } namespace TheArchive.Features.Cosmetic { [RundownConstraint(/*Could not decode attribute arguments.*/)] public class BotCustomization : Feature { public class NamedBotsSettings { public class VanitySettings { public uint Helmet { get; set; } public uint Torso { get; set; } public uint Legs { get; set; } public uint Backpack { get; set; } public uint Palette { get; set; } public uint Get(ClothesType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected I4, but got Unknown return (int)type switch { 0 => Helmet, 1 => Torso, 2 => Legs, 3 => Backpack, 4 => Palette, _ => 0u, }; } public void Set(ClothesType type, uint id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected I4, but got Unknown switch ((int)type) { default: return; case 0: Helmet = id; break; case 1: Torso = id; break; case 2: Legs = id; break; case 3: Backpack = id; break; case 4: Palette = id; break; } Feature.MarkSettingsAsDirty(Settings); } } [FSMaxLength(25)] [FSDisplayName("Woods")] public string Woods { get; set; } = "Woods"; [FSMaxLength(25)] [FSDisplayName("Dauda")] public string Dauda { get; set; } = "Dauda"; [FSMaxLength(25)] [FSDisplayName("Hackett")] public string Hackett { get; set; } = "Hackett"; [FSMaxLength(25)] [FSDisplayName("Bishop")] public string Bishop { get; set; } = "Bishop"; [FSHide] [FSDisplayName("Vanity Woods")] public VanitySettings VanityWoods { get; set; } = new VanitySettings(); [FSHide] [FSDisplayName("Vanity Dauda")] public VanitySettings VanityDauda { get; set; } = new VanitySettings(); [FSHide] [FSDisplayName("Vanity Hackett")] public VanitySettings VanityHackett { get; set; } = new VanitySettings(); [FSHide] [FSDisplayName("Vanity Bishop")] public VanitySettings VanityBishop { get; set; } = new VanitySettings(); public VanitySettings GetVanity(int characterIndex) { return (characterIndex % 4) switch { 1 => VanityDauda, 2 => VanityHackett, 3 => VanityBishop, _ => VanityWoods, }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerAIBot_Setup_Patch { public static Type Type() { return typeof(PlayerAIBot); } public static void Postfix(PlayerAIBot __instance, PlayerAgent agent) { SetBotName(agent); SetVanity(agent); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_UpdatePlayer_Patch { public static void Postfix(CM_PlayerLobbyBar __instance, SNet_Player player) { GameObject orCreateClothesButton = GetOrCreateClothesButton(__instance); if ((Object)(object)player == (Object)null || !SharedUtils.SafeIsBot(player)) { orCreateClothesButton.SetActive(false); } else { orCreateClothesButton.SetActive(!GameStateManager.IsReady & SNet.IsMaster); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerBackpackManager_LocalBackpack_Getter_Patch { public static bool Prefix(ref PlayerBackpack __result) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (!WantsToSyncBotPlayer) { return true; } if (!SharedUtils.SafeIsBot(BotPlayerToSync)) { return true; } SNet_Player botPlayerToSync = BotPlayerToSync; if (!PlayerBackpackManager.Current.m_backpacks.ContainsKey(botPlayerToSync.Lookup)) { PlayerBackpack val = new PlayerBackpack(botPlayerToSync); PlayerBackpackManager.Current.m_backpacks.Add(botPlayerToSync.Lookup, val); } __result = PlayerBackpackManager.Current.m_backpacks[botPlayerToSync.Lookup]; return false; } } public class LocalPlayerOverride : IDisposable { private static LocalPlayerOverride _instance; private SNet_Player _localPlayer; public LocalPlayerOverride(SNet_Player botPlayer) { if (_instance != null) { FeatureLogger.Warning("LocalPlayerOverride used twice at the same time! This might cause issues!"); } _localPlayer = SNet.s_localPlayer; BotPlayerToSync = botPlayer; SNet.s_localPlayer = botPlayer; WantsToSyncBotPlayer = true; _instance = this; } public void Dispose() { SNet.s_localPlayer = _localPlayer; WantsToSyncBotPlayer = false; _instance = null; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerBackpackManager_ForceSyncBotInventory_Patch { public static bool Prefix(SNet_Player botPlayer, SNet_Player toPlayer) { ForceSyncBotInventoryWithVanity(botPlayer, toPlayer); return false; } public static void ForceSyncBotInventoryWithVanity(SNet_Player botPlayer, SNet_Player toPlayer = null) { if ((!((Object)(object)toPlayer != (Object)null) || !SharedUtils.SafeIsBot(toPlayer)) && SNet.IsMaster && !((Object)(object)botPlayer == (Object)null) && SNet.HasLocalPlayer && !((Object)(object)PlayerManager.GetLocalPlayerAgent() == (Object)null)) { WithBotAsLocalInput(botPlayer, delegate { PlayerBackpackManager.ForceSyncLocalInventory((SNet_Player)null); }); GuiManager.MainMenuLayer.PageLoadout.UpdatePlayerList(); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_HideLoadoutUI_Patch { public static void Postfix(CM_PlayerLobbyBar __instance) { if ((Object)(object)__instance.m_player == (Object)null || !SharedUtils.SafeIsBot(__instance.m_player)) { return; } GameObject orCreateClothesButton = GetOrCreateClothesButton(__instance, create: false); if (orCreateClothesButton != null) { GameObject gameObject = orCreateClothesButton.gameObject; if (gameObject != null) { gameObject.SetActive(!GameStateManager.IsReady & SNet.IsMaster); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerBackpackManager_GetLocalVanityItem_Patch { public static SNet_Player PlayerToGetApparelSelectVanityFor { get; set; } public static bool Prefix(ClothesType type, ref uint __result) { //IL_0014: 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) if (WantsToSyncBotPlayer) { PlayerBackpack backpack = PlayerBackpackManager.GetBackpack(BotPlayerToSync); __result = backpack.GetBackpackVanityItem(type); return false; } PlayerBackpack val = default(PlayerBackpack); if (PlayerBackpackManager_ForceSyncLocalInventory_Patch.MethodExecuting || (Object)(object)PlayerToGetApparelSelectVanityFor == (Object)null || !PlayerBackpackManager.TryGetBackpack(PlayerToGetApparelSelectVanityFor, ref val)) { return true; } __result = val.GetBackpackVanityItem(type); return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerBackpackManager_ForceSyncLocalInventory_Patch { public static bool MethodExecuting { get; private set; } public static void Prefix() { MethodExecuting = true; } public static void Postfix() { MethodExecuting = false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PlayerLobbyBar_ShowClothesSelect_Patch { public static bool PreventVanityItemFavoritesSaving { get; private set; } public static void Prefix(CM_PlayerLobbyBar __instance, out LocalPlayerOverride __state) { __state = null; if (!((Object)(object)((__instance != null) ? __instance.m_player : null) == (Object)null)) { if (SharedUtils.SafeIsBot(__instance.m_player) || !__instance.m_player.IsLocal) { PreventVanityItemFavoritesSaving = true; __state = new LocalPlayerOverride(__instance.m_player); PlayerBackpackManager_GetLocalVanityItem_Patch.PlayerToGetApparelSelectVanityFor = __instance.m_player; } else { PreventVanityItemFavoritesSaving = false; PlayerBackpackManager_GetLocalVanityItem_Patch.PlayerToGetApparelSelectVanityFor = null; } } } public static void Postfix(LocalPlayerOverride __state) { __state?.Dispose(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GearManager_RegisterVanityItemAsEquipped_Patch { public static bool Prefix(uint vanityItemId, ClothesType type) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (CM_PlayerLobbyBar_ShowClothesSelect_Patch.PreventVanityItemFavoritesSaving) { SNet_Player playerToGetApparelSelectVanityFor = PlayerBackpackManager_GetLocalVanityItem_Patch.PlayerToGetApparelSelectVanityFor; Settings.GetVanity(playerToGetApparelSelectVanityFor.CharacterIndex).Set(type, vanityItemId); return false; } return true; } } private static ClothesType[] _vanity; public const string CLOTHES_BUTTON_NAME = "BotCustomization_ClothesButton"; public override string Name => "Bot Customization"; public override GroupBase Group => (GroupBase)(object)GroupManager.Cosmetic; public override string Description => "Customize your bots - Change their name and Vanity\n\nAdds the Apparel button to bots if you're host.\n(Bot clothing only works if dropping from lobby atm!)"; public override bool SkipInitialOnEnable => true; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static NamedBotsSettings Settings { get; set; } public static SNet_Player BotPlayerToSync { get; set; } public static bool WantsToSyncBotPlayer { get; private set; } public override void OnEnable() { SetAllBotNamesAndVanity(); } public override void OnDisable() { if (!Feature.IsApplicationQuitting) { SetAllBotNamesAndVanity(setToDefault: true); } } public override void OnFeatureSettingChanged(FeatureSetting setting) { SetAllBotNamesAndVanity(); } public static void SetAllBotNamesAndVanity(bool setToDefault = false) { if (!SNet.IsInLobby) { return; } foreach (SNet_Slot item in (Il2CppArrayBase)(object)SNet.Slots.PlayerSlots) { SNet_Player player = item.player; if (!((Object)(object)player == (Object)null) && player.HasPlayerAgent && SharedUtils.SafeIsBot(player)) { PlayerAgent agent = SharedUtils.TryCastTo((Il2CppObjectBase)(object)player.PlayerAgent); SetBotName(agent, setToDefault); SetVanity(agent, setToDefault); } } } public static void SetBotName(PlayerAgent agent, bool setToDefault = false) { if (SNet.IsMaster && SharedUtils.SafeIsBot(agent.Owner)) { string text = agent.CharacterID switch { 1 => setToDefault ? "Dauda" : Settings.Dauda, 2 => setToDefault ? "Hackett" : Settings.Hackett, 3 => setToDefault ? "Bishop" : Settings.Bishop, _ => setToDefault ? "Woods" : Settings.Woods, }; if (agent.Owner.NickName != text) { agent.Owner.NickName = text; } } } public static void SetVanity(PlayerAgent agent, bool setToDefault = false) { //IL_0049: 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) PlayerBackpack val = default(PlayerBackpack); if (SNet.IsMaster && SharedUtils.SafeIsBot(agent.Owner) && PlayerBackpackManager.TryGetBackpack(agent.Owner, ref val)) { NamedBotsSettings.VanitySettings vanity = Settings.GetVanity(agent.Owner.CharacterIndex); ClothesType[] vanity2 = _vanity; foreach (ClothesType val2 in vanity2) { val.EquipVanityItem(val2, (!setToDefault) ? vanity.Get(val2) : 0u); } } } public static GameObject GetOrCreateClothesButton(CM_PlayerLobbyBar playerLobbyBar, bool create = true) { //IL_00a1: 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_00b5: 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) Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)playerLobbyBar.m_clothesButton).transform.parent, "BotCustomization_ClothesButton"); GameObject val = ((childWithExactName != null) ? ((Component)childWithExactName).gameObject : null); if (!create) { return val; } if ((Object)(object)val == (Object)null) { val = Object.Instantiate(((Component)playerLobbyBar.m_clothesButton).gameObject); val.transform.SetParent(((Component)playerLobbyBar.m_clothesButton).transform.parent); ((Object)val).name = "BotCustomization_ClothesButton"; val.transform.position = ((Component)playerLobbyBar.m_clothesButton).transform.position + new Vector3(0f, 100f); val.transform.localScale = Vector3.one; SharedUtils.SetCMItemEvents((CM_Item)(object)val.GetComponent(), (Action)delegate { playerLobbyBar.ShowClothesSelect(); }, (Action)null); } return val; } public static void WithBotAsLocalInput(SNet_Player botPlayer, Action action) { SNet_Player s_localPlayer = SNet.s_localPlayer; BotPlayerToSync = botPlayer; SNet.s_localPlayer = botPlayer; WantsToSyncBotPlayer = true; action?.Invoke(); SNet.s_localPlayer = s_localPlayer; WantsToSyncBotPlayer = false; } static BotCustomization() { ClothesType[] array = new ClothesType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); _vanity = (ClothesType[])(object)array; BotPlayerToSync = null; WantsToSyncBotPlayer = false; } } internal class CustomWeaponFOV : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ItemEquipable_GetItemFovZoom_Patch { public static bool Prefix(ItemEquippable __instance, ref float __result) { if (!Settings.IgnoreSightSettings) { return true; } __result = __instance.ItemFPSData.ItemCameraFOVZoom; return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ItemEquipable_GetWorldCameraZoomFov_Patch { public static bool Prefix(ItemEquippable __instance, ref float __result) { if (!Settings.IgnoreSightSettings) { return true; } __result = __instance.ItemFPSData.LookCameraFOVZoom; return false; } } public class WeaponFOVSettings { [FSDisplayName("Override Sights Settings")] public bool IgnoreSightSettings { get; set; } = true; [FSDisplayName("Item FPS Settings")] [FSReadOnly(false)] public Dictionary ItemFPSSettings { get; set; } = new Dictionary(); [FSHeader("Add to all", true)] [FSHide] [FSReadOnly(true)] public string IGNORE_EMPTY { get; set; } = string.Empty; [FSInline] public CustomItemFPSSettingsEntry GlobalAddition { get; set; } = new CustomItemFPSSettingsEntry(); } public class CustomItemFPSSettingsEntry { [FSDisplayName("Item FOV Default")] public int ItemCameraFOVDefault { get; set; } [FSDisplayName("Item FOV ADS")] public int ItemCameraFOVZoom { get; set; } [FSDisplayName("Camera FOV ADS")] public int LookCameraFOVZoom { get; set; } public void SetValuesOnBlock(ItemFPSSettingsDataBlock block) { block.ItemCameraFOVDefault = ItemCameraFOVDefault + Settings.GlobalAddition.ItemCameraFOVDefault; block.ItemCameraFOVZoom = ItemCameraFOVZoom + Settings.GlobalAddition.ItemCameraFOVZoom; block.LookCameraFOVZoom = LookCameraFOVZoom + Settings.GlobalAddition.LookCameraFOVZoom; } } private static Dictionary _defaultItemFPSSettings; private static ItemFPSSettingsDataBlock[] _allFPSSettingsBlocks; public override string Name => "Weapon FOV Adjustments"; public override GroupBase Group => (GroupBase)(object)GroupManager.Cosmetic; public override string Description => "Adjust the Field of View of weapons, consumables and big items."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static WeaponFOVSettings Settings { get; set; } public override void OnEnable() { if (Feature.DataBlocksReady) { SetupDefaultData(); SetCustomValues(); } } public override void OnDisable() { SetDefaultValues(); } public override void OnDatablocksReady() { SetupDefaultData(); SetCustomValues(); } public override void OnFeatureSettingChanged(FeatureSetting setting) { SetCustomValues(); } public static string GetID(ItemFPSSettingsDataBlock data) { if (data == null) { FeatureLogger.Warning("Received null ItemFPSSettingsDataBlock."); return string.Empty; } return $"{((GameDataBlockBase)(object)data).persistentID}_{((GameDataBlockBase)(object)data).name}"; } public void SetCustomValues() { if (_allFPSSettingsBlocks == null) { return; } ItemFPSSettingsDataBlock[] allFPSSettingsBlocks = _allFPSSettingsBlocks; foreach (ItemFPSSettingsDataBlock val in allFPSSettingsBlocks) { string iD = GetID(val); if (Settings.ItemFPSSettings.TryGetValue(iD, out var value)) { value.SetValuesOnBlock(val); } } } public void SetDefaultValues() { if (_allFPSSettingsBlocks == null) { return; } ItemFPSSettingsDataBlock[] allFPSSettingsBlocks = _allFPSSettingsBlocks; foreach (ItemFPSSettingsDataBlock val in allFPSSettingsBlocks) { string iD = GetID(val); if (_defaultItemFPSSettings.TryGetValue(iD, out var value)) { value.SetValuesOnBlock(val); } } } private void SetupDefaultData() { _allFPSSettingsBlocks = Il2CppArrayBase.op_Implicit(GameDataBlockBase.GetAllBlocks()); if (_defaultItemFPSSettings == null) { _defaultItemFPSSettings = new Dictionary(); ItemFPSSettingsDataBlock[] allFPSSettingsBlocks = _allFPSSettingsBlocks; foreach (ItemFPSSettingsDataBlock val in allFPSSettingsBlocks) { string iD = GetID(val); _defaultItemFPSSettings.Add(iD, new CustomItemFPSSettingsEntry { ItemCameraFOVDefault = val.ItemCameraFOVDefault, ItemCameraFOVZoom = val.ItemCameraFOVZoom, LookCameraFOVZoom = val.LookCameraFOVZoom }); } } foreach (KeyValuePair defaultItemFPSSetting in _defaultItemFPSSettings) { if (!Settings.ItemFPSSettings.ContainsKey(defaultItemFPSSetting.Key)) { Settings.ItemFPSSettings.Add(defaultItemFPSSetting.Key, defaultItemFPSSetting.Value); } } } } public class DisableTracers : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal class FX_TracerInstant_Update_Patch { public static bool Prefix(FX_TracerInstant __instance) { _A_FX_EffectBase_m_trigger.Get((FX_EffectBase)(object)__instance).OnTriggeredDone(); ((FX_EffectBase_Poolable)__instance).ReturnToPool(); return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal class FX_TracerMoving_Update_Patch { public static bool Prefix(FX_TracerMoving __instance) { _A_FX_EffectBase_m_trigger.Get((FX_EffectBase)(object)__instance).OnTriggeredDone(); ((FX_EffectBase_Poolable)__instance).ReturnToPool(); return false; } } private static IValueAccessor _A_FX_EffectBase_m_trigger; public override string Name => "Disable Bullet Tracers"; public override GroupBase Group => (GroupBase)(object)GroupManager.Cosmetic; public override string Description => "Removes Bullet Tracer Effects"; public override void Init() { _A_FX_EffectBase_m_trigger = AccessorBase.GetValueAccessor("m_trigger", false); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class EnableLegacyHammers : Feature { private static readonly Dictionary _oldHammers = new Dictionary { { "Maul", "{\"Ver\":1,\"Name\":\"Maul\",\"Packet\":{\"Comps\":{\"Length\":8,\"a\":{\"c\":2,\"v\":14},\"b\":{\"c\":3,\"v\":100},\"c\":{\"c\":4,\"v\":13},\"d\":{\"c\":44,\"v\":3},\"e\":{\"c\":46,\"v\":5},\"f\":{\"c\":48,\"v\":2},\"g\":{\"c\":50,\"v\":5}},\"MatTrans\":{\"tDecalA\":{\"scale\":0.1},\"tDecalB\":{\"scale\":0.1},\"tPattern\":{\"scale\":0.1}},\"publicName\":{\"data\":\"Maul\"}}}" }, { "Mallet", "{\"Ver\":1,\"Name\":\"Mallet\",\"Packet\":{\"Comps\":{\"Length\":8,\"a\":{\"c\":2,\"v\":14},\"b\":{\"c\":3,\"v\":100},\"c\":{\"c\":4,\"v\":13},\"d\":{\"c\":44,\"v\":6},\"e\":{\"c\":46,\"v\":9},\"f\":{\"c\":48,\"v\":10},\"g\":{\"c\":50,\"v\":8}},\"MatTrans\":{\"tDecalA\":{\"scale\":0.1},\"tDecalB\":{\"scale\":0.1},\"tPattern\":{\"scale\":0.1}},\"publicName\":{\"data\":\"Mallet\"}}}" }, { "Gavel", "{\"Ver\":1,\"Name\":\"Gavel\",\"Packet\":{\"Comps\":{\"Length\":8,\"a\":{\"c\":2,\"v\":14},\"b\":{\"c\":3,\"v\":100},\"c\":{\"c\":4,\"v\":13},\"d\":{\"c\":44,\"v\":5},\"e\":{\"c\":46,\"v\":3},\"f\":{\"c\":48,\"v\":5},\"g\":{\"c\":50,\"v\":2}},\"MatTrans\":{\"tDecalA\":{\"scale\":0.1},\"tDecalB\":{\"scale\":0.1},\"tPattern\":{\"scale\":0.1}},\"publicName\":{\"data\":\"Gavel\"}}}" }, { "Sledgehammer", "{\"Ver\":1,\"Name\":\"Sledgehammer\",\"Packet\":{\"Comps\":{\"Length\":8,\"a\":{\"c\":2,\"v\":14},\"b\":{\"c\":3,\"v\":100},\"c\":{\"c\":4,\"v\":13},\"d\":{\"c\":44,\"v\":11},\"e\":{\"c\":46,\"v\":12},\"f\":{\"c\":48,\"v\":6},\"g\":{\"c\":50,\"v\":4}},\"MatTrans\":{\"tDecalA\":{\"scale\":0.1},\"tDecalB\":{\"scale\":0.1},\"tPattern\":{\"scale\":0.1}},\"publicName\":{\"data\":\"Sledgehammer\"}}}" } }; public override string Name => "Enable old Hammers"; public override GroupBase Group => (GroupBase)(object)GroupManager.Cosmetic; public override string Description => "Re-enable the pre-R6 Hammers:\nMaul, Gavel, Sledge and Mallet"; public override bool RequiresRestart => true; public static IArchiveLogger FeatureLogger { get; set; } public override void OnEnable() { DataBlockManager.RegisterTransformationFor((Action>)Transform, -10); } public static void Transform(List allPlayerOfflineGearDataBlocks) { //IL_0096: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00b3: 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_00cb: Expected O, but got Unknown //IL_00d1: Expected O, but got Unknown if (Is.A2OrLater) { IEnumerable source = ((IEnumerable)GameDataBlockBase.GetAllBlocks()).AsEnumerable(); { foreach (KeyValuePair kvp in _oldHammers) { if (source.Any((PlayerOfflineGearDataBlock block) => ((GameDataBlockBase)(object)block).name == kvp.Key)) { FeatureLogger.Debug("> Skipping block '" + kvp.Key + "' because one with the same name already exists!"); continue; } FeatureLogger.Info("> Adding old hammer '" + kvp.Key + "' as new block ..."); PlayerOfflineGearDataBlock val = new PlayerOfflineGearDataBlock { Type = (eOfflineGearType)1 }; ((GameDataBlockBase)val).name = kvp.Key; val.GearJSON = kvp.Value; ((GameDataBlockBase)val).internalEnabled = true; GameDataBlockBase.AddBlock(val, -1); } return; } } List list = _oldHammers.Keys.ToList(); foreach (PlayerOfflineGearDataBlock allPlayerOfflineGearDataBlock in allPlayerOfflineGearDataBlocks) { if (list.Contains(((GameDataBlockBase)(object)allPlayerOfflineGearDataBlock).name)) { FeatureLogger.Success($"> Enabling block: ID: {((GameDataBlockBase)(object)allPlayerOfflineGearDataBlock).persistentID}, Name: '{((GameDataBlockBase)(object)allPlayerOfflineGearDataBlock).name}'"); ((GameDataBlockBase)(object)allPlayerOfflineGearDataBlock).internalEnabled = true; } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class Glowsticks : Feature { public class GlowstickSettings { [Localized] public enum LocalOverrideMode { Default, ForceColor, UsePlayerColor } [Localized] public enum GlowstickType { Green, Red, Orange, Yellow } [FSHeader("://Synced to other players", true)] [FSDisplayName("Override")] [FSDescription("Should any thrown glowsticks type be changed?")] public bool Override { get; set; } [FSDisplayName("Override Color")] [FSDescription("The color overriden glowsticks should be.\n(enable setting above!)\n(Orange is only available in R5 and later!)\n(Yellow is only available on ALT://R1 and later!)")] public GlowstickType OverrideType { get; set; } [FSDisplayName("Auto Festive Glowsticks")] [FSDescription("Automatically switch to festive versions on holidays.\n(<#F00>XMas => Red)\n(Halloween => Orange)")] public bool AutoFestiveGlowsticks { get; set; } [FSHeader("://Locally visible only settings", true)] [FSDisplayName("Local Color")] [FSDescription("Change colors for you only\n\n<#404>Default: Do whatever the game does\n<#404>ForceColor: Force Glowstick Colors\n<#404>UsePlayerColor: Player color determines Glowstick color\n\n(NOTICE: The first time per game start, after throwing the first glowstick, the game might stutter a little for a second to generate a texture)")] public LocalOverrideMode Mode { get; set; } [FSDisplayName("Force Color")] [FSDescription("Sets the Glowstick color for every glowstick\nSet Mode above to ForceColor to use this!")] public SColor ForcedColor { get; set; } = new SColor(0f, 1f, 0f, (float?)null); [FSDisplayName("Scale up dark colors")] [FSDescription("Turns dark colors bright to actually make them glow")] public bool ScaleUpColors { get; set; } = true; [FSDisplayName("Blue is Blue")] [FSDescription("Adds a third of the blue component as green to the current color if the green component is below that amount.\n\nBasically makes blue look blue instead of purple.")] public bool BlueIsBlue { get; set; } = true; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ItemReplicationManager__OnItemSpawn__Patch { public static SNet_Player LastItemSpawner { get; set; } public static void Prefix(pItemSpawnData spawnData) { SNet_Player lastItemSpawner = default(SNet_Player); ((pPlayer)(ref spawnData.owner)).GetPlayer(ref lastItemSpawner); LastItemSpawner = lastItemSpawner; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GlowstickInstance__Setup__Patch { [CompilerGenerated] private sealed class d__10 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GlowstickInstance glowstickInstance; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0082: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_011a: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00ba: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; Color val; switch (Settings.Mode) { default: return false; case GlowstickSettings.LocalOverrideMode.ForceColor: val = SColorExtensions.ToUnityColor(Settings.ForcedColor); break; case GlowstickSettings.LocalOverrideMode.UsePlayerColor: { SNet_Player lastItemSpawner = ItemReplicationManager__OnItemSpawn__Patch.LastItemSpawner; val = (Color)((lastItemSpawner != null) ? lastItemSpawner.PlayerColor : new Color(1f, 0f, 1f)); break; } } if (Settings.ScaleUpColors) { float num = 0f; if (val.r > num) { num = val.r; } if (val.g > num) { num = val.g; } if (val.b > num) { num = val.b; } if (num > 0f) { float num2 = 1f / num; ((Color)(ref val))..ctor(val.r * num2, val.g * num2, val.b * num2); } else { val = Color.white; } } if (Settings.BlueIsBlue) { ((Color)(ref val))..ctor(val.r, Math.Max(val.g, 0.333f * val.b), val.b); } ChangeLightColor(glowstickInstance, val); <>2__current = CreateAndOrAssignEmission(glowstickInstance, val); <>1__state = 2; return true; } case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__13 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GlowstickInstance glowstickInstance; public Color col; private MeshRenderer 5__2; private MaterialPropertyBlock 5__3; private RenderTexture 5__4; private Texture2D 5__5; private Il2CppStructArray 5__6; private Color[] 5__7; private float 5__8; private int 5__9; private float 5__10; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; 5__4 = null; 5__5 = null; 5__6 = null; 5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_020d: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: 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_030b: 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) byte[] bytes; switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = ((Component)SharedUtils.GetChildWithExactName(((Component)glowstickInstance).transform.GetChild(0).GetChild(0), "Glowstick_1")).GetComponent(); 5__3 = new MaterialPropertyBlock(); 5__3.SetVector(EMISSIVE_COLOR, Color.op_Implicit(SharedUtils.WithAlpha(col, 0.2f))); goto IL_00a3; case 1: <>1__state = -1; goto IL_00a3; case 2: { <>1__state = -1; RenderTexture active2 = RenderTexture.active; RenderTexture.active = 5__4; 5__5.ReadPixels(new Rect(0f, 0f, (float)((Texture)5__4).width, (float)((Texture)5__4).height), 0, 0); 5__5.Apply(); RenderTexture.active = active2; RenderTexture.ReleaseTemporary(5__4); <>2__current = null; <>1__state = 3; return true; } case 3: <>1__state = -1; 5__6 = 5__5.GetPixels(); 5__7 = (Color[])(object)new Color[((Il2CppArrayBase)(object)5__6).Length]; 5__8 = 0f; 5__9 = 0; goto IL_0297; case 4: <>1__state = -1; goto IL_0285; case 5: { <>1__state = -1; goto IL_033f; } IL_0297: if (5__9 < ((Il2CppArrayBase)(object)5__6).Length) { Color val = ((Il2CppArrayBase)(object)5__6)[5__9]; float grayscale = ((Color)(ref val)).grayscale; if (grayscale > 5__8) { 5__8 = grayscale; } 5__7[5__9] = new Color(grayscale, grayscale, grayscale, ((Il2CppArrayBase)(object)5__6)[5__9].a); if (5__9 % 17600 == 17599) { <>2__current = null; <>1__state = 4; return true; } goto IL_0285; } if (5__8 < 1f && 5__8 > 0f) { 5__10 = 1f / 5__8; 5__9 = 0; goto IL_0351; } goto IL_0361; IL_0285: 5__9++; goto IL_0297; IL_0351: if (5__9 < 5__7.Length) { 5__7[5__9] *= 5__10; if (5__9 % 17600 == 17599) { <>2__current = null; <>1__state = 5; return true; } goto IL_033f; } goto IL_0361; IL_00a3: if (_creatingTexture && (Object)(object)EmissiveMapMonochrome == (Object)null) { <>2__current = null; <>1__state = 1; return true; } if ((Object)(object)EmissiveMapMonochrome == (Object)null || DebugForceEmissionMapRegeneration) { _creatingTexture = true; Texture2D val2 = SharedUtils.TryCastTo((Il2CppObjectBase)(object)((Renderer)5__2).sharedMaterial.GetTexture(EMISSIVE_MAP)); 5__4 = RenderTexture.GetTemporary(((Texture)val2).width, ((Texture)val2).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1); RenderTexture active = RenderTexture.active; Graphics.Blit((Texture)(object)val2, 5__4); RenderTexture.active = active; 5__5 = new Texture2D(((Texture)val2).width, ((Texture)val2).height); <>2__current = null; <>1__state = 2; return true; } break; IL_033f: 5__9++; goto IL_0351; IL_0361: 5__5.SetPixels(Il2CppStructArray.op_Implicit(5__7)); 5__5.Apply(); EmissiveMapMonochrome = 5__5; ((Object)EmissiveMapMonochrome).hideFlags = (HideFlags)61; FeatureLogger.Info("Saving emissive map to disk."); bytes = ((IEnumerable)ImageConversion.EncodeToPNG(5__5)).ToArray(); File.WriteAllBytes(GlowstickEmissiveMapPath, bytes); _creatingTexture = false; 5__4 = null; 5__5 = null; 5__6 = null; 5__7 = null; break; } 5__3.SetTexture(EMISSIVE_MAP, (Texture)(object)EmissiveMapMonochrome); ((Renderer)5__2).SetPropertyBlock(5__3); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static bool _creatingTexture; public static bool DebugForceEmissionMapRegeneration { get; set; } public static Texture2D EmissiveMapMonochrome { get; internal set; } public static void Postfix(GlowstickInstance __instance) { if (Settings.Mode != 0) { LoaderWrapper.StartCoroutine(ColorGlowstick(__instance)); } } [IteratorStateMachine(typeof(d__10))] public static IEnumerator ColorGlowstick(GlowstickInstance glowstickInstance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__10(0) { glowstickInstance = glowstickInstance }; } public static void ChangeLightColor(GlowstickInstance glowstickInstance, Color col) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (Is.A1OrLater) { ChangeLightColorAltAndLater(glowstickInstance, col); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void ChangeLightColorAltAndLater(GlowstickInstance glowstickInstance, Color col) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) glowstickInstance.m_LightColorTarget = col; } [IteratorStateMachine(typeof(d__13))] public static IEnumerator CreateAndOrAssignEmission(GlowstickInstance glowstickInstance, Color col) { //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 decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__13(0) { glowstickInstance = glowstickInstance, col = col }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ItemReplicationManager__ThrowItem__Patch { private static HashSet _glowstickIDs; public static void Init() { _glowstickIDs = new HashSet(GlowstickLookup.Values); } public static void Prefix(ref pItemData data) { if (!_glowstickIDs.Contains(data.itemID_gearCRC) || !Settings.Override || !GlowstickLookup.TryGetValue(Settings.OverrideType, out var overrideId)) { return; } if (Settings.AutoFestiveGlowsticks) { if (IsXMas) { overrideId = GlowstickLookup[GlowstickSettings.GlowstickType.Red]; } if (IsHalloween) { overrideId = GlowstickLookup[GlowstickSettings.GlowstickType.Orange]; } } if (((IEnumerable)GameDataBlockBase.GetAllBlocks()).All((ItemDataBlock x) => ((GameDataBlockBase)(object)x).persistentID != overrideId)) { overrideId = GlowstickLookup[GlowstickSettings.GlowstickType.Green]; } data.itemID_gearCRC = overrideId; } } public static readonly Dictionary GlowstickLookup = new Dictionary { { GlowstickSettings.GlowstickType.Green, 114u }, { GlowstickSettings.GlowstickType.Red, 130u }, { GlowstickSettings.GlowstickType.Orange, 167u }, { GlowstickSettings.GlowstickType.Yellow, 174u } }; private static readonly int EMISSIVE_COLOR = Shader.PropertyToID("_EmissiveColor"); private static readonly int EMISSIVE_MAP = Shader.PropertyToID("_EmissiveMap"); public override string Name => "Glowsticks!"; public override GroupBase Group => (GroupBase)(object)GroupManager.Cosmetic; public override string Description => "Customize your glow-y little friends!\n\nAllows you to change the built in glowstick type and/or customize the color to your liking, or color it based on the player who threw the glowstick."; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static GlowstickSettings Settings { get; set; } public static bool IsXMas { get; private set; } = false; public static bool IsHalloween { get; private set; } = false; private static string GlowstickEmissiveMapPath { get; set; } public override void Init() { DateTime utcNow = DateTime.UtcNow; DateTime dateTime = new DateTime(utcNow.Year, 12, 25); IsXMas = dateTime.AddDays(-1.0) <= utcNow && utcNow <= dateTime.AddDays(7.0); DateTime dateTime2 = new DateTime(utcNow.Year, 10, 31); IsHalloween = dateTime2.AddDays(-1.0) <= utcNow && utcNow <= dateTime2.AddDays(7.0); } public override void OnGameDataInitialized() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown GlowstickEmissiveMapPath = Path.Combine(LocalFiles.GameLogsAndCachePath, "Glowsticks_EmissiveMap.png"); if (File.Exists(GlowstickEmissiveMapPath)) { FeatureLogger.Info("Loading cached emissive map from disk."); Texture2D val = new Texture2D(2, 2); if (ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(File.ReadAllBytes(GlowstickEmissiveMapPath)))) { GlowstickInstance__Setup__Patch.EmissiveMapMonochrome = val; ((Object)GlowstickInstance__Setup__Patch.EmissiveMapMonochrome).hideFlags = (HideFlags)61; } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class VanityDirtControl : Feature { public class VanityDirtControlSettings { [FSDisplayName("Dirt Amount")] [FSDescription("The amount of dirt on the player characters clothes.\n0 to 1 range.\n\n0 = clean\n1 = covered")] [FSSlider(/*Could not decode attribute arguments.*/)] public float DirtAmount { get; set; } = 0.75f; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerSyncModelData_FindGfxParts_Patch { public static Type Type() { return typeof(PlayerSyncModelData); } public static void Postfix(PlayerSyncModelData __instance) { float dirtAmount = Settings.DirtAmount; SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)__instance.m_gfxArms), dirtAmount); SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)__instance.m_gfxHead), dirtAmount); SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)__instance.m_gfxTorso), dirtAmount); SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)__instance.m_gfxLegs), dirtAmount); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerFPSBody_UpdateModel_Patch { public static Type Type() { return typeof(PlayerFPSBody); } public static void Postfix(PlayerFPSBody __instance) { SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)__instance.m_gfxArms), Settings.DirtAmount); } } private static int _shaderPropertyID = -1; public static readonly string dirtAmountPropertyName = "_DirtAmount"; public override string Name => "Vanity Dirt Control"; public override GroupBase Group => (GroupBase)(object)GroupManager.Cosmetic; public override string Description => "Set all vanity items (clothes) dirt amount."; public override bool InlineSettingsIntoParentMenu => true; public override bool SkipInitialOnEnable => true; [FeatureConfig] public static VanityDirtControlSettings Settings { get; set; } public override void Init() { _shaderPropertyID = Shader.PropertyToID(dirtAmountPropertyName); } public override void OnEnable() { UpdateAllAgentsMaterials(); } public override void OnDisable() { UpdateAllAgentsMaterials(0.75f); } public override void OnFeatureSettingChanged(FeatureSetting setting) { UpdateAllAgentsMaterials(); } private static void UpdateAllAgentsMaterials() { UpdateAllAgentsMaterials(Settings.DirtAmount); } private static void UpdateAllAgentsMaterials(float dirtValue) { if ((Object)(object)SNet.Slots == (Object)null) { return; } List playersSynchedWithGame = SNet.Slots.PlayersSynchedWithGame; if (playersSynchedWithGame == null) { return; } Enumerator enumerator = playersSynchedWithGame.GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; if ((Object)(object)current == (Object)null || !current.HasPlayerAgent) { continue; } PlayerAgent val = ((Il2CppObjectBase)current.PlayerAgent).Cast(); if ((Object)(object)val == (Object)null || (Object)(object)val.PlayerSyncModel == (Object)null) { continue; } SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val.PlayerSyncModel.m_gfxArms), dirtValue); SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val.PlayerSyncModel.m_gfxHead), dirtValue); SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val.PlayerSyncModel.m_gfxTorso), dirtValue); SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val.PlayerSyncModel.m_gfxLegs), dirtValue); if (((Agent)val).IsLocallyOwned) { FirstPersonItemHolder fPItemHolder = val.FPItemHolder; object obj; if (fPItemHolder == null) { obj = null; } else { PlayerFPSBody fPSArms = fPItemHolder.FPSArms; obj = ((fPSArms != null) ? fPSArms.m_gfxArms : null); } SetMaterialProperties(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)obj), dirtValue); } } } private static void SetMaterialProperties(GameObject[] gfx, float dirtValue) { if (gfx == null) { return; } foreach (GameObject val in gfx) { if ((Object)(object)val == (Object)null) { continue; } SkinnedMeshRenderer component = val.GetComponent(); if ((Object)(object)component == (Object)null) { continue; } foreach (Material item in (Il2CppArrayBase)(object)((Renderer)component).sharedMaterials) { if (!((Object)(object)item == (Object)null) && item.HasProperty(_shaderPropertyID)) { item.SetFloat(_shaderPropertyID, dirtValue); } } } } } } namespace TheArchive.Features.Audio { [RundownConstraint(/*Could not decode attribute arguments.*/)] public class DisableArtifactSoundLoop : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ArtifactPickup_Core_Setup_Patch { public static void Postfix(ArtifactPickup_Core __instance) { __instance.m_sound.Recycle(); } } [CompilerGenerated] private sealed class d__8 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private ItemInLevel <>2__current; private int <>l__initialThreadId; private IEnumerator <>7__wrap1; private Enumerator <>7__wrap2; private IEnumerator <>7__wrap3; ItemInLevel IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -4) <= 1u || num == 1) { try { if (num == -4 || num == 1) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>7__wrap2 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -4; goto IL_00aa; } <>1__state = -1; <>7__wrap1 = SharedUtils.GetAllZones().GetEnumerator(); <>1__state = -3; goto IL_00d8; IL_00d8: if (<>7__wrap1.MoveNext()) { LG_Zone current = <>7__wrap1.Current; <>7__wrap2 = current.m_areas.GetEnumerator(); goto IL_00c4; } <>m__Finally1(); <>7__wrap1 = null; return false; IL_00c4: if (<>7__wrap2.MoveNext()) { LG_Area current2 = <>7__wrap2.Current; <>7__wrap3 = ((Component)current2).GetComponentsInChildren().GetEnumerator(); <>1__state = -4; goto IL_00aa; } <>7__wrap2 = null; goto IL_00d8; IL_00aa: if (<>7__wrap3.MoveNext()) { ArtifactPickup_Core current3 = <>7__wrap3.Current; <>2__current = (ItemInLevel)(object)current3; <>1__state = 1; return true; } <>m__Finally2(); <>7__wrap3 = null; goto IL_00c4; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } private void <>m__Finally2() { <>1__state = -3; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__8(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public override string Name => "Disable Artifact Sound Loop"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Removes the Artifacts idle audio loop."; public override void OnEnable() { if (!Feature.DataBlocksReady) { return; } foreach (ItemInLevel allArtifact in GetAllArtifacts()) { SharedUtils.TryCastTo((Il2CppObjectBase)(object)allArtifact).m_sound.Recycle(); } } public override void OnDisable() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown uint num = SoundEventCache.Resolve("ARTIFACT_EMITTER_LOOP", false); foreach (ItemInLevel allArtifact in GetAllArtifacts()) { ArtifactPickup_Core obj = SharedUtils.TryCastTo((Il2CppObjectBase)(object)allArtifact); obj.m_sound = new CellSoundPlayer(((Component)obj).transform.position); obj.m_sound.Post(num, true); } } [IteratorStateMachine(typeof(d__8))] public static IEnumerable GetAllArtifacts() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(-2); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class DisableRespawnSackAudio : Feature { private class EnemyRespawnerVisualWrapper { public EnemyRespawnerVisual enemyRespawnerVisual; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class EnemyRespawnerVisual_Start_Patch { public static bool Prefix() { return false; } } [CompilerGenerated] private sealed class d__9 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private EnemyRespawnerVisualWrapper <>2__current; private int <>l__initialThreadId; private IEnumerator <>7__wrap1; private Enumerator <>7__wrap2; private IEnumerator <>7__wrap3; EnemyRespawnerVisualWrapper IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__9(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -4) <= 1u || num == 1) { try { if (num == -4 || num == 1) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>7__wrap2 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -4; goto IL_00b5; } <>1__state = -1; <>7__wrap1 = SharedUtils.GetAllZones().GetEnumerator(); <>1__state = -3; goto IL_00e6; IL_00e6: if (<>7__wrap1.MoveNext()) { LG_Zone current = <>7__wrap1.Current; <>7__wrap2 = current.m_areas.GetEnumerator(); goto IL_00cf; } <>m__Finally1(); <>7__wrap1 = null; return false; IL_00cf: if (<>7__wrap2.MoveNext()) { LG_Area current2 = <>7__wrap2.Current; <>7__wrap3 = ((Component)current2).GetComponentsInChildren().GetEnumerator(); <>1__state = -4; goto IL_00b5; } <>7__wrap2 = null; goto IL_00e6; IL_00b5: if (<>7__wrap3.MoveNext()) { EnemyRespawnerVisual current3 = <>7__wrap3.Current; <>2__current = new EnemyRespawnerVisualWrapper { enemyRespawnerVisual = current3 }; <>1__state = 1; return true; } <>m__Finally2(); <>7__wrap3 = null; goto IL_00cf; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } private void <>m__Finally2() { <>1__state = -3; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__9(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public override string Name => "Disable Respawn Sack Audio"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Prevents Respawn Sacks from emitting audio."; public override void OnEnable() { foreach (EnemyRespawnerVisualWrapper allEnemyRespawnerVisual in GetAllEnemyRespawnerVisuals()) { allEnemyRespawnerVisual.enemyRespawnerVisual.OnDestroy(); } } public override void OnDisable() { foreach (EnemyRespawnerVisualWrapper allEnemyRespawnerVisual in GetAllEnemyRespawnerVisuals()) { EnemyRespawnerVisual enemyRespawnerVisual = allEnemyRespawnerVisual.enemyRespawnerVisual; enemyRespawnerVisual.OnDestroy(); enemyRespawnerVisual.Start(); } } [IteratorStateMachine(typeof(d__9))] private static IEnumerable GetAllEnemyRespawnerVisuals() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__9(-2); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] public class DisableSpitterAudio : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class InfectionSpitter_TryPlaySound_Patch { public static bool Prefix(InfectionSpitter __instance, uint id) { _A_CleanupSound.Invoke(__instance); return false; } } private static MethodAccessor _A_CleanupSound; public override string Name => "Disable Spitter Audio"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Completely Removes all Audio from spitters.\n\nKeep in mind that you won't get any auditory warnings before it's too late"; public override void Init() { _A_CleanupSound = MethodAccessor.GetAccessor("CleanupSound", (Type[])null, false); } public override void OnEnable() { if (!Feature.DataBlocksReady) { return; } foreach (LG_Zone allZone in SharedUtils.GetAllZones()) { foreach (InfectionSpitter componentsInChild in ((Component)allZone).GetComponentsInChildren()) { _A_CleanupSound.Invoke(componentsInChild); } } } } } namespace TheArchive.Features.Accessibility { public class ChatTweaks : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerChatManager_PostMessage_Patch { public static void Prefix() { _shouldClone = true; string chatValue = GetChatValue(); if (!string.IsNullOrWhiteSpace(chatValue)) { _lastPostedMessages.Push(chatValue); if (_lastPostedMessages.Count > MaxChatBacklog) { _lastPostedMessages = new Stack(_lastPostedMessages.Reverse().Skip(1)); } } } } private static Stack _lastPostedMessages = new Stack(11); private static Stack _lastPostedMessagesClone = new Stack(); private static Stack _poppedMessages = new Stack(); private static string _cached = string.Empty; private static bool _shouldClone = false; public override string Name => "Chat Tweaks"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Use (Up/Down) arrow keys to cycle through the last sent messages.\nCTRL+C copies and CTRL+V pastes into the chat box"; public static int MaxChatBacklog { get; set; } = 10; public override void Update() { if (!PlayerChatManager.InChatMode) { return; } if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) { if (Input.GetKeyDown((KeyCode)118)) { string text = GetChatValue() + GUIUtility.systemCopyBuffer; if (text.Length > 50) { text = text.Substring(0, 50); } SetChatValue(text); } if (Input.GetKeyDown((KeyCode)99)) { GUIUtility.systemCopyBuffer = GetChatValue(); } } if (Input.GetKeyDown((KeyCode)273)) { if (_shouldClone) { _cached = GetChatValue(); _lastPostedMessagesClone?.Clear(); _lastPostedMessagesClone = new Stack(_lastPostedMessages.Reverse()); _poppedMessages.Clear(); _shouldClone = false; } if (_lastPostedMessagesClone.Count == _lastPostedMessages.Count) { _cached = GetChatValue(); } if (_lastPostedMessagesClone.Count > 0) { string text2 = _lastPostedMessagesClone.Pop(); SetChatValue(text2); if (!string.IsNullOrWhiteSpace(text2)) { _poppedMessages.Push(text2); } } } if (!Input.GetKeyDown((KeyCode)274)) { return; } if (_poppedMessages.Count > 0) { string text3 = _poppedMessages.Pop(); if (!string.IsNullOrWhiteSpace(text3)) { _lastPostedMessagesClone.Push(text3); } string text4 = null; if (_poppedMessages.Count > 0) { text4 = _poppedMessages.Peek(); } if (string.IsNullOrWhiteSpace(text4)) { text4 = _cached; } SetChatValue(text4); } else { SetChatValue(_cached); } } public static void SetChatValue(string str) { PlayerChatManager.Current.m_currentValue = str; } public static string GetChatValue() { return PlayerChatManager.Current.m_currentValue; } } public class DisableAmbientParticles : Feature { [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class AmbientParticles_Awake_Patch { public static Type Type() { return typeof(AmbientParticles); } public static void Postfix(AmbientParticles __instance) { ((Behaviour)__instance).enabled = false; } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class AirParticleSystem_State_Patch { public static void Prefix(ref AirParticleState value) { value = (AirParticleState)0; } } public override string Name => "Disable Ambient Particles"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Disable the little floating dust particles in the air."; public override void OnEnable() { if (Is.R6OrLater) { MonoBehaviour ambientParticlesR6Plus = GetAmbientParticlesR6Plus(); if ((Object)(object)ambientParticlesR6Plus != (Object)null) { ((Behaviour)ambientParticlesR6Plus).enabled = false; } } else { OnEnableR5Below(); } } public override void OnDisable() { if (Feature.IsApplicationQuitting) { return; } if (Is.R6OrLater) { MonoBehaviour ambientParticlesR6Plus = GetAmbientParticlesR6Plus(); if ((Object)(object)ambientParticlesR6Plus != (Object)null) { ((Behaviour)ambientParticlesR6Plus).enabled = true; } } else { OnDisableR5Below(); } } [MethodImpl(MethodImplOptions.NoInlining)] public void OnEnableR5Below() { AirParticleSystem.State = (AirParticleState)0; } [MethodImpl(MethodImplOptions.NoInlining)] public void OnDisableR5Below() { //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) //IL_000a: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 eGameStateName val = (eGameStateName)(byte)Feature.CurrentGameState; if ((int)val == 10) { AirParticleSystem.State = (AirParticleState)2; } if ((int)val == 6 || (int)val == 7 || (int)val == 8) { AirParticleSystem.State = (AirParticleState)1; } } [MethodImpl(MethodImplOptions.NoInlining)] public static MonoBehaviour GetAmbientParticlesR6Plus() { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (localPlayerAgent == null) { return null; } FPSCamera fPSCamera = localPlayerAgent.FPSCamera; if (fPSCamera == null) { return null; } GameObject gameObject = ((Component)fPSCamera).gameObject; if (gameObject == null) { return null; } return (MonoBehaviour)(object)gameObject.GetComponent(); } } public class DisableDeathDrone : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PLOC_Downed_Enter_Patch { public static void Postfix(PLOC_Downed __instance) { SetDownedSoundEnabled(__instance, value: false); } } private static PLOC_State _PLOC_State_Downed = Utils.GetEnumFromName("Downed"); private static uint _ID_PLAYER_DOWNED_1ST_PERSON; private static uint _ID_PLAYER_REVIVED_1ST_PERSON; public override string Name => "Disable Downed Sound"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Removes the droning sound that playes whenever you're downed."; public override bool SkipInitialOnEnable => true; public override void OnEnable() { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (IsPlayerDowned(localPlayerAgent)) { SetDownedSoundEnabled(SharedUtils.TryCastTo((Il2CppObjectBase)(object)((StateMachine)(object)localPlayerAgent.Locomotion).CurrentState), value: false); } } public override void OnDisable() { if (!Feature.IsApplicationQuitting) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (IsPlayerDowned(localPlayerAgent)) { SetDownedSoundEnabled(SharedUtils.TryCastTo((Il2CppObjectBase)(object)((StateMachine)(object)localPlayerAgent.Locomotion).CurrentState), value: true); } } } public override void OnDatablocksReady() { SoundEventCache.TryResolve("PLAYER_DOWNED_1ST_PERSON", ref _ID_PLAYER_DOWNED_1ST_PERSON); SoundEventCache.TryResolve("PLAYER_REVIVED_1ST_PERSON", ref _ID_PLAYER_REVIVED_1ST_PERSON); } public static bool IsPlayerDowned(PlayerAgent player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } PlayerLocomotion locomotion = player.Locomotion; if (((locomotion != null) ? new PLOC_State?(locomotion.m_currentStateEnum) : null) != (PLOC_State?)_PLOC_State_Downed) { return false; } return true; } public static void SetDownedSoundEnabled(PLOC_Downed downedState, bool value) { if (downedState == null) { return; } PlayerAgent owner = ((PLOC_Base)downedState).m_owner; if (owner != null) { CellSoundPlayer sound = owner.Sound; if (sound != null) { SharedUtils.SafePost(sound, value ? _ID_PLAYER_DOWNED_1ST_PERSON : _ID_PLAYER_REVIVED_1ST_PERSON, true); } } } } internal class DisableHudSway : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerGuiLayer_ApplyMovementSway_Patch { public static void Prefix(ref Vector3 sway) { //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) sway = Vector3.zero; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerGuiLayer_ApplyMovementScale_Patch { public static void Prefix(ref float scale) { scale = 1f; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class WatermarkGuiLayer_ApplyMovementSway_Patch { public static void Prefix(ref Vector3 sway) { //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) sway = Vector3.zero; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class WatermarkGuiLayer_ApplyMovementScale_Patch { public static void Prefix(ref float scale) { scale = 1f; } } public override string Name => "Disable HUD Sway"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Disables the in-game HUD sway while walking / jumping around."; } public class DisableUIMirroring : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class UI_Apply_ApplySetttings_Patch { public static void Prefix() { A_s_mirrorOpacity.Set((UI_Apply)null, 0f); A_s_reflectionOpacity.Set((UI_Apply)null, 0f); } } private static IValueAccessor A_s_mirrorOpacity; private static IValueAccessor A_s_reflectionOpacity; private static MethodAccessor A_ApplySetttings; public override string Name => "Disable UI Mirroring"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Removes the mirroring effect of UI elements."; public static IArchiveLogger FeatureLogger { get; set; } public override void Init() { A_s_mirrorOpacity = AccessorBase.GetValueAccessor("s_mirrorOpacity", true); A_s_reflectionOpacity = AccessorBase.GetValueAccessor("s_reflectionOpacity", true); A_ApplySetttings = MethodAccessor.GetAccessor("ApplySetttings", Array.Empty(), false); } public override void OnEnable() { A_ApplySetttings.Invoke((UI_Apply)null); } public override void OnDisable() { A_s_mirrorOpacity.Set((UI_Apply)null, 0.4f); A_s_reflectionOpacity.Set((UI_Apply)null, 0.05f); A_ApplySetttings.Invoke((UI_Apply)null); } } public class DisableUIParalax : Feature { [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GuiManager_GlobalContentMovementEnabled_Patch { public static void Postfix(ref bool __result) { __result = false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageBase_SetPageActive_Patch { public static void Postfix(CM_PageBase __instance) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!IsR5Plus) { __instance.ContenMovementEnabled = false; } ((Transform)__instance.m_movingContentHolder).localPosition = Vector3.zero; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageLoadout_SetPageActive_Patch { public static void Postfix(CM_PageLoadout __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)__instance).transform, "PlayerMovement"); if ((Object)(object)childWithExactName != (Object)null) { childWithExactName.localPosition = Vector3.zero; } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageRundown_New_SetPageActive_Patch { public static void Postfix(CM_PageRundown_New __instance) { SetPageRundownExpeditionPopupMovementEnabled(__instance, enabled: false); } } public override string Name => "Disable UI Paralax"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Disables the Paralax/Moving of UI elements in menu screens.\n(Some elements might get partially or fully cut off-screen!)\n\n(Only partially works on R4://EXT builds, might fix later.)"; public override bool SkipInitialOnEnable => true; public static bool IsR5Plus { get; private set; } public static MainMenuGuiLayer MainMenuGuiLayer_Current => MainMenuGuiLayer.Current; public static CM_PageBase[] MainMenuGuiLayer_AllPages => Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)MainMenuGuiLayer_Current.m_pages); public override void Init() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) GameBuildInfo buildInfo = Feature.BuildInfo; IsR5Plus = RundownFlagsExtensions.IsIncludedIn(((GameBuildInfo)(ref buildInfo)).Rundown, RundownFlagsExtensions.ToLatest((RundownFlags)16)); } public override void OnEnable() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (MainMenuGuiLayer_Current == null) { return; } CM_PageBase page = MainMenuGuiLayer_Current.GetPage(Utils.GetEnumFromName("CMP_SETTINGS")); if ((Object)(object)page != (Object)null) { ((Transform)page.m_movingContentHolder).localPosition = Vector3.zero; } SetPageRundownExpeditionPopupMovementEnabled(enabled: false); if (IsR5Plus) { return; } CM_PageBase[] mainMenuGuiLayer_AllPages = MainMenuGuiLayer_AllPages; foreach (CM_PageBase val in mainMenuGuiLayer_AllPages) { if (!((Object)(object)val == (Object)null)) { val.ContenMovementEnabled = false; } } } public override void OnDisable() { SetPageRundownExpeditionPopupMovementEnabled(enabled: true); if (IsR5Plus) { return; } CM_PageBase[] mainMenuGuiLayer_AllPages = MainMenuGuiLayer_AllPages; foreach (CM_PageBase val in mainMenuGuiLayer_AllPages) { if (!((Object)(object)val == (Object)null)) { val.ContenMovementEnabled = true; } } } public static void SetPageRundownExpeditionPopupMovementEnabled(bool enabled) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (MainMenuGuiLayer_Current != null) { MainMenuGuiLayer mainMenuGuiLayer_Current = MainMenuGuiLayer_Current; object pageRundown; if (mainMenuGuiLayer_Current == null) { pageRundown = null; } else { CM_PageBase page = mainMenuGuiLayer_Current.GetPage(Utils.GetEnumFromName("CMP_RUNDOWN_NEW")); pageRundown = ((page != null) ? SharedUtils.TryCastTo((Il2CppObjectBase)(object)page) : null); } SetPageRundownExpeditionPopupMovementEnabled((CM_PageRundown_New)pageRundown, enabled); } } public static void SetPageRundownExpeditionPopupMovementEnabled(CM_PageRundown_New pageRundown, bool enabled) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pageRundown == (Object)null) { return; } Transform childWithExactName = SharedUtils.GetChildWithExactName(((Component)pageRundown).transform, "PopupMovement"); if ((Object)(object)childWithExactName != (Object)null) { CM_MovingContentLayer component = ((Component)childWithExactName).GetComponent(); if ((Object)(object)component != (Object)null) { component.m_moveEvenThoughContentMoveIsDisabled = enabled; } if (!enabled) { childWithExactName.localPosition = Vector3.zero; } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class GlassLiquidOverride : Feature { public class GlassLiquidOverrideSettings { [FSDisplayName("Enable Liquid System")] [FSDescription("Turning this off stops the Glass Liquid System from updating.\n\nMake sure that nothing's left on your visor or else it'll be stuck there until you re-enable this setting.")] public bool EnableGlassLiquidSystem { get; set; } = true; [FSDisplayName("Quality")] [FSDescription("The resolution used to render the liquid effects.\n\nIncreasing this settings might decrease performance on weaker hardware!")] public GlassLiquidSystemQuality Quality { get; set; } = GlassLiquidSystemQuality.Default; [FSDisplayName("Clean Screen")] [FSDescription("Applies the Disinfect Station visuals to clear any other liquids.\n\n(Might fix bad cases of liquid bug if spammed a bunch!)")] public FButton ApplyDisinfectButton { get; set; } = new FButton("Clean", (string)null, (Action)null, false); [FSHeader("Warning", true)] [FSDisplayName("Completely Disable System")] [FSDescription("Toggling this option on completely disables the Glass Liquid System and makes you unable to re-enable it mid game.\nMight save some frames on lower end graphics hardware.\n\nA re-drop into the level is required after disabling this to re-enable the system!")] public bool CompletelyDisable { get; set; } } [Localized] public enum GlassLiquidSystemQuality { VeryBad = 1, Bad, SlightlyWorse, Default, Good, Better, Amazing, Extraordinary } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class LocalPlayerAgent_Setup_Patch { public static Type Type() { return typeof(LocalPlayerAgent); } public static void Postfix(LocalPlayerAgent __instance) { PlayerAgent_Setup_Patch.Postfix((PlayerAgent)(object)__instance); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerAgent_Setup_Patch { public static void Postfix(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned) { SetGlassLiquidSystemActive(Settings.EnableGlassLiquidSystem, __instance); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class GlassLiquidSystem_Setup_Patch { public static Type Type() { return typeof(GlassLiquidSystem); } public static void Prefix(ref int quality) { quality = (int)Settings.Quality; } } private static bool _isDisabling; public override string Name => "Glass Liquid System Override"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Adjust the games \"Glass Liquid System\"\nThe thing that renders the blood splatters etc on your visor."; [FeatureConfig] public static GlassLiquidOverrideSettings Settings { get; set; } public override void OnEnable() { _isDisabling = false; SetGlassLiquidSystemActive(Settings.EnableGlassLiquidSystem); } public override void OnDisable() { _isDisabling = true; SetGlassLiquidSystemActive(active: true); } public override void OnButtonPressed(ButtonSetting setting) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!Settings.CompletelyDisable && setting.ButtonID.Contains("ApplyDisinfectButton")) { ScreenLiquidManager.DirectApply((ScreenLiquidSettingName)10, new Vector2(0.5f, 0.5f), Vector2.zero); } } public override void OnFeatureSettingChanged(FeatureSetting setting) { SetGlassLiquidSystemActive(Settings.EnableGlassLiquidSystem); } public static void SetGlassLiquidSystemActive(bool active, PlayerAgent player = null) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (player == null) { player = PlayerManager.GetLocalPlayerAgent(); } if ((Object)(object)player == (Object)null || !((Agent)player).IsLocallyOwned) { return; } FPSCamera fPSCamera = player.FPSCamera; if ((Object)(object)fPSCamera == (Object)null) { return; } GlassLiquidSystem component = ((Component)fPSCamera).GetComponent(); if (Settings.CompletelyDisable && !_isDisabling) { if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } ScreenLiquidManager.Clear(); ScreenLiquidManager.LiquidSystem = null; SetCollectCommandsScreenLiquid(fPSCamera, value: false); } else if (!((Object)(object)component == (Object)null)) { if (active) { SetCollectCommandsScreenLiquid(fPSCamera, value: true); component.OnResolutionChange(Screen.currentResolution); } else { ScreenLiquidManager.Clear(); ScreenLiquidManager.LiquidSystem = null; SetCollectCommandsScreenLiquid(fPSCamera, value: false); } } } private static void SetCollectCommandsScreenLiquid(FPSCamera camera, bool value) { if (Is.R6OrLater) { SetCollectCommandsScreenLiquidR6(camera, value); } } private static void SetCollectCommandsScreenLiquidR6(FPSCamera camera, bool value) { camera.CollectCommandsScreenLiquid = value; } } public class Nickname : Feature { public class NicknameSettings { [FSMaxLength(25)] [FSDisplayName("Nickname")] [FSDescription("A custom Nickname.\nOverrides your steam name in game.\nLimited to 25 characters maximum\n\nIf 11 or less characters: Full color support\nIf 19 or less characters: Partial color support, colors are gonna escape!\nIf 20 or more characters: No color support")] public string Nickname { get; set; } = string.Empty; [FSDisplayName("Use Color")] [FSDescription("If the color below should be used as nickname color\nUsing a color removes 6 characters from your nickname budget minimum!")] public bool UseColor { get; set; } [FSDisplayName("Color")] [FSDescription("The color used to tint your name.")] public SColor Color { get; set; } = new SColor(0f, 1f, 0.75f, (float?)null); public FLabel InfoLabelTop { get; set; } = new FLabel("///", (string)null); public FLabel InfoLabelBottom { get; set; } = new FLabel("///", (string)null); [FSHeader("Nickname :// Others", true)] [FSDisplayName("Allow Other Player Nicknames")] [FSIdentifier("AllowNicks")] public bool AllowRemotePlayerNicknames { get; set; } = true; [FSDisplayName("See Other Players Colors")] [FSIdentifier("AllowTags")] public bool AllowRemoteTMPTags { get; set; } = true; [FSHide] [FSDisplayName("Has Migrated")] public bool HasMigrated { get; set; } [FSHide] public FLabel HiddenSettingsWarningLabel { get; set; } = new FLabel("Old settings below, do not use!", (string)null); [FSHide] [FSDisplayName("Mode")] [FSDescription("Modes explained using <#C21F4E>this as the character color and <#404>this as the custom color:\n\n<#E4A818>Normal:\n <#C21F4E>> > Nickname: Some chat message here.\n<#E4A818>Color:\n <#C21F4E>> > <#404>Nickname: Some chat message here.\n<#E4A818>TerminatedColor:\n <#C21F4E>> > <#404>Nickname: Some chat message here.")] public NicknameMode Mode { get; set; } [FSHide] [FSMaxLength(25)] [FSDisplayName("Nick (25) (No Color)")] [FSDescription("Un-colored nickname (use character color), max length of 25 characters.\n\nOnly used if Mode is set to <#E4A818>Normal!")] public string Nick25 { get; set; } [FSHide] [FSMaxLength(19)] [FSDisplayName("Nick (19) <#E4A818>(Colored)")] [FSDescription("Colored nickname, max length of 19 characters.\n\nOnly used if Mode is set to <#E4A818>Color!")] public string Nick19 { get; set; } [FSHide] [FSMaxLength(11)] [FSDisplayName("Nick (11) <#E4A818>(C + Terminated)")] [FSDescription("Terminated colored nickname, max length of 11 characters.\n\nOnly used if Mode is set to <#E4A818>TerminatedColor!")] public string Nick11 { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PUI_GameEventLog_AddLogItem_Patch { public static void Prefix(ref string log, eGameEventChatLogType type) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if (Settings.Mode == NicknameMode.Color && (int)type == 1) { Match match = Regex.Match(log, ""); if (!match.Success) { FeatureLogger.Warning("Couldn't parse outgoing chat message from local player! This should not happen?!"); return; } string text = log.Remove(0, match.Value.Length); log = match.Value + "" + text; } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class SNet_Player_UpdateVisibleName_Patch { public static bool Prefix(SNet_Player __instance) { if (__instance.IsLocal) { return true; } if (!Settings.AllowRemotePlayerNicknames) { ResetNickname(__instance, callUpdateVisiblePlayerName: false); return false; } if (!Settings.AllowRemoteTMPTags) { __instance.Profile.nick.data = Utils.StripTMPTagsRegex(__instance.Profile.nick.data); } return true; } } [Localized] public enum NicknameMode { Normal, Color, TerminatedColor, Advanced } private static Color? _currentNicknameColor; private static bool _hasMigrated; public override string Name => "Nickname"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Nickname related settings.\n\nChange your in game nickname, handy color picker included!"; [FeatureConfig] public static NicknameSettings Settings { get; set; } public static IArchiveLogger FeatureLogger { get; set; } public static Color CurrentNicknameColor { get { //IL_0057: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!_currentNicknameColor.HasValue) { if (Settings.Mode == NicknameMode.Advanced && PlayerColorOverride.GetColorFromNickname(Settings.Nickname, out var color)) { _currentNicknameColor = color; } else { _currentNicknameColor = SColorExtensions.ToUnityColor(Settings.Color); } } return _currentNicknameColor.Value; } } public static bool IsNicknameColorEnabled { get { NicknameMode mode = Settings.Mode; if ((uint)(mode - 1) <= 2u) { return true; } return false; } } public override void Init() { HandleSettingsChanged(); } public override void OnEnable() { if (string.IsNullOrEmpty(Settings.Nickname) && !Settings.HasMigrated) { MigrateOldSettings(); } SetNickname(); PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (localPlayerAgent != null) { SNet_Player owner = localPlayerAgent.Owner; if (owner != null) { owner.UpdateVisibleName(); } } } private void MigrateOldSettings() { Settings.HasMigrated = true; _hasMigrated = true; NicknameMode mode = Settings.Mode; if ((uint)(mode - 1) <= 1u) { Settings.UseColor = true; } else { Settings.UseColor = false; } if (!string.IsNullOrWhiteSpace(Settings.Nick11)) { Settings.Nickname = Settings.Nick11; } else if (!string.IsNullOrWhiteSpace(Settings.Nick19)) { Settings.Nickname = Settings.Nick19; } else if (!string.IsNullOrWhiteSpace(Settings.Nick25)) { Settings.Nickname = Settings.Nick25; } } public override void OnDisable() { if (!Feature.IsApplicationQuitting) { ResetNickname(); } } public void OnGameStateChanged(eGameStateName state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)state != 4) { return; } FeatureLogger.Notice($"State changed to {4}, initially setting nickname ..."); if (_hasMigrated) { _hasMigrated = false; Feature.MarkSettingsAsDirty(Settings); } HandleSettingsChanged(); SetNickname(); PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (localPlayerAgent != null) { SNet_Player owner = localPlayerAgent.Owner; if (owner != null) { owner.UpdateVisibleName(); } } } public override void OnFeatureSettingChanged(FeatureSetting setting) { //IL_0018: 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) HandleSettingsChanged(); if (Settings.Mode != NicknameMode.Advanced) { _currentNicknameColor = SColorExtensions.ToUnityColor(Settings.Color); } if (setting.Identifier.StartsWith("Allow")) { Enumerator enumerator = SNet.LobbyPlayers.GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; if (!current.IsLocal) { current.UpdateVisibleName(); } } return; } SetNickname(); PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (localPlayerAgent != null) { SNet_Player owner = localPlayerAgent.Owner; if (owner != null) { owner.UpdateVisibleName(); } } } private void HandleSettingsChanged() { //IL_0072: 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_00ca: Unknown result type (might be due to invalid IL or missing references) int length = Settings.Nickname.Length; bool flag = Settings.Nickname.IndexOf("<#") >= 0; string text = string.Empty; if (length > 0 && length <= 11 && Settings.UseColor && !flag) { Settings.Mode = NicknameMode.TerminatedColor; Settings.Nick11 = Settings.Nickname; text = "<" + SColorExtensions.ToShortHexString(Settings.Color) + ">"; } else if (length > 0 && length <= 19 && Settings.UseColor && !flag) { Settings.Mode = NicknameMode.Color; Settings.Nick19 = Settings.Nickname; text = "<" + SColorExtensions.ToShortHexString(Settings.Color) + ">"; } else { Settings.Mode = NicknameMode.Normal; Settings.Nick25 = Settings.Nickname; } if (flag) { Settings.Mode = NicknameMode.Advanced; if (PlayerColorOverride.GetColorFromNickname(Settings.Nickname, out var color)) { _currentNicknameColor = color; } } string text2 = ((Feature)this).Localization.Format(1u, "Nickname budget: {0} / 25 => {1}", new object[2] { length, text + Settings.Nickname }); if (Settings.InfoLabelTop.HasPrimaryText) { ((TMP_Text)SharedUtils.TryCastTo((Il2CppObjectBase)(object)Settings.InfoLabelTop.PrimaryText)).text = text2; } Settings.InfoLabelTop.LabelText = text2; string text3 = ((Feature)this).Localization.Get(Settings.Mode); if (length > 19 && Settings.UseColor) { text3 = ((Feature)this).Localization.GetById(4u, (string)null); } if (flag) { text3 = ((Feature)this).Localization.Format(5u, "<#440144>/!\\ Custom Color Tags detected! => {0}", new object[1] { Settings.Nickname }); } if (Settings.InfoLabelBottom.HasPrimaryText) { ((TMP_Text)SharedUtils.TryCastTo((Il2CppObjectBase)(object)Settings.InfoLabelBottom.PrimaryText)).text = text3; } Settings.InfoLabelBottom.LabelText = text3; } public static void ResetNickname() { ResetNickname(SNet.LocalPlayer); } public static void ResetNickname(SNet_Player player, bool callUpdateVisiblePlayerName = true) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } try { object obj; if (player == null) { obj = null; } else { SNet_PlatformData platformData = player.PlatformData; obj = ((platformData != null) ? SharedUtils.TryCastTo((Il2CppObjectBase)(object)platformData) : null); } SNet_SteamPlayerData val = (SNet_SteamPlayerData)obj; if (val != null) { string friendPersonaName = SteamFriends.GetFriendPersonaName(val.SteamID); player.NickName = Utils.StripTMPTagsRegex(friendPersonaName); } if (callUpdateVisiblePlayerName) { player.UpdateVisibleName(); } } catch (Exception ex) { if (!ex.Message.Contains("Steamworks")) { throw; } } } public static void SetNickname() { //IL_0077: 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) if ((Object)(object)SNet.LocalPlayer == (Object)null) { return; } switch (Settings.Mode) { default: if (!string.IsNullOrWhiteSpace(Settings.Nick25)) { SNet.LocalPlayer.NickName = Settings.Nick25; return; } break; case NicknameMode.Color: if (!string.IsNullOrWhiteSpace(Settings.Nick19)) { SNet.LocalPlayer.NickName = "<" + SColorExtensions.ToShortHexString(Settings.Color) + ">" + Settings.Nick19; return; } break; case NicknameMode.TerminatedColor: if (!string.IsNullOrWhiteSpace(Settings.Nick11)) { SNet.LocalPlayer.NickName = $"<{SColorExtensions.ToShortHexString(Settings.Color)}>{Settings.Nick11}"; return; } break; } ResetNickname(); } } [EnableFeatureByDefault] public class PlayerColorOverride : Feature { public class PlayerColorOverrideSettings { [Localized] public enum ColorizationMode { NicknameOnly, LocalOnly, Character, CharacterAndLocal, OtherAndLocal } [FSDisplayName("Mode")] public ColorizationMode Mode { get; set; } [FSDisplayName("Your Color")] public SColor LocalPlayer { get; set; } = SColorExtensions.FromHexString("#44D2CD"); [FSDisplayName("Other Players' Color")] public SColor OtherPlayers { get; set; } = SColorExtensions.FromHexString("#5AE55D"); [FSHeader("Character Colors", true)] [FSDisplayName("Color for <#C21F4E>Woods (P1)")] public SColor P1_Woods { get; set; } = SColorExtensions.FromHexString("#C21F4E"); [FSDisplayName("Color for <#18935E>Dauda (P2)")] public SColor P2_Dauda { get; set; } = SColorExtensions.FromHexString("#18935E"); [FSDisplayName("Color for <#20558C>Hackett (P3)")] public SColor P3_Hackett { get; set; } = SColorExtensions.FromHexString("#20558C"); [FSDisplayName("Color for <#7A1A8E>Bishop (P4)")] public SColor P4_Bishop { get; set; } = SColorExtensions.FromHexString("#7A1A8E"); [FSHeader("Misc", true)] [FSDisplayName("Local Nickname Color")] [FSDescription("Use the Nickname Features color as your own player color.")] public bool LocalUseNicknameColorAsPlayerColor { get; set; } = true; [FSDisplayName("Remote Nickname Color")] [FSDescription("Use a remote players custom (colored) nickname as the players color.\n\nWarning! This overrides the above settings if the remote player has a colored nickname!")] public bool RemoteUseNicknameColorAsPlayerColor { get; set; } = true; [FSDisplayName("Only fully colored names")] [FSDescription("Only pick the nickname color if the whole name is colored.\n\nExample:\n<#404>Nickname -> <#0c0>use as player color\n<#404>Nickname -> <#c00>don't use as player color")] public bool OnlyColorIfWholeNameIsColored { get; set; } = true; } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LocalPlayerAgent_Setup_Patch { public static Type Type() { return typeof(LocalPlayerAgent); } public static void Postfix(LocalPlayerAgent __instance, int characterID) { PlayerAgent_Setup_Patch.Postfix((PlayerAgent)(object)__instance, characterID); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerAgent_PlayerName_Patch { public static bool Prefix(PlayerAgent __instance, ref string __result) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) __result = $"<{SColorExtensions.ToHexString(__instance.Owner.PlayerColor)}>{__instance.Owner.GetName()}"; if (Is.R6OrLater) { SetInteractionNameBackingFieldR6OrLater(__instance, __result); } return false; } private static void SetInteractionNameBackingFieldR6OrLater(PlayerAgent player, string interactionName) { player._InteractionName_k__BackingField = interactionName; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerAgent_Setup_Patch { public static void Postfix(PlayerAgent __instance, int characterID) { SetupColor(__instance.Owner, characterID); } public static void SetupColor(SNet_Player player, int characterID) { //IL_006e: 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_0023: Unknown result type (might be due to invalid IL or missing references) Color color; Color col; if (player.IsLocal && Settings.LocalUseNicknameColorAsPlayerColor && FeatureManager.IsFeatureEnabled() && Nickname.IsNicknameColorEnabled) { player.PlayerColor = Nickname.CurrentNicknameColor; } else if (!player.IsLocal && Settings.RemoteUseNicknameColorAsPlayerColor && ShouldApplyNickNameColor(player.Profile.nick.data, out color)) { player.PlayerColor = color; } else if (TryGetColor(characterID, out col)) { player.PlayerColor = col; } } public static bool TryGetColor(int playerIndex, out Color col) { //IL_000d: 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_0054: 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_0042: 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_0077: 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_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_00c9: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_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_010e: 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_013b: 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_011f: 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) //IL_0129: Unknown result type (might be due to invalid IL or missing references) if (Settings.Mode == PlayerColorOverrideSettings.ColorizationMode.NicknameOnly) { col = Color.white; return false; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); int num = ((localPlayerAgent != null) ? localPlayerAgent.CharacterID : (-1)); if (Settings.Mode == PlayerColorOverrideSettings.ColorizationMode.LocalOnly) { if (num == playerIndex) { col = SColorExtensions.ToUnityColor(Settings.LocalPlayer); return true; } col = Color.white; return false; } if (Settings.Mode == PlayerColorOverrideSettings.ColorizationMode.CharacterAndLocal && num == playerIndex) { col = SColorExtensions.ToUnityColor(Settings.LocalPlayer); return true; } PlayerColorOverrideSettings.ColorizationMode mode = Settings.Mode; if ((uint)(mode - 2) <= 1u || mode != PlayerColorOverrideSettings.ColorizationMode.OtherAndLocal) { switch (playerIndex % 4) { case 0: col = SColorExtensions.ToUnityColor(Settings.P1_Woods); break; case 1: col = SColorExtensions.ToUnityColor(Settings.P2_Dauda); break; case 2: col = SColorExtensions.ToUnityColor(Settings.P3_Hackett); break; default: col = SColorExtensions.ToUnityColor(Settings.P4_Bishop); break; } } else if (num == playerIndex) { col = SColorExtensions.ToUnityColor(Settings.LocalPlayer); } else { col = SColorExtensions.ToUnityColor(Settings.OtherPlayers); } return true; } } internal static class SNet_Player_UpdateVisibleName_Patch { public static void Prefix(SNet_Player __instance) { //IL_005f: 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) FeatureLogger.Debug("SNet_Player.UpdateVisibleName() called for player " + __instance.NickName); if (!__instance.IsLocal && !Settings.RemoteUseNicknameColorAsPlayerColor) { ResetColor(__instance); return; } if (!ShouldApplyNickNameColor(__instance.Profile.nick.data, out var color)) { ResetColor(__instance); return; } FeatureLogger.Debug("Applying color: " + ColorUtility.ToHtmlStringRGB(color)); __instance.PlayerColor = color; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class SNet_GlobalManager_OnPlayerEvent_Patch { public static void Postfix(SNet_Player player, SNet_PlayerEvent playerEvent, SNet_PlayerEventReason reason) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)playerEvent == 7) { SNet_Player_UpdateVisibleName_Patch.Prefix(player); } } } private static readonly Regex _ShortColorTagRegex = new Regex("\\<\\#([0-9a-fA-F]{3})\\>"); public override string Name => "Player Color Override"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Override the built in player colors."; public override bool SkipInitialOnEnable => true; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static PlayerColorOverrideSettings Settings { get; set; } public override void OnEnable() { foreach (PlayerAgent allPlayer in GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !((Object)(object)((allPlayer != null) ? allPlayer.Owner : null) == (Object)null)) { PlayerAgent_Setup_Patch.SetupColor(allPlayer.Owner, allPlayer.Owner.CharacterIndex); } } } public override void OnDisable() { foreach (PlayerAgent allPlayer in GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !((Object)(object)((allPlayer != null) ? allPlayer.Owner : null) == (Object)null)) { ResetColor(allPlayer); } } } public static void ResetColor(PlayerAgent player) { ResetColor(player.Owner); } public static void ResetColor(SNet_Player player) { //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && player.IsInSlot && player.HasPlayerAgent) { Color staticPlayerColor = PlayerManager.GetStaticPlayerColor(player.CharacterIndex); player.PlayerColor = staticPlayerColor; } } private IEnumerable GetAllPlayers() { return GetAllPlayersR2Plus(); } [MethodImpl(MethodImplOptions.NoInlining)] private IEnumerable GetAllPlayersR2Plus() { return (IEnumerable)PlayerManager.PlayerAgentsInLevel.ToArray(); } public static bool GetColorFromNickname(string nick, out Color color) { //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) color = Color.white; Match match = _ShortColorTagRegex.Match(nick); if (!match.Success) { return false; } if (match.Groups.Count <= 1) { return false; } string text = match.Groups[1].ToString(); return ColorUtility.TryParseHtmlString("#" + text, ref color); } public static bool ShouldApplyNickNameColor(string nick, out Color color) { if (!GetColorFromNickname(nick, out color)) { return false; } if (Settings.OnlyColorIfWholeNameIsColored) { int num = nick.IndexOf("<#"); if (num > 0) { switch (nick.Substring(0, num)) { default: return false; case "": case "": case "": case "": break; } } else if (!nick.StartsWith("<#")) { return false; } if (nick.Contains("")) { if (nick.EndsWith("")) { return true; } return false; } } return true; } } public class SentryMarkerTweaks : Feature { public class SentryMarkersSettings { [FSDisplayName("Show sentry owner name")] [FSDescription("Displays the name of the sentries owner above it.")] public bool DisplayPlayerNameAboveMarker { get; set; } [FSDisplayName("Name text size")] [FSDescription("Adjust the size of the nametag where 1 is 100% (normal) size.")] [FSSlider(/*Could not decode attribute arguments.*/)] public float PlayerNameSize { get; set; } = 0.75f; [FSDisplayName("Use player color for markers")] [FSDescription("Colors the markers according to the players color.")] public bool UsePlayerColorForMarkers { get; set; } = true; [FSDisplayName("Show Sentry Type")] [FSDescription("Displays the sentries type below the players name.")] public bool ShowSentryArchetype { get; set; } = true; [FSDisplayName("Show Sentry Ammo Percentage")] [FSDescription("Displays the sentries ammo percentage below the players name.")] public bool ShowSentryAmmoPercentage { get; set; } [FSHeader("Marker Toggles", true)] [FSDisplayName("Show your own marker")] [FSDescription("Don't forget where you placed it down!")] public bool ShowOwnMarker { get; set; } = true; [FSDisplayName("Show other players markers")] public bool ShowRemoteMarkers { get; set; } = true; [FSDisplayName("Show bots markers")] public bool ShowBotMarkers { get; set; } = true; } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class SentryGunInstance_CheckIsSetup_Patch { [CompilerGenerated] private sealed class d__4 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SentryGunInstance __instance; private PlaceNavMarkerOnGO 5__2; private SNet_Player 5__3; private bool 5__4; private WaitForSecondsRealtime 5__5; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; 5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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_025d: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; 5__2 = A_PlaceNavMarkerOnGO.Get(__instance); SentryGunInstance _instance = __instance; object obj; if (_instance == null) { obj = null; } else { PlayerAgent owner = ((Item)_instance).Owner; obj = ((owner != null) ? owner.Owner : null); } 5__3 = (SNet_Player)obj; if ((Object)(object)5__3 == (Object)null) { return false; } 5__4 = SharedUtils.SafeIsBot(5__3); <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; 5__5 = new WaitForSecondsRealtime(0.2f); break; case 2: <>1__state = -1; break; case 3: <>1__state = -1; break; case 4: <>1__state = -1; break; case 5: <>1__state = -1; break; case 6: <>1__state = -1; break; } if (!Settings.ShowBotMarkers & 5__4) { HideMarker(5__2); <>2__current = 5__5; <>1__state = 2; return true; } if (!Settings.ShowRemoteMarkers && !5__3.IsLocal && !5__4) { HideMarker(5__2); <>2__current = 5__5; <>1__state = 3; return true; } if (!Settings.ShowBotMarkers & 5__4) { HideMarker(5__2); <>2__current = 5__5; <>1__state = 4; return true; } if (!Settings.ShowOwnMarker && !5__4 && 5__3.IsLocal) { HideMarker(5__2); <>2__current = 5__5; <>1__state = 5; return true; } Color val = MARKER_GREEN; string text = string.Empty; if (Settings.DisplayPlayerNameAboveMarker) { text = $"{5__3.NickName}"; } if (Settings.UsePlayerColorForMarkers) { val = 5__3.PlayerColor; text = $"<#{ColorUtility.ToHtmlStringRGB(5__3.PlayerColor)}>{text}"; } else { text = "" + text + ""; } string sentryArchAndAmmo = GetSentryArchAndAmmo(__instance, 5__3); 5__2.UpdateName(text, sentryArchAndAmmo); 5__2.UpdatePlayerColor(val); <>2__current = 5__5; <>1__state = 6; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IValueAccessor A_PlaceNavMarkerOnGO; public static void Init() { A_PlaceNavMarkerOnGO = AccessorBase.GetValueAccessor("m_navMarkerPlacer", false); } public static void Postfix(SentryGunInstance __instance) { //IL_00cc: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_01dc: Unknown result type (might be due to invalid IL or missing references) if (!SharedUtils.SafeContains((IList)_sentryGunInstances, __instance)) { _sentryGunInstances.Add(__instance); ((MonoBehaviour)__instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(UpdateMarkerInfo(__instance))); } PlaceNavMarkerOnGO val = A_PlaceNavMarkerOnGO.Get(__instance); object obj; if (__instance == null) { obj = null; } else { PlayerAgent owner = ((Item)__instance).Owner; obj = ((owner != null) ? owner.Owner : null); } SNet_Player val2 = (SNet_Player)obj; if ((Object)(object)val2 == (Object)null) { return; } bool flag = SharedUtils.SafeIsBot(val2); if (!Settings.ShowBotMarkers && flag) { HideMarker(val); return; } if (!Settings.ShowRemoteMarkers && !val2.IsLocal && !flag) { HideMarker(val); return; } if (!Settings.ShowBotMarkers && flag) { HideMarker(val); return; } if (!Settings.ShowOwnMarker && !flag && val2.IsLocal) { HideMarker(val); return; } Color val3 = MARKER_GREEN; string text = string.Empty; if (Settings.DisplayPlayerNameAboveMarker) { text = $"{val2.NickName}"; } if (Settings.UsePlayerColorForMarkers) { val3 = val2.PlayerColor; text = $"<#{ColorUtility.ToHtmlStringRGB(val2.PlayerColor)}>{text}"; } else { text = "" + text + ""; } string sentryArchAndAmmo = GetSentryArchAndAmmo(__instance, val2); val.PlaceMarker((GameObject)null); val.SetMarkerVisible(true); val.UpdateName(text, sentryArchAndAmmo); val.UpdatePlayerColor(val3); } private static string GetSentryArchAndAmmo(SentryGunInstance __instance, SNet_Player snetPlayer) { string text = string.Empty; if (Settings.ShowSentryArchetype) { text = ((Item)__instance).ArchetypeName; } if (Settings.ShowSentryAmmoPercentage) { float value = (float)Mathf.FloorToInt(__instance.Ammo / __instance.CostOfBullet) / (float)Mathf.FloorToInt(__instance.AmmoMaxCap / __instance.CostOfBullet) * 100f; text = $"{text} {value:N0}%"; } if (!string.IsNullOrWhiteSpace(text)) { text = $"{text}"; } return text; } [IteratorStateMachine(typeof(d__4))] private static IEnumerator UpdateMarkerInfo(SentryGunInstance __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(0) { __instance = __instance }; } private static string GetColorHexString(float min, float max, float value) { //IL_000d: 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_0050: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01((value - min) / (max - min)); float num2 = default(float); float num3 = default(float); float num4 = default(float); Color.RGBToHSV(Color.red, ref num2, ref num3, ref num4); float num5 = default(float); float num6 = default(float); float num7 = default(float); Color.RGBToHSV(Color.green, ref num5, ref num6, ref num7); float num8 = Mathf.Lerp(num2, num5, num); float num9 = Mathf.Lerp(num3, num6, num); float num10 = Mathf.Lerp(num4, num7, num); return SColorExtensions.ToHexString(Color.HSVToRGB(num8, num9, num10)); } public static void ExtResetMarker(SentryGunInstance sentryGunInstance) { PlaceNavMarkerOnGO val = A_PlaceNavMarkerOnGO.Get(sentryGunInstance); if (!((Object)(object)val == (Object)null)) { ResetMarker(val); } } public static void ExtHideMarker(SentryGunInstance sentryGunInstance) { PlaceNavMarkerOnGO val = A_PlaceNavMarkerOnGO.Get(sentryGunInstance); if (!((Object)(object)val == (Object)null)) { HideMarker(val); } } private static void ResetMarker(PlaceNavMarkerOnGO navMarkerPlacer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) navMarkerPlacer.PlaceMarker((GameObject)null); navMarkerPlacer.UpdateName(string.Empty, string.Empty); navMarkerPlacer.UpdatePlayerColor(MARKER_GREEN); navMarkerPlacer.SetMarkerVisible(true); } private static void HideMarker(PlaceNavMarkerOnGO navMarkerPlacer) { navMarkerPlacer.PlaceMarker((GameObject)null); navMarkerPlacer.UpdateName(string.Empty, string.Empty); navMarkerPlacer.SetMarkerVisible(false); } } public static readonly Color MARKER_GREEN = new Color(0.341f, 0.576f, 0.137f); private static readonly eGameStateName _eGameStateName_InLevel = Utils.GetEnumFromName("InLevel"); private static List _sentryGunInstances = new List(); public override string Name => "Sentry Markers"; public override GroupBase Group => (GroupBase)(object)GroupManager.Accessibility; public override string Description => "Add hud markers onto placed down sentry guns and tweak how those are shown."; public override bool SkipInitialOnEnable => true; [FeatureConfig] public static SentryMarkersSettings Settings { get; set; } public override void OnEnable() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between I4 and Unknown if ((byte)Feature.CurrentGameState == (int)_eGameStateName_InLevel) { _sentryGunInstances = (from sgi in ((IEnumerable)Object.FindObjectsOfType()).ToArray() where ((Object)((Component)sgi).gameObject).name != "SentryGunInstance" select sgi).ToList(); } UpdateAllKnownMarkers(); } public override void OnDisable() { if (Feature.IsApplicationQuitting) { return; } foreach (SentryGunInstance sentryGunInstance in _sentryGunInstances) { if (!((Object)(object)sentryGunInstance == (Object)null)) { if (sentryGunInstance.IsLocallyOwned && !SharedUtils.SafeIsBot(((Item)sentryGunInstance).Owner.Owner)) { SentryGunInstance_CheckIsSetup_Patch.ExtResetMarker(sentryGunInstance); } else { SentryGunInstance_CheckIsSetup_Patch.ExtHideMarker(sentryGunInstance); } } } } public override void OnFeatureSettingChanged(FeatureSetting setting) { UpdateAllKnownMarkers(); } private void UpdateAllKnownMarkers() { foreach (SentryGunInstance sentryGunInstance in _sentryGunInstances) { if (!((Object)(object)sentryGunInstance == (Object)null)) { SentryGunInstance_CheckIsSetup_Patch.Postfix(sentryGunInstance); } } } } [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class DisableInfectionBreathing : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerBreathing_UpdateInfectionRTPC_Patch { public static bool Prefix(PlayerBreathing __instance) { SetInfectionBreathingIntensity(__instance, 0f); return false; } } public override string Name => "Disable Breathing (<#1F835F>Infection)"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Disables the infection \"drinking-straw-sucking\" sounding sound."; public static void SetInfectionBreathingIntensity(PlayerBreathing playerBreathing, float value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) DisableStaminaBreathing.A_m_sfxBreathe.Get(playerBreathing).SetRTPCValue(GAME_PARAMETERS.INFECTION_LEVEL, value); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] internal class DisableInfectionCoughing : Feature { public override string Name => "Disable Coughing (<#1F835F>Infection)"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Disables the cough sound effect whenever a player looses HP due to infection.\n\n(SoundEvent=\"PLAY_COUGHSOFT01\")"; public override bool SkipInitialOnEnable => true; public override void OnEnable() { FilterCough(); } public override void OnGameDataInitialized() { if (((Feature)this).Enabled) { FilterCough(); } } public void FilterCough() { PlayerDialogFilter.AddEventToFilter("PLAY_COUGHSOFT01"); } public override void OnDisable() { PlayerDialogFilter.RemoveEventFromFilter("PLAY_COUGHSOFT01"); } } internal class DisableStaminaBreathing : Feature { [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class PlayerBreathing_Setup_Patch { public static void Postfix(PlayerBreathing __instance) { ((Behaviour)__instance).enabled = false; } } public static IValueAccessor A_m_sfxBreathe; public override string Name => "Disable Breathing (<#8ED7E4>Stamina)"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Disables the player breathing and panting due to running around or enemy encounters in pre-R6 builds."; public static IArchiveLogger FeatureLogger { get; set; } public override void Init() { A_m_sfxBreathe = AccessorBase.GetValueAccessor("m_sfxBreathe", false); } public override void OnEnable() { //IL_0045: 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_004d: 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) PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (!((Object)(object)localPlayerAgent == (Object)null) && !((Object)(object)localPlayerAgent.Breathing == (Object)null)) { ((Behaviour)localPlayerAgent.Breathing).enabled = false; SharedUtils.SafePost(A_m_sfxBreathe.Get(localPlayerAgent.Breathing), EVENTS.INTENSITY_0_SILENT, true); GameBuildInfo buildInfo = Feature.BuildInfo; if (RundownFlagsExtensions.IsIncludedIn(((GameBuildInfo)(ref buildInfo)).Rundown, RundownFlagsExtensions.ToLatest((RundownFlags)32))) { StaminaGoneR6Plus(localPlayerAgent); } } } private static void StaminaGoneR6Plus(PlayerAgent localPlayer) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) localPlayer.Breathing.m_sfxBreathe.Post(EVENTS.STAMINA_EXHAUSTED_STOP, ((Agent)localPlayer).Position); } public override void OnDisable() { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if (!((Object)(object)localPlayerAgent == (Object)null) && !((Object)(object)localPlayerAgent.Breathing == (Object)null)) { ((Behaviour)localPlayerAgent.Breathing).enabled = true; } } } [EnableFeatureByDefault] public class DynamicVolumeOverride : Feature { public class DynamicVolumeSettings { [Localized] public enum FocusChangeMode { Default, MuteInBackground, DoNothingInBackground, OverrideInBackground } [FSSlider(/*Could not decode attribute arguments.*/)] [FSDisplayName("Volume Override")] [FSDescription("Volume percent to use during the games' intro and elevator ride sequences.")] public float VolumeOverrideValue { get; set; } = 0.1f; [FSHide] [Obsolete] [FSDisplayName("Volume Override")] public float VolumeOverride { get; set; } = 10f; [FSDisplayName("Volume Interpolation (Seconds)")] [FSDescription("The time it takes to transition from the override volume to the game settings volume.\n(Interpolation time)")] public float LerpTime { get; set; } = 5f; [FSDisplayName("Focus Change Behaviour")] [FSDescription("Set what happens to audio whenever you tab out.\n\nDefault Use the games implementation\nMuteInBackground Mute audio when not focused\nDoNothingInBackground Keep audio on unfocus\nOverrideInBackground Use override volume on unfocus")] [FSIdentifier("FocusChangeBehaviour")] public FocusChangeMode FocusChangeBehaviour { get; set; } = FocusChangeMode.OverrideInBackground; [FSDisplayName("Reset Game Volume")] [FSDescription("Press if for some reason the audio volume settings don't seem to be back at their default values even though they should be.")] public FButton OopsMySoundSomehowBrokePleaseReset { get; set; } = new FButton("Reset Volume", (string)null, (Action)null, false); } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CM_PageRundown_New_OnEnable_Patch { private static int _state; public static void Prefix() { if (_state >= 2) { return; } if (_state == 1) { LerpVolume(Settings.VolumeOverrideValue * 100f, GetPlayerSFXSettings(), Settings.LerpTime, delegate { IsOverrideActive = false; if (Feature.IsApplicationFocused) { ResetAllVolume(); } }); } _state++; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class ElevatorRide_StartPreReleaseSequence_Patch { public static void Prefix() { IsOverrideActive = true; SetSFXVolume(Settings.VolumeOverrideValue * 100f, "ElevatorRide.StartPreReleaseSequence"); } } [RundownConstraint(/*Could not decode attribute arguments.*/)] [ArchivePatch(/*Could not decode attribute arguments.*/)] internal static class CellSettingsManager_OnApplicationFocus_Patch { public static bool Prefix(bool focus) { if (Settings.FocusChangeBehaviour == DynamicVolumeSettings.FocusChangeMode.Default) { return true; } return false; } } [CompilerGenerated] private sealed class d__38 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float duration; public float to; public float from; public Action onDone; private float 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (duration <= 0f) { SetSFXVolume(to, "Lerp Aborted, duration <= 0"); return false; } IsLerpActive = true; 5__2 = 0f; if (Feature.IsApplicationFocused) { SetSFXVolume(from, "Lerp Start"); } break; case 1: <>1__state = -1; break; } if (5__2 < duration) { float num = 5__2 / duration; float volume = Mathf.Lerp(from, to, num); if (Feature.IsApplicationFocused) { SetSFXVolume(volume); } 5__2 += Mathf.Min(Time.deltaTime, duration - 5__2); <>2__current = null; <>1__state = 1; return true; } if (Feature.IsApplicationFocused) { SetSFXVolume(to, "Lerp End"); } IsLerpActive = false; onDone?.Invoke(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly eGameStateName _eGameStateName_Offline = Utils.GetEnumFromName("Offline"); private static readonly eGameStateName _eGameStateName_StopElevatorRide = Utils.GetEnumFromName("StopElevatorRide"); private static readonly eGameStateName _eGameStateName_InLevel = Utils.GetEnumFromName("InLevel"); private static readonly eGameStateName _eGameStateName_Lobby = Utils.GetEnumFromName("Lobby"); public override string Name => "Loud Volume Override"; public override GroupBase Group => (GroupBase)(object)GroupManager.Audio; public override string Description => "Lower the game volume during loud sections:\n - game intro\n - elevator drop\n\nAdjust alt-tab sound behavior."; public static bool IsOverrideActive { get; private set; } = false; public static bool IsLerpActive { get; private set; } = false; public static IArchiveLogger FeatureLogger { get; set; } [FeatureConfig] public static DynamicVolumeSettings Settings { get; set; } public override void Init() { if (Settings.VolumeOverride >= 0f) { Settings.VolumeOverrideValue = Settings.VolumeOverride / 100f; Settings.VolumeOverride = -1f; } } public override void OnButtonPressed(ButtonSetting setting) { if (setting.ButtonID == "OopsMySoundSomehowBrokePleaseReset") { ResetAllVolume(); IsOverrideActive = false; } } public override void OnFeatureSettingChanged(FeatureSetting setting) { if (setting.Identifier == "FocusChangeBehaviour") { ResetAllVolume(); } } public override void OnDisable() { ResetAllVolume(); } public override void OnApplicationFocusChanged(bool focus) { if (Settings.FocusChangeBehaviour == DynamicVolumeSettings.FocusChangeMode.Default) { return; } if (focus) { if (IsOverrideActive) { SetSFXVolume(Settings.VolumeOverrideValue * 100f); } else { ResetAllVolume(); } return; } switch (Settings.FocusChangeBehaviour) { case DynamicVolumeSettings.FocusChangeMode.MuteInBackground: SetAllVolume(0f); break; case DynamicVolumeSettings.FocusChangeMode.DoNothingInBackground: ResetAllVolume(); break; case DynamicVolumeSettings.FocusChangeMode.OverrideInBackground: SetAllVolume(Settings.VolumeOverrideValue * 100f); break; case DynamicVolumeSettings.FocusChangeMode.Default: break; } } public static float GetPlayerSFXSettings() { return CellSettingsManager.SettingsData.Audio.SFXVolume.Value * 100f; } public static void SetSFXVolume(float volume, string debug = "") { //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(debug)) { FeatureLogger.Debug($"Setting SFX volume to {volume} percent. ({debug})"); } CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_SFX, volume); } public static void SetAllVolume(float volume) { //IL_0027: 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_0081: Unknown result type (might be due to invalid IL or missing references) float num = Math.Min(CellSettingsManager.SettingsData.Audio.SFXVolume.Value * 100f, volume); CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_SFX, num); num = Math.Min(CellSettingsManager.SettingsData.Audio.MusicVolume.Value * 100f, volume); CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_MUSIC, num); num = Math.Min(CellSettingsManager.SettingsData.Audio.DialogVolume.Value * 100f, volume); CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_DIALOG, num); } public static void ResetAllVolume() { //IL_001f: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_SFX, CellSettingsManager.SettingsData.Audio.SFXVolume.Value * 100f); CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_MUSIC, CellSettingsManager.SettingsData.Audio.MusicVolume.Value * 100f); CellSound.SetGlobalRTPCValue(GAME_PARAMETERS.VOLUME_SETTING_DIALOG, CellSettingsManager.SettingsData.Audio.DialogVolume.Value * 100f); } public void OnGameStateChanged(eGameStateName state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0029: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (state == _eGameStateName_Offline) { IsOverrideActive = true; SetSFXVolume(Settings.VolumeOverrideValue * 100f, "OnGameStateChanged, Offline"); } if (state == _eGameStateName_StopElevatorRide || (state == _eGameStateName_InLevel && !IsLerpActive && IsOverrideActive)) { LerpVolume(Settings.VolumeOverrideValue * 100f, GetPlayerSFXSettings(), Settings.LerpTime, delegate { IsOverrideActive = false; if (Feature.IsApplicationFocused) { ResetAllVolume(); } }); } if (state == _eGameStateName_Lobby) { IsOverrideActive = false; if (Feature.IsApplicationFocused) { ResetAllVolume(); } } } private static void LerpVolume(float from, float to, float duration, Action onDone = null) { LoaderWrapper.StartCoroutine(LerpVolumeCoroutine(from, to, duration, onDone)); } [IteratorStateMachine(typeof(d__38))] private static IEnumerator LerpVolumeCoroutine(float from, float to, float duration, Action onDone = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__38(0) { from = from, to = to, duration = duration, onDone = onDone }; } } }