Decompiled source of HangarShip v1.3.0

Mods/HangarShip.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using HangarShip;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppKeepsake;
using Il2CppSystem;
using Il2CppSystem.Reflection;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "HangarShip", "1.3.0", "Isaac", null)]
[assembly: MelonGame(null, null)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HangarShip")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HangarShip")]
[assembly: AssemblyTitle("HangarShip")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HangarShip
{
	public class Mod : MelonMod
	{
		private MelonPreferences_Entry<bool> _auto;

		private MelonPreferences_Entry<bool> _interior;

		private MelonPreferences_Entry<int> _layer;

		private MelonPreferences_Entry<string> _key;

		private float _nextCheck;

		private string _lastSig = "";

		private float _nextSync;

		private readonly List<(MeshCollider col, MeshRenderer mr, MeshFilter mf, int owner)> _mine = new List<(MeshCollider, MeshRenderer, MeshFilter, int)>();

		private readonly List<int> _seen = new List<int>();

		private int _curId;

		private string _lastIds = "";

		public override void OnInitializeMelon()
		{
			MelonPreferences_Category val = MelonPreferences.CreateCategory("HangarShip");
			_auto = val.CreateEntry<bool>("AutoCollision", true, "Automatically add collision to the hangar ship model, and again whenever the ship model changes", (string)null, false, false, (ValueValidator)null, (string)null);
			_interior = val.CreateEntry<bool>("IncludeInterior", true, "Also add collision to the ship interior", (string)null, false, false, (ValueValidator)null, (string)null);
			_layer = val.CreateEntry<int>("Layer", -1, "Physics layer for the new colliders (-1 = copy the most common layer of the hangar's existing colliders)", (string)null, false, false, (ValueValidator)null, (string)null);
			_key = val.CreateEntry<string>("RefreshKey", "F11", "Key that re-applies collision right now", (string)null, false, false, (ValueValidator)null, (string)null);
			((MelonBase)this).LoggerInstance.Msg("HangarShip ready.");
		}

		public override void OnUpdate()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Keyboard current = Keyboard.current;
				if (current != null)
				{
					_ = ((ButtonControl)current[(Key)103]).wasPressedThisFrame;
				}
				if (current != null && Enum.TryParse<Key>(_key.Value, ignoreCase: true, out Key result) && ((ButtonControl)current[result]).wasPressedThisFrame)
				{
					Apply(force: true);
					return;
				}
				if (Time.unscaledTime >= _nextSync)
				{
					_nextSync = Time.unscaledTime + 0.5f;
					Il2CppArrayBase<CinematicShipReference> val = Object.FindObjectsOfType<CinematicShipReference>(true);
					StringBuilder stringBuilder = new StringBuilder();
					foreach (CinematicShipReference item in val)
					{
						stringBuilder.Append(((Object)item).GetInstanceID()).Append(',');
					}
					string text = stringBuilder.ToString();
					if (text != _lastIds)
					{
						_lastIds = text;
						UpdateCurrent(Il2CppArrayBase<CinematicShipReference>.op_Implicit(val));
						if (_auto.Value && val.Length > 0)
						{
							Apply(force: true);
						}
					}
					Sync();
				}
				if (_auto.Value && !(Time.unscaledTime < _nextCheck))
				{
					_nextCheck = Time.unscaledTime + 2f;
					Apply(force: false);
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("update: " + ex.Message);
			}
		}

		private static string Signature(CinematicShipReference[] refs)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (CinematicShipReference val in refs)
			{
				int num = 0;
				foreach (MeshRenderer componentsInChild in ((Component)val).GetComponentsInChildren<MeshRenderer>(false))
				{
					if (((Renderer)componentsInChild).enabled && !((Renderer)componentsInChild).forceRenderingOff && ((Component)componentsInChild).gameObject.activeInHierarchy)
					{
						num++;
					}
				}
				stringBuilder.Append(((Object)val).GetInstanceID()).Append(':').Append(num)
					.Append(';');
			}
			return stringBuilder.ToString();
		}

		private void Probe()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Invalid comparison between Unknown and I4
			try
			{
				Camera main = Camera.main;
				if ((Object)(object)main == (Object)null)
				{
					((MelonBase)this).LoggerInstance.Msg("PROBE no camera");
					return;
				}
				Il2CppStructArray<RaycastHit> val = Physics.RaycastAll(((Component)main).transform.position, ((Component)main).transform.forward, 60f);
				((MelonBase)this).LoggerInstance.Msg("PROBE cur=" + _curId + " hits=" + ((Il2CppArrayBase<RaycastHit>)(object)val).Length);
				foreach (RaycastHit item in (Il2CppArrayBase<RaycastHit>)(object)val)
				{
					RaycastHit current = item;
					Collider collider = ((RaycastHit)(ref current)).collider;
					GameObject gameObject = ((Component)collider).gameObject;
					string text = ((Object)gameObject).name;
					Transform parent = gameObject.transform.parent;
					int num = 0;
					while ((Object)(object)parent != (Object)null && num++ < 5)
					{
						text = ((Object)parent).name + "/" + text;
						parent = parent.parent;
					}
					CinematicShipReference componentInParent = gameObject.GetComponentInParent<CinematicShipReference>();
					bool flag = false;
					foreach (var item2 in _mine)
					{
						if ((Object)(object)item2.col != (Object)null && ((Il2CppObjectBase)item2.col).Pointer == ((Il2CppObjectBase)collider).Pointer)
						{
							flag = true;
							break;
						}
					}
					MeshRenderer component = gameObject.GetComponent<MeshRenderer>();
					((MelonBase)this).LoggerInstance.Msg("PROBE d=" + ((RaycastHit)(ref current)).distance.ToString("F1") + " " + ((MemberInfo)((Object)collider).GetIl2CppType()).Name + " " + text + " layer=" + gameObject.layer + " trig=" + collider.isTrigger + " ours=" + flag + " ref=" + (((Object)(object)componentInParent == (Object)null) ? "none" : ((Object)componentInParent).GetInstanceID().ToString()) + " rend=" + (((Object)(object)component == (Object)null) ? "none" : ((Renderer)component).enabled.ToString()));
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("probe: " + ex.Message);
			}
			try
			{
				foreach (CinematicShipReference item3 in Object.FindObjectsOfType<CinematicShipReference>(true))
				{
					int num2 = 0;
					int num3 = 0;
					int num4 = 0;
					int num5 = 0;
					int num6 = 0;
					int num7 = 0;
					int num8 = 0;
					Dictionary<int, int> dictionary = new Dictionary<int, int>();
					foreach (MeshRenderer componentsInChild in ((Component)item3).GetComponentsInChildren<MeshRenderer>(true))
					{
						num2++;
						if (((Renderer)componentsInChild).enabled && ((Component)componentsInChild).gameObject.activeInHierarchy)
						{
							num3++;
						}
						if (((Renderer)componentsInChild).forceRenderingOff)
						{
							num4++;
						}
						if (((Renderer)componentsInChild).isVisible)
						{
							num5++;
						}
						if ((int)((Renderer)componentsInChild).shadowCastingMode == 3)
						{
							num6++;
						}
						dictionary.TryGetValue(((Component)componentsInChild).gameObject.layer, out var value);
						dictionary[((Component)componentsInChild).gameObject.layer] = value + 1;
						MeshCollider component2 = ((Component)componentsInChild).GetComponent<MeshCollider>();
						if ((Object)(object)component2 != (Object)null)
						{
							num7++;
							if (((Collider)component2).enabled && ((Component)componentsInChild).gameObject.activeInHierarchy)
							{
								num8++;
							}
						}
					}
					StringBuilder stringBuilder = new StringBuilder();
					foreach (KeyValuePair<int, int> item4 in dictionary)
					{
						stringBuilder.Append(item4.Key).Append('=').Append(item4.Value)
							.Append(' ');
					}
					((MelonBase)this).LoggerInstance.Msg("PROBE3 ref=" + ((Object)item3).GetInstanceID() + ((((Object)item3).GetInstanceID() == _curId) ? " (CUR)" : "") + " rend=" + num2 + " enabled=" + num3 + " forceOff=" + num4 + " isVisible=" + num5 + " shadowOnly=" + num6 + " cols=" + num7 + " colsOn=" + num8 + " layers: " + stringBuilder);
					for (int i = 0; i < ((Component)item3).transform.childCount; i++)
					{
						Transform child = ((Component)item3).transform.GetChild(i);
						int num9 = 0;
						int num10 = 0;
						for (int j = 0; j < child.childCount; j++)
						{
							num9++;
							if (((Component)child.GetChild(j)).gameObject.activeSelf)
							{
								num10++;
							}
						}
						((MelonBase)this).LoggerInstance.Msg("PROBE3    " + ((Object)child).name + " self=" + ((Component)child).gameObject.activeSelf + " kids=" + num9 + " kidsActive=" + num10);
					}
				}
			}
			catch (Exception ex2)
			{
				((MelonBase)this).LoggerInstance.Warning("probe3: " + ex2.Message);
			}
			try
			{
				Camera main2 = Camera.main;
				if ((Object)(object)main2 == (Object)null)
				{
					return;
				}
				Il2CppReferenceArray<Collider> val2 = Physics.OverlapSphere(((Component)main2).transform.position, 6f);
				((MelonBase)this).LoggerInstance.Msg("PROBE2 near=" + ((Il2CppArrayBase<Collider>)(object)val2).Length + " cam=" + ((object)((Component)main2).transform.position/*cast due to .constrained prefix*/).ToString());
				int num11 = 0;
				foreach (Collider item5 in (Il2CppArrayBase<Collider>)(object)val2)
				{
					if (item5.isTrigger)
					{
						continue;
					}
					GameObject gameObject2 = ((Component)item5).gameObject;
					string text2 = ((Object)gameObject2).name;
					Transform parent2 = gameObject2.transform.parent;
					int num12 = 0;
					while ((Object)(object)parent2 != (Object)null && num12++ < 4)
					{
						text2 = ((Object)parent2).name + "/" + text2;
						parent2 = parent2.parent;
					}
					CinematicShipReference componentInParent2 = gameObject2.GetComponentInParent<CinematicShipReference>();
					bool flag2 = false;
					foreach (var item6 in _mine)
					{
						if ((Object)(object)item6.col != (Object)null && ((Il2CppObjectBase)item6.col).Pointer == ((Il2CppObjectBase)item5).Pointer)
						{
							flag2 = true;
							break;
						}
					}
					MeshRenderer component3 = gameObject2.GetComponent<MeshRenderer>();
					((MelonBase)this).LoggerInstance.Msg("PROBE2 " + ((MemberInfo)((Object)item5).GetIl2CppType()).Name + " " + text2 + " layer=" + gameObject2.layer + " ours=" + flag2 + " ref=" + (((Object)(object)componentInParent2 == (Object)null) ? "none" : ((Object)componentInParent2).GetInstanceID().ToString()) + " colEn=" + item5.enabled + " rend=" + (((Object)(object)component3 == (Object)null) ? "none" : (((Renderer)component3).enabled + "/off=" + ((Renderer)component3).forceRenderingOff)));
					if (++num11 >= 40)
					{
						break;
					}
				}
			}
			catch (Exception ex3)
			{
				((MelonBase)this).LoggerInstance.Warning("probe2: " + ex3.Message);
			}
		}

		private void UpdateCurrent(CinematicShipReference[] refs)
		{
			HashSet<int> alive = new HashSet<int>();
			List<int> list = new List<int>();
			for (int i = 0; i < refs.Length; i++)
			{
				int instanceID = ((Object)refs[i]).GetInstanceID();
				alive.Add(instanceID);
				if (!_seen.Contains(instanceID))
				{
					list.Add(instanceID);
				}
			}
			_seen.RemoveAll((int id) => !alive.Contains(id));
			list.Sort();
			for (int num = list.Count - 1; num >= 0; num--)
			{
				_seen.Add(list[num]);
			}
			_curId = ((_seen.Count > 0) ? _seen[_seen.Count - 1] : 0);
		}

		private void Sync()
		{
			for (int num = _mine.Count - 1; num >= 0; num--)
			{
				try
				{
					var (val, val2, val3, _) = _mine[num];
					if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
					{
						_mine.RemoveAt(num);
					}
					else
					{
						bool flag = ((Renderer)val2).enabled && !((Renderer)val2).forceRenderingOff && ((Component)val2).gameObject.activeInHierarchy;
						if (((Collider)val).enabled != flag)
						{
							((Collider)val).enabled = flag;
						}
						Mesh sharedMesh = val3.sharedMesh;
						if (flag && (Object)(object)sharedMesh != (Object)null && (Object)(object)val.sharedMesh != (Object)(object)sharedMesh)
						{
							val.sharedMesh = sharedMesh;
						}
					}
				}
				catch
				{
					_mine.RemoveAt(num);
				}
			}
		}

		private void Apply(bool force)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			Il2CppArrayBase<CinematicShipReference> val = Object.FindObjectsOfType<CinematicShipReference>(true);
			if (val == null || val.Length == 0)
			{
				_lastSig = "";
				return;
			}
			string text = Signature(Il2CppArrayBase<CinematicShipReference>.op_Implicit(val));
			if (!force && text == _lastSig)
			{
				return;
			}
			int num = _layer.Value;
			if (num < 0)
			{
				Dictionary<int, int> dictionary = new Dictionary<int, int>();
				foreach (MeshCollider item in Object.FindObjectsOfType<MeshCollider>(true))
				{
					if (((Collider)item).isTrigger)
					{
						continue;
					}
					Scene scene = ((Component)item).gameObject.scene;
					if (((Scene)(ref scene)).name.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					bool flag = false;
					foreach (CinematicShipReference item2 in val)
					{
						if (((Component)item).transform.IsChildOf(((Component)item2).transform))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						int layer = ((Component)item).gameObject.layer;
						if (layer != 13 && layer != 31 && layer != 7 && layer != 20)
						{
							dictionary.TryGetValue(layer, out var value);
							dictionary[layer] = value + 1;
						}
					}
				}
				int num2 = 0;
				int num3 = -1;
				foreach (KeyValuePair<int, int> item3 in dictionary)
				{
					if (item3.Value > num3)
					{
						num2 = item3.Key;
						num3 = item3.Value;
					}
				}
				num = num2;
			}
			int num4 = 0;
			foreach (CinematicShipReference item4 in val)
			{
				foreach (MeshRenderer componentsInChild in ((Component)item4).GetComponentsInChildren<MeshRenderer>(true))
				{
					try
					{
						GameObject gameObject = ((Component)componentsInChild).gameObject;
						string name = ((Object)gameObject).name;
						if (name.IndexOf("_Lod1", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("_Lod2", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("_Lod3", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							continue;
						}
						if (_interior.Value)
						{
							goto IL_0272;
						}
						Transform val2 = gameObject.transform;
						bool flag2 = false;
						int num5 = 0;
						while ((Object)(object)val2 != (Object)null && num5++ < 20)
						{
							if (((Object)val2).name.StartsWith("Interior"))
							{
								flag2 = true;
								break;
							}
							val2 = val2.parent;
						}
						if (!flag2)
						{
							goto IL_0272;
						}
						goto end_IL_01ce;
						IL_0272:
						if ((Object)(object)gameObject.GetComponent<Collider>() != (Object)null)
						{
							continue;
						}
						MeshFilter component = gameObject.GetComponent<MeshFilter>();
						if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null))
						{
							Bounds bounds = ((Renderer)componentsInChild).bounds;
							Vector3 size = ((Bounds)(ref bounds)).size;
							if (!(Mathf.Max(size.x, Mathf.Max(size.y, size.z)) < 0.3f))
							{
								MeshCollider val3 = gameObject.AddComponent<MeshCollider>();
								val3.sharedMesh = component.sharedMesh;
								gameObject.layer = num;
								((Collider)val3).enabled = ((Renderer)componentsInChild).enabled && !((Renderer)componentsInChild).forceRenderingOff && gameObject.activeInHierarchy;
								_mine.Add((val3, componentsInChild, component, ((Object)item4).GetInstanceID()));
								num4++;
							}
						}
						end_IL_01ce:;
					}
					catch
					{
					}
				}
			}
			_lastSig = Signature(Il2CppArrayBase<CinematicShipReference>.op_Implicit(val));
			if (num4 > 0)
			{
				((MelonBase)this).LoggerInstance.Msg("Added " + num4 + " colliders (" + val.Length + " ship instance(s), current " + _curId + ") (layer " + num + ")");
			}
		}
	}
}