Decompiled source of TowableBoats v0.2.2

TowableBoats.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[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: AssemblyVersion("0.0.0.0")]
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace TowableBoats;

internal class AssetTools
{
	public static AssetBundle bundle;

	private const string assetDir = "TowableBoats";

	private const string assetFile = "towable_boats.assets";

	public static void LoadAssetBundles()
	{
		string text = Path.Combine(Paths.PluginPath, "TowableBoats", "towable_boats.assets");
		string text2 = Path.Combine(Paths.PluginPath, "towable_boats.assets");
		bundle = AssetBundle.LoadFromFile(File.Exists(text) ? text : text2);
		if ((Object)(object)bundle == (Object)null)
		{
			Debug.LogError((object)"Bundle not loaded! Did you place it in the correct folder?");
		}
		else
		{
			Debug.Log((object)("TowableBoats: loaded bundle " + ((object)bundle).ToString()));
		}
	}
}
internal class BoatPerformancePatches
{
	[HarmonyPatch(typeof(BoatHorizon))]
	private static class BoatHorizonPatch
	{
		[HarmonyPatch("UpdateKinematic")]
		[HarmonyPostfix]
		public static void BoatKinematicPatch(BoatHorizon __instance, ref Rigidbody ___rigidbody)
		{
			if (___rigidbody.isKinematic && GameState.sleeping)
			{
				TowingSet componentInParent = ((Component)__instance).GetComponentInParent<TowingSet>();
				if (componentInParent != null)
				{
					___rigidbody.isKinematic = !componentInParent.PhysicsMode();
				}
			}
		}
	}

