Decompiled source of RandomValueMod v2.0.0

plugins/RandomValueMod.dll

Decompiled 2 weeks ago
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using RandomValueLib;
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;

	internal static void TriggerItemRandomized(ValuableObject vo, float oldPrice, float newPrice)
	{
		RandomValueAPI.OnItemRandomized?.Invoke(vo, oldPrice, newPrice);
	}
}
[Serializable]
public class RandomValueConfigSnapshot
{
	public float minMultiplier;

	public float maxMultiplier;

	public bool enableBlacklist;

	public bool enableWhitelist;

	public bool excludeHigh;

	public bool cashBag;

	public string blacklist;

	public string whitelist;

	public float highThreshold;

	public int levelSeed;

	public long revision;
}
[Serializable]
public class PriceSyncData
{
	public List<PriceEntry> prices = new List<PriceEntry>();
}
[Serializable]
public class PriceEntry
{
	public int viewId;

	public float price;
}
public class RandomValueRpcRelay : MonoBehaviourPunCallbacks
{
	[CompilerGenerated]
	private sealed class <PublishConfigDelayed>d__4 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public RandomValueRpcRelay <>4__this;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <PublishConfigDelayed>d__4(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom)
				{
					RandomValueMod.CurrentLevelSeed = <>4__this.GetLevelSeed();
					<>4__this.PublishConfigSnapshot(RandomValueMod.CurrentConfig, RandomValueMod.CurrentLevelSeed);
					RandomValueMod.StaticLogger.LogInfo((object)"[Config] 延迟发布配置快照完成");
				}
				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();
		}
	}

	private static RandomValueRpcRelay _instance;

	public static RandomValueRpcRelay Instance
	{
		get
		{
			if ((Object)(object)_instance == (Object)null)
			{
				PunManager val = Object.FindObjectOfType<PunManager>();
				if ((Object)(object)val != (Object)null)
				{
					_instance = ((Component)val).GetComponent<RandomValueRpcRelay>();
					if ((Object)(object)_instance == (Object)null)
					{
						_instance = ((Component)val).gameObject.AddComponent<RandomValueRpcRelay>();
					}
				}
			}
			return _instance;
		}
	}

	private void Awake()
	{
		if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)this);
			return;
		}
		_instance = this;
		if ((Object)(object)((Component)this).GetComponent<PhotonView>() == (Object)null)
		{
			((Component)this).gameObject.AddComponent<PhotonView>();
		}
	}

	[IteratorStateMachine(typeof(<PublishConfigDelayed>d__4))]
	private IEnumerator PublishConfigDelayed()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PublishConfigDelayed>d__4(0)
		{
			<>4__this = this
		};
	}

	[PunRPC]
	public void RequestItemPriceRPC(int viewId, int requesterActorNumber)
	{
		if (!PhotonNetwork.IsMasterClient)
		{
			return;
		}
		ValuableObject val = FindValuableByViewId(viewId);
		if (!((Object)(object)val == (Object)null))
		{
			float itemPrice = RandomValueService.GetItemPrice(val);
			float num = RandomValueService.ApplyRandomPrice(val, RandomValueMod.CurrentConfig, (int?)RandomValueMod.CurrentLevelSeed);
			if (RandomValueMod.EnableVerboseLogging.Value)
			{
				string name = ((Object)val).name;
				float num2 = ((itemPrice > 0f) ? (num / itemPrice) : 0f);
				RandomValueMod.StaticLogger.LogInfo((object)$"[Host] 计算价格: {name} | {itemPrice:F0} → {num:F0} | 倍率: {num2:F2}x");
			}
			if (Math.Abs(num - itemPrice) > 0.01f)
			{
				RandomValueMod.priceCache[viewId] = num;
				((MonoBehaviourPun)this).photonView.RPC("SetItemPriceRPC", (RpcTarget)0, new object[3] { viewId, num, itemPrice });
			}
		}
	}

	[PunRPC]
	public void SetItemPriceRPC(int viewId, float newPrice, float oldPrice)
	{
		ValuableObject val = FindValuableByViewId(viewId);
		if (!((Object)(object)val == (Object)null))
		{
			RandomValueService.SetItemPrice(val, newPrice);
			RandomValueAPI.TriggerItemRandomized(val, oldPrice, newPrice);
			RandomValueMod.modifiedItemViewIDs.Add(viewId);
			RandomValueMod.priceCache[viewId] = newPrice;
			if (RandomValueMod.EnableVerboseLogging.Value)
			{
				string name = ((Object)val).name;
				float num = ((oldPrice > 0f) ? (newPrice / oldPrice) : 0f);
				RandomValueMod.StaticLogger.LogInfo((object)$"[Sync] {name} | {oldPrice:F0} → {newPrice:F0} | 倍率: {num:F2}x");
			}
		}
	}

	[PunRPC]
	public void SyncAllPricesRPC(int targetActor, string priceDataJson)
	{
		if (PhotonNetwork.LocalPlayer.ActorNumber != targetActor)
		{
			return;
		}
		PriceSyncData priceSyncData = JsonUtility.FromJson<PriceSyncData>(priceDataJson);
		if (priceSyncData == null)
		{
			return;
		}
		foreach (PriceEntry price in priceSyncData.prices)
		{
			ValuableObject val = FindValuableByViewId(price.viewId);
			if ((Object)(object)val != (Object)null)
			{
				RandomValueService.SetItemPrice(val, price.price);
				RandomValueMod.modifiedItemViewIDs.Add(price.viewId);
				RandomValueMod.priceCache[price.viewId] = price.price;
			}
		}
		if (RandomValueMod.EnableVerboseLogging.Value)
		{
			RandomValueMod.StaticLogger.LogInfo((object)$"[Sync] 新玩家补发 {priceSyncData.prices.Count} 个物品价格");
		}
	}

	public override void OnPlayerEnteredRoom(Player newPlayer)
	{
		if (!PhotonNetwork.IsMasterClient)
		{
			return;
		}
		PriceSyncData priceSyncData = new PriceSyncData();
		foreach (KeyValuePair<int, float> item in RandomValueMod.priceCache)
		{
			priceSyncData.prices.Add(new PriceEntry
			{
				viewId = item.Key,
				price = item.Value
			});
		}
		string text = JsonUtility.ToJson((object)priceSyncData);
		((MonoBehaviourPun)this).photonView.RPC("SyncAllPricesRPC", newPlayer, new object[2] { newPlayer.ActorNumber, text });
	}

	public void PublishConfigSnapshot(RandomizationConfig config, int levelSeed)
	{
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom)
		{
			RandomValueConfigSnapshot randomValueConfigSnapshot = new RandomValueConfigSnapshot
			{
				minMultiplier = config.MinMultiplier,
				maxMultiplier = config.MaxMultiplier,
				enableBlacklist = config.EnableBlacklist,
				blacklist = string.Join(",", config.BlacklistKeywords),
				enableWhitelist = config.EnableWhitelist,
				whitelist = string.Join(",", config.WhitelistKeywords),
				excludeHigh = config.ExcludeHighValueItems,
				highThreshold = config.HighValueThreshold,
				cashBag = config.RandomizeCashBags,
				levelSeed = levelSeed,
				revision = DateTime.UtcNow.Ticks
			};
			string text = JsonUtility.ToJson((object)randomValueConfigSnapshot);
			Hashtable val = new Hashtable { [(object)"rv_config"] = text };
			PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}

	public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
	{
		if (!((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"rv_config"))
		{
			return;
		}
		string text = propertiesThatChanged[(object)"rv_config"] as string;
		if (!string.IsNullOrEmpty(text))
		{
			RandomValueConfigSnapshot randomValueConfigSnapshot = JsonUtility.FromJson<RandomValueConfigSnapshot>(text);
			if (randomValueConfigSnapshot != null)
			{
				ApplySnapshot(randomValueConfigSnapshot);
			}
		}
	}

	public override void OnJoinedRoom()
	{
		((MonoBehaviour)this).StartCoroutine(PublishConfigDelayed());
	}

	private void ApplySnapshot(RandomValueConfigSnapshot snapshot)
	{
		RandomValueMod.MinValueMultiplier.Value = snapshot.minMultiplier;
		RandomValueMod.MaxValueMultiplier.Value = snapshot.maxMultiplier;
		RandomValueMod.EnableBlacklistMode.Value = snapshot.enableBlacklist;
		RandomValueMod.BlacklistKeywords.Value = snapshot.blacklist;
		RandomValueMod.EnableWhitelistMode.Value = snapshot.enableWhitelist;
		RandomValueMod.WhitelistKeywords.Value = snapshot.whitelist;
		RandomValueMod.ExcludeHighValueItems.Value = snapshot.excludeHigh;
		RandomValueMod.HighValueThreshold.Value = snapshot.highThreshold;
		RandomValueMod.CashBagRandomizationToggle.Value = snapshot.cashBag;
		RandomValueMod.CurrentLevelSeed = snapshot.levelSeed;
		RandomValueMod.StaticLogger.LogInfo((object)$"[Config] 快照已应用 (rev {snapshot.revision})");
	}

	public int GetLevelSeed()
	{
		if (PhotonNetwork.InRoom)
		{
			int serverTimestamp = PhotonNetwork.ServerTimestamp;
			RunManager instance = RunManager.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				Level levelCurrent = instance.levelCurrent;
				obj = ((levelCurrent != null) ? ((Object)levelCurrent).name : null);
			}
			if (obj == null)
			{
				obj = "default";
			}
			string text = (string)obj;
			return serverTimestamp ^ text.GetHashCode();
		}
		return Random.Range(1, int.MaxValue);
	}

	private ValuableObject FindValuableByViewId(int viewId)
	{
		PhotonView val = PhotonView.Find(viewId);
		return (val != null) ? ((Component)val).GetComponent<ValuableObject>() : null;
	}
}
[BepInPlugin("dyxc666.RandomValuablePrice", "随机贵重物品价格", "2.0.0")]
[BepInProcess("REPO.exe")]
public class RandomValueMod : BaseUnityPlugin
{
	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> EnableBlacklistMode;

