Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of WhoIsTalking v1.0.1
WhoIsTalking.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WhoIsTalking")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WhoIsTalking")] [assembly: AssemblyTitle("WhoIsTalking")] [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 WhoIsTalkingMod { [BepInPlugin("WhoIsTalking", "WhoIsTalking", "1.0.1")] public class Plugin : BaseUnityPlugin { public const string Guid = "WhoIsTalking"; public const string Name = "WhoIsTalking"; public const string Version = "1.0.1"; internal static ManualLogSource Log; internal static ConfigEntry<bool> ShowSelf; internal static ConfigEntry<bool> ShowDeadWhileAlive; internal static ConfigEntry<int> MaxRows; internal static ConfigEntry<float> FadeSeconds; internal static ConfigEntry<float> Scale; internal static ConfigEntry<float> OffsetX; internal static ConfigEntry<float> OffsetY; private void Awake() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; MigrateOldConfig("markj.whoistalking"); ShowSelf = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowYourself", true, "Show your own name when you talk."); ShowDeadWhileAlive = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDeadPlayersWhileAlive", false, "Dead players can only be heard by other dead players. Leave this off so the list doesn't show talkers you can't hear."); MaxRows = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "MaxNames", 8, "Most names shown at once."); FadeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "FadeSeconds", 0.6f, "How long a name stays after someone stops talking."); Scale = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "Scale", 1f, "Size of the list. 1 = normal."); OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "OffsetFromRight", 24f, "Gap from the right edge of the screen (pixels at 1080p)."); OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "OffsetFromBottom", 140f, "Gap from the bottom edge of the screen (pixels at 1080p)."); new Harmony("WhoIsTalking").PatchAll(typeof(Patches)); Log.LogInfo((object)"WhoIsTalking 1.0.1 loaded."); } private void MigrateOldConfig(string oldId) { try { string text = Path.Combine(Paths.ConfigPath, oldId + ".cfg"); if (File.Exists(text)) { if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { File.Copy(text, ((BaseUnityPlugin)this).Config.ConfigFilePath); ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Moved settings from " + oldId + ".cfg")); } File.Delete(text); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Couldn't move old settings from " + oldId + ".cfg: " + ex.Message)); } } } [HarmonyPatch] internal static class Patches { private static bool _loggedError; [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void PlayerUpdate() { try { VoiceHud.Tick(); } catch (Exception ex) { if (!_loggedError) { _loggedError = true; Plugin.Log.LogError((object)("Voice list update failed: " + ex)); } } } } internal static class VoiceHud { private class Row { public RectTransform Rt; public CanvasGroup Group; public Image Dot; public Image Ring; public TextMeshProUGUI Tmp; public Text Legacy; public float LastSpoke = -999f; public float StartedSpeaking; public bool WasSpeaking; public float SmoothAmp; } private const float RowHeight = 34f; private const float RowWidth = 260f; private const float RowGap = 6f; private static int _lastFrame = -1; private static GameObject _canvasGo; private static RectTransform _root; private static TMP_FontAsset _font; private static Sprite _circle; private static Sprite _panel; private static readonly Dictionary<PlayerControllerB, Row> Rows = new Dictionary<PlayerControllerB, Row>(); private static bool _loggedVoiceMissing; private static readonly Dictionary<(Type, string), MemberInfo> Members = new Dictionary<(Type, string), MemberInfo>(); public static void Tick() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) if (Time.frameCount == _lastFrame) { return; } _lastFrame = Time.frameCount; StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { if ((Object)(object)_canvasGo != (Object)null) { _canvasGo.SetActive(false); } return; } EnsureCanvas(); if (!_canvasGo.activeSelf) { _canvasGo.SetActive(true); } ((Transform)_root).localScale = Vector3.one * Mathf.Clamp(Plugin.Scale.Value, 0.3f, 3f); _root.anchoredPosition = new Vector2(0f - Plugin.OffsetX.Value, Plugin.OffsetY.Value); PlayerControllerB val = FindLocal(instance); object obj = Get(instance, "voiceChatModule"); object obj2 = null; if (obj != null) { string text = Get(obj, "LocalPlayerName") as string; if (!string.IsNullOrEmpty(text)) { obj2 = Call(obj, "FindPlayer", text); } } float now = Time.unscaledTime; bool flag = (Object)(object)val != (Object)null && !val.isPlayerDead; PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; bool flag3 = default(bool); foreach (PlayerControllerB val2 in allPlayerScripts) { if ((Object)(object)val2 == (Object)null) { continue; } bool num = val2.isPlayerControlled || val2.isPlayerDead; bool flag2 = (Object)(object)val2 == (Object)(object)val; if (!num || (flag2 && !Plugin.ShowSelf.Value) || (val2.isPlayerDead && flag && !Plugin.ShowDeadWhileAlive.Value && !flag2)) { if (Rows.TryGetValue(val2, out var value)) { value.LastSpoke = -999f; } continue; } object obj3 = (flag2 ? (obj2 ?? Get(val2, "voicePlayerState")) : Get(val2, "voicePlayerState")); if (obj3 == null) { if (!_loggedVoiceMissing && !flag2 && val2.isPlayerControlled && instance.connectedPlayersAmount > 0) { _loggedVoiceMissing = true; Plugin.Log.LogInfo((object)("No voice data yet for " + val2.playerUsername + " (normal for a few seconds after they join).")); } continue; } object obj4 = Get(obj3, "IsSpeaking"); int num2; if (obj4 is bool) { flag3 = (bool)obj4; num2 = 1; } else { num2 = 0; } bool flag4 = (byte)((uint)num2 & (flag3 ? 1u : 0u)) != 0; float num3 = ((Get(obj3, "Amplitude") is float num4) ? num4 : 0f); if (!Rows.TryGetValue(val2, out var value2) || (Object)(object)value2.Rt == (Object)null) { value2 = CreateRow(); Rows[val2] = value2; } if (flag4) { if (!value2.WasSpeaking) { value2.StartedSpeaking = now; } value2.LastSpoke = now; } value2.WasSpeaking = flag4; value2.SmoothAmp = Mathf.Lerp(value2.SmoothAmp, flag4 ? num3 : 0f, 1f - Mathf.Exp((0f - Time.unscaledDeltaTime) * 18f)); string text2 = val2.playerUsername + (val2.isPlayerDead ? " (dead)" : ""); Color color = (Color)(val2.isPlayerDead ? new Color(0.7f, 0.7f, 0.7f) : Color.white); if ((Object)(object)value2.Tmp != (Object)null) { ((TMP_Text)value2.Tmp).text = text2; ((Graphic)value2.Tmp).color = color; } if ((Object)(object)value2.Legacy != (Object)null) { value2.Legacy.text = text2; ((Graphic)value2.Legacy).color = color; } } foreach (PlayerControllerB item in Rows.Keys.Where((PlayerControllerB k) => (Object)(object)k == (Object)null).ToList()) { if ((Object)(object)Rows[item].Rt != (Object)null) { Object.Destroy((Object)(object)((Component)Rows[item].Rt).gameObject); } Rows.Remove(item); } float fade = Mathf.Max(0.05f, Plugin.FadeSeconds.Value); List<Row> list = (from kv in (from kv in Rows where (Object)(object)kv.Value.Rt != (Object)null && now - kv.Value.LastSpoke < fade orderby kv.Value.StartedSpeaking descending select kv).Take(Mathf.Max(1, Plugin.MaxRows.Value)) select kv.Value).ToList(); foreach (Row value3 in Rows.Values) { if ((Object)(object)value3.Rt != (Object)null && !list.Contains(value3) && ((Component)value3.Rt).gameObject.activeSelf) { ((Component)value3.Rt).gameObject.SetActive(false); } } for (int num5 = 0; num5 < list.Count; num5++) { Row row = list[num5]; if (!((Component)row.Rt).gameObject.activeSelf) { ((Component)row.Rt).gameObject.SetActive(true); } row.Rt.anchoredPosition = new Vector2(0f, (float)num5 * 40f); bool wasSpeaking = row.WasSpeaking; row.Group.alpha = (wasSpeaking ? 1f : Mathf.Clamp01(1f - (now - row.LastSpoke) / fade)); float num6 = Mathf.Clamp01(row.SmoothAmp * 10f); ((Transform)((Graphic)row.Dot).rectTransform).localScale = Vector3.one * (0.75f + num6 * 0.45f); ((Graphic)row.Dot).color = Color.Lerp(new Color(0.2f, 0.75f, 0.3f), new Color(0.45f, 1f, 0.5f), num6); ((Graphic)row.Ring).color = new Color(0.45f, 1f, 0.5f, 0.15f + num6 * 0.6f); } } private static PlayerControllerB FindLocal(StartOfRound sor) { PlayerControllerB[] allPlayerScripts = sor.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).IsOwner && val.isPlayerControlled) { return val; } } if ((Object)(object)sor.localPlayerController != (Object)null) { return sor.localPlayerController; } if (!((Object)(object)GameNetworkManager.Instance != (Object)null)) { return null; } return GameNetworkManager.Instance.localPlayerController; } private static void EnsureCanvas() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00b1: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvasGo != (Object)null)) { _canvasGo = new GameObject("WhoIsTalkingCanvas"); Object.DontDestroyOnLoad((Object)(object)_canvasGo); Canvas obj = _canvasGo.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 60; CanvasScaler obj2 = _canvasGo.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 1f; GameObject val = new GameObject("List", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(_canvasGo.transform, false); _root = (RectTransform)val.transform; RectTransform root = _root; RectTransform root2 = _root; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 0f); root2.anchorMax = val2; root.anchorMin = val2; _root.pivot = new Vector2(1f, 0f); _root.sizeDelta = new Vector2(260f, 34f); Rows.Clear(); } } private static Row CreateRow() { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_font == (Object)null && (Object)(object)HUDManager.Instance != (Object)null) { _font = (from t in ((Component)HUDManager.Instance).GetComponentsInChildren<TextMeshProUGUI>(true) select ((TMP_Text)t).font).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null)); } if ((Object)(object)_font == (Object)null) { _font = (from t in Object.FindObjectsOfType<TextMeshProUGUI>() select ((TMP_Text)t).font).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null)); } GameObject val = new GameObject("Speaker", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_root, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(1f, 0f); val2.sizeDelta = new Vector2(260f, 34f); CanvasGroup val4 = val.AddComponent<CanvasGroup>(); val4.blocksRaycasts = false; val4.interactable = false; Image obj = val.AddComponent<Image>(); obj.sprite = PanelSprite(); obj.type = (Type)1; ((Graphic)obj).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj).raycastTarget = false; Image ring = MakeCircle(val2, "Ring", 26f); Image dot = MakeCircle(val2, "Dot", 16f); GameObject val5 = new GameObject("Name", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent((Transform)(object)val2, false); RectTransform val6 = (RectTransform)val5.transform; val6.anchorMin = new Vector2(0f, 0f); val6.anchorMax = new Vector2(1f, 1f); val6.offsetMin = new Vector2(12f, 0f); val6.offsetMax = new Vector2(-40f, 0f); Row row = new Row { Rt = val2, Group = val4, Dot = dot, Ring = ring }; if ((Object)(object)_font != (Object)null) { row.Tmp = val5.AddComponent<TextMeshProUGUI>(); ((TMP_Text)row.Tmp).font = _font; ((TMP_Text)row.Tmp).fontSize = 18f; ((TMP_Text)row.Tmp).alignment = (TextAlignmentOptions)4100; ((TMP_Text)row.Tmp).overflowMode = (TextOverflowModes)1; ((Graphic)row.Tmp).raycastTarget = false; } else { row.Legacy = val5.AddComponent<Text>(); row.Legacy.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); row.Legacy.fontSize = 18; row.Legacy.alignment = (TextAnchor)5; ((Graphic)row.Legacy).raycastTarget = false; } val.SetActive(false); return row; } private static Image MakeCircle(RectTransform parent, string name, float size) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = new Vector2(-20f, 0f); val2.sizeDelta = new Vector2(size, size); Image obj = val.AddComponent<Image>(); obj.sprite = CircleSprite(); ((Graphic)obj).raycastTarget = false; return obj; } private static Sprite CircleSprite() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002d: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circle != (Object)null) { return _circle; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[4096]; float num = 32f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num2 = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num, num)); byte b = (byte)(Mathf.Clamp01(num - num2) * 255f); array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(); _circle = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); return _circle; } private static Sprite PanelSprite() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002d: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel != (Object)null) { return _panel; } Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[1024]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num = Mathf.Clamp((float)j + 0.5f, 10f, 22f); float num2 = Mathf.Clamp((float)i + 0.5f, 10f, 22f); float num3 = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num, num2)); byte b = (byte)(Mathf.Clamp01(10f - num3) * 255f); array[i * 32 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(); _panel = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(11f, 11f, 11f, 11f)); return _panel; } private static object Get(object obj, string name) { if (obj == null) { return null; } (Type, string) key = (obj.GetType(), name); if (!Members.TryGetValue(key, out var value)) { value = (MemberInfo)(((object)AccessTools.Property(obj.GetType(), name)) ?? ((object)AccessTools.Field(obj.GetType(), name))); Members[key] = value; if (value == null) { Plugin.Log.LogWarning((object)("Voice chat member not found: " + obj.GetType().Name + "." + name)); } } try { if (value is PropertyInfo propertyInfo) { return propertyInfo.GetValue(obj); } if (value is FieldInfo fieldInfo) { return fieldInfo.GetValue(obj); } } catch { } return null; } private static object Call(object obj, string name, params object[] args) { try { return AccessTools.Method(obj.GetType(), name, args.Select((object a) => a.GetType()).ToArray(), (Type[])null)?.Invoke(obj, args); } catch { return null; } } } }