Decompiled source of StinkBong v1.1.2

plugins/com.github.MuttFromMars.StinkBong.dll

Decompiled 3 months 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 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.StinkBong")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("com.github.MuttFromMars.StinkBong")]
[assembly: AssemblyTitle("StinkBong")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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;
		}
	}
}
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 StinkBongMod
{
	[BepInPlugin("com.github.MuttFromMars.StinkBong", "Stink Bong", "1.1.1")]
	public class PrefabRedirector : BaseUnityPlugin
	{
		private sealed class RedirectMap
		{
			private readonly Dictionary<string, string> _m = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "bingbong", "stinkbong" } };

			public bool Try(string id, out string repl)
			{
				repl = null;
				if (string.IsNullOrEmpty(id))
				{
					return false;
				}
				if (_m.TryGetValue(id, out repl))
				{
					return true;
				}
				string text;
				if (!id.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
				{
					text = id;
				}
				else
				{
					text = id.Substring(0, id.Length - 7);
				}
				string text2 = text;
				if ((object)text2 != id && _m.TryGetValue(text2, out repl))
				{
					return true;
				}
				string fileName = Path.GetFileName(text2);
				if (!string.IsNullOrEmpty(fileName))
				{
					return _m.TryGetValue(fileName, out repl);
				}
				return false;
			}
		}

		private sealed class RedirectingPool : IPunPrefabPool
		{
			private readonly IPunPrefabPool _inner;

			public RedirectingPool(IPunPrefabPool inner)
			{
				_inner = inner;
			}

			public GameObject Instantiate(string prefabId, Vector3 position, Quaternion rotation)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				if (Map.Try(prefabId, out string repl))
				{
					prefabId = repl;
				}
				GameObject val = ((_inner != null) ? _inner.Instantiate(prefabId, position, rotation) : null);
				if ((Object)(object)val == (Object)null)
				{
					GameObject val2 = Resources.Load<GameObject>(prefabId) ?? Resources.Load<GameObject>(prefabId + ".prefab");
					if (Object.op_Implicit((Object)(object)val2))
					{
						val = Object.Instantiate<GameObject>(val2, position, rotation);
					}
				}
				return val;
			}

			public void Destroy(GameObject go)
			{
				if (_inner != null)
				{
					_inner.Destroy(go);
				}
				else if (Object.op_Implicit((Object)(object)go))
				{
					Object.Destroy((Object)(object)go);
				}
			}
		}

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

			private object <>2__current;

			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__13(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;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 120)
				{
					IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
					if (prefabPool != null && !(prefabPool is RedirectingPool))
					{
						PhotonNetwork.PrefabPool = (IPunPrefabPool)(object)new RedirectingPool(prefabPool);
					}
					<>2__current = null;
					<>1__state = 1;
					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 _stinkMat;

		private const int TARGET_ITEM_ID = 13;

		private const string STINK_NAME = "STINK BONG";

		private static Sprite s_Icon;

		private static Texture2D s_IconTex;

		private static bool s_LogSwapTex;

		private static bool s_LogSwapSprite;

		private static readonly RedirectMap Map = new RedirectMap();

		private void Awake()
		{
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
				string text = Path.Combine(directoryName, "stinkbong");
				_bundle = (File.Exists(text) ? AssetBundle.LoadFromFile(text) : null);
				AssetBundle bundle = _bundle;
				GameObject val = ((bundle != null) ? bundle.LoadAsset<GameObject>("StinkBong.prefab") : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					RebindShaders(val);
					Material val2 = _bundle.LoadAsset<Material>("M_StinkBong.mat");
					Shader val3 = Shader.Find("W/Character");
					_stinkMat = new Material(val3);
					if (Object.op_Implicit((Object)(object)val2))
					{
						_stinkMat.CopyPropertiesFromMaterial(val2);
					}
					ApplyMaterial(val, _stinkMat);
					RemoveBingBongsVisuals(val);
					NetworkPrefabManager.RegisterNetworkPrefab("stinkbong", val);
				}
				if (Object.op_Implicit((Object)(object)_bundle))
				{
					s_Icon = _bundle.LoadAsset<Sprite>("stinkbong_icon");
					if (!Object.op_Implicit((Object)(object)s_Icon))
					{
						s_IconTex = _bundle.LoadAsset<Texture2D>("stinkbong_icon");
					}
					if (!Object.op_Implicit((Object)(object)s_Icon) && Object.op_Implicit((Object)(object)s_IconTex))
					{
						Rect val4 = default(Rect);
						((Rect)(ref val4))..ctor(0f, 0f, (float)((Texture)s_IconTex).width, (float)((Texture)s_IconTex).height);
						s_Icon = Sprite.Create(s_IconTex, val4, new Vector2(0.5f, 0.5f), 100f);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
			((MonoBehaviour)this).StartCoroutine(EnsureWrappedPool());
			SceneManager.activeSceneChanged += delegate
			{
				((MonoBehaviour)this).StartCoroutine(EnsureWrappedPool());
			};
			_harmony = new Harmony("com.github.MuttFromMars.StinkBong");
			Type type = AccessTools.TypeByName("Item");
			if (type != null)
			{
				TryPostfix(type, "GetName", "Postfix_Item_GetName");
				TryPostfix(type, "GetIcon", "Postfix_Item_GetIcon");
			}
			Type type2 = AccessTools.TypeByName("ItemUIData") ?? AccessTools.TypeByName("ItemUI");
			if (type2 != null)
			{
				TryPostfix(type2, "GetName", "Postfix_GetName_ById");
				MethodInfo methodInfo = AccessTools.Method(type2, "GetIcon", Type.EmptyTypes, (Type[])null);
				if (methodInfo != null)
				{
					string text2 = ((methodInfo.ReturnType == typeof(Texture2D)) ? "Postfix_UI_GetIcon_Tex" : "Postfix_UI_GetIcon_Sprite");
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PrefabRedirector), text2, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			Type type3 = AccessTools.TypeByName("ItemData") ?? AccessTools.TypeByName("ItemDefinition");
			if (type3 != null)
			{
				TryPostfix(type3, "GetName", "Postfix_GetName_ById");
			}
			TryPrefix(typeof(PhotonNetwork), "Instantiate", "Prefix_Photon_Instantiate", new Type[5]
			{
				typeof(string),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(byte),
				typeof(object[])
			});
			TryPrefix(typeof(NetworkPrefabManager), "SpawnNetworkPrefab", "Prefix_SpawnNetworkPrefab", new Type[5]
			{
				typeof(string),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(byte),
				typeof(object[])
			});
		}

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

		private void TryPrefix(Type t, string name, string prefix, Type[] args)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(t, name, args, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PrefabRedirector), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private void TryPostfix(Type t, string name, string postfix)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(t, name, Type.EmptyTypes, (Type[])null);
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PrefabRedirector), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void RebindShaders(GameObject root)
		{
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				if (sharedMaterials == null)
				{
					continue;
				}
				foreach (Material val2 in sharedMaterials)
				{
					if (Object.op_Implicit((Object)(object)val2))
					{
						Shader val3 = Shader.Find(Object.op_Implicit((Object)(object)val2.shader) ? ((Object)val2.shader).name : "");
						if (Object.op_Implicit((Object)(object)val3) && (Object)(object)val3 != (Object)(object)val2.shader)
						{
							val2.shader = val3;
						}
					}
				}
			}
		}

		private static void ApplyMaterial(GameObject root, Material mat)
		{
			if (!Object.op_Implicit((Object)(object)root) || !Object.op_Implicit((Object)(object)mat))
			{
				return;
			}
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer) && !(val is TrailRenderer) && !(val is LineRenderer))
				{
					Material[] sharedMaterials = val.sharedMaterials;
					if (sharedMaterials == null || sharedMaterials.Length == 0)
					{
						val.sharedMaterial = mat;
						continue;
					}
					Array.Fill(sharedMaterials, mat);
					val.sharedMaterials = sharedMaterials;
				}
			}
		}

		private static void RemoveBingBongsVisuals(GameObject go)
		{
			Type type = AccessTools.TypeByName("BingBongsVisuals");
			if (type == null)
			{
				return;
			}
			Component[] componentsInChildren = go.GetComponentsInChildren(type, true);
			Component[] array = componentsInChildren;
			foreach (Component val in array)
			{
				if (val != null)
				{
					Component val2 = val;
					Object.Destroy((Object)(object)val2);
				}
			}
		}

		public static void Postfix_Item_GetName(object __instance, ref string __result)
		{
			if (GetId(__instance) == 13)
			{
				__result = "STINK BONG";
			}
		}

		public static void Postfix_GetName_ById(object __instance, ref string __result)
		{
			if (GetId(__instance) == 13)
			{
				__result = "STINK BONG";
			}
		}

		public static void Postfix_Item_GetIcon(object __instance, ref Sprite __result)
		{
			if (GetId(__instance) == 13 && Object.op_Implicit((Object)(object)s_Icon))
			{
				__result = s_Icon;
			}
		}

		public static void Postfix_UI_GetIcon_Tex(object __instance, ref Texture2D __result)
		{
			if (GetId(__instance) == 13)
			{
				if (Object.op_Implicit((Object)(object)s_Icon) && Object.op_Implicit((Object)(object)s_Icon.texture))
				{
					__result = s_Icon.texture;
					if (!s_LogSwapTex)
					{
						s_LogSwapTex = true;
						Debug.Log((object)"[UI] Replaced storage icon (Texture2D).");
					}
				}
				else if (Object.op_Implicit((Object)(object)s_IconTex))
				{
					__result = s_IconTex;
					if (!s_LogSwapTex)
					{
						s_LogSwapTex = true;
						Debug.Log((object)"[UI] Replaced storage icon (Texture2D, direct).");
					}
				}
			}
			else if (Object.op_Implicit((Object)(object)__result) && NameLooksLikeBing(((Object)__result).name))
			{
				if (Object.op_Implicit((Object)(object)s_Icon) && Object.op_Implicit((Object)(object)s_Icon.texture))
				{
					__result = s_Icon.texture;
				}
				else if (Object.op_Implicit((Object)(object)s_IconTex))
				{
					__result = s_IconTex;
				}
			}
		}

		public static void Postfix_UI_GetIcon_Sprite(object __instance, ref Sprite __result)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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)
			if (GetId(__instance) == 13)
			{
				if (Object.op_Implicit((Object)(object)s_Icon))
				{
					__result = s_Icon;
					if (!s_LogSwapSprite)
					{
						s_LogSwapSprite = true;
						Debug.Log((object)"[UI] Replaced backpack icon (Sprite).");
					}
				}
				else if (Object.op_Implicit((Object)(object)s_IconTex))
				{
					Rect val = default(Rect);
					((Rect)(ref val))..ctor(0f, 0f, (float)((Texture)s_IconTex).width, (float)((Texture)s_IconTex).height);
					__result = Sprite.Create(s_IconTex, val, new Vector2(0.5f, 0.5f), 100f);
				}
			}
			else if (Object.op_Implicit((Object)(object)__result) && NameLooksLikeBing(((Object)__result).name))
			{
				if (Object.op_Implicit((Object)(object)s_Icon))
				{
					__result = s_Icon;
				}
				else if (Object.op_Implicit((Object)(object)s_IconTex))
				{
					Rect val2 = default(Rect);
					((Rect)(ref val2))..ctor(0f, 0f, (float)((Texture)s_IconTex).width, (float)((Texture)s_IconTex).height);
					__result = Sprite.Create(s_IconTex, val2, new Vector2(0.5f, 0.5f), 100f);
				}
			}
		}

		private static int GetId(object o)
		{
			if (o == null)
			{
				return -1;
			}
			Type type = o.GetType();
			string[] array = new string[5] { "itemID", "ItemID", "id", "Id", "ID" };
			foreach (string name in array)
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					try
					{
						return Convert.ToInt32(field.GetValue(o));
					}
					catch
					{
					}
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanRead)
				{
					try
					{
						return Convert.ToInt32(property.GetValue(o));
					}
					catch
					{
					}
				}
			}
			string[] array2 = new string[6] { "item", "Item", "data", "Data", "def", "Def" };
			foreach (string name2 in array2)
			{
				FieldInfo field2 = type.GetField(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 != null)
				{
					object value = field2.GetValue(o);
					int id = GetId(value);
					if (id >= 0)
					{
						return id;
					}
				}
				PropertyInfo property2 = type.GetProperty(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property2 != null && property2.CanRead)
				{
					object value2 = property2.GetValue(o);
					int id2 = GetId(value2);
					if (id2 >= 0)
					{
						return id2;
					}
				}
			}
			return -1;
		}

		private static bool NameLooksLikeBing(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return false;
			}
			s = s.Replace(" ", "").Replace("_", "").ToLowerInvariant();
			return s.Contains("bingbong");
		}

		private static string R(string id)
		{
			if (!Map.Try(id, out string repl))
			{
				return id;
			}
			return repl;
		}

		public static bool Prefix_Photon_Instantiate(ref string prefabName, Vector3 pos, Quaternion rot, byte group, object[] data)
		{
			prefabName = R(prefabName);
			return true;
		}

		public static bool Prefix_SpawnNetworkPrefab(ref string prefabId, Vector3 pos, Quaternion rot, byte group, object[] data)
		{
			prefabId = R(prefabId);
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}