using System;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
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 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.8.3")]
[BepInProcess("REPO.exe")]
public class RandomValueMod : BaseUnityPlugin
{
private static readonly FieldInfo dollarValueCurrentField;
private static readonly FieldInfo dollarValueOriginalField;
private readonly Harmony harmony = new Harmony("dyxc666.RandomValuablePrice");
public static ConfigEntry<bool> EnableValueRandomization;
public static ConfigEntry<float> MinValueMultiplier;
public static ConfigEntry<float> MaxValueMultiplier;
public static ConfigEntry<bool> EnableVerboseLogging;
public static ConfigEntry<string> BlacklistKeywords;
public static ConfigEntry<string> WhitelistKeywords;
public static ConfigEntry<bool> EnableWhitelistMode;
public static ConfigEntry<bool> EnableBlacklistMode;
public static ConfigEntry<bool> ExcludeHighValueItems;
public static ConfigEntry<float> HighValueThreshold;
public static ConfigEntry<bool> CashBagRandomizationToggle;
private static GameObject _netSyncObject;
private static NetSync _netSync;
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; }
public static NetSync NetSync => _netSync;
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);
}
internal static void EnsureNetSync()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
if ((Object)(object)_netSyncObject == (Object)null)
{
_netSyncObject = new GameObject("RandomValueNetSync");
Object.DontDestroyOnLoad((Object)(object)_netSyncObject);
_netSync = _netSyncObject.AddComponent<NetSync>();
StaticLogger.LogInfo((object)"NetSync component created.");
}
}
private void Awake()
{
StaticLogger = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"=========================================");
((BaseUnityPlugin)this).Logger.LogInfo((object)"随机贵重物品的价格 v1.8.2 (多人同步版 - 调试版)");
((BaseUnityPlugin)this).Logger.LogInfo((object)"=========================================");
CreateConfigEntries();
UpdateKeywordLists();
BlacklistKeywords.SettingChanged += delegate
{
UpdateKeywordLists();
};
WhitelistKeywords.SettingChanged += delegate
{
UpdateKeywordLists();
};
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)(" 现金袋保护: " + (CashBagRandomizationToggle.Value ? "❌ 已禁用" : "✅ 已启用")));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("❌ 模组初始化失败: " + ex.Message));
}
}
private void ApplyHarmonyPatches()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(PhysGrabObject), "GrabStarted", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PhysGrabObjectPatch).GetMethod("Postfix_GrabStarted")), (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo methodInfo2 = AccessTools.Method(typeof(PhysGrabObject), "GrabEnded", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(PhysGrabObjectPatch).GetMethod("Postfix_GrabEnded")), (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo methodInfo3 = AccessTools.Method(typeof(RoundDirector), "StartRoundLogic", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(NetSync).GetMethod("Prefix_StartRoundLogic")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"✅ Harmony 补丁应用完成");
}
private void CreateConfigEntries()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Expected O, but got Unknown
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Expected O, but got Unknown
EnableValueRandomization = ((BaseUnityPlugin)this).Config.Bind<bool>("基础设置", "随机化物品价格", true, "是否随机化贵重物品的价格");
MinValueMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("价格设置", "最小价格倍率", 0.5f, new ConfigDescription("价格的最小倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
MaxValueMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("价格设置", "最大价格倍率", 2f, new ConfigDescription("价格的最大倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
EnableBlacklistMode = ((BaseUnityPlugin)this).Config.Bind<bool>("黑白名单", "启用黑名单模式", true, "启用黑名单,匹配的物品将不被随机化");
BlacklistKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("黑白名单", "黑名单关键词", "", "逗号分隔的关键词列表 (例如: keycard,computer)");
EnableWhitelistMode = ((BaseUnityPlugin)this).Config.Bind<bool>("黑白名单", "启用白名单模式", false, "启用白名单,只有匹配白名单的物品才会被随机化");
WhitelistKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("黑白名单", "白名单关键词", "", "逗号分隔的关键词列表");
ExcludeHighValueItems = ((BaseUnityPlugin)this).Config.Bind<bool>("特殊排除规则", "排除高价物品", false, "不随机化价格超过阈值的物品");
HighValueThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("特殊排除规则", "高价物品阈值", 50000f, new ConfigDescription("价格超过此值的物品不随机化", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1000f, 1000000f), Array.Empty<object>()));
CashBagRandomizationToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("特殊排除规则", "现金袋随机化", false, "如果为true,则现金袋也会被随机化");
EnableVerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("调试设置", "详细日志输出", 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());
}
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, int? extraSeed = null)
{
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);
int num3 = instanceID;
if (extraSeed.HasValue)
{
num3 ^= extraSeed.Value;
}
Random random = new Random(num3);
float num4 = (float)(random.NextDouble() * (double)(num2 - num) + (double)num);
if (EnableVerboseLogging.Value)
{
StaticLogger.LogInfo((object)$"[调试] 物品ID {instanceID}: 原价={originalPrice:F0}, min={num:F2}, max={num2:F2}, 乘数={num4:F2}, 种子={num3}");
}
float num5 = originalPrice;
if (originalPrice > 0f && EnableValueRandomization.Value)
{
num5 = originalPrice * num4;
num5 = Mathf.Clamp(num5, 1f, 1000000f);
}
itemRandomizationCache[instanceID] = num5;
return num5;
}
}
public class NetSync : MonoBehaviourPunCallbacks
{
public int currentLevelSeed;
private void Start()
{
if (PhotonNetwork.IsConnected && (Object)(object)((MonoBehaviourPun)this).photonView == (Object)null)
{
((Component)this).gameObject.AddComponent<PhotonView>();
RandomValueMod.StaticLogger.LogInfo((object)"NetSync: PhotonView added.");
}
else
{
RandomValueMod.StaticLogger.LogInfo((object)"NetSync: Photon not connected, skipping PhotonView creation.");
}
}
[HarmonyPatch(typeof(RoundDirector), "StartRoundLogic")]
[HarmonyPrefix]
public static void Prefix_StartRoundLogic(int value)
{
RandomValueMod.StaticLogger.LogInfo((object)$"Prefix_StartRoundLogic called, value={value}, IsMasterClient={PhotonNetwork.IsMasterClient}");
if (!PhotonNetwork.IsMasterClient)
{
return;
}
RandomValueMod.EnsureNetSync();
NetSync netSync = RandomValueMod.NetSync;
if ((Object)(object)netSync != (Object)null)
{
netSync.currentLevelSeed = value;
if ((Object)(object)((MonoBehaviourPun)netSync).photonView == (Object)null)
{
((Component)netSync).gameObject.AddComponent<PhotonView>();
RandomValueMod.StaticLogger.LogInfo((object)"Prefix_StartRoundLogic: Added PhotonView on host.");
}
((MonoBehaviourPun)netSync).photonView.RPC("SyncConfigRPC", (RpcTarget)1, new object[11]
{
RandomValueMod.EnableValueRandomization.Value,
RandomValueMod.MinValueMultiplier.Value,
RandomValueMod.MaxValueMultiplier.Value,
RandomValueMod.EnableBlacklistMode.Value,
RandomValueMod.BlacklistKeywords.Value,
RandomValueMod.EnableWhitelistMode.Value,
RandomValueMod.WhitelistKeywords.Value,
RandomValueMod.ExcludeHighValueItems.Value,
RandomValueMod.HighValueThreshold.Value,
RandomValueMod.CashBagRandomizationToggle.Value,
value
});
RandomValueMod.StaticLogger.LogInfo((object)$"主机广播配置和种子: {value}");
}
}
[PunRPC]
public void SyncConfigRPC(bool enableRandomization, float minMult, float maxMult, bool enableBlacklist, string blacklist, bool enableWhitelist, string whitelist, bool excludeHigh, float highThreshold, bool cashBag, int seed)
{
RandomValueMod.StaticLogger.LogInfo((object)$"客户端收到主机配置,种子: {seed}");
RandomValueMod.EnableValueRandomization.Value = enableRandomization;
RandomValueMod.MinValueMultiplier.Value = minMult;
RandomValueMod.MaxValueMultiplier.Value = maxMult;
RandomValueMod.EnableBlacklistMode.Value = enableBlacklist;
RandomValueMod.BlacklistKeywords.Value = blacklist;
RandomValueMod.EnableWhitelistMode.Value = enableWhitelist;
RandomValueMod.WhitelistKeywords.Value = whitelist;
RandomValueMod.ExcludeHighValueItems.Value = excludeHigh;
RandomValueMod.HighValueThreshold.Value = highThreshold;
RandomValueMod.CashBagRandomizationToggle.Value = cashBag;
currentLevelSeed = seed;
RandomValueMod.BlacklistKeywords.Value = blacklist;
RandomValueMod.WhitelistKeywords.Value = whitelist;
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
((MonoBehaviourPunCallbacks)this).OnPlayerEnteredRoom(newPlayer);
if (PhotonNetwork.IsMasterClient)
{
RandomValueMod.StaticLogger.LogInfo((object)("OnPlayerEnteredRoom: 新玩家 " + newPlayer.NickName + " 加入,发送配置"));
((MonoBehaviourPun)this).photonView.RPC("SyncConfigRPC", newPlayer, new object[11]
{
RandomValueMod.EnableValueRandomization.Value,
RandomValueMod.MinValueMultiplier.Value,
RandomValueMod.MaxValueMultiplier.Value,
RandomValueMod.EnableBlacklistMode.Value,
RandomValueMod.BlacklistKeywords.Value,
RandomValueMod.EnableWhitelistMode.Value,
RandomValueMod.WhitelistKeywords.Value,
RandomValueMod.ExcludeHighValueItems.Value,
RandomValueMod.HighValueThreshold.Value,
RandomValueMod.CashBagRandomizationToggle.Value,
currentLevelSeed
});
}
}
}
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)
{
RandomValueMod.StaticLogger.LogInfo((object)$"[调试] 修改后价格: {newPrice:F0}");
}
RandomValueAPI.TriggerItemRandomized(vo, itemPrice, newPrice);
return true;
}
return false;
}
catch (Exception ex)
{
RandomValueMod.StaticLogger.LogError((object)("修改物品属性时出错: " + ex.Message));
return false;
}
}
}
[HarmonyPatch(typeof(PhysGrabObject))]
public static class PhysGrabObjectPatch
{
[HarmonyPatch("GrabStarted")]
[HarmonyPostfix]
public static void Postfix_GrabStarted(PhysGrabObject __instance, PhysGrabber player)
{
try
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
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))
{
return;
}
float itemPrice = RandomValueMod.GetItemPrice(component);
if (!(itemPrice <= 0f) && RandomValueMod.ShouldItemBeRandomized(((Component)__instance).gameObject, component))
{
int? extraSeed = (((Object)(object)RandomValueMod.NetSync != (Object)null) ? new int?(RandomValueMod.NetSync.currentLevelSeed) : null);
float deterministicRandomPrice = RandomValueMod.GetDeterministicRandomPrice(instanceID, itemPrice, extraSeed);
ItemModifier.ModifyItemAttributes(__instance, component, deterministicRandomPrice);
RandomValueMod.modifiedItemIDs.Add(instanceID);
if (RandomValueMod.EnableVerboseLogging.Value)
{
RandomValueMod.StaticLogger.LogInfo((object)$"[抓取时] 物品 {((Object)component).name} 价格随机化: {itemPrice:F0} -> {deterministicRandomPrice:F0}");
}
}
}
catch (Exception ex)
{
RandomValueMod.StaticLogger.LogError((object)("PhysGrabObject.GrabStarted 补丁出错: " + ex.Message));
}
}
[HarmonyPatch("GrabEnded")]
[HarmonyPostfix]
public static void Postfix_GrabEnded(PhysGrabObject __instance, PhysGrabber player)
{
if (RandomValueMod.EnableVerboseLogging.Value)
{
ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>();
if ((Object)(object)component != (Object)null)
{
RandomValueMod.StaticLogger.LogInfo((object)("[抓取结束] 物品 " + ((Object)component).name));
}
}
}
}