Decompiled source of PEAKMeneBong v1.2.3

com.github.muttfrommars.PeakMeneBong.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.muttfrommars.PeakMeneBong")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("com.github.muttfrommars.PeakMeneBong")]
[assembly: AssemblyTitle("MeneBong")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
[BepInPlugin("com.github.muttfrommars.PeakMeneBong", "MeneBong", "1.2.0")]
public class PrefabRedirector : BaseUnityPlugin
{
	private sealed class RedirectingPool : IPunPrefabPool
	{
		private readonly IPunPrefabPool _inner;

		private readonly RedirectMap _map;

		private readonly ManualLogSource _log;

		public RedirectingPool(IPunPrefabPool inner, RedirectMap map, ManualLogSource log)
		{
			_inner = inner;
			_map = map;
			_log = log;
		}

		public GameObject Instantiate(string prefabId, Vector3 position, Quaternion rotation)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			string text = prefabId;
			int num = text.LastIndexOfAny(new char[2] { '/', '\\' });
			if (num >= 0)
			{
				string text2 = text;
				int num2 = num + 1;
				text = text2.Substring(num2, text2.Length - num2);
			}
			if (text.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
			{
				string text2 = text;
				text = text2.Substring(0, text2.Length - 7);
			}
			if (string.Equals(text, "bingbong", StringComparison.OrdinalIgnoreCase))
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)("[Redirector/Pool] '" + prefabId + "' -> 'menebong'"));
				}
				prefabId = "menebong";
			}
			else
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogInfo((object)("[Redirector/Pool] requested '" + prefabId + "' (no redirect)"));
				}
			}
			return _inner.Instantiate(prefabId, position, rotation);
		}

		public void Destroy(GameObject gameObject)
		{
			_inner.Destroy(gameObject);
		}
	}

	public sealed class RedirectMap
	{
		private readonly Dictionary<string, string> _mapCI;

		public RedirectMap(Dictionary<string, string> mapCI)
		{
			_mapCI = mapCI;
		}

		public bool TryRedirect(string id, out string replacement)
		{
			if (id == null)
			{
				replacement = null;
				return false;
			}
			if (_mapCI.TryGetValue(id, out replacement))
			{
				return true;
			}
			string text;
			if (!id.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
			{
				text = id;
			}
			else
			{
				string text2 = id;
				text = text2.Substring(0, text2.Length - 7);
			}
			string text3 = text;
			if ((object)text3 != id && _mapCI.TryGetValue(text3, out replacement))
			{
				return true;
			}
			int num = text3.LastIndexOfAny(new char[2] { '/', '\\' });
			if (num >= 0)
			{
				string text2 = text3;
				int num2 = num + 1;
				string key = text2.Substring(num2, text2.Length - num2);
				if (_mapCI.TryGetValue(key, out replacement))
				{
					return true;
				}
			}
			replacement = null;
			return false;
		}

		public bool TryRedirectByTrailingSegment(string path, out string replacement)
		{
			replacement = null;
			if (string.IsNullOrEmpty(path))
			{
				return false;
			}
			int num = path.LastIndexOfAny(new char[2] { '/', '\\' });
			if (num < 0)
			{
				return false;
			}
			int num2 = num + 1;
			string id = path.Substring(num2, path.Length - num2);
			return TryRedirect(id, out replacement);
		}
	}

	[CompilerGenerated]
	private sealed class <EnsureWrappedPool>d__7 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public PrefabRedirector <>4__this;

		private int <i>5__2;

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

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

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

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

		private bool MoveNext()
		{
			int num = <>1__state;
			PrefabRedirector prefabRedirector = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<i>5__2 = 0;
				goto IL_0059;
			case 1:
				<>1__state = -1;
				<i>5__2++;
				goto IL_0059;
			case 2:
				{
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				IL_0059:
				if (<i>5__2 < 30)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				prefabRedirector.WrapIfNeeded();
				<i>5__2 = 0;
				break;
			}
			if (<i>5__2 < 300)
			{
				if (prefabRedirector.WrapIfNeeded())
				{
					((BaseUnityPlugin)prefabRedirector).Logger.LogInfo((object)"[Redirector] Re-wrapped pool after a late swap.");
				}
				<>2__current = null;
				<>1__state = 2;
				return true;
			}
			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 AssetBundle _bundle;

	private Harmony _harmony;

	private Material _menebongMat;

	private Texture2D _menebongTex;

	private static readonly RedirectMap Map = new RedirectMap(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "bingbong", "menebong" } });

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Expected O, but got Unknown
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Expected O, but got Unknown
		Application.logMessageReceived += (LogCallback)delegate(string cond, string stack, LogType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			if ((int)type == 0 || (int)type == 4)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[UnityLog] " + cond));
			}
		};
		try
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string text = Path.Combine(directoryName, "menebong");
			_bundle = (File.Exists(text) ? AssetBundle.LoadFromFile(text) : null);
			if ((Object)(object)_bundle == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Bundle 'menebong' not found (skipping). If 'menebong' is in Resources, this is fine.");
			}
			else
			{
				GameObject val = _bundle.LoadAsset<GameObject>("MeneBong.prefab");
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"MeneBong.prefab not found in bundle.");
				}
				else
				{
					if ((Object)(object)val.GetComponent<PhotonView>() == (Object)null)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"MeneBong.prefab has no PhotonView; add one if this is network-spawned.");
					}
					try
					{
						_menebongMat = _bundle.LoadAsset<Material>("M_MeneBong.mat");
						if ((Object)(object)_menebongMat == (Object)null)
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)"M_MeneBong.mat not found in bundle.");
						}
						if ((Object)(object)_menebongMat != (Object)null)
						{
							string text2 = (((Object)(object)_menebongMat.shader != (Object)null) ? ((Object)_menebongMat.shader).name : "<null>");
							Shader val2 = ((!string.IsNullOrEmpty(text2)) ? Shader.Find(text2) : null);
							if ((Object)(object)_menebongMat.shader == (Object)null || !_menebongMat.shader.isSupported || ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)_menebongMat.shader))
							{
								try
								{
									if ((Object)(object)val2 == (Object)null)
									{
										((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not find runtime shader '" + text2 + "'. Material may render pink if its compiled backend is missing."));
									}
									else
									{
										Material val3 = new Material(val2);
										val3.CopyPropertiesFromMaterial(_menebongMat);
										_menebongMat = val3;
										((BaseUnityPlugin)this).Logger.LogInfo((object)("Rebound MeneBong material to runtime shader '" + ((Object)val2).name + "'."));
									}
								}
								catch (Exception ex)
								{
									((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to rebind MeneBong shader '" + text2 + "': " + ex.Message));
								}
							}
							_menebongTex = _bundle.LoadAsset<Texture2D>("t_menebong.png");
							if ((Object)(object)_menebongTex != (Object)null)
							{
								if (_menebongMat.HasProperty("_BaseMap"))
								{
									_menebongMat.SetTexture("_BaseMap", (Texture)(object)_menebongTex);
								}
								if (_menebongMat.HasProperty("_MainTex"))
								{
									_menebongMat.SetTexture("_MainTex", (Texture)(object)_menebongTex);
								}
							}
						}
						ApplyMenebongMaterial(val, _menebongMat);
						NetworkPrefabManager.RegisterNetworkPrefab("menebong", val);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered 'menebong' with NetworkPrefabManager using M_MeneBong.mat.");
					}
					catch (Exception ex2)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("RegisterNetworkPrefab warning: " + ex2.Message));
					}
				}
			}
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Bundle/load error: {arg}");
		}
		((MonoBehaviour)this).StartCoroutine(EnsureWrappedPool());
		SceneManager.activeSceneChanged += delegate
		{
			((MonoBehaviour)this).StartCoroutine(EnsureWrappedPool());
		};
		_harmony = new Harmony("com.github.muttfrommars.PeakMeneBong");
		TryPatchPhotonInstantiate();
		TryPatchPeakLibSpawn();
		TryPatchResourcesLoad(optional: false);
	}

	private static void ApplyMenebongMaterial(GameObject root, Material mat)
	{
		if ((Object)(object)root == (Object)null || (Object)(object)mat == (Object)null)
		{
			return;
		}
		Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			if (sharedMaterials == null || sharedMaterials.Length == 0)
			{
				val.sharedMaterial = mat;
				continue;
			}
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				sharedMaterials[j] = mat;
			}
			val.sharedMaterials = sharedMaterials;
		}
	}

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

	private bool WrapIfNeeded()
	{
		IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
		if (prefabPool is RedirectingPool)
		{
			return false;
		}
		string text = ((object)prefabPool)?.GetType().FullName ?? "<null>";
		if (prefabPool == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[Redirector] PhotonNetwork.PrefabPool is null; will try later.");
			return false;
		}
		PhotonNetwork.PrefabPool = (IPunPrefabPool)(object)new RedirectingPool(prefabPool, Map, ((BaseUnityPlugin)this).Logger);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[Redirector] Wrapped " + text + " with RedirectingPool."));
		return true;
	}

	private void TryPatchPhotonInstantiate()
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		try
		{
			Type typeFromHandle = typeof(PhotonNetwork);
			MethodInfo methodInfo = AccessTools.Method(typeFromHandle, "Instantiate", new Type[5]
			{
				typeof(string),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(byte),
				typeof(object[])
			}, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PrefabRedirector), "Prefix_Photon_Instantiate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Redirector] Patched PhotonNetwork.Instantiate.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Redirector] PhotonNetwork.Instantiate overload not found (version mismatch?).");
			}
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Patch PhotonNetwork.Instantiate failed: {arg}");
		}
	}

	private void TryPatchPeakLibSpawn()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(NetworkPrefabManager), "SpawnNetworkPrefab", new Type[5]
			{
				typeof(string),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(byte),
				typeof(object[])
			}, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PrefabRedirector), "Prefix_PeakLib_Spawn", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Redirector] Patched NetworkPrefabManager.SpawnNetworkPrefab.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Redirector] NetworkPrefabManager.SpawnNetworkPrefab not found.");
			}
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Patch SpawnNetworkPrefab failed: {arg}");
		}
	}

	private void TryPatchResourcesLoad(bool optional)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		try
		{
			MethodInfo method = typeof(Resources).GetMethod("Load", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
			if (method != null)
			{
				_harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(PrefabRedirector), "Prefix_Resources_Load", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Redirector] Patched Resources.Load(string).");
			}
			else if (!optional)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Redirector] Resources.Load(string) not found (unexpected).");
			}
		}
		catch (Exception arg)
		{
			if (!optional)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Patch Resources.Load failed: {arg}");
			}
		}
	}

	public static bool Prefix_Photon_Instantiate(ref string prefabName, Vector3 position, Quaternion rotation, byte group, object[] data)
	{
		if (Map.TryRedirect(prefabName, out string replacement))
		{
			Debug.Log((object)("[Redirector/Photon] '" + prefabName + "' -> '" + replacement + "'"));
			prefabName = replacement;
		}
		else
		{
			Debug.Log((object)("[Redirector/Photon] requested '" + prefabName + "' (no redirect)"));
		}
		return true;
	}

	public static bool Prefix_PeakLib_Spawn(ref string prefabId, Vector3 position, Quaternion rotation, byte group, object[] data)
	{
		if (Map.TryRedirect(prefabId, out string replacement))
		{
			Debug.Log((object)("[Redirector/PEAK] '" + prefabId + "' -> '" + replacement + "'"));
			prefabId = replacement;
		}
		else
		{
			Debug.Log((object)("[Redirector/PEAK] requested '" + prefabId + "' (no redirect)"));
		}
		return true;
	}

	public static bool Prefix_Resources_Load(ref string path)
	{
		if (Map.TryRedirect(path, out string replacement))
		{
			Debug.Log((object)("[Redirector/Resources] '" + path + "' -> '" + replacement + "'"));
			path = replacement;
		}
		else if (Map.TryRedirectByTrailingSegment(path, out replacement))
		{
			Debug.Log((object)("[Redirector/Resources] (trail) '" + path + "' -> '" + replacement + "'"));
			path = replacement;
		}
		return true;
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}