	public static ConfigEntry<bool> EnableWhitelistMode;

	public static ConfigEntry<bool> ExcludeHighValueItems;

	public static ConfigEntry<float> HighValueThreshold;

	public static ConfigEntry<bool> CashBagRandomizationToggle;

	public static HashSet<int> modifiedItemViewIDs = new HashSet<int>();

	public static Dictionary<int, float> priceCache = new Dictionary<int, float>();

	public static RandomizationConfig CurrentConfig { get; private set; }

	public static int CurrentLevelSeed { get; set; }

	public static ManualLogSource StaticLogger { get; private set; }

	private void Awake()
	{
		StaticLogger = ((BaseUnityPlugin)this).Logger;
		StaticLogger.LogInfo((object)"随机贵重物品价格 v2.0.0 (详细日志版)");
		CreateConfigEntries();
		UpdateConfig();
		MinValueMultiplier.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		MaxValueMultiplier.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		EnableBlacklistMode.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		BlacklistKeywords.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		EnableWhitelistMode.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		WhitelistKeywords.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		ExcludeHighValueItems.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		HighValueThreshold.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		CashBagRandomizationToggle.SettingChanged += delegate
		{
			UpdateConfig();
			PublishConfigIfMaster();
		};
		ApplyHarmonyPatches();
	}

