Decompiled source of DSPMinerMultiplier v1.4.1

DSPMinerMultiplier.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using NebulaAPI;
using NebulaAPI.GameState;
using NebulaAPI.Interfaces;
using NebulaAPI.Networking;
using NebulaAPI.Packets;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DSPMinerMultiplier")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("DSPMinerMultiplier")]
[assembly: AssemblyTitle("DSPMinerMultiplier")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace DSPMinerMultiplier;

[BepInPlugin("com.byboy.dsp.minermultiplier", "DSP Miner Multiplier", "1.3.0")]
public class MinerMultiplierPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.byboy.dsp.minermultiplier";

	public const string PluginName = "DSP Miner Multiplier";

	public const string PluginVersion = "1.3.0";

	internal static ManualLogSource Log;

	public static float MiningMultiplier = 10f;

	public static float PowerMultiplier = 1f;

	internal static ConfigEntry<float> MiningMultiplierEntry;

	private ConfigEntry<float> _miningMultiplier;

	private ConfigEntry<KeyCode> _modifierKey;

	private ConfigEntry<KeyCode> _toggleKey;

	private MultiplierUI _ui;

	private void Awake()
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		_miningMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "采矿倍率 MiningMultiplier", 10f, new ConfigDescription("采矿机的采矿速度倍率,范围 1 ~ 1000。耗电按 1~256 线性同步增长。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>()));
		_modifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "修饰键 ModifierKey", (KeyCode)308, "与切换键组合使用的修饰键");
		_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "切换键 ToggleKey", (KeyCode)282, "与修饰键组合打开/关闭倍率面板");
		ApplyMiningMultiplier(_miningMultiplier.Value);
		MiningMultiplierEntry = _miningMultiplier;
		_miningMultiplier.SettingChanged += delegate
		{
			if (Math.Abs(_miningMultiplier.Value - MiningMultiplier) > 0.001f)
			{
				ApplyMiningMultiplier(_miningMultiplier.Value);
			}
		};
		Harmony val = new Harmony("com.byboy.dsp.minermultiplier");
		val.PatchAll(typeof(MinerPatches));
		val.PatchAll(typeof(DisplayPatches));
		_ui = ((Component)this).gameObject.AddComponent<MultiplierUI>();
		_ui.Init(_miningMultiplier, _modifierKey, _toggleKey);
		InitNebula();
		((BaseUnityPlugin)this).Config.Save();
		((BaseUnityPlugin)this).Logger.LogInfo((object)(string.Format("{0} {1} 已加载,采矿 {2}x,耗电 {3:F2}x。", "DSP Miner Multiplier", "1.3.0", MiningMultiplier, PowerMultiplier) + $"按 {_modifierKey.Value}+{_toggleKey.Value} 打开倍率面板。" + (NebulaSync.Available ? "Nebula 联机同步已启用。" : "")));
	}

	private void InitNebula()
	{
		try
		{
			if (!Chainloader.PluginInfos.ContainsKey("dsp.nebula-multiplayer-api"))
			{
				return;
			}
			NebulaSync.Available = true;
			NebulaModAPI.RegisterPackets(Assembly.GetExecutingAssembly());
			NebulaModAPI.OnMultiplayerGameStarted = (Action)Delegate.Combine(NebulaModAPI.OnMultiplayerGameStarted, (Action)delegate
			{
				Log.LogInfo((object)$"联机游戏已开始 (主机={NebulaModAPI.MultiplayerSession.IsServer})");
				if (NebulaModAPI.MultiplayerSession.IsServer)
				{
					NebulaSync.Broadcast();
				}
				else
				{
					Log.LogInfo((object)"等待主机同步采矿倍率…");
				}
			});
			NebulaModAPI.OnPlayerJoinedGame = (Action<IPlayerData>)Delegate.Combine(NebulaModAPI.OnPlayerJoinedGame, (Action<IPlayerData>)delegate
			{
				if (NebulaModAPI.MultiplayerSession != null && NebulaModAPI.MultiplayerSession.IsServer)
				{
					NebulaSync.Broadcast();
				}
			});
			NebulaModAPI.OnMultiplayerGameEnded = (Action)Delegate.Combine(NebulaModAPI.OnMultiplayerGameEnded, (Action)delegate
			{
				Log.LogInfo((object)"联机游戏已结束,倍率恢复为本机配置。");
				ApplyMiningMultiplier(_miningMultiplier.Value);
			});
			Log.LogInfo((object)"Nebula API 已接入,联机倍率同步可用。");
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("初始化 Nebula 同步失败(将以单机模式运行): " + ex.Message));
		}
	}

	public static void ApplyMiningMultiplier(float value)
	{
		value = ((value < 1f) ? 1f : ((value > 1000f) ? 1000f : value));
		MiningMultiplier = value;
		PowerMultiplier = 1f + (value - 1f) * 255f / 999f;
	}

	public static void SetMultiplier(ConfigEntry<float> entry, float value)
	{
		ApplyMiningMultiplier(value);
		entry.Value = MiningMultiplier;
		NebulaSync.Broadcast();
	}
}
public class MinerMultiplierPacket : INetSerializable
{
	public float MiningMultiplier { get; set; }

