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 LuckyTouch v1.2.1
plugins/LuckyTouch.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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("LuckyTouch")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LuckyTouch")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1450d209-6bd5-4127-ab3d-8d0632c3f5f5")] [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 LuckyTouch { [BepInPlugin("dyxc666.LuckyTouch", "LuckyTouch", "1.2.1")] [BepInProcess("REPO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LuckyTouchMod : BaseUnityPlugin { [CompilerGenerated] private sealed class <DelayedRefresh>d__38 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PhysGrabber grabber; public LuckyTouchMod <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedRefresh>d__38(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; colorStatesMethod?.Invoke(grabber, null); 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 readonly Harmony harmony = new Harmony("dyxc666.LuckyTouch"); public static ConfigField<bool> EnableLuckSystem; public static ConfigField<float> LuckAccumulationRate; public static ConfigField<float> LuckDecayRate; public static ConfigField<float> LuckMaxDelta; public static ConfigField<float> LuckMin; public static ConfigField<float> LuckMax; public static ConfigField<string> HighLuckColorHex; public static ConfigField<string> LowLuckColorHex; public static ConfigField<bool> EnableVerboseLogging; public static float CurrentLuck = 1f; public static float LastMultiplier = 1f; internal static Color highLuckColor = Color.green; internal static Color lowLuckColor = Color.red; private static FieldInfo dollarValueCurrentField; private static FieldInfo dollarValueOriginalField; private static MethodInfo colorStatesMethod; public static ManualLogSource StaticLogger { get; private set; } public static LuckyTouchMod Instance { get; private set; } private void Awake() { Instance = this; StaticLogger = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================="); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LuckyTouch 模组 v1.2.1 已加载"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"作者: dyxc666"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================="); CreateConfigEntries(); ParseColorConfigs(); HighLuckColorHex.ValueChanged += delegate { ParseColorConfigs(); }; LowLuckColorHex.ValueChanged += delegate { ParseColorConfigs(); }; try { InitializeReflection(); CacheRefreshMethod(); ApplyHarmonyPatches(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"✅ 模组初始化成功"); if (EnableVerboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"⚙\ufe0f 当前配置:积累={LuckAccumulationRate.Value},衰减={LuckDecayRate.Value},上限={LuckMaxDelta.Value}"); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("❌ 模组初始化失败: " + ex.Message)); } } private void InitializeReflection() { dollarValueCurrentField = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); dollarValueOriginalField = typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private void CacheRefreshMethod() { colorStatesMethod = AccessTools.Method(typeof(PhysGrabber), "ColorStates", Type.EmptyTypes, (Type[])null); if (colorStatesMethod == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"未能找到 ColorStates 方法,颜色刷新可能不即时"); } } private void ParseColorConfigs() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!ColorUtility.TryParseHtmlString(HighLuckColorHex.Value, ref highLuckColor)) { highLuckColor = Color.green; } if (!ColorUtility.TryParseHtmlString(LowLuckColorHex.Value, ref lowLuckColor)) { lowLuckColor = Color.red; } } private ConfigField<bool> CreateBoolConfig(string section, string key, bool defaultValue, string description, bool sync = true) { return new ConfigBuilder<bool>("LuckyTouch").File("LuckyTouch.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>("LuckyTouch").File("LuckyTouch.cfg").Section(section).Key(key) .Default(defaultValue) .Description(description) .Range(min, max) .Sync(sync) .Build(); } private ConfigField<string> CreateStringConfig(string section, string key, string defaultValue, string description, bool sync = true) { return new ConfigBuilder<string>("LuckyTouch").File("LuckyTouch.cfg").Section(section).Key(key) .Default(defaultValue) .Description(description) .Sync(sync) .Build(); } private void CreateConfigEntries() { EnableLuckSystem = CreateBoolConfig("基础设置", "启用运气系统", defaultValue: true, "总开关"); LuckAccumulationRate = CreateFloatConfig("平衡参数", "价格_积累比例", 0.03f, "价格变化绝对值计入运气的比例", 0f, 0.5f); LuckDecayRate = CreateFloatConfig("平衡参数", "自然衰减比例", 0.15f, "每次抓取后运气值向1.0衰减的比例", 0f, 0.5f); LuckMaxDelta = CreateFloatConfig("平衡参数", "单次变化上限", 0.15f, "每次运气值变化的最大绝对值", 0f, 1f); LuckMin = CreateFloatConfig("平衡参数", "运气最小值", 0.2f, "允许的最低运气值", 0.1f, 1f); LuckMax = CreateFloatConfig("平衡参数", "运气最大值", 2.2f, "允许的最高运气值", 1f, 5f); HighLuckColorHex = CreateStringConfig("视觉效果", "高运气颜色", "#00FF00", "涨价时抓取光束颜色 (十六进制)"); LowLuckColorHex = CreateStringConfig("视觉效果", "低运气颜色", "#FF0000", "跌价时抓取光束颜色 (十六进制)"); EnableVerboseLogging = CreateBoolConfig("调试", "详细日志输出", defaultValue: false, "输出核心运气变化数据", sync: false); } 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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(GrabPatch).GetMethod("Postfix_GrabStarted")), (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(typeof(PhysGrabObject), "GrabLink", (Type[])null, (Type[])null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(GrabPatch).GetMethod("Postfix_GrabLink")), (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(PhysGrabber), "ColorStateSetColor", (Type[])null, (Type[])null); if (methodInfo3 == null) { methodInfo3 = AccessTools.Method(typeof(PhysGrabber), "SetBeamColor", (Type[])null, (Type[])null); } if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(BeamColorPatch).GetMethod("Prefix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"无法找到光束颜色方法!颜色反馈将不可用。"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"✅ 成功应用 Harmony 补丁"); } public static float GetItemPrice(ValuableObject vo) { return (dollarValueCurrentField != null) ? ((float)dollarValueCurrentField.GetValue(vo)) : 0f; } public static void SetItemPrice(ValuableObject vo, float newPrice) { dollarValueCurrentField?.SetValue(vo, newPrice); dollarValueOriginalField?.SetValue(vo, newPrice); } public static PlayerAvatar GetGrabbingPlayer(PhysGrabObject pgo) { PropertyInfo property = ((object)pgo).GetType().GetProperty("playerAvatar"); if (property != null) { object? value = property.GetValue(pgo); return (PlayerAvatar)((value is PlayerAvatar) ? value : null); } FieldInfo field = ((object)pgo).GetType().GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object? value2 = field.GetValue(pgo); return (PlayerAvatar)((value2 is PlayerAvatar) ? value2 : null); } field = ((object)pgo).GetType().GetField("playerGrabbing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object? value3 = field.GetValue(pgo); return (PlayerAvatar)((value3 is PlayerAvatar) ? value3 : null); } return null; } public static void RefreshBeamColor(PhysGrabObject pgo) { PlayerAvatar grabbingPlayer = GetGrabbingPlayer(pgo); if ((Object)(object)grabbingPlayer != (Object)null && (Object)(object)grabbingPlayer.physGrabber != (Object)null && colorStatesMethod != null) { colorStatesMethod.Invoke(grabbingPlayer.physGrabber, null); } } [IteratorStateMachine(typeof(<DelayedRefresh>d__38))] private IEnumerator DelayedRefresh(PhysGrabber grabber) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedRefresh>d__38(0) { <>4__this = this, grabber = grabber }; } public void DelayedRefreshBeamColor(PhysGrabber grabber) { ((MonoBehaviour)this).StartCoroutine(DelayedRefresh(grabber)); } } [HarmonyPatch] public static class GrabPatch { private static HashSet<int> processedItems = new HashSet<int>(); public static void Postfix_GrabStarted(PhysGrabObject __instance) { ProcessGrab(__instance); } public static void Postfix_GrabLink(PhysGrabObject __instance) { ProcessGrab(__instance); } private static void ProcessGrab(PhysGrabObject pgo) { if (!LuckyTouchMod.EnableLuckSystem.Value) { return; } ValuableObject component = ((Component)pgo).GetComponent<ValuableObject>(); if ((Object)(object)component == (Object)null) { return; } int instanceID = ((Object)((Component)pgo).gameObject).GetInstanceID(); if (processedItems.Contains(instanceID)) { return; } float itemPrice = LuckyTouchMod.GetItemPrice(component); if (!(itemPrice <= 0f)) { float num = Random.Range(0.5f, 2f); float num2 = num * LuckyTouchMod.CurrentLuck; float num3 = itemPrice * num2; num3 = Mathf.Clamp(num3, 1f, 1000000f); LuckyTouchMod.SetItemPrice(component, num3); float num4 = Mathf.Abs(num3 - itemPrice); float num5 = num4 * LuckyTouchMod.LuckAccumulationRate.Value; num5 = Mathf.Clamp(num5, 0f - LuckyTouchMod.LuckMaxDelta.Value, LuckyTouchMod.LuckMaxDelta.Value); if (num3 > itemPrice) { LuckyTouchMod.CurrentLuck += num5; } else { LuckyTouchMod.CurrentLuck -= num5; } float value = LuckyTouchMod.LuckDecayRate.Value; LuckyTouchMod.CurrentLuck = Mathf.Lerp(LuckyTouchMod.CurrentLuck, 1f, value); LuckyTouchMod.CurrentLuck = Mathf.Clamp(LuckyTouchMod.CurrentLuck, LuckyTouchMod.LuckMin.Value, LuckyTouchMod.LuckMax.Value); LuckyTouchMod.LastMultiplier = num2; processedItems.Add(instanceID); if (LuckyTouchMod.EnableVerboseLogging.Value) { LuckyTouchMod.StaticLogger.LogInfo((object)$"[运气] 物品: {((Object)pgo).name} | 基础倍率={num:F2} | 最终乘数={num2:F2} | 运气变化={num5:F2} | 当前运气={LuckyTouchMod.CurrentLuck:F2}"); } LuckyTouchMod.RefreshBeamColor(pgo); PlayerAvatar grabbingPlayer = LuckyTouchMod.GetGrabbingPlayer(pgo); if ((Object)(object)grabbingPlayer != (Object)null && (Object)(object)grabbingPlayer.physGrabber != (Object)null) { LuckyTouchMod.Instance.DelayedRefreshBeamColor(grabbingPlayer.physGrabber); } } } } [HarmonyPatch] public static class BeamColorPatch { public static void Prefix(PhysGrabber __instance, ref Color mainColor, ref Color emissionColor) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (LuckyTouchMod.EnableLuckSystem.Value) { float lastMultiplier = LuckyTouchMod.LastMultiplier; if (lastMultiplier > 1f) { mainColor = LuckyTouchMod.highLuckColor; emissionColor = LuckyTouchMod.highLuckColor; } else if (lastMultiplier < 1f) { mainColor = LuckyTouchMod.lowLuckColor; emissionColor = LuckyTouchMod.lowLuckColor; } } } } }