using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("hvg-solutions")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5ad59b41bed3459e7c6566ef40ecf925dd1c0cba")] [assembly: AssemblyProduct("ShopCurator")] [assembly: AssemblyTitle("ShopCurator")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } namespace ShopCurator { [HarmonyPatch(typeof(PunManager), "SpawnShopItem")] internal static class ForcePlacementPatch { [HarmonyPrefix] private static bool Prefix(ItemVolume itemVolume, List itemList, ref int spawnCount, bool isSecret, ref bool __result) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.Enabled.Value || !ModConfig.IgnoreItemSizes.Value) { return true; } ShopManager instance = ShopManager.instance; if ((Object)(object)instance == (Object)null || itemList != instance.potentialItems) { return true; } if (IsDedicatedShelf(itemVolume.itemVolume) || itemList.Count == 0) { __result = false; return false; } Item val = itemList[itemList.Count - 1]; ((Component)instance.itemRotateHelper).transform.parent = ((Component)itemVolume).transform; ((Component)instance.itemRotateHelper).transform.localRotation = val.spawnRotationOffset; Quaternion rotation = ((Component)instance.itemRotateHelper).transform.rotation; ((Component)instance.itemRotateHelper).transform.parent = ((Component)instance).transform; if (SemiFunc.IsMultiplayer()) { PhotonNetwork.InstantiateRoomObject(((PrefabRef)(object)val.prefab).ResourcePath, ((Component)itemVolume).transform.position, rotation, (byte)0, (object[])null); } else { Object.Instantiate(((PrefabRef)(object)val.prefab).Prefab, ((Component)itemVolume).transform.position, rotation); } itemList.RemoveAt(itemList.Count - 1); if (!isSecret) { spawnCount++; } __result = true; return false; } private static bool IsDedicatedShelf(itemVolume v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 return (int)v == 6 || (int)v == 7 || (int)v == 4; } } internal static class ModConfig { internal static ConfigEntry Enabled = null; internal static ConfigEntry IgnoreItemSizes = null; internal static ConfigEntry MaxShopItems = null; internal static ConfigEntry EnableDebugKeys = null; internal static ConfigEntry PreviewKey = null; private static readonly Dictionary> TypeWeights = new Dictionary>(); internal static void Init(ConfigFile cfg) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown Enabled = cfg.Bind("General", "Enabled", true, "Enable the mod. If false, the shop stays vanilla."); IgnoreItemSizes = cfg.Bind("General", "Ignore Item Sizes", false, "Let weapons spawn on any shelf, ignoring item size. Weights then act as a true spawn rate, so one type can fill the whole shop. Dedicated shelves (upgrades/health/crystals) stay untouched."); MaxShopItems = cfg.Bind("General", "Max Shop Items", 0, new ConfigDescription("Max number of weapons in the shop. 0 = game default (~8).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 40), Array.Empty())); EnableDebugKeys = cfg.Bind("Debug", "Enable Debug Keys", false, "Enable the shop preview key below. Off by default."); PreviewKey = cfg.Bind("Debug", "Preview Key", (KeyCode)289, "Log the weighted shop contents to the console, without visiting the shop."); foreach (itemType value in Enum.GetValues(typeof(itemType))) { itemType key = value; TypeWeights[key] = cfg.Bind("Item Types", "Weight " + ((object)(itemType)(ref key)).ToString(), 1, new ConfigDescription("0 = never, 1 = normal, 2+ = more frequent.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10), Array.Empty())); } } internal static int GetWeight(itemType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ConfigEntry value; return (!TypeWeights.TryGetValue(type, out value)) ? 1 : Mathf.Max(0, value.Value); } internal static bool IsTypeAllowed(itemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return GetWeight(type) > 0; } internal static string WeightsSummary() { return string.Join(", ", from kv in TypeWeights.Where>>((KeyValuePair> kv) => kv.Value.Value != 1).OrderBy(delegate(KeyValuePair> kv) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) itemType key = kv.Key; return ((object)(itemType)(ref key)).ToString(); }) select $"{kv.Key}x{kv.Value.Value}"); } } [BepInPlugin("hvg-solutions.ShopCurator", "ShopCurator", "1.0")] public class ShopCurator : BaseUnityPlugin { internal static ShopCurator Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; ModConfig.Init(((BaseUnityPlugin)this).Config); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded."); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (ModConfig.EnableDebugKeys.Value && Input.GetKeyDown(ModConfig.PreviewKey.Value)) { ShopPreview.LogPreview(); } } } [HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")] internal static class ShopFilterPatch { [HarmonyPostfix] private static void Postfix(ShopManager __instance) { if (!ModConfig.Enabled.Value || SemiFunc.IsNotMasterClient()) { return; } ApplyWeights(__instance.potentialItems); ApplyWeights(__instance.potentialItemConsumables); ApplyWeights(__instance.potentialItemUpgrades); ApplyWeights(__instance.potentialItemHealthPacks); foreach (List value in __instance.potentialSecretItems.Values) { ApplyWeights(value); } if (ModConfig.MaxShopItems.Value > 0) { __instance.itemSpawnTargetAmount = ModConfig.MaxShopItems.Value; } string text = ModConfig.WeightsSummary(); ShopCurator.Logger.LogInfo((object)("Shop weighted. Non-default weights: " + ((text.Length == 0) ? "none" : text))); } private static void ApplyWeights(List items) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) List list = new List(items.Count); foreach (Item item in items) { if (!((Object)(object)item == (Object)null)) { for (int i = 0; i < ModConfig.GetWeight(item.itemType); i++) { list.Add(item); } } } items.Clear(); items.AddRange(list); for (int num = items.Count - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); int index = num; int index2 = num2; Item value = items[num2]; Item value2 = items[num]; items[index] = value; items[index2] = value2; } } } internal static class ShopPreview { internal static void LogPreview() { //IL_00e3: 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) StatsManager instance = StatsManager.instance; if ((Object)(object)instance == (Object)null || instance.itemDictionary == null || instance.itemDictionary.Count == 0) { ShopCurator.Logger.LogWarning((object)"[Preview] StatsManager not ready - start a run first."); return; } ShopCurator.Logger.LogInfo((object)"===== Shop preview (weight per type) ====="); IOrderedEnumerable> orderedEnumerable = (from i in instance.itemDictionary.Values where (Object)(object)i != (Object)null group i by i.itemType).OrderBy(delegate(IGrouping g) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) itemType key = g.Key; return ((object)(itemType)(ref key)).ToString(); }); foreach (IGrouping item in orderedEnumerable) { int weight = ModConfig.GetWeight(item.Key); string arg = weight switch { 1 => "normal", 0 => "blocked", _ => $"x{weight}", }; string arg2 = string.Join(", ", item.Select((Item i) => $"{i.itemName} <{i.itemVolume}>")); ShopCurator.Logger.LogInfo((object)$" {item.Key,-14} ({arg}) : {arg2}"); } } } }