	public void Serialize(INetDataWriter writer)
	{
		writer.Put(MiningMultiplier);
	}

	public void Deserialize(INetDataReader reader)
	{
		MiningMultiplier = reader.GetFloat();
	}
}
[RegisterPacketProcessor]
public class MinerMultiplierPacketProcessor : BasePacketProcessor<MinerMultiplierPacket>
{
	public override void ProcessPacket(MinerMultiplierPacket packet, INebulaConnection conn)
	{
		MinerMultiplierPlugin.Log.LogInfo((object)$"收到主机同步的采矿倍率: {packet.MiningMultiplier}x");
		MinerMultiplierPlugin.ApplyMiningMultiplier(packet.MiningMultiplier);
	}
}
public static class NebulaSync
{
	public static bool Available { get; set; }

	public static void Broadcast()
	{
		if (!Available || !NebulaModAPI.IsMultiplayerActive)
		{
			return;
		}
		try
		{
			IMultiplayerSession multiplayerSession = NebulaModAPI.MultiplayerSession;
			if (multiplayerSession != null && multiplayerSession.IsServer)
			{
				multiplayerSession.Network.SendPacket<MinerMultiplierPacket>(new MinerMultiplierPacket
				{
					MiningMultiplier = MinerMultiplierPlugin.MiningMultiplier
				});
				MinerMultiplierPlugin.Log.LogInfo((object)$"已向客户端广播采矿倍率: {MinerMultiplierPlugin.MiningMultiplier}x");
			}
		}
		catch (Exception ex)
		{
			MinerMultiplierPlugin.Log.LogWarning((object)("广播倍率失败: " + ex.Message));
		}
	}
}
[HarmonyPatch]
public static class MinerPatches
{
	[HarmonyPatch(typeof(MinerComponent), "InternalUpdate")]
	[HarmonyPrefix]
	public static void InternalUpdate_Prefix(ref float miningSpeed)
	{
		miningSpeed *= MinerMultiplierPlugin.MiningMultiplier;
	}

	[HarmonyPatch(typeof(MinerComponent), "SetPCState")]
	[HarmonyPostfix]
	public static void SetPCState_Postfix(MinerComponent __instance, PowerConsumerComponent[] pcPool)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.pcId > 0 && pcPool != null && __instance.pcId < pcPool.Length)
		{
			double requiredEnergy = (double)(__instance.speedDamper * (float)__instance.speed * (float)__instance.speed) / 100000000.0 * (double)MinerMultiplierPlugin.PowerMultiplier;
			((PowerConsumerComponent)(ref pcPool[__instance.pcId])).SetRequiredEnergy(requiredEnergy);
		}
	}
}
[HarmonyPatch]
public static class DisplayPatches
{
	private static readonly Regex LeadingNumber = new Regex("^(\\d+(?:\\.\\d+)?)");

	private static readonly Regex NumberBeforeSlashMin = new Regex("(\\d+(?:\\.\\d+)?)( ?)/min");

	private static readonly Regex IntegerPerMin = new Regex("^(\\d+) /min$");

	private static int _propIndex;

	public static string ScaleLeadingNumber(string text, float factor)
	{
		if (string.IsNullOrEmpty(text) || factor == 1f)
		{
			return null;
		}
		Match match = LeadingNumber.Match(text);
		if (!match.Success || !float.TryParse(match.Groups[1].Value, out var result))
		{
			return null;
		}
		float num = result * factor;
		string text2 = ((num >= 100f) ? num.ToString("0") : num.ToString("0.#"));
		return text.Substring(0, match.Groups[1].Index) + text2 + text.Substring(match.Groups[1].Index + match.Groups[1].Length);
	}

