using 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
{
[BepInPlugin("dyxc666.RandomValuablePrice", "随机贵重物品的价格", "1.5.6")]
[BepInProcess("REPO.exe")]
[BepInDependency("nickklmao.repoconfig", "1.2.3")]
[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 List<string> blacklistKeywordsList = new List<string>();
private static List<string> whitelistKeywordsList = new List<string>();
public static HashSet<int> modifiedItemIDs = new HashSet<int>();
public static Dictionary<int, float> itemRandomizationCache = new Dictionary<int, float>();
public static ManualLogSource StaticLogger { get; private set; }
private void Awake()
{
StaticLogger = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"=========================================");
((BaseUnityPlugin)this).Logger.LogInfo((object)"随机贵重物品的价格模组 v1.5.6 已加载");
((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 void CreateConfigEntries()
{
EnableValueRandomization = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("基础设置").Key("随机化物品价格")
.Default(true)
.Description("是否随机化贵重物品的价格")
.Range(false, true)
.Sync(true)
.Build();
MinValueMultiplier = new ConfigBuilder<float>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("价格设置").Key("最小价格倍率")
.Default(0.5f)
.Description("价格的最小倍率")
.Range(0.1f, 5f)
.Sync(true)
.Build();
MaxValueMultiplier = new ConfigBuilder<float>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("价格设置").Key("最大价格倍率")
.Default(2f)
.Description("价格的最大倍率")
.Range(0.5f, 10f)
.Sync(true)
.Build();
EnableBlacklistMode = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("黑白名单").Key("启用黑名单模式")
.Default(true)
.Description("启用黑名单,匹配的物品将不被随机化")
.Range(false, true)
.Sync(true)
.Build();
BlacklistKeywords = new ConfigBuilder<string>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("黑白名单").Key("黑名单关键词")
.Default("")
.Description("逗号分隔的关键词列表")
.Sync(true)
.Build();
EnableWhitelistMode = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("黑白名单").Key("启用白名单模式")
.Default(false)
.Description("启用白名单,只有匹配白名单的物品才会被随机化")
.Range(false, true)
.Sync(true)
.Build();
WhitelistKeywords = new ConfigBuilder<string>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("黑白名单").Key("白名单关键词")
.Default("")
.Description("逗号分隔的关键词列表")
.Sync(true)
.Build();
ExcludeHighValueItems = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("特殊排除规则").Key("排除高价物品")
.Default(false)
.Description("不随机化价格超过阈值的物品")
.Range(false, true)
.Sync(true)
.Build();
HighValueThreshold = new ConfigBuilder<float>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("特殊排除规则").Key("高价物品阈值")
.Default(50000f)
.Description("价格超过此值的物品不随机化")
.Range(1000f, 1000000f)
.Sync(true)
.Build();
CashBagRandomizationToggle = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("特殊排除规则").Key("现金袋随机化")
.Default(false)
.Description("如果为true,则现金袋也会被随机化")
.Range(false, true)
.Sync(true)
.Build();
ForceRefreshUI = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("调试设置").Key("强制刷新UI")
.Default(true)
.Description("尝试强制刷新UI显示")
.Range(false, true)
.Sync(false)
.Build();
EnableVerboseLogging = new ConfigBuilder<bool>("RandomValuablePrice").File("RandomValuablePrice.cfg").Section("调试设置").Key("详细日志输出")
.Default(false)
.Description("输出每个物品修改前后的具体数值")
.Range(false, true)
.Sync(false)
.Build();
}
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)
{
FieldInfo field = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return (field != null) ? ((float)field.GetValue(vo)) : 0f;
}
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)
{
typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(vo, newPrice);
typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(vo, 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, instanceID);
}
}
}
catch
{
}
}
private static void ApplyRandomization(PhysGrabObject pgo, ValuableObject vo, float newPrice, int instanceID)
{
if (ItemModifier.ModifyItemAttributes(pgo, vo, newPrice))
{
RandomValueMod.modifiedItemIDs.Add(instanceID);
float num = newPrice / RandomValueMod.GetItemPrice(vo);
RandomValueMod.StaticLogger.LogInfo((object)string.Format("[提示] 抓取时随机化: {0} ${1:F0} → ${2:F0} ({3}{4:F1}倍)", ((Object)((Component)pgo).gameObject).name, RandomValueMod.GetItemPrice(vo), 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
};
}
}
}