Decompiled source of RailgunsRetargetMini v1.3.2

RailgunsRetargetMini.dll

Decompiled 3 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using NebulaAPI;
using NebulaAPI.Networking;
using NebulaAPI.Packets;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("RailgunsRetargetMini")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.2.0")]
[assembly: AssemblyInformationalVersion("1.3.2")]
[assembly: AssemblyProduct("RailgunsRetargetMini")]
[assembly: AssemblyTitle("RailgunsRetargetMini")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.2.0")]
[module: UnverifiableCode]
namespace RailgunsRetargetMini;

public static class NebulaCompat
{
	public const string GUID = "dsp.nebula-multiplayer";

	public static bool IsMultiplayer { get; private set; }

	public static bool IsClient { get; private set; }

	public static void Init()
	{
		if (!Chainloader.PluginInfos.ContainsKey("dsp.nebula-multiplayer"))
		{
			return;
		}
		try
		{
			Patch();
			Plugin.Log.LogInfo((object)"Nebula Compatibility - OK");
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)"Nebula Compatibility failed!");
			Plugin.Log.LogError((object)ex);
		}
	}

	public static void Patch()
	{
		if (NebulaModAPI.NebulaIsInstalled)
		{
			NebulaModAPI.RegisterPackets(Assembly.GetExecutingAssembly());
			NebulaModAPI.OnMultiplayerGameStarted = (Action)Delegate.Combine(NebulaModAPI.OnMultiplayerGameStarted, new Action(OnMultiplayerGameStarted));
			NebulaModAPI.OnMultiplayerGameEnded = (Action)Delegate.Combine(NebulaModAPI.OnMultiplayerGameEnded, new Action(OnMultiplayerGameEnded));
		}
	}

	public static void OnMultiplayerGameStarted()
	{
		IsMultiplayer = NebulaModAPI.IsMultiplayerActive;
		IsClient = NebulaModAPI.IsMultiplayerActive && NebulaModAPI.MultiplayerSession.LocalPlayer.IsClient;
	}

	public static void OnMultiplayerGameEnded()
	{
		IsMultiplayer = false;
		IsClient = false;
	}

	public static void SendPacket(in StarData starData, int orbitId)
	{
		NebulaModAPI.MultiplayerSession.Network.SendPacket<EjectorOrbitChangePacket>(new EjectorOrbitChangePacket(in starData, orbitId));
	}
}
internal class EjectorOrbitChangePacket
{
	public int StarId { get; set; }

	public int OrbitId { get; set; }

	public string Message { get; set; }

	public EjectorOrbitChangePacket()
	{
	}

	public EjectorOrbitChangePacket(in StarData starData, int orbitId, string message = "")
	{
		StarId = starData.id;
		OrbitId = orbitId;
		Message = message;
	}
}
[RegisterPacketProcessor]
internal class PauseNotificationProcessor : BasePacketProcessor<EjectorOrbitChangePacket>
{
	public override void ProcessPacket(EjectorOrbitChangePacket packet, INebulaConnection conn)
	{
		StarData starData = GameMain.galaxy.StarById(packet.StarId);
		int orbitId = packet.OrbitId;
		if (orbitId < 0)
		{
			if (base.IsHost)
			{
				conn.SendPacket<EjectorOrbitChangePacket>(new EjectorOrbitChangePacket(in starData, orbitId, UIPatch.GetStatus(starData)));
			}
			else
			{
				UIPatch.ShowMessage(packet.Message, starData, -orbitId);
			}
			return;
		}
		UIPatch.SetOrbit(starData, orbitId);
		if (base.IsHost)
		{
			NebulaModAPI.MultiplayerSession.Network.SendPacket<EjectorOrbitChangePacket>(packet);
		}
	}
}
public class Patch1
{
	private static int checkIndex;