	public static string ScalePerMinNumber(string text, float factor)
	{
		if (string.IsNullOrEmpty(text) || factor == 1f)
		{
			return null;
		}
		return NumberBeforeSlashMin.Replace(text, delegate(Match m)
		{
			if (!float.TryParse(m.Groups[1].Value, out var result))
			{
				return m.Value;
			}
			float num = result * factor;
			return ((num >= 100f) ? num.ToString("0.#") : num.ToString("0.##")) + m.Groups[2].Value + "/min";
		});
	}

	[HarmonyPatch(typeof(UIMinerWindow), "_OnUpdate")]
	[HarmonyPostfix]
	public static void UIMinerWindow_OnUpdate_Postfix(UIMinerWindow __instance)
	{
		Text speedText = __instance.speedText;
		if (!((Object)(object)speedText == (Object)null))
		{
			string text = ScaleLeadingNumber(speedText.text, MinerMultiplierPlugin.MiningMultiplier);
			if (text != null)
			{
				speedText.text = text;
			}
		}
	}

	[HarmonyPatch(typeof(BuildingGizmo), "SetGizmoDesc")]
	[HarmonyPostfix]
	public static void BuildingGizmo_SetGizmoDesc_Postfix(BuildingGizmo __instance)
	{
		TextMesh buildText = __instance.buildText;
		if (!((Object)(object)buildText == (Object)null))
		{
			string text = ScalePerMinNumber(buildText.text, MinerMultiplierPlugin.MiningMultiplier);
			if (text != null)
			{
				buildText.text = text;
			}
		}
	}

	[HarmonyPatch(typeof(ItemProto), "GetPropValue")]
	[HarmonyPrefix]
	public static void ItemProto_GetPropValue_Prefix(int index)
	{
		_propIndex = index;
	}

	[HarmonyPatch(typeof(ItemProto), "GetPropValue")]
	[HarmonyPostfix]
	public static void ItemProto_GetPropValue_Postfix(ItemProto __instance, ref string __result)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		if (_propIndex == 19 && __result != null && __instance.prefabDesc != null && (int)__instance.prefabDesc.minerType != 0)
		{
			string text = ScaleLeadingNumber(__result, MinerMultiplierPlugin.MiningMultiplier);
			if (text != null)
			{
				__result = text;
			}
		}
	}

	[HarmonyPatch(typeof(UIVeinCollectorPanel), "_OnUpdate")]
	[HarmonyPostfix]
	public static void UIVeinCollectorPanel_OnUpdate_Postfix(UIVeinCollectorPanel __instance)
	{
		object? obj = AccessTools.Field(typeof(UIVeinCollectorPanel), "speedText")?.GetValue(__instance);
		Text val = (Text)((obj is Text) ? obj : null);
		string text = ScaleLeadingNumber((val != null) ? val.text : null, MinerMultiplierPlugin.MiningMultiplier);
		if (text != null && (Object)(object)val != (Object)null)
		{
			val.text = text;
		}
	}

	[HarmonyPatch(typeof(UIControlPanelVeinCollectorPanel), "_OnUpdate")]
	[HarmonyPostfix]
	public static void UIControlPanelVeinCollectorPanel_OnUpdate_Postfix(UIControlPanelVeinCollectorPanel __instance)
	{
		object? obj = AccessTools.Field(typeof(UIControlPanelVeinCollectorPanel), "speedText")?.GetValue(__instance);
		Text val = (Text)((obj is Text) ? obj : null);
		string text = ScaleLeadingNumber((val != null) ? val.text : null, MinerMultiplierPlugin.MiningMultiplier);
		if (text != null && (Object)(object)val != (Object)null)
		{
			val.text = text;
		}
	}

	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPostfix]
	public static void ResAmountEntry_ValueString_Postfix(UIResAmountEntry __instance, string value)
	{
		if (!string.IsNullOrEmpty(value))
		{
			Match match = IntegerPerMin.Match(value);
			if (match.Success && float.TryParse(match.Groups[1].Value, out var result))
			{
				float num = result * MinerMultiplierPlugin.MiningMultiplier;
				__instance.valueText.text = $"{num:0} /min";
			}
		}
	}

	[HarmonyPatch(typeof(UIControlPanelAdvancedMinerEntry), "_OnUpdate")]
	[HarmonyPostfix]
	public static void AdvancedMinerEntry_OnUpdate_Postfix(UIControlPanelAdvancedMinerEntry __instance)
	{
		Text maxChargePowerValue = __instance.maxChargePowerValue;
		if (!((Object)(object)maxChargePowerValue == (Object)null))
		{
			string text = ScaleLeadingNumber(maxChargePowerValue.text, MinerMultiplierPlugin.PowerMultiplier);
			if (text != null)
			{
				maxChargePowerValue.text = text;
			}
		}
	}
}
public class MultiplierUI : MonoBehaviour
{
	private ConfigEntry<float> _miningMultiplier;

