Decompiled source of SafehouseProgressionModeCode Beta v0.1.6
NGA.SHPlibs.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using Atlas; using BepInEx; using BepInEx.Logging; using FistVR; using HarmonyLib; using Microsoft.CodeAnalysis; using NGA.ItemShop; using Sodalite.Api; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("NGA")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Persistent player progression! Raid, stash loot, and deploy with seemless scene/loadout saving.")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("NGA.SHPlibs")] [assembly: AssemblyTitle("BepInEx Plugin Title")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class BaseViewModel { public event Action Changed; protected void NotifyListeners() { this.Changed?.Invoke(); } public virtual void Initialize() { } public virtual void Dispose() { } } public class ViewModelRegistry : MonoBehaviour { private static ViewModelRegistry _instance; private readonly Dictionary<Type, object> _map = new Dictionary<Type, object>(); private void Awake() { if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private static void EnsureInstance() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("ViewModelRegistry"); _instance = val.AddComponent<ViewModelRegistry>(); Object.DontDestroyOnLoad((Object)(object)val); } } public static T Get<T>() where T : BaseViewModel, new() { EnsureInstance(); Type typeFromHandle = typeof(T); if (!_instance._map.TryGetValue(typeFromHandle, out var value)) { T val = new T(); val.Initialize(); _instance._map[typeFromHandle] = val; value = val; } return (T)value; } public static void Prewarm<T>() where T : BaseViewModel, new() { Get<T>(); } public static void Ensure() { EnsureInstance(); } public static void Register<T>(T instance) where T : BaseViewModel { EnsureInstance(); _instance._map[typeof(T)] = instance; } public static void DisposeAll() { EnsureInstance(); foreach (KeyValuePair<Type, object> item in _instance._map) { ((BaseViewModel)item.Value).Dispose(); } _instance._map.Clear(); } } public class UIElementAnimator { public static IEnumerator AnimateRoutine(Transform rect, Transform targetTransform, float duration) { Vector3 startPos = rect.position; Quaternion startRot = rect.rotation; Vector3 targetPos = targetTransform.position; Quaternion targetRot = targetTransform.rotation; float t = 0f; while (t < duration) { t += Time.deltaTime; float lerpT = Mathf.Clamp01(t / duration); rect.position = Vector3.Lerp(startPos, targetPos, lerpT); rect.rotation = Quaternion.Lerp(startRot, targetRot, lerpT); yield return null; } rect.position = targetPos; rect.rotation = targetRot; } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace NGA { public static class BankUtils { public const string BITTIES_SYMBOL = "₿"; public const string SPADES_SYMBOL = "♠"; public const string BITTIES_COLOR = "yellow"; public const string SPADES_COLOR = "lightblue"; public static string BITTIES_SYMBOL_COLORED = "<color=yellow>₿</color>"; public static string SPADES_SYMBOL_COLORED = "<color=lightblue>♠</color>"; private static readonly CultureInfo Invariant = CultureInfo.InvariantCulture; public static string FormatAmount(int amount) { return amount.ToString("N0", Invariant); } public static string FormatBitties(int amount, bool bold = true) { string text = FormatAmount(amount); string text2 = "<color=yellow>₿</color>" + text; return bold ? ("<b>" + text2 + "</b>") : text2; } public static string FormatBitties(float amount, bool bold = true) { string text = amount.ToString("N2", Invariant).TrimEnd(new char[1] { '0' }).TrimEnd(new char[1] { Invariant.NumberFormat.NumberDecimalSeparator[0] }); string text2 = "<color=yellow>₿</color>" + text; return bold ? ("<b>" + text2 + "</b>") : text2; } public static string FormatSpades(int amount, bool bold = true) { string text = FormatAmount(amount); string text2 = "<color=lightblue>♠</color>" + text; return bold ? ("<b>" + text2 + "</b>") : text2; } public static string FormatBoth(int bitties, int spades) { return FormatBitties(bitties) + " " + FormatSpades(spades); } } public class BankViewModel : BaseViewModel { public static BankViewModel Instance => ViewModelRegistry.Get<BankViewModel>(); private bool IsAnyProfileActive() { return SHGM.saveState.currentProfile != null; } public bool ProcessTransaction(ShBank.TransactionRecord record) { if (!IsAnyProfileActive()) { Debug.LogWarning((object)"Try buy: No current profile found"); return false; } bool flag = SHGM.saveState.currentProfile.bank.ProcessTransaction(record, forceDecrement: false); if (flag) { NotifyListeners(); } return flag; } public int GetSpades() { if (!IsAnyProfileActive()) { return 0; } return SHGM.saveState.currentProfile.bank.playerSpades; } public void AddSpades(int amount) { if (!IsAnyProfileActive()) { Debug.LogWarning((object)"Spades: No current profile found"); } else if (amount != 0) { SHGM.saveState.currentProfile.bank.IncrementSpades(amount); NotifyListeners(); } } public bool TrySpendSpades(int amount) { if (!IsAnyProfileActive()) { Debug.LogWarning((object)"Spades: No current profile found"); return false; } bool flag = SHGM.saveState.currentProfile.bank.TryDecrementSpades(amount); if (flag) { NotifyListeners(); } return flag; } public void ForceSpendSpades(int amount) { if (!IsAnyProfileActive()) { Debug.LogWarning((object)"Spades: No current profile found"); return; } SHGM.saveState.currentProfile.bank.ForceDecrementSpades(amount); NotifyListeners(); } } [Serializable] public class ShBank { [Serializable] public class TransactionRecord { public int amount; public string description; public TransactionRecord(int amount, string description) { this.amount = amount; this.description = description; } } public int playerBalance; public List<TransactionRecord> transactions; public int playerSpades; public ShBank() { playerBalance = 0; transactions = new List<TransactionRecord>(); playerSpades = 0; } public bool TryDecrementPlyBalance(int amount) { if (playerBalance >= amount) { playerBalance -= amount; return true; } return false; } public void ForceDecrementPlyBalance(int amount) { playerBalance -= amount; } public void IncrementPlyBalance(int amount) { playerBalance += amount; } public bool ProcessTransaction(TransactionRecord transaction, bool forceDecrement) { if (transaction.amount < 0) { if (forceDecrement) { ForceDecrementPlyBalance(-transaction.amount); } else if (!TryDecrementPlyBalance(-transaction.amount)) { return false; } } else { IncrementPlyBalance(transaction.amount); } transactions.Insert(0, transaction); return true; } public bool TryDecrementSpades(int amount) { if (playerSpades >= amount) { playerSpades -= amount; return true; } return false; } public void ForceDecrementSpades(int amount) { playerSpades -= amount; } public void IncrementSpades(int amount) { playerSpades += amount; } } public class GiftMate : MonoBehaviour { public int refreshRate = 30; public float timeSinceRefresh = 0f; public int selectedIx = 0; public void Start() { drawGifts(); } public void Update() { timeSinceRefresh += Time.deltaTime; if (timeSinceRefresh >= (float)refreshRate) { timeSinceRefresh = 0f; drawGifts(); } } private void drawGifts() { SHGM.saveState.currentProfile.giftsList.giftsQueue.ForEach(delegate { }); } public void BTN_SpawnSelected() { ShGiftsList giftsList = SHGM.saveState.currentProfile.giftsList; if (selectedIx >= 0 && selectedIx < giftsList.giftsQueue.Count) { giftsList.giftsQueue[selectedIx].idsToSpawn.ForEach(delegate { }); giftsList.RemoveGift(giftsList.giftsQueue[selectedIx]); drawGifts(); } } } [Serializable] public class ShGift { public string tinyMessage; public List<string> idsToSpawn; public ShGift(string tinyMessage, List<string> idsToSpawn) { this.tinyMessage = tinyMessage; this.idsToSpawn = idsToSpawn; } } [Serializable] public class ShGiftsList { public List<ShGift> giftsQueue; public ShGiftsList() { giftsQueue = new List<ShGift>(); } public void AddGift(ShGift g) { giftsQueue.Add(g); } public void RemoveGift(ShGift g) { giftsQueue.Remove(g); } } [Serializable] public class BaseItemData { public float Price; public List<string> Tags = new List<string>(); public string ObjectID { get; protected set; } public BaseItemData(string objectId, float price) { ObjectID = objectId; Price = price; } public override string ToString() { return string.Format("[Base Item Data] ID: {0}, Price: {1:C}, Tags: {2}", ObjectID, Price, string.Join(", ", Tags.ToArray())); } } [Serializable] public class GunData : BaseItemData { public GunData(string objectId, float price) : base(objectId, price) { } } public class ItemExtractedFeatures { public string Family; public ObjectCategory Category; public bool IsModContent; public float Mass; public int MagazineCapacity; public bool RequiresPicatinnySight; public OTagEra TagEra; public OTagSet TagSet; public OTagFirearmSize TagFirearmSize; public OTagFirearmAction TagFirearmAction; public OTagFirearmRoundPower TagFirearmRoundPower; public OTagFirearmCountryOfOrigin TagFirearmCountryOfOrigin; public int TagFirearmFirstYear; public OTagFirearmMount TagAttachmentMount; public OTagAttachmentFeature TagAttachmentFeature; public OTagMeleeStyle TagMeleeStyle; public OTagMeleeHandedness TagMeleeHandedness; public OTagPowerupType TagPowerupType; public OTagThrownType TagThrownType; public OTagThrownDamageType TagThrownDamageType; public List<OTagFirearmFiringMode> TagFirearmFiringModes; public List<OTagFirearmFeedOption> TagFirearmFeedOption; public List<OTagFirearmMount> TagFirearmMounts; public FireArmMagazineType MagazineType; public FireArmClipType ClipType; public bool UsesRoundTypeFlag; public FireArmRoundType RoundType; public List<string> CompatibleMagazines; public List<string> CompatibleClips; public List<string> CompatibleSpeedLoaders; public List<string> CompatibleSingleRounds; public List<string> BespokeAttachments; public List<string> RequiredSecondaryPieces; public int CreditCost; } internal static class ItemFeatureExtractor { internal static void TryEnrichFromFvrObject(ItemIndexRecord rec) { if (rec != null && !string.IsNullOrEmpty(rec.ItemID)) { if (!IM.OD.TryGetValue(rec.ItemID, out var value) || (Object)(object)value == (Object)null) { rec.FvrObject = null; return; } rec.FvrObject = value; Extract(rec, value); } } private static void Extract(ItemIndexRecord rec, FVRObject fvr) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_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_0081: 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_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_0099: 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_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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0241: 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_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) rec.StringTags.Clear(); rec.TagTokenSet.Clear(); ItemExtractedFeatures itemExtractedFeatures = new ItemExtractedFeatures(); itemExtractedFeatures.Family = fvr.Family; itemExtractedFeatures.Category = fvr.Category; itemExtractedFeatures.IsModContent = fvr.IsModContent; itemExtractedFeatures.Mass = fvr.Mass; itemExtractedFeatures.MagazineCapacity = fvr.MagazineCapacity; itemExtractedFeatures.RequiresPicatinnySight = fvr.RequiresPicatinnySight; itemExtractedFeatures.TagEra = fvr.TagEra; itemExtractedFeatures.TagSet = fvr.TagSet; itemExtractedFeatures.TagFirearmSize = fvr.TagFirearmSize; itemExtractedFeatures.TagFirearmAction = fvr.TagFirearmAction; itemExtractedFeatures.TagFirearmRoundPower = fvr.TagFirearmRoundPower; itemExtractedFeatures.TagFirearmCountryOfOrigin = fvr.TagFirearmCountryOfOrigin; itemExtractedFeatures.TagFirearmFirstYear = fvr.TagFirearmFirstYear; itemExtractedFeatures.TagAttachmentMount = fvr.TagAttachmentMount; itemExtractedFeatures.TagAttachmentFeature = fvr.TagAttachmentFeature; itemExtractedFeatures.TagMeleeStyle = fvr.TagMeleeStyle; itemExtractedFeatures.TagMeleeHandedness = fvr.TagMeleeHandedness; itemExtractedFeatures.TagPowerupType = fvr.TagPowerupType; itemExtractedFeatures.TagThrownType = fvr.TagThrownType; itemExtractedFeatures.TagThrownDamageType = fvr.TagThrownDamageType; itemExtractedFeatures.TagFirearmFiringModes = ((fvr.TagFirearmFiringModes != null) ? new List<OTagFirearmFiringMode>(fvr.TagFirearmFiringModes) : null); itemExtractedFeatures.TagFirearmFeedOption = ((fvr.TagFirearmFeedOption != null) ? new List<OTagFirearmFeedOption>(fvr.TagFirearmFeedOption) : null); itemExtractedFeatures.TagFirearmMounts = ((fvr.TagFirearmMounts != null) ? new List<OTagFirearmMount>(fvr.TagFirearmMounts) : null); itemExtractedFeatures.MagazineType = fvr.MagazineType; itemExtractedFeatures.ClipType = fvr.ClipType; itemExtractedFeatures.UsesRoundTypeFlag = fvr.UsesRoundTypeFlag; itemExtractedFeatures.RoundType = fvr.RoundType; itemExtractedFeatures.CreditCost = fvr.CreditCost; itemExtractedFeatures.CompatibleMagazines = ExtractIds(fvr.CompatibleMagazines); itemExtractedFeatures.CompatibleClips = ExtractIds(fvr.CompatibleClips); itemExtractedFeatures.CompatibleSpeedLoaders = ExtractIds(fvr.CompatibleSpeedLoaders); itemExtractedFeatures.CompatibleSingleRounds = ExtractIds(fvr.CompatibleSingleRounds); itemExtractedFeatures.BespokeAttachments = ExtractIds(fvr.BespokeAttachments); itemExtractedFeatures.RequiredSecondaryPieces = ExtractIds(fvr.RequiredSecondaryPieces); rec.Features = itemExtractedFeatures; AddEnumTag(rec, "Era", itemExtractedFeatures.TagEra); AddEnumTag(rec, "Set", itemExtractedFeatures.TagSet); AddEnumTag(rec, "FirearmSize", itemExtractedFeatures.TagFirearmSize); AddEnumTag(rec, "FirearmAction", itemExtractedFeatures.TagFirearmAction); AddEnumTag(rec, "FirearmRoundPower", itemExtractedFeatures.TagFirearmRoundPower); AddEnumTag(rec, "Country", itemExtractedFeatures.TagFirearmCountryOfOrigin); AddEnumTag(rec, "AttachmentMount", itemExtractedFeatures.TagAttachmentMount); AddEnumTag(rec, "AttachmentFeature", itemExtractedFeatures.TagAttachmentFeature); AddEnumTag(rec, "MeleeStyle", itemExtractedFeatures.TagMeleeStyle); AddEnumTag(rec, "MeleeHandedness", itemExtractedFeatures.TagMeleeHandedness); AddEnumTag(rec, "PowerupType", itemExtractedFeatures.TagPowerupType); AddEnumTag(rec, "ThrownType", itemExtractedFeatures.TagThrownType); AddEnumTag(rec, "ThrownDamage", itemExtractedFeatures.TagThrownDamageType); if (itemExtractedFeatures.TagFirearmFirstYear > 0) { AddStringTag(rec, "Year_" + itemExtractedFeatures.TagFirearmFirstYear); } if (itemExtractedFeatures.TagFirearmFiringModes != null) { for (int i = 0; i < itemExtractedFeatures.TagFirearmFiringModes.Count; i++) { AddEnumTag(rec, "FiringMode", itemExtractedFeatures.TagFirearmFiringModes[i]); } } if (itemExtractedFeatures.TagFirearmFeedOption != null) { for (int j = 0; j < itemExtractedFeatures.TagFirearmFeedOption.Count; j++) { AddEnumTag(rec, "FeedOption", itemExtractedFeatures.TagFirearmFeedOption[j]); } } if (itemExtractedFeatures.TagFirearmMounts != null) { for (int k = 0; k < itemExtractedFeatures.TagFirearmMounts.Count; k++) { AddEnumTag(rec, "FirearmMount", itemExtractedFeatures.TagFirearmMounts[k]); } } AddStringTag(rec, "RoundType_" + ((object)(FireArmRoundType)(ref itemExtractedFeatures.RoundType)).ToString()); AddStringTag(rec, "MagazineType_" + ((object)(FireArmMagazineType)(ref itemExtractedFeatures.MagazineType)).ToString()); AddStringTag(rec, "ClipType_" + ((object)(FireArmClipType)(ref itemExtractedFeatures.ClipType)).ToString()); AddStringTag(rec, "AttachmentMount_" + ((object)(OTagFirearmMount)(ref itemExtractedFeatures.TagAttachmentMount)).ToString()); if (rec.Data != null) { rec.Data.Tags.Clear(); rec.Data.Tags.AddRange(rec.StringTags); } } private static List<string> ExtractIds(List<FVRObject> objs) { if (objs == null || objs.Count == 0) { return null; } List<string> list = new List<string>(objs.Count); for (int i = 0; i < objs.Count; i++) { FVRObject val = objs[i]; if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(val.ItemID)) { list.Add(val.ItemID); } } return list; } private static void AddEnumTag(ItemIndexRecord rec, string prefix, object enumValue) { if (enumValue != null) { string text = enumValue.ToString(); if (!string.Equals(text, "None", StringComparison.OrdinalIgnoreCase)) { AddStringTag(rec, prefix + "_" + text); } } } private static void AddStringTag(ItemIndexRecord rec, string tag) { if (!string.IsNullOrEmpty(tag)) { string text = tag.Trim(); if (text.Length != 0) { rec.StringTags.Add(text); rec.TagTokenSet.Add(ItemToken.StableToken(text)); } } } } public static class ItemIndex { [Serializable] public sealed class FilterRequest { public string ItemID; public string Family; public ObjectCategory? Category; public OTagEra? TagEra; public OTagSet? TagSet; public OTagFirearmSize? TagFirearmSize; public OTagFirearmAction? TagFirearmAction; public OTagFirearmRoundPower? TagFirearmRoundPower; public OTagFirearmCountryOfOrigin? TagFirearmCountryOfOrigin; public OTagFirearmMount? TagAttachmentMount; public OTagAttachmentFeature? TagAttachmentFeature; public OTagMeleeStyle? TagMeleeStyle; public OTagMeleeHandedness? TagMeleeHandedness; public OTagPowerupType? TagPowerupType; public OTagThrownType? TagThrownType; public OTagThrownDamageType? TagThrownDamageType; public int? FirearmFirstYearMin; public int? FirearmFirstYearMax; public float? MassMin; public float? MassMax; public FireArmRoundType? RoundType; public FireArmMagazineType? MagazineType; public FireArmClipType? ClipType; public List<OTagFirearmFiringMode> RequireAnyFiringModes; public List<OTagFirearmFeedOption> RequireAnyFeedOptions; public List<OTagFirearmMount> RequireAnyFirearmMounts; public List<string> RequireAllStringTags; public List<string> RequireAnyStringTags; public bool? IsModContent; public int MaxResults = 100; } public struct SimilarityResult { public string ItemID; public float Score; public BaseItemData Data; } public static void Clear() { ItemIndexStore.Clear(); } public static void AddOrUpdateItem(BaseItemData item) { if (item != null && !string.IsNullOrEmpty(item.ObjectID)) { ItemIndexRecord orCreate = ItemIndexStore.GetOrCreate(item.ObjectID); orCreate.Data = item; ItemFeatureExtractor.TryEnrichFromFvrObject(orCreate); ItemIndexStore.Commit(orCreate); } } public static void AddOrUpdateItem(string itemId) { if (!string.IsNullOrEmpty(itemId)) { ItemIndexRecord orCreate = ItemIndexStore.GetOrCreate(itemId); if (orCreate.Data == null) { orCreate.Data = new BaseItemData(itemId, 0f); } ItemFeatureExtractor.TryEnrichFromFvrObject(orCreate); ItemIndexStore.Commit(orCreate); } } public static void AddItems(List<string> objectIds) { if (objectIds != null) { for (int i = 0; i < objectIds.Count; i++) { AddOrUpdateItem(objectIds[i]); } } } public static void AddItems(List<BaseItemData> items) { if (items != null) { for (int i = 0; i < items.Count; i++) { AddOrUpdateItem(items[i]); } } } public static void EnsureIndexed(string itemId) { if (!string.IsNullOrEmpty(itemId) && !ItemIndexStore.Contains(itemId)) { AddOrUpdateItem(new BaseItemData(itemId, 0f)); } } public static ItemExtractedFeatures GetItemFeatures(string itemId) { if (string.IsNullOrEmpty(itemId)) { return null; } ItemIndexStore.TryGet(itemId, out var rec); return rec?.Features; } public static List<BaseItemData> Query(FilterRequest request) { return ItemQueryEngine.Query(request); } public static List<SimilarityResult> FindNearestNeighbors(string seedItemId, int k = 10) { return ItemSimilarityEngine.FindNearestNeighbors(seedItemId, k); } public static float PredictPrice(string seedItemId, int k = 5) { return ItemSimilarityEngine.PredictPrice(seedItemId, k); } public static List<BaseItemData> FindByItemId(string itemId) { if (string.IsNullOrEmpty(itemId)) { return new List<BaseItemData>(0); } return Query(new FilterRequest { ItemID = itemId, MaxResults = 1 }); } public static List<BaseItemData> FindByCategory(ObjectCategory category, int maxResults = 100) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Query(new FilterRequest { Category = category, MaxResults = maxResults }); } public static List<BaseItemData> FindByFamily(string family, int maxResults = 100) { return Query(new FilterRequest { Family = family, MaxResults = maxResults }); } public static List<BaseItemData> FindByEra(OTagEra era, int maxResults = 100) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Query(new FilterRequest { TagEra = era, MaxResults = maxResults }); } public static List<BaseItemData> FindBySet(OTagSet set, int maxResults = 100) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Query(new FilterRequest { TagSet = set, MaxResults = maxResults }); } public static List<BaseItemData> FindByRoundType(FireArmRoundType roundType, int maxResults = 100) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Query(new FilterRequest { RoundType = roundType, MaxResults = maxResults }); } public static List<BaseItemData> FindByMagazineType(FireArmMagazineType magazineType, int maxResults = 100) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Query(new FilterRequest { MagazineType = magazineType, MaxResults = maxResults }); } public static List<BaseItemData> FindByClipType(FireArmClipType clipType, int maxResults = 100) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Query(new FilterRequest { ClipType = clipType, MaxResults = maxResults }); } public static List<BaseItemData> FindByFirstYearRange(int minInclusive, int maxInclusive, int maxResults = 100) { return Query(new FilterRequest { FirearmFirstYearMin = minInclusive, FirearmFirstYearMax = maxInclusive, MaxResults = maxResults }); } public static List<BaseItemData> FindByTagsAll(int maxResults, params string[] tags) { FilterRequest filterRequest = new FilterRequest { MaxResults = maxResults, RequireAllStringTags = new List<string>() }; if (tags != null) { for (int i = 0; i < tags.Length; i++) { if (!string.IsNullOrEmpty(tags[i])) { filterRequest.RequireAllStringTags.Add(tags[i]); } } } if (filterRequest.RequireAllStringTags.Count == 0) { filterRequest.RequireAllStringTags = null; } return Query(filterRequest); } public static List<BaseItemData> FindByTagsAny(int maxResults, params string[] tags) { FilterRequest filterRequest = new FilterRequest { MaxResults = maxResults, RequireAnyStringTags = new List<string>() }; if (tags != null) { for (int i = 0; i < tags.Length; i++) { if (!string.IsNullOrEmpty(tags[i])) { filterRequest.RequireAnyStringTags.Add(tags[i]); } } } if (filterRequest.RequireAnyStringTags.Count == 0) { filterRequest.RequireAnyStringTags = null; } return Query(filterRequest); } public static List<BaseItemData> FindByAnyFiringMode(int maxResults, params OTagFirearmFiringMode[] modes) { FilterRequest filterRequest = new FilterRequest { MaxResults = maxResults, RequireAnyFiringModes = new List<OTagFirearmFiringMode>() }; if (modes != null) { for (int i = 0; i < modes.Length; i++) { filterRequest.RequireAnyFiringModes.Add(modes[i]); } } if (filterRequest.RequireAnyFiringModes.Count == 0) { filterRequest.RequireAnyFiringModes = null; } return Query(filterRequest); } public static HashSet<string> GetIdsByCategoryCopy(ObjectCategory category) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) HashSet<string> byCategory = ItemIndexStore.GetByCategory(category); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string item in byCategory) { hashSet.Add(item); } return hashSet; } public static HashSet<string> GetIdsByFamilyCopy(string family) { HashSet<string> byFamily = ItemIndexStore.GetByFamily(family); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string item in byFamily) { hashSet.Add(item); } return hashSet; } public static HashSet<string> GetIdsByStringTagCopy(string tag) { int tok = ItemToken.StableToken(tag); HashSet<string> byTagToken = ItemIndexStore.GetByTagToken(tok); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string item in byTagToken) { hashSet.Add(item); } return hashSet; } public static bool TryGetIndexedPrice(string itemId, out float price) { price = 0f; if (string.IsNullOrEmpty(itemId)) { return false; } if (!ItemIndexStore.TryGet(itemId, out var rec)) { return false; } if (rec.Data == null) { return false; } price = rec.Data.Price; return true; } public static void OverrideIndexedPrice(string itemId, float newPrice) { if (!string.IsNullOrEmpty(itemId)) { ItemIndexRecord orCreate = ItemIndexStore.GetOrCreate(itemId); if (orCreate.Data == null) { orCreate.Data = new BaseItemData(itemId, newPrice); ItemIndexStore.Commit(orCreate); } else { orCreate.Data.Price = newPrice; ItemIndexStore.Commit(orCreate); } } } } internal sealed class ItemIndexRecord { public string ItemID; public BaseItemData Data; public FVRObject FvrObject; public ItemExtractedFeatures Features; public readonly List<string> StringTags = new List<string>(32); public readonly HashSet<int> TagTokenSet = new HashSet<int>(); } internal static class ItemIndexStore { private static readonly Dictionary<string, ItemIndexRecord> _recordsById = new Dictionary<string, ItemIndexRecord>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<ObjectCategory, HashSet<string>> _byCategory = new Dictionary<ObjectCategory, HashSet<string>>(); private static readonly Dictionary<string, HashSet<string>> _byFamily = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<int, HashSet<string>> _byTagToken = new Dictionary<int, HashSet<string>>(); internal static void Clear() { _recordsById.Clear(); _byCategory.Clear(); _byFamily.Clear(); _byTagToken.Clear(); } internal static bool Contains(string itemId) { return _recordsById.ContainsKey(itemId); } internal static bool TryGet(string itemId, out ItemIndexRecord rec) { return _recordsById.TryGetValue(itemId, out rec); } internal static ItemIndexRecord GetOrCreate(string itemId) { if (_recordsById.TryGetValue(itemId, out var value)) { return value; } value = new ItemIndexRecord { ItemID = itemId }; _recordsById[itemId] = value; return value; } internal static void Commit(ItemIndexRecord rec) { _recordsById[rec.ItemID] = rec; ReindexAppendOnly(rec); } internal static IEnumerable<KeyValuePair<string, ItemIndexRecord>> EnumerateAll() { return _recordsById; } internal static HashSet<string> GetAllIds() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair<string, ItemIndexRecord> item in _recordsById) { hashSet.Add(item.Key); } return hashSet; } internal static HashSet<string> GetByCategory(ObjectCategory cat) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) HashSet<string> value; return _byCategory.TryGetValue(cat, out value) ? value : new HashSet<string>(StringComparer.OrdinalIgnoreCase); } internal static HashSet<string> GetByFamily(string family) { if (string.IsNullOrEmpty(family)) { return new HashSet<string>(StringComparer.OrdinalIgnoreCase); } HashSet<string> value; return _byFamily.TryGetValue(family, out value) ? value : new HashSet<string>(StringComparer.OrdinalIgnoreCase); } internal static HashSet<string> GetByTagToken(int tok) { HashSet<string> value; return _byTagToken.TryGetValue(tok, out value) ? value : new HashSet<string>(StringComparer.OrdinalIgnoreCase); } internal static HashSet<string> IntersectCandidates(HashSet<string> current, HashSet<string> next) { if (current == null) { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string item in next) { hashSet.Add(item); } return hashSet; } if (current.Count == 0) { return current; } List<string> list = new List<string>(); foreach (string item2 in current) { if (!next.Contains(item2)) { list.Add(item2); } } for (int i = 0; i < list.Count; i++) { current.Remove(list[i]); } return current; } private static void ReindexAppendOnly(ItemIndexRecord rec) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) if (rec == null) { return; } ItemExtractedFeatures features = rec.Features; string itemID = rec.ItemID; if (string.IsNullOrEmpty(itemID)) { return; } if (features != null) { ObjectCategory category = features.Category; if (!_byCategory.TryGetValue(category, out var value)) { value = new HashSet<string>(StringComparer.OrdinalIgnoreCase); _byCategory[category] = value; } value.Add(itemID); } string text = features?.Family; if (!string.IsNullOrEmpty(text)) { if (!_byFamily.TryGetValue(text, out var value2)) { value2 = new HashSet<string>(StringComparer.OrdinalIgnoreCase); _byFamily[text] = value2; } value2.Add(itemID); } HashSet<int> tagTokenSet = rec.TagTokenSet; if (tagTokenSet == null) { return; } foreach (int item in tagTokenSet) { if (!_byTagToken.TryGetValue(item, out var value3)) { value3 = new HashSet<string>(StringComparer.OrdinalIgnoreCase); _byTagToken[item] = value3; } value3.Add(itemID); } } } internal static class ItemQueryEngine { internal static List<BaseItemData> Query(ItemIndex.FilterRequest request) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (request == null) { return new List<BaseItemData>(0); } HashSet<string> hashSet = null; if (request.Category.HasValue) { hashSet = ItemIndexStore.IntersectCandidates(hashSet, ItemIndexStore.GetByCategory(request.Category.Value)); } if (!string.IsNullOrEmpty(request.Family)) { hashSet = ItemIndexStore.IntersectCandidates(hashSet, ItemIndexStore.GetByFamily(request.Family)); } if (request.RequireAllStringTags != null && request.RequireAllStringTags.Count > 0) { for (int i = 0; i < request.RequireAllStringTags.Count; i++) { int tok = ItemToken.StableToken(request.RequireAllStringTags[i]); hashSet = ItemIndexStore.IntersectCandidates(hashSet, ItemIndexStore.GetByTagToken(tok)); if (hashSet != null && hashSet.Count == 0) { break; } } } if (hashSet == null) { hashSet = ItemIndexStore.GetAllIds(); } List<BaseItemData> list = new List<BaseItemData>(Math.Max(0, request.MaxResults)); foreach (string item in hashSet) { if (ItemIndexStore.TryGet(item, out var rec) && Matches(request, rec)) { if (rec.Data != null) { list.Add(rec.Data); } if (list.Count >= request.MaxResults) { break; } } } return list; } private static bool Matches(ItemIndex.FilterRequest req, ItemIndexRecord rec) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0114: 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_0147: 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_017a: 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) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) ItemExtractedFeatures features = rec.Features; if (!string.IsNullOrEmpty(req.ItemID) && !string.Equals(req.ItemID, rec.ItemID, StringComparison.OrdinalIgnoreCase)) { return false; } if (!string.IsNullOrEmpty(req.Family) && !string.Equals(req.Family, features.Family, StringComparison.OrdinalIgnoreCase)) { return false; } if (req.Category.HasValue && req.Category.Value != features.Category) { return false; } if (req.IsModContent.HasValue && req.IsModContent.Value != features.IsModContent) { return false; } if (req.TagEra.HasValue && req.TagEra.Value != features.TagEra) { return false; } if (req.TagSet.HasValue && req.TagSet.Value != features.TagSet) { return false; } if (req.TagFirearmSize.HasValue && req.TagFirearmSize.Value != features.TagFirearmSize) { return false; } if (req.TagFirearmAction.HasValue && req.TagFirearmAction.Value != features.TagFirearmAction) { return false; } if (req.TagFirearmRoundPower.HasValue && req.TagFirearmRoundPower.Value != features.TagFirearmRoundPower) { return false; } if (req.TagFirearmCountryOfOrigin.HasValue && req.TagFirearmCountryOfOrigin.Value != features.TagFirearmCountryOfOrigin) { return false; } if (req.TagAttachmentMount.HasValue && req.TagAttachmentMount.Value != features.TagAttachmentMount) { return false; } if (req.TagAttachmentFeature.HasValue && req.TagAttachmentFeature.Value != features.TagAttachmentFeature) { return false; } if (req.TagMeleeStyle.HasValue && req.TagMeleeStyle.Value != features.TagMeleeStyle) { return false; } if (req.TagMeleeHandedness.HasValue && req.TagMeleeHandedness.Value != features.TagMeleeHandedness) { return false; } if (req.TagPowerupType.HasValue && req.TagPowerupType.Value != features.TagPowerupType) { return false; } if (req.TagThrownType.HasValue && req.TagThrownType.Value != features.TagThrownType) { return false; } if (req.TagThrownDamageType.HasValue && req.TagThrownDamageType.Value != features.TagThrownDamageType) { return false; } if (req.FirearmFirstYearMin.HasValue && features.TagFirearmFirstYear < req.FirearmFirstYearMin.Value) { return false; } if (req.FirearmFirstYearMax.HasValue && features.TagFirearmFirstYear > req.FirearmFirstYearMax.Value) { return false; } if (req.MassMin.HasValue && features.Mass < req.MassMin.Value) { return false; } if (req.MassMax.HasValue && features.Mass > req.MassMax.Value) { return false; } if (req.RoundType.HasValue && req.RoundType.Value != features.RoundType) { return false; } if (req.MagazineType.HasValue && req.MagazineType.Value != features.MagazineType) { return false; } if (req.ClipType.HasValue && req.ClipType.Value != features.ClipType) { return false; } if (req.RequireAnyFiringModes != null && req.RequireAnyFiringModes.Count > 0) { if (features.TagFirearmFiringModes == null || features.TagFirearmFiringModes.Count == 0) { return false; } if (!OverlapsAny(req.RequireAnyFiringModes, features.TagFirearmFiringModes)) { return false; } } if (req.RequireAnyFeedOptions != null && req.RequireAnyFeedOptions.Count > 0) { if (features.TagFirearmFeedOption == null || features.TagFirearmFeedOption.Count == 0) { return false; } if (!OverlapsAny(req.RequireAnyFeedOptions, features.TagFirearmFeedOption)) { return false; } } if (req.RequireAnyFirearmMounts != null && req.RequireAnyFirearmMounts.Count > 0) { if (features.TagFirearmMounts == null || features.TagFirearmMounts.Count == 0) { return false; } if (!OverlapsAny(req.RequireAnyFirearmMounts, features.TagFirearmMounts)) { return false; } } if (req.RequireAnyStringTags != null && req.RequireAnyStringTags.Count > 0) { bool flag = false; for (int i = 0; i < req.RequireAnyStringTags.Count; i++) { int item = ItemToken.StableToken(req.RequireAnyStringTags[i]); if (rec.TagTokenSet.Contains(item)) { flag = true; break; } } if (!flag) { return false; } } if (req.RequireAllStringTags != null && req.RequireAllStringTags.Count > 0) { for (int j = 0; j < req.RequireAllStringTags.Count; j++) { int item2 = ItemToken.StableToken(req.RequireAllStringTags[j]); if (!rec.TagTokenSet.Contains(item2)) { return false; } } } return true; } private static bool OverlapsAny<T>(List<T> requiredAny, List<T> actual) { for (int i = 0; i < requiredAny.Count; i++) { T x = requiredAny[i]; for (int j = 0; j < actual.Count; j++) { if (EqualityComparer<T>.Default.Equals(x, actual[j])) { return true; } } } return false; } } internal static class ItemSimilarityEngine { internal static List<ItemIndex.SimilarityResult> FindNearestNeighbors(string seedItemId, int k) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(seedItemId)) { return new List<ItemIndex.SimilarityResult>(0); } if (!ItemIndexStore.TryGet(seedItemId, out var rec)) { ItemIndex.EnsureIndexed(seedItemId); if (!ItemIndexStore.TryGet(seedItemId, out rec)) { return new List<ItemIndex.SimilarityResult>(0); } } ItemSimilarityProfile profile = GetProfile(rec); HashSet<string> hashSet = null; if (profile.RequireSameCategory) { hashSet = ItemIndexStore.IntersectCandidates(hashSet, ItemIndexStore.GetByCategory(rec.Features.Category)); } if ((Object)(object)rec.FvrObject != (Object)null) { if (profile.RequireSameRoundTypeForFirearms) { hashSet = ItemIndexStore.IntersectCandidates(hashSet, ItemIndexStore.GetByTagToken(ItemToken.StableToken("RoundType_" + ((object)(FireArmRoundType)(ref rec.Features.RoundType)).ToString()))); } if (profile.RequireSameAttachmentMountForAttachments) { hashSet = ItemIndexStore.IntersectCandidates(hashSet, ItemIndexStore.GetByTagToken(ItemToken.StableToken("AttachmentMount_" + ((object)(OTagFirearmMount)(ref rec.Features.TagAttachmentMount)).ToString()))); } } if (hashSet == null) { hashSet = ItemIndexStore.GetAllIds(); } List<ItemIndex.SimilarityResult> list = new List<ItemIndex.SimilarityResult>(Mathf.Min(Mathf.Max(8, k * 8), hashSet.Count)); foreach (string item in hashSet) { if (!string.Equals(item, seedItemId, StringComparison.OrdinalIgnoreCase) && ItemIndexStore.TryGet(item, out var rec2)) { float num = ScoreSimilarity(rec, rec2, profile); if (!(num <= 0f)) { list.Add(new ItemIndex.SimilarityResult { ItemID = item, Score = num, Data = rec2.Data }); } } } list.Sort((ItemIndex.SimilarityResult a, ItemIndex.SimilarityResult b) => b.Score.CompareTo(a.Score)); if (k < 1) { k = 1; } if (list.Count > k) { list.RemoveRange(k, list.Count - k); } return list; } internal static float PredictPrice(string seedItemId, int k = 3) { List<ItemIndex.SimilarityResult> list = FindNearestNeighbors(seedItemId, Mathf.Max(1, k * 3)); float num = 0f; int num2 = 0; for (int i = 0; i < list.Count; i++) { BaseItemData data = list[i].Data; if (data != null && !(data.Price <= 0f)) { num += data.Price; num2++; if (num2 >= k) { break; } } } return (num2 == 0) ? 0f : (num / (float)num2); } private static ItemSimilarityProfile GetProfile(ItemIndexRecord seed) { return ItemSimilarityPolicy.Default; } private static float ScoreSimilarity(ItemIndexRecord a, ItemIndexRecord b, ItemSimilarityProfile p) { //IL_000d: 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_007d: 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_00e5: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if (a.Features.Category == b.Features.Category) { num += p.WeightCategory; } if (!string.IsNullOrEmpty(a.Features.Family) && string.Equals(a.Features.Family, b.Features.Family, StringComparison.OrdinalIgnoreCase)) { num += p.WeightFamily; } if (((object)(OTagEra)(ref a.Features.TagEra)).Equals((object?)b.Features.TagEra)) { num += p.WeightEra; } if (((object)(OTagSet)(ref a.Features.TagSet)).Equals((object?)b.Features.TagSet)) { num += p.WeightSet; } if (((object)(OTagFirearmAction)(ref a.Features.TagFirearmAction)).Equals((object?)b.Features.TagFirearmAction)) { num += p.WeightAction; } if (((object)(OTagFirearmSize)(ref a.Features.TagFirearmSize)).Equals((object?)b.Features.TagFirearmSize)) { num += p.WeightSize; } if (((object)(OTagFirearmRoundPower)(ref a.Features.TagFirearmRoundPower)).Equals((object?)b.Features.TagFirearmRoundPower)) { num += p.WeightRoundPower; } if (((object)(OTagFirearmCountryOfOrigin)(ref a.Features.TagFirearmCountryOfOrigin)).Equals((object?)b.Features.TagFirearmCountryOfOrigin)) { num += p.WeightCountry; } if (((object)(OTagFirearmMount)(ref a.Features.TagAttachmentMount)).Equals((object?)b.Features.TagAttachmentMount)) { num += p.WeightAttachmentMount; } if (((object)(FireArmRoundType)(ref a.Features.RoundType)).Equals((object?)b.Features.RoundType)) { num += p.WeightRoundType; } if (a.Features.TagFirearmFirstYear > 0 && b.Features.TagFirearmFirstYear > 0) { int num2 = Mathf.Abs(a.Features.TagFirearmFirstYear - b.Features.TagFirearmFirstYear); float num3 = 1f / (1f + (float)num2 / Mathf.Max(1f, p.FirstYearScale)); num += num3 * p.WeightFirstYear; } num += OverlapScore(a.Features.TagFirearmFiringModes, b.Features.TagFirearmFiringModes) * p.WeightFiringModes; num += OverlapScore(a.Features.TagFirearmFeedOption, b.Features.TagFirearmFeedOption) * p.WeightFeedOptions; num += OverlapScore(a.Features.TagFirearmMounts, b.Features.TagFirearmMounts) * p.WeightMounts; num += CompatibilityOverlapScore(a.Features, b.Features) * p.WeightCompatibility; if (a.TagTokenSet.Count > 0 && b.TagTokenSet.Count > 0) { int num4 = 0; if (a.TagTokenSet.Count <= b.TagTokenSet.Count) { foreach (int item in a.TagTokenSet) { if (b.TagTokenSet.Contains(item)) { num4++; } } } else { foreach (int item2 in b.TagTokenSet) { if (a.TagTokenSet.Contains(item2)) { num4++; } } } int num5 = Mathf.Max(1, Mathf.Min(a.TagTokenSet.Count, b.TagTokenSet.Count)); float num6 = (float)num4 / (float)num5; num += num6 * p.WeightStringTags; } return num; } private static float OverlapScore<T>(List<T> a, List<T> b) { if (a == null || b == null) { return 0f; } if (a.Count == 0 || b.Count == 0) { return 0f; } int num = 0; for (int i = 0; i < a.Count; i++) { T x = a[i]; for (int j = 0; j < b.Count; j++) { if (EqualityComparer<T>.Default.Equals(x, b[j])) { num++; break; } } } int num2 = Mathf.Max(1, Mathf.Min(a.Count, b.Count)); return (float)num / (float)num2; } private static float CompatibilityOverlapScore(ItemExtractedFeatures a, ItemExtractedFeatures b) { int num = 0; int denom = 0; num += OverlapCount(a.CompatibleMagazines, b.CompatibleMagazines, ref denom); num += OverlapCount(a.CompatibleClips, b.CompatibleClips, ref denom); num += OverlapCount(a.CompatibleSpeedLoaders, b.CompatibleSpeedLoaders, ref denom); num += OverlapCount(a.CompatibleSingleRounds, b.CompatibleSingleRounds, ref denom); num += OverlapCount(a.BespokeAttachments, b.BespokeAttachments, ref denom); return (denom <= 0) ? 0f : ((float)num / (float)denom); } private static int OverlapCount(List<string> a, List<string> b, ref int denom) { if (a == null || b == null) { return 0; } if (a.Count == 0 || b.Count == 0) { return 0; } denom += Mathf.Max(1, Mathf.Min(a.Count, b.Count)); int num = 0; for (int i = 0; i < a.Count; i++) { string a2 = a[i]; for (int j = 0; j < b.Count; j++) { if (string.Equals(a2, b[j], StringComparison.OrdinalIgnoreCase)) { num++; break; } } } return num; } } internal sealed class ItemSimilarityProfile { public bool RequireSameCategory = true; public bool RequireSameRoundTypeForFirearms = false; public bool RequireSameAttachmentMountForAttachments = false; public float WeightCategory = 5f; public float WeightFamily = 4f; public float WeightSet = 4f; public float WeightRoundPower = 3f; public float WeightRoundType = 3f; public float WeightFirstYear = 2f; public float FirstYearScale = 25f; public float WeightEra = 2f; public float WeightStringTags = 2f; public float WeightAction = 2f; public float WeightFiringModes = 2f; public float WeightCountry = 1f; public float WeightFeedOptions = 1f; public float WeightMounts = 1f; public float WeightCompatibility = 0f; public float WeightAttachmentMount = 0f; public float WeightSize = 0f; } internal static class ItemSimilarityPolicy { internal static readonly ItemSimilarityProfile Default = new ItemSimilarityProfile(); } internal static class ItemToken { internal static int StableToken(string s) { if (s == null) { return 0; } int num = 23; for (int i = 0; i < s.Length; i++) { char c = char.ToLowerInvariant(s[i]); num = num * 31 + c; } return num; } } public static class CsvItemPriceLoader { public static List<BaseItemData> LoadBaseItems(string relativePath) { List<BaseItemData> list = new List<BaseItemData>(); string text = Path.Combine(ShFileIoHandler.GetPluginModFolder(), relativePath); if (!File.Exists(text)) { Debug.LogError((object)("CSV Load Error: File not found at path: " + text)); return list; } int num = 0; try { string[] array = File.ReadAllLines(text); string[] array2 = array; foreach (string text2 in array2) { num++; string text3 = text2.Trim(); if (string.IsNullOrEmpty(text3)) { continue; } string[] array3 = text3.Split(new char[1] { ',' }); if (array3.Length < 2) { Debug.LogWarning((object)$"CSV Parsing Warning on line {num}: Skipping malformed line."); continue; } string text4 = array3[0].Trim(); float result; if (string.IsNullOrEmpty(text4)) { Debug.LogWarning((object)$"CSV Parsing Warning on line {num}: Empty ObjectID. Skipping."); } else if (!float.TryParse(array3[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out result)) { Debug.LogError((object)$"CSV Parsing Error on line {num}: Could not parse Price as float: '{array3[1]}'"); } else { list.Add(new BaseItemData(text4, result)); } } Debug.Log((object)$"Successfully loaded {list.Count} items from CSV '{relativePath}'."); } catch (Exception ex) { Debug.LogError((object)$"CRITICAL CSV LOAD FAILURE for '{relativePath}' on line {num}: {ex.Message}"); list.Clear(); } return list; } } public static class ItemPricesManager { private static readonly Dictionary<string, float> _priceCache = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase); public static float CHEAPEND_SELL_PRICE = 0.1f; public static float SELL_DISCOUNT = 0.95f; public static List<ObjectCategory> sellCheapenedCategories = new List<ObjectCategory> { (ObjectCategory)2, (ObjectCategory)4, (ObjectCategory)3, (ObjectCategory)8, (ObjectCategory)64 }; public static void LoadAndApplyCsvPrices() { _priceCache.Clear(); ApplyCsv("Attachment.csv"); ApplyCsv("Attachment2Temp.csv"); ApplyCsv("Cartridge.csv"); ApplyCsv("Clip.csv"); ApplyCsv("Magazine.csv"); ApplyCsv("MeatFortress.csv"); ApplyCsv("Melee.csv"); ApplyCsv("Misc.csv"); ApplyCsv("Pistol.csv"); ApplyCsv("Shotgun.csv"); ApplyCsv("SMG_Rifle.csv"); ApplyCsv("Speedloader.csv"); ApplyCsv("Support.csv"); } private static void ApplyCsv(string relativePath) { List<BaseItemData> list = CsvItemPriceLoader.LoadBaseItems(relativePath); if (list == null || list.Count == 0) { return; } for (int i = 0; i < list.Count; i++) { BaseItemData baseItemData = list[i]; if (baseItemData != null && !string.IsNullOrEmpty(baseItemData.ObjectID)) { ItemIndex.EnsureIndexed(baseItemData.ObjectID); ItemIndex.OverrideIndexedPrice(baseItemData.ObjectID, baseItemData.Price); _priceCache[baseItemData.ObjectID] = baseItemData.Price; } } } public static float GetPrice(string objectId, int k = 3) { if (string.IsNullOrEmpty(objectId)) { Debug.LogError((object)"GetPrice called with null or empty objectId."); return 0f; } if (_priceCache.TryGetValue(objectId, out var value)) { return value; } if (ItemIndex.TryGetIndexedPrice(objectId, out var price) && price > 0f) { _priceCache[objectId] = price; return price; } float num = ItemIndex.PredictPrice(objectId, Mathf.Max(1, k)); _priceCache[objectId] = num; return num; } public static float GetSellPrice(string objectId) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) ItemExtractedFeatures itemFeatures = ItemIndex.GetItemFeatures(objectId); if (sellCheapenedCategories.Contains(itemFeatures.Category)) { return CHEAPEND_SELL_PRICE; } float price = GetPrice(objectId); return price * SELL_DISCOUNT; } public static void ClearCache() { _priceCache.Clear(); } } [Serializable] public class ShLoadout { public string displayName; public string uid; public string fullFileName; public string lastUsedorSaved; public bool IsOfficialExtract; private ShLoadout(string displayName, bool isOfficialExtract) { uid = Guid.NewGuid().ToString(); this.displayName = displayName; fullFileName = ""; lastUsedorSaved = ShTimeCalculator.dateTimeToString(DateTime.UtcNow); IsOfficialExtract = isOfficialExtract; } internal static ShLoadout Create(string displayName, bool isOfficialExtract) { return new ShLoadout(displayName, isOfficialExtract); } public void UpdateLastSavedTime() { lastUsedorSaved = ShTimeCalculator.dateTimeToString(DateTime.UtcNow); } public void ChangeDisplayName(string newname) { displayName = newname; } } public static class ShLoadoutFactory { private const string DEFAULT_NAME = "Unnamed Loadout"; private const string DEFAULT_EXTRACT_NAME = "Extracted Loadout"; public static ShLoadout CreateDefault() { return ShLoadout.Create("Unnamed Loadout", isOfficialExtract: false); } public static ShLoadout CreateNamed(string name) { if (string.IsNullOrEmpty(name)) { name = "Unnamed Loadout"; } return ShLoadout.Create(name, isOfficialExtract: false); } public static ShLoadout CreateOfficialExtract() { return ShLoadout.Create("Extracted Loadout", isOfficialExtract: true); } } [Serializable] public class ShLoadoutRack { public List<ShLoadout> loadouts; public ShLoadoutRack() { Init(); } public void Init() { if (loadouts == null) { loadouts = new List<ShLoadout>(); } } public ShLoadout CreateEmptyLoadout() { if (loadouts == null) { loadouts = new List<ShLoadout>(); } int num = 0; foreach (ShLoadout loadout in loadouts) { if (loadout != null && !loadout.IsOfficialExtract) { num++; } } int num2 = num + 1; string name = $"Loadout {num2}"; ShLoadout shLoadout = ShLoadoutFactory.CreateNamed(name); loadouts.Add(shLoadout); return shLoadout; } public ShLoadout EnsureExtractionLoadout() { List<ShLoadout> list = new List<ShLoadout>(); foreach (ShLoadout loadout in loadouts) { if (loadout != null && loadout.IsOfficialExtract) { list.Add(loadout); } } if (list.Count == 0) { ShLoadout shLoadout = ShLoadoutFactory.CreateOfficialExtract(); loadouts.Add(shLoadout); return shLoadout; } if (list.Count == 1) { return list[0]; } ShLoadout shLoadout2 = list[0]; DateTime dateTime = ShTimeCalculator.stringToDateTime(shLoadout2.lastUsedorSaved); for (int i = 1; i < list.Count; i++) { DateTime dateTime2 = ShTimeCalculator.stringToDateTime(list[i].lastUsedorSaved); if (dateTime2 > dateTime) { shLoadout2 = list[i]; dateTime = dateTime2; } } for (int num = loadouts.Count - 1; num >= 0; num--) { ShLoadout shLoadout3 = loadouts[num]; if (shLoadout3 != null && shLoadout3.IsOfficialExtract && shLoadout3 != shLoadout2) { loadouts.RemoveAt(num); } } return shLoadout2; } public ShLoadout GetLoadout(string uid) { foreach (ShLoadout loadout in loadouts) { if (loadout.uid == uid) { return loadout; } } return null; } public void ConsumeLoadout(string uid) { for (int num = loadouts.Count - 1; num >= 0; num--) { ShLoadout shLoadout = loadouts[num]; if (shLoadout != null && shLoadout.uid == uid) { loadouts.RemoveAt(num); break; } } } public List<ShLoadout> listLoadoutsSortedByUpdateTime() { ShLoadout item = EnsureExtractionLoadout(); loadouts.Sort(delegate(ShLoadout a, ShLoadout b) { if (a == null && b == null) { return 0; } if (a == null) { return 1; } if (b == null) { return -1; } DateTime value = ShTimeCalculator.stringToDateTime(a.lastUsedorSaved); return ShTimeCalculator.stringToDateTime(b.lastUsedorSaved).CompareTo(value); }); for (int num = loadouts.Count - 1; num >= 0; num--) { ShLoadout shLoadout = loadouts[num]; if (shLoadout != null && shLoadout.IsOfficialExtract) { loadouts.RemoveAt(num); } } loadouts.Insert(0, item); return loadouts; } public List<ShLoadout> ListLoadoutsUnsorted() { ShLoadout item = EnsureExtractionLoadout(); for (int num = loadouts.Count - 1; num >= 0; num--) { ShLoadout shLoadout = loadouts[num]; if (shLoadout != null && shLoadout.IsOfficialExtract) { loadouts.RemoveAt(num); } } loadouts.Insert(0, item); return loadouts; } } public static class ShLoadoutsVault { private const string LOADOUTS_FOLDER = "Loadouts"; private const string EXTR_LOADY_FILE = "ExtractionLoady.json"; private const string LOADY_EXT = "_.json"; public static string GetVaultProfileRoot(string profileUid) { return Path.Combine(Path.Combine(ShFileIoHandler.GetH3SaveFolder(), ShFileIoHandler.rootSaveFolder), profileUid); } public static string GetLoadoutsFolder(string profileUid) { return Path.Combine(GetVaultProfileRoot(profileUid), "Loadouts"); } public static string GetExtractionLoadyFile(string profileUid) { return Path.Combine(GetLoadoutsFolder(profileUid), "ExtractionLoady.json"); } public static string GetLoadyFileFromUid(string profileUid, string loadyUid) { return Path.Combine(GetLoadoutsFolder(profileUid), loadyUid + "_.json"); } public static bool TrySaveExtractionLoady(string profileUid, out string error) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown error = null; VaultFile vf = new VaultFile(); if (!TryScanCurrentLoadout(out vf, out error)) { error = "[TrySaveExtractionLoady] Scanning quickbelt failed."; return false; } string extractionLoadyFile = GetExtractionLoadyFile(profileUid); ShFileIoHandler.EnsureFile(extractionLoadyFile); if (!ShFileIoHandler.TrySaveJson(vf, extractionLoadyFile, out error)) { error = "[TrySaveExtractionLoady] Failed to save w error: " + error; return false; } return true; } public static VaultFile TryGetExtractionLoadyVault(string profileUid, out string error) { string extractionLoadyFile = GetExtractionLoadyFile(profileUid); ShFileIoHandler.EnsureFile(extractionLoadyFile); if (!ShFileIoHandler.TryLoadJson<VaultFile>(extractionLoadyFile, out VaultFile obj, out error)) { if (error == "File was empty") { return null; } error = "[TryGetExtractionLoady]: Failed to parse json w: " + error + " on file " + extractionLoadyFile; return null; } return obj; } public static bool TryLoadExtractionLoady(string profileUid, out string error) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) string extractionLoadyFile = GetExtractionLoadyFile(profileUid); ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(extractionLoadyFile)); if (!ShFileIoHandler.TryLoadJson<VaultFile>(extractionLoadyFile, out VaultFile obj, out error)) { error = "[TryLoadExtractionLoady]: Failed to parse json w: " + error + " on file " + extractionLoadyFile; return false; } Transform transform = ((Component)GM.CurrentPlayerBody).transform; return VaultSystem.SpawnObjects((VaultFileType)2, obj, ref error, transform, Vector3.zero); } public static bool TryClearExtractionLoadyFile(string profileUid, out string error) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown VaultFile obj = new VaultFile(); string extractionLoadyFile = GetExtractionLoadyFile(profileUid); ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(extractionLoadyFile)); if (!ShFileIoHandler.TrySaveJson(obj, extractionLoadyFile, out error)) { Debug.LogError((object)("[TrySaveExtractionLoady] Failed to save w error: " + error)); return false; } return true; } public static bool TrySaveCustomLoady(string profileUid, string loadyUid, out string fullFileName, out string error) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown error = null; fullFileName = null; VaultFile vf = new VaultFile(); if (!TryScanCurrentLoadout(out vf, out error)) { Debug.LogError((object)"[TrySaveCustomLoady] Scanning quickbelt failed."); return false; } string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid); ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid)); if (!ShFileIoHandler.TrySaveJson(vf, loadyFileFromUid, out error)) { Debug.LogError((object)("[TrySaveCustomLoady] Failed to save w error: " + error)); return false; } fullFileName = loadyFileFromUid; return true; } public static VaultFile TryGetCustomLoadyFile(string profileUid, string loadyUid, out string error) { string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid); ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid)); if (!ShFileIoHandler.TryLoadJson<VaultFile>(loadyFileFromUid, out VaultFile obj, out error)) { error = "[TryGetCustomLoadyFile]: Failed to parse json w: " + error + " on file " + loadyFileFromUid; return null; } return obj; } public static bool TryLoadCustomLoady(string profileUid, string loadyUid, out string error) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid); ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid)); if (!ShFileIoHandler.TryLoadJson<VaultFile>(loadyFileFromUid, out VaultFile obj, out error)) { error = "[TryLoadCustomLoady]: Failed to parse json w: " + error + " on file " + loadyFileFromUid; return false; } Transform transform = ((Component)GM.CurrentPlayerBody).transform; return VaultSystem.SpawnObjects((VaultFileType)2, obj, ref error, transform, Vector3.zero); } public static bool TryDeleteCustomLoady(string profileUid, string loadyUid, out string error) { error = null; string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid); ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid)); try { if (File.Exists(loadyFileFromUid)) { File.Delete(loadyFileFromUid); } return true; } catch (Exception ex) { error = ex.Message; Debug.LogError((object)("[TryDeleteCustomLoady]: Failed to delete w: " + error + " on file " + loadyFileFromUid)); return false; } } public static bool TryDeleteExtractionLoady(string profileUid, out string error) { error = null; string extractionLoadyFile = GetExtractionLoadyFile(profileUid); try { if (File.Exists(extractionLoadyFile)) { File.Delete(extractionLoadyFile); } return true; } catch (Exception ex) { error = ex.Message; Debug.LogError((object)("[TryDeleteExtractionLoady]: Failed to delete w: " + error + " on file " + extractionLoadyFile)); return false; } } private static bool TryScanCurrentLoadout(out VaultFile vf, out string error) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown vf = new VaultFile(); error = null; if (!VaultSystem.FindAndScanObjectsInQuickbelt(vf)) { error = "Loady scan failed."; return false; } return true; } } public class LootCalculator { public static List<string> GetOrderedItemsIDs(List<ObjectCategory> orderedCategories) { int count = orderedCategories?.Count ?? 0; List<string> result = NewBlankResultList(count); Dictionary<int, string> firearmAtIndex = new Dictionary<int, string>(); string lastFirearmId = string.Empty; PlaceFirearms(orderedCategories, result, firearmAtIndex, ref lastFirearmId); FillNonFirearms(orderedCategories, result, firearmAtIndex, ref lastFirearmId); return result; } private static List<string> NewBlankResultList(int count) { List<string> list = new List<string>(count); for (int i = 0; i < count; i++) { list.Add(string.Empty); } return list; } private static void PlaceFirearms(List<ObjectCategory> cats, List<string> result, Dictionary<int, string> firearmAtIndex, ref string lastFirearmId) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 for (int i = 0; i < cats.Count; i++) { ObjectCategory val = cats[i]; if (!IsAnyCategory(val) && (int)val == 1) { FVRObject obj = PickRandomFromCategory((ObjectCategory)1); string text2 = (result[i] = ToItemId(obj)); if (!string.IsNullOrEmpty(text2)) { firearmAtIndex[i] = text2; lastFirearmId = text2; } } } } private static void FillNonFirearms(List<ObjectCategory> cats, List<string> result, Dictionary<int, string> firearmAtIndex, ref string lastFirearmId) { //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_0029: 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_0030: 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_0056: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < cats.Count; i++) { if (!string.IsNullOrEmpty(result[i])) { continue; } ObjectCategory cat = cats[i]; cat = ResolveAnyCategory(cat); if (IsAmmoCategory(cat)) { result[i] = GetAmmoItemId(i, cats.Count, firearmAtIndex, ref lastFirearmId); } else if ((int)cat == 1) { FVRObject obj = PickRandomFromCategory((ObjectCategory)1); result[i] = ToItemId(obj); if (!string.IsNullOrEmpty(result[i])) { lastFirearmId = result[i]; } } else { result[i] = ToItemId(PickRandomFromCategory(cat)); } } } private static bool IsAnyCategory(ObjectCategory cat) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 return (int)cat == 0; } private static ObjectCategory ResolveAnyCategory(ObjectCategory cat) { //IL_0001: 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_000f: 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_0057: 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_0033: Unknown result type (might be due to invalid IL or missing references) if (!IsAnyCategory(cat)) { return cat; } Dictionary<ObjectCategory, List<FVRObject>> odicTagCategory = ManagerSingleton<IM>.Instance.odicTagCategory; if (odicTagCategory == null || odicTagCategory.Count == 0) { return (ObjectCategory)0; } List<ObjectCategory> list = new List<ObjectCategory>(odicTagCategory.Keys); list.Remove((ObjectCategory)0); return list[Random.Range(0, list.Count)]; } private static bool IsAmmoCategory(ObjectCategory cat) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 return (int)cat == 2 || (int)cat == 6 || (int)cat == 3 || (int)cat == 4; } private static string GetAmmoItemId(int index, int totalCount, Dictionary<int, string> firearmAtIndex, ref string lastFirearmId) { string text = ((!string.IsNullOrEmpty(lastFirearmId)) ? lastFirearmId : FindWeaponAhead(index, totalCount, firearmAtIndex)); if (!string.IsNullOrEmpty(text)) { FVRObject val = IM.OD[text]; FVRObject randomAmmoObject = IM.OD[text].GetRandomAmmoObject(val, (List<OTagEra>)null, -1, -1, (List<OTagSet>)null); string text2 = ToItemId(randomAmmoObject); if (!string.IsNullOrEmpty(text2)) { return text2; } } return ToItemId(PickRandomFromCategory((ObjectCategory)2)); } private static string FindWeaponAhead(int idx, int totalCount, Dictionary<int, string> firearmAtIndex) { for (int i = idx + 1; i < totalCount; i++) { if (firearmAtIndex.TryGetValue(i, out var value)) { return value; } } return string.Empty; } private static FVRObject PickRandomFromCategory(ObjectCategory cat) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) Dictionary<ObjectCategory, List<FVRObject>> odicTagCategory = ManagerSingleton<IM>.Instance.odicTagCategory; if (odicTagCategory == null) { Debug.LogError((object)"PickRandomFromCategory: failed get odicTagCategory at all"); return null; } if (!odicTagCategory.TryGetValue(cat, out var value) || value == null || value.Count == 0) { Debug.LogError((object)("PickRandomFromCategory: failed get category " + ((object)(ObjectCategory)(ref cat)).ToString())); return null; } return value[Random.Range(0, value.Count)]; } private static string ToItemId(FVRObject obj) { if ((Object)(object)obj == (Object)null) { Debug.LogError((object)"ToItemId: obj in put is null"); return string.Empty; } try { if (!string.IsNullOrEmpty(obj.ItemID)) { return obj.ItemID; } } catch { Debug.LogError((object)"ToItemId: ItemID is not present in the object"); return string.Empty; } return string.Empty; } } public class ShowLootUiOnInteract : MonoBehaviour { private bool ready = false; private SosigLink slink; private SLinkLootController controller; public void Init(SosigLink Slink, SLinkLootController Controller) { ready = true; slink = Slink; controller = Controller; } private void Update() { if (ready) { controller.SetUiActive(((FVRInteractiveObject)slink.O).IsHeld); } } } public class SLinkLootController : MonoBehaviour { private Canvas canvas; private List<SpawnOnGrab> grabbies; public void Awake() { FindUiVariables(); } private void FindUiVariables() { canvas = ((Component)((Component)this).transform).GetComponent<Canvas>(); grabbies = new List<SpawnOnGrab>(((Component)this).GetComponentsInChildren<SpawnOnGrab>()); } public static void AttachToSosig(Sosig theSosig) { //IL_0038: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_00b2: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)theSosig).transform.Find("Sosig_Torso"); if ((Object)(object)val == (Object)null) { Debug.LogError((object)"AttachToSosig: could not find Sosig_Torso"); return; } GameObject val2 = ShSpawnItems.SpawnItemFromID("NGA_torsoLootUi"); if ((Object)(object)val2 == (Object)null) { Debug.LogError((object)"AttachToSosig: SpawnItemFromOD returned null for torso"); return; } val2.transform.SetParent(val); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = new Vector3(0.007f, 0.007f, 0.007f); SLinkLootController component = val2.GetComponent<SLinkLootController>(); component.EnableLooting(theSosig); if ((Object)(object)component == (Object)null) { Debug.LogError((object)"AttachToSosig: torso UI prefab has no SLinkLootController"); return; } ShowLootUiOnInteract showLootUiOnInteract = ((Component)val).gameObject.AddComponent<ShowLootUiOnInteract>(); showLootUiOnInteract.Init(((Component)val).GetComponent<SosigLink>(), component); Transform val3 = val.Find("UpperLink"); if ((Object)(object)val3 == (Object)null) { Debug.LogError((object)"AttachToSosig: could not find Upper link"); return; } GameObject val4 = ShSpawnItems.SpawnItemFromID("NGA_waistLootUi"); if ((Object)(object)val4 == (Object)null) { Debug.LogError((object)"AttachToSosig: SpawnItemFromOD returned null for waist"); return; } val4.transform.SetParent(val3); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; val4.transform.localScale = new Vector3(0.007f, 0.007f, 0.007f); SLinkLootController component2 = val4.GetComponent<SLinkLootController>(); component2.EnableLooting(theSosig); if ((Object)(object)component2 == (Object)null) { Debug.LogError((object)"AttachToSosig: torso UI prefab has no SLinkLootController"); return; } ShowLootUiOnInteract showLootUiOnInteract2 = ((Component)val3).gameObject.AddComponent<ShowLootUiOnInteract>(); showLootUiOnInteract2.Init(((Component)val3).GetComponent<SosigLink>(), component2); } public void EnableLooting(Sosig killedSosig) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) List<ObjectCategory> list = new List<ObjectCategory>(grabbies.Count); foreach (SpawnOnGrab grabby in grabbies) { list.Add(grabby.itemType); } List<string> orderedItemsIDs = LootCalculator.GetOrderedItemsIDs(list); for (int i = 0; i < grabbies.Count; i++) { grabbies[i].SetItem(orderedItemsIDs[i]); } SetUiActive(value: false); } public void SetUiActive(bool value) { ((Behaviour)canvas).enabled = value; } } public class SpawnOnGrab : FVRInteractiveObject { private RawImage backgroundImage; private RawImage itemImage; private readonly HashSet<FVRPhysicalObject> _inside = new HashSet<FVRPhysicalObject>(); private readonly HashSet<FVRPhysicalObject> _waitingRelease = new HashSet<FVRPhysicalObject>(); private Collider collectionTrigger; private bool destroyCollectedObject = true; public Color defaultColor = Color32.op_Implicit(new Color32((byte)86, (byte)70, (byte)70, (byte)128)); public Color hoveredColor = Color32.op_Implicit(new Color32((byte)161, (byte)161, (byte)55, byte.MaxValue)); private static readonly List<FVRPhysicalObject> _toProcess = new List<FVRPhysicalObject>(32); [Header("Spawner params")] public ObjectCategory itemType = (ObjectCategory)(-1); public string itemID; [Tooltip("How many objects can be taken from this spawner before it runs out")] public int currObjectCapacity; private FVRObject fob; private AnvilCallback<GameObject> itemLoader; protected override void Awake() { ((FVRInteractiveObject)this).Awake(); FindUiVariables(); if (!string.IsNullOrEmpty(itemID) && IM.OD.ContainsKey(itemID)) { itemLoader = ((AnvilAsset)IM.OD[itemID]).GetGameObjectAsync(); } if (!string.IsNullOrEmpty(itemID)) { itemLoader = ((AnvilAsset)IM.OD[itemID]).GetGameObjectAsync(); } } private void FindUiVariables() { backgroundImage = ((Component)((Component)this).transform).GetComponent<RawImage>(); itemImage = ((Component)((Component)this).transform.Find("ItemImage")).GetComponent<RawImage>(); collectionTrigger = ((Component)this).GetComponent<Collider>(); } public void Redraw() { if (!IM.HasSpawnedID(fob.SpawnedFromId)) { Debug.LogWarning((object)("SpawnedID not exist for: " + fob.ItemID)); } if (currObjectCapacity > 0 && IM.HasSpawnedID(fob.SpawnedFromId)) { ((Behaviour)itemImage).enabled = true; itemImage.texture = (Texture)(object)IM.GetSpawnerID(fob.SpawnedFromId).Sprite.texture; } else { ((Behaviour)itemImage).enabled = true; } } public override void BeginInteraction(FVRViveHand hand) { //IL_004a: 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) if (currObjectCapacity >= 1) { ((FVRInteractiveObject)this).BeginInteraction(hand); if (!((AnvilCallbackBase)itemLoader).IsCompleted) { ((AnvilCallbackBase)itemLoader).CompleteNow(); } FVRPhysicalObject component = Object.Instantiate<GameObject>(itemLoader.Result, ((Component)hand).transform.position, ((Component)hand).transform.rotation).GetComponent<FVRPhysicalObject>(); if ((Object)(object)component != (Object)null) { hand.ForceSetInteractable((FVRInteractiveObject)(object)component); ((FVRInteractiveObject)component).BeginInteraction(hand); } RemoveItem(); } } public void RemoveItem() { if (currObjectCapacity >= 1) { currObjectCapacity--; if (currObjectCapacity < 1) { ((Behaviour)itemImage).enabled = false; } } } public void AddItem(string ID, int objectAmount = 1) { if (string.IsNullOrEmpty(ID) || objectAmount < 1) { Debug.LogWarning((object)"SpawnOnGrab.AddItem: You tried to give me an empty item id or negative or zero objectAmount. Nice try."); } else if (!string.IsNullOrEmpty(itemID) && currObjectCapacity > 0) { Debug.LogWarning((object)("SpawnOnGrab.AddItem: I cant add an item if there are some already present: " + itemID + " for " + currObjectCapacity)); } else if (ID == itemID) { currObjectCapacity += objectAmount; Redraw(); } else { SetItem(ID, objectAmount); } } public void SetItem(string ID, int objectCapacity = 1) { if (string.IsNullOrEmpty(ID)) { Debug.LogError((object)"SpawnOnGrab was given an empty or null id"); return; } if (!IM.OD.ContainsKey(ID)) { Debug.LogError((object)("SpawnOnGrab was given key that's not present in IM.OD: " + ID)); return; } itemID = ID; fob = IM.OD[itemID]; itemLoader = ((AnvilAsset)fob).GetGameObjectAsync(); currObjectCapacity = objectCapacity; Redraw(); } private void OnTriggerEnter(Collider other) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)other == (Object)null) { return; } ((Graphic)backgroundImage).color = hoveredColor; FVRPhysicalObject componentInParent = ((Component)other).GetComponentInParent<FVRPhysicalObject>(); if (!((Object)(object)componentInParent == (Object)null)) { _inside.Add(componentInParent); if (((FVRInteractiveObject)componentInParent).IsHeld) { _waitingRelease.Add(componentInParent); } } } private void OnTriggerExit(Collider other) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)other == (Object)null)) { ((Graphic)backgroundImage).color = defaultColor; FVRPhysicalObject componentInParent = ((Component)other).GetComponentInParent<FVRPhysicalObject>(); if (!((Object)(object)componentInParent == (Object)null)) { _inside.Remove(componentInParent); _waitingRelease.Remove(componentInParent); } } } private void Update() { if (_inside.Count == 0) { return; } _toProcess.Clear(); foreach (FVRPhysicalObject item in _inside) { if ((Object)(object)item != (Object)null) { _toProcess.Add(item); } } foreach (FVRPhysicalObject item2 in _toProcess) { if ((Object)(object)item2 == (Object)null) { continue; } if (((FVRInteractiveObject)item2).IsHeld) { _waitingRelease.Add(item2); } else { if (!_waitingRelease.Contains(item2)) { continue; } FVRObject objectWrapper = item2.ObjectWrapper; if ((Object)(object)objectWrapper != (Object)null) { AddItem(objectWrapper.ItemID); if (destroyCollectedObject && (Object)(object)((Component)item2).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)item2).gameObject); } } _waitingRelease.Remove(item2); _inside.Remove(item2); } } } } [BepInPlugin("NGA.SafehouseProgressionMPatchy", "SafehouseProgressionMPatchy", "0.0.1")] [BepInDependency("nrgill28.Sodalite", "1.4.1")] [BepInProcess("h3vr.exe")] public class SafehouseProgressionMPatchy : BaseUnityPlugin { [HarmonyPatch(typeof(GM))] [HarmonyPatch("Awake")] public class SH_GM_Initializer { private static void Postfix(GM __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)SHGM.Instance == (Object)null) { GameObject val = new GameObject("SH_GM"); val.AddComponent<SHGM>(); Object.DontDestroyOnLoad((Object)(object)val); } SceneTravelManager.Ensure(); } } [HarmonyPatch(typeof(FVRSceneSettings))] [HarmonyPatch("LoadDefaultSceneRoutine")] private class FVRSceneSettingsLoadDefaultSceneRoutineHook { private static bool Prefix(FVRSceneSettings __instance) { if (SceneTravelManager.Instance._pending.HasValue) { return false; } return true; } } [HarmonyPatch(typeof(TNH_Manager), "HoldPointCompleted")] private class HoldPointManagerCompleted { private static void Postfix(TNH_Manager __instance) { BankViewModel.Instance.AddSpades(2); } } [HarmonyPatch(typeof(TNH_Manager))] [HarmonyPatch("SetPhase_Completed")] private class HoldPointManagerSetPhase_Completed { private static void Postfix(TNH_Manager __instance) { BankViewModel.Instance.AddSpades(5); } } [HarmonyPatch(typeof(TNH_Manager))] [HarmonyPatch("SetPhase_Dead")] private class HoldPointManagerSetPhase_Dead { private static void Postfix(TNH_Manager __instance) { GM.CurrentPlayerBody.WipeQuickbeltContents(); } } [HarmonyPatch(typeof(Sosig), "Configure")] private class SosigLootAttach { private static void Postfix(Sosig __instance) { } } [HarmonyPatch(typeof(FVRWristMenu2))] [HarmonyPatch("Awake")] private class WristMenuAwakeHook { private static void Postfix(FVRWristMenu2 __instance) { if ((Object)(object)__instance == (Object)null) { Logger.LogMessage((object)"FVRWristMenu2 is null!?"); } try { FVRWristMenuSection_Safehouse2 fVRWristMenuSection_Safehouse = AddWristMenuSection(__instance); } catch (Exception ex) { Debug.LogError((object)("[AddWristMenuSection] Failed with error: " + ex.Message)); } } } public class SwapIconHandler : MonoBehaviour { private FVRWristMenuSectionButton b; private bool swapped; private void Awake() { b = ((Component)this).GetComponent<FVRWristMenuSectionButton>(); } private void Update() { //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022d: 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_023c: Unknown result type (might be due to invalid IL or missing references) if (swapped) { return; } if ((Object)(object)b == (Object)null) { b = ((Component)this).GetComponent<FVRWristMenuSectionButton>(); } else { if ((Object)(object)b.ButtonText == (Object)null || !(b.ButtonText.text == "SHP3-swap")) { return; } swapped = true; b.ButtonText.text = ""; Transform val = ((Component)this).transform.Find("Backing"); if ((Object)(object)val == (Object)null) { Debug.LogError((object)"[SwapIconHandler] Could not find child named 'Backing'."); return; } Image component = ((Component)val).GetComponent<Image>(); if ((Object)(object)component == (Object)null) { Debug.LogError((object)"[SwapIconHandler] 'Backing' found but it has no Image component."); return; } string text = Path.Combine(ShFileIoHandler.GetPluginModFolder(), "wideIcon.png"); string text2 = Path.Combine(ShFileIoHandler.GetPluginModFolder(), "redNot.png"); if (!File.Exists(text) || !File.Exists(text2)) { Debug.LogError((object)("[SwapIconHandler] File not found: " + text)); return; } Texture2D val2 = ShFileIoHandler.LoadTextureFromFullPath(text); Texture2D val3 = ShFileIoHandler.LoadTextureFromFullPath(text2); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { Debug.LogError((object)"[SwapIconHandler] Loader returned null Texture2D."); return; } Rect val4 = default(Rect); ((Rect)(ref val4))..ctor(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height); Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(0.5f, 0.5f); Sprite sprite = Sprite.Create(val2, val4, val5); component.sprite = sprite; if (((Graphic)component).color.a < 1f) { ((Graphic)component).color = new Color(1f, 1f, 1f, 1f); } FVRPointableButton component2 = ((Component)this).GetComponent<FVRPointableButton>(); if ((Object)(object)component2 != (Object)null) { component2.Image = component; component2.ColorUnselected = component2.ColorSelected; component2.ColorSelected *= 2f; } GameObject val6 = new GameObject("Notification"); val6.transform.SetParent(val, false); RawImage val7 = val6.AddComponent<RawImage>(); val7.texture = (Texture)(object)val3; RectTransform component3 = val6.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(1f, 1f); component3.anchorMax = new Vector2(1f, 1f); component3.pivot = new Vector2(1f, 1f); component3.anchoredPosition = Vector2.zero; component3.sizeDelta = new Vector2(100f, 100f); } } } public class FVRWristMenuSection_Safehouse2 : FVRWristMenuSection { public override void Enable() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) GameObject val = ShSpawnItems.SpawnItemFromID("NGA_sp3Hud"); val.transform.Rotate(0f, -90f, 0f, (Space)1); ((Component)this).gameObject.SetActive(false); base.Menu.SectionSet.SetSelectedButton(-1); } } internal static ManualLogSource Logger { get; private set; } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Harmony val = new Harmony("NGA.SafehouseProgressionMPatchy"); Logger.LogMessage((object)"New harmony"); SetUpConfigFields(); Logger.LogMessage((object)"Setted the fields"); val.PatchAll(); Logger.LogMessage((object)"Hello, world! Sent from NGA.SafehouseProgressionMPatchy"); } private void SetUpConfigFields() { } public static FVRWristMenuSection_Safehouse2 AddWristMenuSection(FVRWristMenu2 wristMenu) { //IL_0035: 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_00ac: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown FVRWristMenuSection val = wristMenu.Sections.First((FVRWristMenuSection x) => (object)((object)x).GetType() == typeof(FVRWristMenuSection_Spawn)); Transform transform = ((Component)val).transform; FVRWristMenuSection val2 = Object.Instantiate<FVRWristMenuSection>(val, transform.position, transform.rotation, transform.parent); GameObject gameObject = ((Component)val2).gameObject; GameObject gameObject2 = ((Component)gameObject.transform.parent).gameObject; Object.Destroy((Object)(object)val2); Image component = gameObject.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { string pluginModFolder = ShFileIoHandler.GetPluginModFolder(); string absolutePath = Path.Combine(pluginModFolder, "icon.png"); Texture2D val3 = ShFileIoHandler.LoadTextureFromFullPath(absolutePath); RectTransform rectTransform = ((Graphic)component).rectTransform; Vector2 sizeDelta = rectTransform.sizeDelta; Sprite sprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f)); component.sprite = sprite; rectTransform.sizeDelta = sizeDelta; } else { Logger.LogError((object)"No Image component found in my Section."); } FVRWristMenuSection_Safehouse2 fVRWristMenuSection_Safehouse = gameObject.AddComponent<FVRWristMenuSection_Safehouse2>(); ((FVRWristMenuSection)fVRWristMenuSection_Safeho