	[HarmonyPatch(typeof(BoatPerformanceSwitcher))]
	private static class BoatPerformanceSwitcherPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool BoatPerformaceSwitcherPatch(BoatPerformanceSwitcher __instance, ref Rigidbody ___body, BoatDamage ___damage)
		{
			if ((Object)(object)GameState.lastBoat == (Object)(object)((Component)__instance).transform || ___damage.sunk)
			{
				return true;
			}
			TowingSet componentInParent = ((Component)__instance).GetComponentInParent<TowingSet>();
			if (componentInParent != null)
			{
				Util.InvokePrivate(__instance, "SetPerformanceMode", !componentInParent.PhysicsMode());
				return false;
			}
			return true;
		}
	}
}
[StructLayout(LayoutKind.Sequential, Size = 1)]
public readonly struct CleatDefs
{
	public static readonly Array[] brig = new Array[6]
	{
		new object[4]
		{
			"cleat_stern_left",
			(object)new Vector3(-14.9f, 4.36f, 2.23f),
			(object)new Quaternion(0.7071068f, 0f, 0f, 0.7071068f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_stern_right",
			(object)new Vector3(-14.9f, 4.36f, -2.23f),
			(object)new Quaternion(0.7071068f, 0f, 0f, 0.7071068f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_aft_left",
			(object)new Vector3(-2.3f, 3.53f, 3.27f),
			(object)new Quaternion(-0.7058f, 0.0252f, -0.0246f, 0.7075f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_aft_right",
			(object)new Vector3(-2.3f, 3.53f, -3.27f),
			(object)new Quaternion(-0.7058f, 0.0252f, -0.0246f, 0.7075f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_fore_left",
			(object)new Vector3(4.85f, 3.57f, 3.02f),
			(object)new Quaternion(-0.7041f, 0.0292f, 0.0692f, 0.7061f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_fore_right",
			(object)new Vector3(4.85f, 3.57f, -3.02f),
			(object)new Quaternion(-0.7036f, -0.0384f, 0.0012f, 0.7095f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		}
	};

	public static readonly Array[] sanbuq = new Array[6]
	{
		new object[4]
		{
			"cleat_stern_left",
			(object)new Vector3(-12.08f, 2.12f, 1.48f),
			(object)new Quaternion(0.4912f, -0.5087f, -0.5087f, -0.4912f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_stern_right",
			(object)new Vector3(-12.08f, 2.12f, -1.48f),
			(object)new Quaternion(0.5087f, -0.4912f, -0.4912f, -0.5087f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_aft_left",
			(object)new Vector3(-1.4f, 2.12f, 2.46f),
			(object)new Quaternion(0.7071068f, 0f, 0f, -0.7071068f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_aft_right",
			(object)new Vector3(-1.4f, 2.12f, -2.46f),
			(object)new Quaternion(0.7071068f, 0f, 0f, -0.7071068f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_fore_left",
			(object)new Vector3(4.2f, 2.32f, 2.25f),
			(object)new Quaternion(-0.7071f, 0f, 0.0371f, 0.7061f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_fore_right",
			(object)new Vector3(4.2f, 2.32f, -2.25f),
			(object)new Quaternion(-0.7058f, -0.0432f, 0.0062f, 0.7071f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		}
	};

	public static readonly Array[] junk = new Array[6]
	{
		new object[4]
		{
			"cleat_stern_left",
			(object)new Vector3(-9.7f, 2.27f, 0.8f),
			(object)new Quaternion(0.4731f, -0.5255f, -0.5255f, -0.4731f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_stern_right",
			(object)new Vector3(-9.7f, 2.27f, -0.8f),
			(object)new Quaternion(0.5255f, -0.4731f, -0.4731f, -0.5255f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_aft_left",
			(object)new Vector3(1.24f, 1.01f, 2.52f),
			(object)new Quaternion(0.7071068f, 0f, 0f, -0.7071068f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_aft_right",
			(object)new Vector3(1.24f, 1.01f, -2.52f),
			(object)new Quaternion(0.7071068f, 0f, 0f, -0.7071068f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_fore_left",
			(object)new Vector3(7.68f, 1.1f, 2.02f),
			(object)new Quaternion(-0.7071f, 0.0062f, 0.0309f, 0.7064f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		},
		new object[4]
		{
			"cleat_mid_fore_right",
			(object)new Vector3(7.68f, 1.1f, -2.02f),
			(object)new Quaternion(-0.7064f, -0.0309f, -0.0061f, 0.7071f),
			(object)new Vector3(0.6f, 0.6f, 0.6f)
		}
	};

	public static readonly Array[] cog = new Array[2]
	{
		new object[4]
		{
			"cleat_stern_left",
			(object)new Vector3(6.66f, 2.41f, 1.25f),
			(object)new Quaternion(0.5f, -0.5f, -0.5f, -0.5f),
			(object)new Vector3(0.5f, 0.5f, 0.5f)
		},
		new object[4]
		{
			"cleat_stern_right",
			(object)new Vector3(6.66f, 2.41f, -1.25f),
			(object)new Quaternion(0.5f, -0.5f, -0.5f, -0.5f),
			(object)new Vector3(0.5f, 0.5f, 0.5f)
		}
	};

	public static readonly Array[] dhow = new Array[2]
	{
		new object[4]
		{
			"cleat_stern_left",
			(object)new Vector3(-6.4f, 1.815f, 1.53f),
			(object)new Quaternion(-0.0616f, -0.7044f, -0.7044f, -0.0616f),
			(object)new Vector3(0.5f, 0.5f, 0.5f)
		},
		new object[4]
		{
			"cleat_stern_right",
			(object)new Vector3(-6.4f, 1.815f, -1.53f),
			(object)new Quaternion(-0.0616f, -0.7044f, -0.7044f, -0.0616f),
			(object)new Vector3(0.5f, 0.5f, 0.5f)
		}
	};

	public static readonly Array[] kakam = new Array[2]
	{
		new object[4]
		{
			"cleat_stern_left",
			(object)new Vector3(-6.3f, 2.86f, 0.64f),
			(object)new Quaternion(0.6744f, 0.2126f, 0.2126f, -0.6744f),
			(object)new Vector3(0.5f, 0.5f, 0.5f)
		},
		new object[4]
		{
			"cleat_stern_right",
			(object)new Vector3(-6.3f, 2.86f, -0.64f),
			(object)new Quaternion(0.6744f, -0.2126f, -0.2126f, -0.6744f),
			(object)new Vector3(0.5f, 0.5f, 0.5f)
		}
	};
}
internal class MooringPatches
{
	[HarmonyPatch(typeof(MooringSet))]
	private static class MooringSetPatches
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void MooringComponentPatch(MooringSet __instance)
		{
			((Component)((Component)__instance).transform.parent).gameObject.AddComponent<TowingSet>();
		}
	}

	[HarmonyPatch(typeof(PickupableBoatMooringRope))]
	private static class BoatMooringRopePatches
	{
		[HarmonyPatch("MoorTo")]
		[HarmonyPostfix]
		public static void MoorToPatch(PickupableBoatMooringRope __instance, GPButtonDockMooring mooring, Rigidbody ___boatRigidbody)
		{
			if (((Component)mooring).gameObject.CompareTag("Boat"))
			{
				TowingSet component = ((Component)___boatRigidbody).GetComponent<TowingSet>();
				TowingSet componentInParent = ((Component)mooring).GetComponentInParent<TowingSet>();
				if (componentInParent != null && (!component.towed || (Object)(object)componentInParent == (Object)(object)component.GetTowedBy()))
				{
					component.UpdateTowedBy();
					componentInParent.UpdateTowedBoats();
				}
			}
		}

		[HarmonyPatch("ThrowRopeTo")]
		[HarmonyPrefix]
		public static bool ThrowRopeToPatch(PickupableBoatMooringRope __instance, GPButtonDockMooring mooring, Rigidbody ___boatRigidbody)
		{
			if (((Component)mooring).gameObject.CompareTag("Boat"))
			{
				if ((Object)(object)((Component)___boatRigidbody).transform != (Object)(object)((Component)((Component)mooring).GetComponentInParent<TowingSet>()).transform)
				{
					__instance.MoorTo(mooring);
				}
				return false;
			}
			return true;
		}

		[HarmonyPatch("Unmoor")]
		[HarmonyPrefix]
		public static void UnmoorPatch(SpringJoint ___mooredToSpring, ref TowingSet __state)
		{
			if ((Object)(object)___mooredToSpring != (Object)null)
			{
				TowingSet componentInParent = ((Component)___mooredToSpring).GetComponentInParent<TowingSet>();
				if (componentInParent != null)
				{
					__state = componentInParent;
				}
			}
		}

		[HarmonyPatch("Unmoor")]
		[HarmonyPostfix]
		public static void UnmoorPostPatch(TowingSet __state, Rigidbody ___boatRigidbody)
		{
			if (Object.op_Implicit((Object)(object)__state))
			{
				__state.UpdateTowedBoats();
			}
			((Component)___boatRigidbody).GetComponent<TowingSet>().UpdateTowedBy();
		}
	}

	[HarmonyPatch(typeof(BoatMooringRopes))]
	private static class BoatMooringRopesPatches
	{
		[HarmonyPatch("UnmoorAllRopes")]
		[HarmonyPostfix]
		public static void UnmoorAllRopesPatch(BoatMooringRopes __instance)
		{
			TowingSet componentInParent = ((Component)__instance).GetComponentInParent<TowingSet>();
			if (componentInParent == null || componentInParent.GetCleats() == null)
			{
				return;
			}
			GPButtonDockMooring[] cleats = componentInParent.GetCleats();
			for (int i = 0; i < cleats.Length; i++)
			{
				PickupableBoatMooringRope componentInChildren = ((Component)cleats[i]).GetComponentInChildren<PickupableBoatMooringRope>();
				if (componentInChildren != null)
				{
					componentInChildren.Unmoor();
					componentInChildren.ResetRopePos();
				}
			}
		}
	}
}
[BepInPlugin("com.nandbrew.towableboats", "Towable Boats", "0.2.2")]
public class Plugin : BaseUnityPlugin
{
	public const string PLUGIN_ID = "com.nandbrew.towableboats";

	public const string PLUGIN_NAME = "Towable Boats";

	public const string PLUGIN_VERSION = "0.2.2";

	internal static ConfigEntry<int> performanceMode;

	internal static ConfigEntry<bool> drag;

	internal static ConfigEntry<bool> smallBoats;

	internal static Plugin instance;

	private void Awake()
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Expected O, but got Unknown
		instance = this;
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.nandbrew.towableboats");
		performanceMode = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "Performance mode", 1, new ConfigDescription("How many boats in the chain behind the current boat get full physics", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 2
			}
		}));
		drag = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Drag", false, new ConfigDescription("Allow boats to pull on the boat towing them (buggy)", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			}
		}));
		smallBoats = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Small boats can tow", true, new ConfigDescription("Add anchor points to small boats", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				IsAdvanced = false,
				Order = 1
			}
		}));
		AssetTools.LoadAssetBundles();
	}
}
internal class SleepPatches
{
	[HarmonyPatch(typeof(Sleep), "CurrentBoatIsMoored")]
	private static class IsMooredPatch
	{
		[HarmonyPostfix]
		public static void Postfix(ref bool __result)
		{
			if (Object.op_Implicit((Object)(object)GameState.currentBoat) && __result && ((Component)GameState.currentBoat).GetComponentInParent<TowingSet>().towed)
			{
				__result = false;
			}
		}
	}
}
internal class TowingSet : MonoBehaviour
{
	private TowingSet towedBy;

	private List<TowingSet> towedBoats;

	public bool towing;

	public bool towed;

	private GPButtonDockMooring[] cleats;

	public bool smallBoat;

	private BoatMooringRopes mooringRopes;

	public List<TowingSet> GetTowedBoats()
	{
		return towedBoats;
	}

	public TowingSet GetTowedBy()
	{
		return towedBy;
	}

	public GPButtonDockMooring[] GetCleats()
	{
		return cleats;
	}

	private void Awake()
	{
		mooringRopes = ((Component)this).GetComponent<BoatMooringRopes>();
		Transform val = ((Component)this).transform.Find("towing set");
		if (val != null)
		{
			if ((Object)(object)((Component)val).GetComponent<BoatPartOption>() == (Object)null)
			{
				((Component)val).gameObject.SetActive(true);
			}
			cleats = ((Component)val).GetComponentsInChildren<GPButtonDockMooring>();
		}
		else
		{
			AddCleats();
		}
	}

	private void FixedUpdate()
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		if (GameState.justStarted)
		{
			UpdateTowedBoats();
			UpdateTowedBy();
		}
		if (cleats == null)
		{
			return;
		}
		if (Plugin.drag.Value)
		{
			for (int i = 0; i < cleats.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)((Component)((Component)cleats[i]).transform).GetComponentInChildren<PickupableBoatMooringRope>()))
				{
					Vector3 val = ((Joint)((Component)((Component)cleats[i]).transform).GetComponentInChildren<SpringJoint>()).currentForce;
					if (((Component)((Joint)((Component)((Component)cleats[i]).transform).GetComponentInChildren<SpringJoint>()).connectedBody).gameObject.GetComponent<BoatPerformanceSwitcher>().performanceModeIsOn())
					{
						val /= 10f;
					}
					((Component)this).gameObject.GetComponent<Rigidbody>().AddForceAtPosition(val / 3f, ((Component)cleats[i]).transform.position, (ForceMode)0);
				}
			}
		}
		if (!smallBoat)
		{
			return;
		}
		GPButtonDockMooring[] array = cleats;
		foreach (GPButtonDockMooring val2 in array)
		{
			if (!Plugin.smallBoats.Value)
			{
				PickupableBoatMooringRope componentInChildren = ((Component)val2).GetComponentInChildren<PickupableBoatMooringRope>();
				if (componentInChildren != null)
				{
					componentInChildren.Unmoor();
					componentInChildren.ResetRopePos();
				}
			}
			((Component)val2).gameObject.SetActive(Plugin.smallBoats.Value);
		}
	}

	public void UpdateTowedBoats()
	{
		towedBoats = new List<TowingSet>();
		bool flag = false;
		if (cleats != null)
		{
			for (int i = 0; i < cleats.Length; i++)
			{
				if ((Object)(object)((Component)((Component)cleats[i]).transform).GetComponentInChildren<PickupableBoatMooringRope>() != (Object)null)
				{
					towedBoats.Add(((Component)((Component)((Component)cleats[i]).transform).GetComponentInChildren<PickupableBoatMooringRope>().GetBoatRigidbody()).GetComponent<TowingSet>());
					flag = true;
				}
			}
		}
		towing = flag;
	}

	public void UpdateTowedBy()
	{
		bool flag = false;
		towedBy = null;
		PickupableBoatMooringRope[] ropes = mooringRopes.ropes;
		foreach (PickupableBoatMooringRope val in ropes)
		{
			if (val.IsMoored())
			{
				object value = Traverse.Create((object)val).Field("mooredToSpring").GetValue();
				SpringJoint val2 = (SpringJoint)((value is SpringJoint) ? value : null);
				if (val2 != null && ((Component)val2).gameObject.CompareTag("Boat"))
				{
					towedBy = ((Component)val2).GetComponentInParent<TowingSet>();
					flag = true;
				}
			}
		}
		towed = flag;
	}

	public bool PhysicsMode()
	{
		if (towed && Plugin.performanceMode.Value > 0)
		{
			TowingSet towingSet = towedBy;
			for (int i = 0; i < Plugin.performanceMode.Value; i++)
			{
				if ((Object)(object)((Component)towingSet).transform == (Object)(object)GameState.currentBoat || (Object)(object)((Component)towingSet).transform == (Object)(object)GameState.lastBoat)
				{
					return true;
				}
				if (!towingSet.towed)
				{
					break;
				}
				towingSet = towingSet.GetTowedBy();
			}
		}
		if (towing)
		{
			List<TowingSet> list = towedBoats;
			for (int j = 0; j < 10; j++)
			{
				bool flag = false;
				foreach (TowingSet item in list)
				{
					if ((Object)(object)((Component)item).transform == (Object)(object)GameState.currentBoat || (Object)(object)((Component)item).transform == (Object)(object)GameState.lastBoat)
					{
						return true;
					}
					if (item.towing)
					{
						list = item.GetTowedBoats();
						flag = true;
					}
				}
				if (!flag)
				{
					break;
				}
			}
		}
		return false;
	}

	public void AddCleats()
	{
		if ((Object)(object)AssetTools.bundle == (Object)null)
		{
			AssetTools.LoadAssetBundles();
		}
		int sceneIndex = ((Component)this).gameObject.GetComponent<SaveableObject>().sceneIndex;
		try
		{
			GameObject val;
			switch (sceneIndex)
			{
			case 50:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set brig.prefab");
				break;
			case 20:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set sanbuq.prefab");
				break;
			case 80:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set junk.prefab");
				break;
			case 70:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set jong.prefab");
				break;
			case 40:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set cog.prefab");
				smallBoat = true;
				break;
			case 10:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set dhow.prefab");
				smallBoat = true;
				break;
			case 90:
				val = AssetTools.bundle.LoadAsset<GameObject>("Assets/TowableBoats/towing set kakam.prefab");
				smallBoat = true;
				break;
			default:
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, ((Component)this).transform, false);
			((Object)val2).name = "towing set";
			cleats = val2.GetComponentsInChildren<GPButtonDockMooring>();
		}
		catch
		{
			Debug.LogError((object)("TowableBoats: Couldn't load towing set for " + ((Object)this).name + "!!"));
		}
	}
}
public static class Util
{
	public static object InvokePrivate(object obj, string name, object arg)
	{
		return AccessTools.Method(obj.GetType(), name, (Type[])null, (Type[])null).Invoke(obj, new object[1] { arg });
	}
}