	private ConfigEntry<KeyCode> _modifierKey;

	private ConfigEntry<KeyCode> _toggleKey;

	private bool _open;

	private Rect _windowRect = new Rect(80f, 80f, 340f, 200f);

	private string _input = "10";

	private bool _inputDirty = true;

	public void Init(ConfigEntry<float> miningMultiplier, ConfigEntry<KeyCode> modifierKey, ConfigEntry<KeyCode> toggleKey)
	{
		_miningMultiplier = miningMultiplier;
		_modifierKey = modifierKey;
		_toggleKey = toggleKey;
		_input = miningMultiplier.Value.ToString("0.#");
	}

	private void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		bool key = Input.GetKey(_modifierKey.Value);
		bool keyDown = Input.GetKeyDown(_toggleKey.Value);
		if (key && keyDown)
		{
			_open = !_open;
			if (_open)
			{
				_input = MinerMultiplierPlugin.MiningMultiplier.ToString("0.#");
				_inputDirty = true;
			}
		}
	}

	private void OnGUI()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		if (_open)
		{
			_windowRect = GUILayout.Window(19792, _windowRect, new WindowFunction(DrawWindow), "DSP 采矿倍率 (Alt+F1)", Array.Empty<GUILayoutOption>());
		}
	}

	private void DrawWindow(int id)
	{
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		GUILayout.Space(6f);
		GUILayout.Label($"当前采矿倍率:{MinerMultiplierPlugin.MiningMultiplier:0.#}x    耗电:{MinerMultiplierPlugin.PowerMultiplier:0.##}x", Array.Empty<GUILayoutOption>());
		float num = GUILayout.HorizontalSlider(MinerMultiplierPlugin.MiningMultiplier, 1f, 1000f, Array.Empty<GUILayoutOption>());
		if (Math.Abs(num - MinerMultiplierPlugin.MiningMultiplier) > 0.001f)
		{
			MinerMultiplierPlugin.SetMultiplier(_miningMultiplier, num);
			_input = MinerMultiplierPlugin.MiningMultiplier.ToString("0.#");
			_inputDirty = true;
		}
		GUILayout.Space(4f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("1x", Array.Empty<GUILayoutOption>()))
		{
			Apply(1f);
		}
		if (GUILayout.Button("10x", Array.Empty<GUILayoutOption>()))
		{
			Apply(10f);
		}
		if (GUILayout.Button("100x", Array.Empty<GUILayoutOption>()))
		{
			Apply(100f);
		}
		if (GUILayout.Button("500x", Array.Empty<GUILayoutOption>()))
		{
			Apply(500f);
		}
		if (GUILayout.Button("1000x", Array.Empty<GUILayoutOption>()))
		{
			Apply(1000f);
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(4f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("手动输入:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) });
		string text = GUILayout.TextField(_inputDirty ? _input : _input, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
		if (!string.Equals(text, _input))
		{
			_input = text;
			_inputDirty = false;
		}
		if (GUILayout.Button("应用", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }) && float.TryParse(_input, out var result))
		{
			Apply(result);
		}
		GUILayout.EndHorizontal();
		GUILayout.FlexibleSpace();
		GUILayout.Label("拖动滑条或点按钮即时生效,并自动保存到配置文件。", Array.Empty<GUILayoutOption>());
		GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
	}

	private void Apply(float v)
	{
		MinerMultiplierPlugin.SetMultiplier(_miningMultiplier, v);
		_input = MinerMultiplierPlugin.MiningMultiplier.ToString("0.#");
		_inputDirty = true;
	}
}