	private void PublishConfigIfMaster()
	{
		if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom)
		{
			RandomValueRpcRelay instance = RandomValueRpcRelay.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				CurrentLevelSeed = instance.GetLevelSeed();
				instance.PublishConfigSnapshot(CurrentConfig, CurrentLevelSeed);
			}
		}
	}

	private void UpdateConfig()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		RandomizationConfig val = new RandomizationConfig();
		val.MinMultiplier = MinValueMultiplier.Value;
		val.MaxMultiplier = MaxValueMultiplier.Value;
		val.EnableBlacklist = EnableBlacklistMode.Value;
		val.BlacklistKeywords = (from k in BlacklistKeywords.Value.Split(new char[3] { ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries)
			select k.Trim().ToLower() into k
			where !string.IsNullOrEmpty(k)
			select k).ToList();
		val.EnableWhitelist = EnableWhitelistMode.Value;
		val.WhitelistKeywords = (from k in WhitelistKeywords.Value.Split(new char[3] { ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries)
			select k.Trim().ToLower() into k
			where !string.IsNullOrEmpty(k)
			select k).ToList();
		val.ExcludeHighValueItems = ExcludeHighValueItems.Value;
		val.HighValueThreshold = HighValueThreshold.Value;
		val.RandomizeCashBags = CashBagRandomizationToggle.Value;
		CurrentConfig = val;
	}

	private void CreateConfigEntries()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		EnableValueRandomization = ((BaseUnityPlugin)this).Config.Bind<bool>("基础设置", "随机化物品价格", true, (ConfigDescription)null);
		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, (ConfigDescription)null);
		BlacklistKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("黑白名单", "黑名单关键词", "", (ConfigDescription)null);
		EnableWhitelistMode = ((BaseUnityPlugin)this).Config.Bind<bool>("黑白名单", "启用白名单模式", false, (ConfigDescription)null);
		WhitelistKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("黑白名单", "白名单关键词", "", (ConfigDescription)null);
		ExcludeHighValueItems = ((BaseUnityPlugin)this).Config.Bind<bool>("特殊排除规则", "排除高价物品", false, (ConfigDescription)null);
		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, (ConfigDescription)null);
		EnableVerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("调试", "详细日志", true, (ConfigDescription)null);
	}

	private void ApplyHarmonyPatches()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Expected O, but got Unknown
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PhysGrabObject), "GrabStarted", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(PhysGrabObjectPatch), "Postfix_GrabStarted", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PhysGrabObject), "GrabEnded", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(PhysGrabObjectPatch), "Postfix_GrabEnded", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
	}
}
[HarmonyPatch(typeof(PhysGrabObject))]
public static class PhysGrabObjectPatch
{
	[HarmonyPostfix]
	[HarmonyPatch("GrabStarted")]
	public static void Postfix_GrabStarted(PhysGrabObject __instance, PhysGrabber player)
	{
		if (!RandomValueMod.EnableValueRandomization.Value)
		{
			return;
		}
		ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		PhotonView component2 = ((Component)component).GetComponent<PhotonView>();
		if ((Object)(object)component2 == (Object)null)
		{
			return;
		}
		int viewID = component2.ViewID;
		if (RandomValueMod.modifiedItemViewIDs.Contains(viewID))
		{
			return;
		}
		RandomValueMod.modifiedItemViewIDs.Add(viewID);
		RandomValueRpcRelay instance = RandomValueRpcRelay.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		if (PhotonNetwork.IsMasterClient)
		{
			float itemPrice = RandomValueService.GetItemPrice(component);
			float num = RandomValueService.ApplyRandomPrice(component, RandomValueMod.CurrentConfig, (int?)RandomValueMod.CurrentLevelSeed);
			if (RandomValueMod.EnableVerboseLogging.Value)
			{
				string name = ((Object)component).name;
				float num2 = ((itemPrice > 0f) ? (num / itemPrice) : 0f);
				RandomValueMod.StaticLogger.LogInfo((object)$"[Host Grab] {name} | {itemPrice:F0} → {num:F0} | 倍率: {num2:F2}x");
			}
			if (Math.Abs(num - itemPrice) > 0.01f)
			{
				RandomValueMod.priceCache[viewID] = num;
				((MonoBehaviourPun)instance).photonView.RPC("SetItemPriceRPC", (RpcTarget)0, new object[3] { viewID, num, itemPrice });
			}
		}
		else
		{
			((MonoBehaviourPun)instance).photonView.RPC("RequestItemPriceRPC", (RpcTarget)2, new object[2] { viewID, 0 });
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch("GrabEnded")]
	public static void Postfix_GrabEnded(PhysGrabObject __instance, PhysGrabber player)
	{
	}
}