Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RandomValuablePrice v1.7.3
plugins/RandomValueMod.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using AdvancedREPO.Config; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RandomValueMod")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RandomValueMod")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("94f4834c-4276-4ed1-92e7-92a919ab9c3b")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace RandomValuablePrice { public static class RandomValueAPI { public static event Action<ValuableObject, float, float> OnItemRandomized; public static float GetItemPrice(ValuableObject vo) { return RandomValueMod.GetItemPrice(vo); } internal static void TriggerItemRandomized(ValuableObject vo, float oldPrice, float newPrice) { RandomValueAPI.OnItemRandomized?.Invoke(vo, oldPrice, newPrice); } } [BepInPlugin("dyxc666.RandomValuablePrice", "随机贵重物品的价格", "1.7.1")] [BepInProcess("REPO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RandomValueMod : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("dyxc666.RandomValuablePrice"); public static ConfigField<bool> EnableValueRandomization; public static ConfigField<float> MinValueMultiplier; public static ConfigField<float> MaxValueMultiplier; public static ConfigField<bool> ForceRefreshUI; public static ConfigField<bool> EnableVerboseLogging; public static ConfigField<string> BlacklistKeywords; public static ConfigField<string> WhitelistKeywords; public static ConfigField<bool> EnableWhitelistMode; public static ConfigField<bool> EnableBlacklistMode; public static ConfigField<bool> ExcludeHighValueItems; public static ConfigField<float> HighValueThreshold; public static ConfigField<bool> CashBagRandomizationToggle; private static FieldInfo dollarValueCurrentField; private static FieldInfo dollarValueOriginalField; private static List<string> blacklistKeywordsList; private static List<string> whitelistKeywordsList; public static HashSet<int> modifiedItemIDs; public static Dictionary<int, float> itemRandomizationCache; public static ManualLogSource StaticLogger { get; private set; } static RandomValueMod() { blacklistKeywordsList = new List<string>(); whitelistKeywordsList = new List<string>(); modifiedItemIDs = new HashSet<int>(); itemRandomizationCache = new Dictionary<int, float>(); dollarValueCurrentField = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); dollarValueOriginalField = typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private void Awake() { StaticLogger = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================="); ((BaseUnityPlugin)this).Logger.LogInfo((object)"随机贵重物品的价格模组 v1.7.0 已加载"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"作者: dyxc666"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"功能: 抓取时随机化物品价格(主机强制统一配置)"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================="); CreateConfigEntries(); UpdateKeywordLists(); BlacklistKeywords.ValueChanged += delegate { UpdateKeywordLists(); }; WhitelistKeywords.ValueChanged += delegate { UpdateKeywordLists(); }; MinValueMultiplier.ValueChanged += delegate { ValidateValueRange(); }; MaxValueMultiplier.ValueChanged += delegate { ValidateValueRange(); }; try { ApplyHarmonyPatches(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"✅ 模组初始化成功"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("\ud83d\udccb 黑名单关键词: " + string.Join(", ", blacklistKeywordsList))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("\ud83d\udccb 白名单关键词: " + string.Join(", ", whitelistKeywordsList))); ((BaseUnityPlugin)this).Logger.LogInfo((object)"⚙\ufe0f 当前功能状态:"); ((BaseUnityPlugin)this).Logger.LogInfo((object)(" 价格随机化: " + (EnableValueRandomization.Value ? "✅" : "❌"))); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" 最小倍率: {MinValueMultiplier.Value:F2}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" 最大倍率: {MaxValueMultiplier.Value:F2}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)" 随机化时机: 抓取时触发"); ((BaseUnityPlugin)this).Logger.LogInfo((object)(" 现金袋保护: " + (CashBagRandomizationToggle.Value ? "❌ 已禁用" : "✅ 已启用"))); CheckForModConflicts(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("❌ 模组初始化失败: " + ex.Message)); } } private void ApplyHarmonyPatches() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(ValuableObject), "Awake", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ValuableObjectPatch).GetMethod("Postfix_Awake")), (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"✅ 成功补丁 ValuableObject.Awake"); } string[] array = new string[3] { "GrabStarted", "GrabEnded", "GrabLink" }; string[] array2 = array; foreach (string text in array2) { MethodInfo methodInfo2 = AccessTools.Method(typeof(PhysGrabObject), text, (Type[])null, (Type[])null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(PhysGrabObjectPatch).GetMethod("Postfix_GrabMethod")), (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)("✅ 成功补丁 PhysGrabObject." + text)); } } } private void CheckForModConflicts() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"\ud83d\udd0d 正在检查Mod兼容性..."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"✅ Mod兼容性检查完成"); } private ConfigField<bool> CreateBoolConfig(string section, string key, bool defaultValue, string description, bool sync = true) { return new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section(section).Key(key) .Default(defaultValue) .Description(description) .Range(false, true) .Sync(sync) .Build(); } private ConfigField<float> CreateFloatConfig(string section, string key, float defaultValue, string description, float min, float max, bool sync = true) { return new ConfigBuilder<float>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section(section).Key(key) .Default(defaultValue) .Description(description) .Range(min, max) .Sync(sync) .Build(); } private void CreateConfigEntries() { EnableValueRandomization = CreateBoolConfig("基础设置", "随机化物品价格", defaultValue: true, "是否随机化贵重物品的价格"); MinValueMultiplier = CreateFloatConfig("价格设置", "最小价格倍率", 0.5f, "价格的最小倍率", 0.1f, 5f); MaxValueMultiplier = CreateFloatConfig("价格设置", "最大价格倍率", 2f, "价格的最大倍率", 0.5f, 10f); EnableBlacklistMode = CreateBoolConfig("黑白名单", "启用黑名单模式", defaultValue: true, "启用黑名单,匹配的物品将不被随机化"); BlacklistKeywords = new ConfigBuilder<string>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("黑白名单").Key("黑名单关键词") .Default("") .Description("逗号分隔的关键词列表") .Sync(true) .Build(); EnableWhitelistMode = CreateBoolConfig("黑白名单", "启用白名单模式", defaultValue: false, "启用白名单,只有匹配白名单的物品才会被随机化"); WhitelistKeywords = new ConfigBuilder<string>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("黑白名单").Key("白名单关键词") .Default("") .Description("逗号分隔的关键词列表") .Sync(true) .Build(); ExcludeHighValueItems = CreateBoolConfig("特殊排除规则", "排除高价物品", defaultValue: false, "不随机化价格超过阈值的物品"); HighValueThreshold = CreateFloatConfig("特殊排除规则", "高价物品阈值", 50000f, "价格超过此值的物品不随机化", 1000f, 1000000f); CashBagRandomizationToggle = CreateBoolConfig("特殊排除规则", "现金袋随机化", defaultValue: false, "如果为true,则现金袋也会被随机化"); ForceRefreshUI = CreateBoolConfig("调试设置", "强制刷新UI", defaultValue: true, "尝试强制刷新UI显示", sync: false); EnableVerboseLogging = CreateBoolConfig("调试设置", "详细日志输出", defaultValue: false, "输出每个物品修改前后的具体数值", sync: false); } private void UpdateKeywordLists() { blacklistKeywordsList = (string.IsNullOrWhiteSpace(BlacklistKeywords.Value) ? new List<string>() : (from k in BlacklistKeywords.Value.Split(new char[3] { ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries) select k.Trim().ToLower() into k where !string.IsNullOrEmpty(k) select k).ToList()); whitelistKeywordsList = (string.IsNullOrWhiteSpace(WhitelistKeywords.Value) ? new List<string>() : (from k in WhitelistKeywords.Value.Split(new char[3] { ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries) select k.Trim().ToLower() into k where !string.IsNullOrEmpty(k) select k).ToList()); } private void ValidateValueRange() { if (MinValueMultiplier.Value < 0.1f) { MinValueMultiplier.Value = 0.1f; } if (MaxValueMultiplier.Value < MinValueMultiplier.Value + 0.1f) { MaxValueMultiplier.Value = MinValueMultiplier.Value + 0.1f; } if (MaxValueMultiplier.Value > 10f) { MaxValueMultiplier.Value = 10f; } } public static bool ShouldItemBeRandomized(GameObject obj, ValuableObject vo) { try { string name = ((Object)obj).name.ToLower(); if (IsCashBag(name) && !CashBagRandomizationToggle.Value) { return false; } if (CheckSpecialExclusionRules(obj, vo)) { return false; } if (EnableBlacklistMode.Value && CheckBlacklist(name)) { return false; } if (EnableWhitelistMode.Value && !CheckWhitelist(name)) { return false; } return EnableValueRandomization.Value; } catch { return true; } } private static bool IsCashBag(string name) { return name.Contains("surplus"); } private static bool CheckSpecialExclusionRules(GameObject obj, ValuableObject vo) { if (ExcludeHighValueItems.Value) { float itemPrice = GetItemPrice(vo); if (itemPrice >= HighValueThreshold.Value) { return true; } } return false; } private static bool CheckBlacklist(string name) { return blacklistKeywordsList.Any((string k) => name.Contains(k)); } private static bool CheckWhitelist(string name) { return whitelistKeywordsList.Count == 0 || whitelistKeywordsList.Any((string k) => name.Contains(k)); } public static float GetItemPrice(ValuableObject vo) { if (dollarValueCurrentField == null) { return 0f; } return (float)dollarValueCurrentField.GetValue(vo); } public static void SetItemPrice(ValuableObject vo, float newPrice) { dollarValueCurrentField?.SetValue(vo, newPrice); dollarValueOriginalField?.SetValue(vo, newPrice); } public static float GetDeterministicRandomPrice(int instanceID, float originalPrice) { if (itemRandomizationCache.TryGetValue(instanceID, out var value)) { return value; } float num = Mathf.Max(0.1f, MinValueMultiplier.Value); float num2 = Mathf.Max(num + 0.1f, MaxValueMultiplier.Value); Random random = new Random(instanceID); float num3 = (float)(random.NextDouble() * (double)(num2 - num) + (double)num); if (EnableVerboseLogging.Value) { StaticLogger.LogInfo((object)$"[调试] 物品ID {instanceID}: 原价={originalPrice:F0}, min={num:F2}, max={num2:F2}, 乘数={num3:F2}"); } float num4 = originalPrice; if (originalPrice > 0f && EnableValueRandomization.Value) { num4 = originalPrice * num3; num4 = Mathf.Clamp(num4, 1f, 1000000f); } itemRandomizationCache[instanceID] = num4; return num4; } } public static class ItemModifier { public static bool ModifyItemAttributes(PhysGrabObject pgo, ValuableObject vo, float newPrice) { try { float itemPrice = RandomValueMod.GetItemPrice(vo); if (RandomValueMod.EnableValueRandomization.Value && itemPrice > 0f) { if (RandomValueMod.EnableVerboseLogging.Value) { RandomValueMod.StaticLogger.LogInfo((object)$"[调试] 修改前价格: {itemPrice:F0}"); } RandomValueMod.SetItemPrice(vo, newPrice); if (RandomValueMod.EnableVerboseLogging.Value) { float itemPrice2 = RandomValueMod.GetItemPrice(vo); RandomValueMod.StaticLogger.LogInfo((object)$"[调试] 修改后价格: {itemPrice2:F0}"); } RandomValueAPI.TriggerItemRandomized(vo, itemPrice, newPrice); if (RandomValueMod.ForceRefreshUI.Value) { try { ((Component)vo).BroadcastMessage("OnValueChanged", (SendMessageOptions)1); } catch { } } } if (RandomValueMod.EnableVerboseLogging.Value && itemPrice > 0f) { float num = newPrice / itemPrice; string text = ((num > 2f) ? " \ud83d\udcb0" : ((num > 1.5f) ? " \ud83d\udcc8" : ((num < 0.9f) ? " \ud83d\udcc9" : ""))); RandomValueMod.StaticLogger.LogInfo((object)$"[RWVM] {((Object)((Component)pgo).gameObject).name}: 价格 ${itemPrice:F0}→${newPrice:F0}(x{num:F2}){text}"); } return true; } catch (Exception ex) { RandomValueMod.StaticLogger.LogError((object)("[RWVM] 修改物品属性失败: " + ex.Message)); return false; } } } [HarmonyPatch] public static class ValuableObjectPatch { [HarmonyPostfix] [HarmonyPatch(typeof(ValuableObject), "Awake")] public static void Postfix_Awake(ValuableObject __instance) { try { PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>(); if (!((Object)(object)component == (Object)null) && !RandomValueMod.modifiedItemIDs.Contains(((Object)((Component)__instance).gameObject).GetInstanceID())) { GrabEventListener grabEventListener = ((Component)component).gameObject.AddComponent<GrabEventListener>(); grabEventListener.valuableObject = __instance; grabEventListener.physGrabObject = component; } } catch { } } } [HarmonyPatch] public static class PhysGrabObjectPatch { [HarmonyPostfix] [HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")] [HarmonyPatch(typeof(PhysGrabObject), "GrabLink")] public static void Postfix_GrabMethod(PhysGrabObject __instance) { try { ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>(); if ((Object)(object)component == (Object)null) { return; } int instanceID = ((Object)((Component)__instance).gameObject).GetInstanceID(); if (!RandomValueMod.modifiedItemIDs.Contains(instanceID) && RandomValueMod.ShouldItemBeRandomized(((Component)__instance).gameObject, component)) { float itemPrice = RandomValueMod.GetItemPrice(component); if (!(itemPrice <= 0f)) { float deterministicRandomPrice = RandomValueMod.GetDeterministicRandomPrice(instanceID, itemPrice); ApplyRandomization(__instance, component, deterministicRandomPrice, itemPrice, instanceID); } } } catch { } } private static void ApplyRandomization(PhysGrabObject pgo, ValuableObject vo, float newPrice, float originalPrice, int instanceID) { if (ItemModifier.ModifyItemAttributes(pgo, vo, newPrice)) { RandomValueMod.modifiedItemIDs.Add(instanceID); float num = newPrice / originalPrice; RandomValueMod.StaticLogger.LogInfo((object)string.Format("[提示] 抓取时随机化: {0} ${1:F0} → ${2:F0} ({3}{4:F1}倍)", ((Object)((Component)pgo).gameObject).name, originalPrice, newPrice, (num > 1f) ? "+" : "", num)); } } } public class GrabEventListener : MonoBehaviour { [CompilerGenerated] private sealed class <DelayedRandomization>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public GrabEventListener <>4__this; private int <id>5__1; private float <original>5__2; private float <newPrice>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedRandomization>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { if ((Object)(object)<>4__this.valuableObject != (Object)null && (Object)(object)<>4__this.physGrabObject != (Object)null && !<>4__this.isRandomized) { <id>5__1 = ((Object)((Component)<>4__this).gameObject).GetInstanceID(); if (!RandomValueMod.modifiedItemIDs.Contains(<id>5__1)) { <original>5__2 = RandomValueMod.GetItemPrice(<>4__this.valuableObject); if (<original>5__2 > 0f) { <newPrice>5__3 = RandomValueMod.GetDeterministicRandomPrice(<id>5__1, <original>5__2); if (ItemModifier.ModifyItemAttributes(<>4__this.physGrabObject, <>4__this.valuableObject, <newPrice>5__3)) { RandomValueMod.modifiedItemIDs.Add(<id>5__1); <>4__this.isRandomized = true; } } } } } catch { } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public ValuableObject valuableObject; public PhysGrabObject physGrabObject; private bool wasGrabbed = false; private int instanceID; private float checkTimer = 0f; private bool isRandomized = false; private void Start() { if ((Object)(object)valuableObject == (Object)null || (Object)(object)physGrabObject == (Object)null) { Object.Destroy((Object)(object)this); } else { instanceID = ((Object)((Component)this).gameObject).GetInstanceID(); } } private void Update() { if (isRandomized || (Object)(object)valuableObject == (Object)null || (Object)(object)physGrabObject == (Object)null) { return; } checkTimer += Time.deltaTime; if (checkTimer < 0.5f) { return; } checkTimer = 0f; try { bool flag = false; FieldInfo field = typeof(PhysGrabObject).GetField("grabbed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { flag = (bool)field.GetValue(physGrabObject); } if (flag && !wasGrabbed && !isRandomized) { ((MonoBehaviour)this).StartCoroutine(DelayedRandomization()); } wasGrabbed = flag; if (isRandomized && RandomValueMod.modifiedItemIDs.Contains(instanceID)) { Object.Destroy((Object)(object)this); } } catch { } } [IteratorStateMachine(typeof(<DelayedRandomization>d__8))] private IEnumerator DelayedRandomization() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedRandomization>d__8(0) { <>4__this = this }; } } }