	[HarmonyPrefix]
	[HarmonyPatch(typeof(GameData), "GameTick")]
	public static void GameData_GameTick()
	{
		checkIndex = ((++checkIndex < Configs.RotatePeriod) ? checkIndex : 0);
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(EjectorComponent), "InternalUpdate")]
	public static void EjectorComponent_InternalUpdate_Postfix(ref EjectorComponent __instance, DysonSwarm swarm)
	{
		//IL_0011: 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)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected I4, but got Unknown
		if (checkIndex != 0 || __instance.bulletCount == 0)
		{
			return;
		}
		ETargetState targetState = __instance.targetState;
		switch ((int)targetState)
		{
		default:
			return;
		case 0:
			if (!Configs.ForceRetargeting)
			{
				return;
			}
			break;
		case 1:
			return;
		case 2:
		case 3:
			break;
		}
		int i;
		for (i = __instance.orbitId + 1; i < swarm.orbitCursor && !swarm.orbits[i].enabled; i++)
		{
		}
		if (i >= swarm.orbitCursor)
		{
			i = 1;
		}
		((EjectorComponent)(ref __instance)).SetOrbit(i);
	}
}
public class Patch2
{
	private static int checkIndex;

	[HarmonyPrefix]
	[HarmonyPatch(typeof(GameData), "GameTick")]
	public static void GameData_GameTick()
	{
		checkIndex = ((++checkIndex < Configs.CheckPeriod) ? checkIndex : 0);
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(EjectorComponent), "InternalUpdate")]
	public static void EjectorComponent_InternalUpdate_Postfix(ref EjectorComponent __instance, DysonSwarm swarm, AstroData[] astroPoses)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected I4, but got Unknown
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.id % Configs.CheckPeriod != checkIndex || __instance.bulletCount == 0)
		{
			return;
		}
		ETargetState targetState = __instance.targetState;
		switch ((int)targetState)
		{
		default:
			return;
		case 0:
			if (!Configs.ForceRetargeting)
			{
				return;
			}
			break;
		case 1:
			return;
		case 2:
		case 3:
			break;
		}
		int orbitId = __instance.orbitId;
		int num = __instance.planetId / 100 * 100;
		float num2 = __instance.localAlt + __instance.pivotY + (__instance.muzzleY - __instance.pivotY) / Mathf.Max(0.1f, Mathf.Sqrt(1f - __instance.localDir.y * __instance.localDir.y));
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(__instance.localPosN.x * num2, __instance.localPosN.y * num2, __instance.localPosN.z * num2);
		VectorLF3 vectorLF = astroPoses[__instance.planetId].uPos + Maths.QRotateLF(astroPoses[__instance.planetId].uRot, VectorLF3.op_Implicit(val));
		Quaternion q = astroPoses[__instance.planetId].uRot * __instance.localRot;
		VectorLF3 b = astroPoses[num].uPos - vectorLF;
		for (int i = 1; i < swarm.orbitCursor; i++)
		{
			if (swarm.orbits[i].id == i && swarm.orbits[i].enabled && i != orbitId)
			{
				__instance.orbitId = i;
				if (IsReachable(in __instance, swarm, num, astroPoses, in vectorLF, in q, in b))
				{
					((EjectorComponent)(ref __instance)).SetOrbit(i);
					return;
				}
			}
		}
		__instance.orbitId = orbitId;
	}

	public static bool IsReachable(in EjectorComponent ejector, DysonSwarm swarm, int starId, AstroData[] astroPoses, in VectorLF3 vectorLF, in Quaternion q, in VectorLF3 b)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: 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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		VectorLF3 uPos = astroPoses[starId].uPos;
		VectorLF3 val = VectorLF3.Cross(VectorLF3.op_Implicit(swarm.orbits[ejector.orbitId].up), b);
		VectorLF3 val2 = uPos + ((VectorLF3)(ref val)).normalized * (double)swarm.orbits[ejector.orbitId].radius - vectorLF;
		double magnitude = ((VectorLF3)(ref val2)).magnitude;
		val2.x /= magnitude;
		val2.y /= magnitude;
		val2.z /= magnitude;
		Vector3 val3 = Maths.QInvRotate(q, VectorLF3.op_Implicit(val2));
		if ((double)val3.y < 0.08715574 || val3.y > 0.8660254f)
		{
			return false;
		}
		for (int i = starId + 1; i <= ejector.planetId + 2; i++)
		{
			if (i == ejector.planetId)
			{
				continue;
			}
			double num = astroPoses[i].uRadius;
			if (!(num > 1.0))
			{
				continue;
			}
			VectorLF3 val4 = astroPoses[i].uPos - vectorLF;
			double num2 = val4.x * val4.x + val4.y * val4.y + val4.z * val4.z;
			double num3 = val4.x * val2.x + val4.y * val2.y + val4.z * val2.z;
			if (num3 > 0.0)
			{
				double num4 = num2 - num3 * num3;
				num += 120.0;
				if (num4 < num * num)
				{
					return false;
				}
			}
		}
		return true;
	}
}
[BepInPlugin("starfi5h.plugin.RailgunsRetargetMini", "RailgunsRetargetMini", "1.3.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string GUID = "starfi5h.plugin.RailgunsRetargetMini";

	public const string NAME = "RailgunsRetargetMini";

	public const string VERSION = "1.3.2";

	public static ManualLogSource Log;

	public static ConfigEntry<bool> ForceRetargeting;

	private Harmony harmony;

	public void Awake()
	{
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Expected O, but got Unknown
		ForceRetargeting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ForceRetargeting", true, "Retarget orbit for unset ejctors\n使未设置的电磁弹射器自动换轨");
		Configs.ForceRetargeting = ForceRetargeting.Value;
		Configs.Method = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Method", 1, "Which retarget algorithm should use (1 or 2). Set other value to disable auto retarget\n使用哪种算法(1 或 2) 设置其他数值以取消自动换轨功能").Value;
		Configs.RotatePeriod = ((BaseUnityPlugin)this).Config.Bind<int>("Method1", "RotatePeriod", 60, "Rotate to next orbit every x ticks.\n无法发射时,每x祯切换至下一个轨道").Value;
		Configs.CheckPeriod = ((BaseUnityPlugin)this).Config.Bind<int>("Method2", "CheckPeriod", 120, "Check reachable orbits every x ticks.\n无法发射时,每x祯检查可用轨道一次").Value;
		Log = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("RailgunsRetargetMini");
		switch (Configs.Method)
		{
		case 1:
			harmony.PatchAll(typeof(Patch1));
			break;
		case 2:
			harmony.PatchAll(typeof(Patch2));
			break;
		}
		try
		{
			harmony.PatchAll(typeof(UIPatch));
			harmony.PatchAll(typeof(UIEjectorWindow_Patch));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Can't patch ejector control UI!");
			((BaseUnityPlugin)this).Logger.LogWarning((object)ex);
		}
		NebulaCompat.Init();
	}

	public void OnDestroy()
	{
		UIPatch.OnDestory();
		UIEjectorWindow_Patch.OnDestory();
		harmony.UnpatchSelf();
	}
}
public static class Configs
{
	public static bool ForceRetargeting = true;

	public static int Method = 1;

	public static int RotatePeriod = 60;

	public static int CheckPeriod = 120;
}
public class UIEjectorWindow_Patch
{
	private static UISwitch forceRetargetToggle;

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIEjectorWindow), "_OnOpen")]
	public static void OnOpen(UIEjectorWindow __instance)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)forceRetargetToggle == (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)__instance.boostSwitch).gameObject, ((Component)__instance.boostSwitch).transform.parent);
				forceRetargetToggle = obj.GetComponent<UISwitch>();
				forceRetargetToggle.SetToggleNoEvent(Configs.ForceRetargeting);
				forceRetargetToggle.uiButton.onClick += Onclick;
				Transform obj2 = obj.transform.Find("label");
				Transform transform = ((Component)obj2).transform;
				transform.localPosition += new Vector3(-10f, 0f, 0f);
				Object.Destroy((Object)(object)((Component)obj2).GetComponent<Localizer>());
				Text component = ((Component)obj2).GetComponent<Text>();
				component.text = "Force Retarget";
				component.horizontalOverflow = (HorizontalWrapMode)1;
				UIButton component2 = obj.GetComponent<UIButton>();
				component2.tips.tipTitle = "[RailgunsRetargetMini]";
				component2.tips.tipText = "Retarget orbit for all unset ejctors";
				component2.tips.corner = 2;
			}
			((Component)forceRetargetToggle).gameObject.SetActive(!GameMain.sandboxToolsEnabled);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)ex);
		}
	}

	public static void OnDestory()
	{
		UISwitch obj = forceRetargetToggle;
		Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
		forceRetargetToggle = null;
	}

	public static void Onclick(int _)
	{
		Configs.ForceRetargeting = !Configs.ForceRetargeting;
		Plugin.ForceRetargeting.Value = Configs.ForceRetargeting;
		Plugin.Log.LogDebug((object)("ForceRetargeting: " + Configs.ForceRetargeting));
	}
}
public class UIPatch
{
	private static Button ejectorInfoBtn;

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIDESwarmOrbitInfo), "_OnRegEvent")]
	public static void OnRegEvent()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		if ((Object)(object)ejectorInfoBtn == (Object)null)
		{
			ejectorInfoBtn = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Dyson Sphere Editor/Dyson Editor Control Panel/inspector/swarm-orbit-group/icon").AddComponent<Button>();
		}
		if ((Object)(object)ejectorInfoBtn != (Object)null)
		{
			((UnityEvent)ejectorInfoBtn.onClick).AddListener(new UnityAction(Onclick));
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIDESwarmOrbitInfo), "_OnUnregEvent")]
	public static void OnUnregEvent()
	{
		if ((Object)(object)ejectorInfoBtn != (Object)null)
		{
			((UnityEventBase)ejectorInfoBtn.onClick).RemoveAllListeners();
		}
	}

	public static void OnDestory()
	{
		Object.Destroy((Object)(object)ejectorInfoBtn);
		ejectorInfoBtn = null;
	}

	public static void Onclick()
	{
		StarData starData = UIRoot.instance.uiGame.dysonEditor.selection.viewStar;
		int num = UIRoot.instance.uiGame.dysonEditor.selection.selectedSwarmOrbitIds[0];
		if (NebulaCompat.IsClient)
		{
			NebulaCompat.SendPacket(in starData, -num);
		}
		else
		{
			ShowMessage(GetStatus(starData), starData, num);
		}
	}

	public static void ShowMessage(string message, StarData starData, int orbitId)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_0048: Expected O, but got Unknown
		UIMessageBox.Show("Railguns Retarget Mini", message, "Cancel", "Unset All", "Set All", 0, (Response)null, (Response)delegate
		{
			OnResponse(starData, 0);
		}, (Response)delegate
		{
			OnResponse(starData, orbitId);
		});
	}

	public static void OnResponse(StarData starData, int orbitId)
	{
		if (orbitId == 0 && Configs.ForceRetargeting)
		{
			UIMessageBox.Show("Railguns Retarget Mini", "Cannot unset because config.ForceRetargeting = true.", "OK", 1, (Response)null);
			return;
		}
		SetOrbit(starData, orbitId);
		if (NebulaCompat.IsMultiplayer)
		{
			NebulaCompat.SendPacket(in starData, orbitId);
		}
	}

	public static void SetOrbit(StarData starData, int orbitId)
	{
		int num = 0;
		PlanetData[] planets = starData.planets;
		foreach (PlanetData val in planets)
		{
			if (val.factory == null)
			{
				continue;
			}
			FactorySystem factorySystem = val.factory.factorySystem;
			for (int j = 1; j < factorySystem.ejectorCursor; j++)
			{
				if (factorySystem.ejectorPool[j].id == j)
				{
					factorySystem.ejectorPool[j].orbitId = orbitId;
					num++;
				}
			}
		}
		Plugin.Log.LogInfo((object)$"Set {num} ejectors in {starData.displayName} to orbit {orbitId}");
	}

	public static string GetStatus(StarData starData)
	{
		if (starData == null)
		{
			return "";
		}
		int[] array = new int[starData.planets.Length];
		int[] array2 = new int[starData.planets.Length];
		int num = 0;
		for (int i = 0; i < starData.planets.Length; i++)
		{
			if (starData.planets[i] == null || starData.planets[i].factory == null)
			{
				continue;
			}
			FactorySystem factorySystem = starData.planets[i].factory.factorySystem;
			for (int j = 1; j < factorySystem.ejectorCursor; j++)
			{
				if (factorySystem.ejectorPool[j].id == j)
				{
					if (factorySystem.ejectorPool[j].orbitId > 0)
					{
						array[i]++;
					}
					else
					{
						array2[i]++;
					}
					num++;
				}
			}
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("EM-Rail Ejectors status: Total count ").Append(num).AppendLine();
		for (int k = 0; k < starData.planets.Length; k++)
		{
			if (array[k] + array2[k] != 0)
			{
				stringBuilder.Append(starData.planets[k].displayName).Append(": Set ").Append(array[k])
					.Append(", Unset ")
					.Append(array2[k])
					.AppendLine();
			}
		}
		return stringBuilder.ToString();
	}
}
public static class PluginInfo
{
	public const string PLUGIN_GUID = "RailgunsRetargetMini";

	public const string PLUGIN_NAME = "RailgunsRetargetMini";

	public const string PLUGIN_VERSION = "1.3.2";
}