Decompiled source of RandomValueMod v1.8.3

plugins/RandomValueMod.dll

Decompiled 3 days ago
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));
			}
		}
	}
}