Please disclose if your mod was created primarily 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 SemiBotChat v1.0.9
DeadSemiBotChat.dll
Decompiled 6 months agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Autodesk.Fbx")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")] [assembly: IgnoresAccessChecksTo("Klattersynth")] [assembly: IgnoresAccessChecksTo("Photon3Unity3D")] [assembly: IgnoresAccessChecksTo("PhotonChat")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")] [assembly: IgnoresAccessChecksTo("PhotonVoice.API")] [assembly: IgnoresAccessChecksTo("PhotonVoice")] [assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization")] [assembly: IgnoresAccessChecksTo("Sirenix.Utilities")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("websocket-sharp")] [assembly: AssemblyCompany("jack.apfel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+858ad45e476fbcd15551f443688dc0de56a9c7ea")] [assembly: AssemblyProduct("DeadSemiBotChat")] [assembly: AssemblyTitle("DeadSemiBotChat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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; } } } namespace SemiBotChat { [BepInPlugin("jack.apfel.SemiBotChat", "SemiBotChat", "1.0.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SemiBotChat : BaseUnityPlugin { [HarmonyPatch(typeof(PlayerAvatar), "Start")] private class PlayerAvatarPatch { private static void Postfix(PlayerAvatar __instance) { LogDebug("PlayerAvatarPatch called!"); FindLocalPlayerAvatar(); PlayerAvatar? localPlayerAvatar = SemiBotChat.localPlayerAvatar; PhotonView arg = SemiBotChat.localPlayerAvatar?.photonView; PlayerAvatar? localPlayerAvatar2 = SemiBotChat.localPlayerAvatar; bool? obj; if (localPlayerAvatar2 == null) { obj = null; } else { PhotonView photonView = localPlayerAvatar2.photonView; obj = ((photonView != null) ? new bool?(photonView.IsMine) : null); } LogDebug($"localPlayerAvatar = {localPlayerAvatar}\nlocalPlayerAvatar.photonView = {arg}\nIsLocalPlayer.isMine = {obj}"); if ((Object)(object)SemiBotChat.localPlayerAvatar != (Object)null && (Object)(object)SemiBotChat.localPlayerAvatar.photonView != (Object)null && SemiBotChat.localPlayerAvatar.photonView.IsMine) { SemiBotChat.localPlayerAvatar.photonView.RPC("RequestConfigSyncRPC", (RpcTarget)2, new object[2] { PhotonNetwork.LocalPlayer.ActorNumber, PhotonNetwork.LocalPlayer.NickName }); } } } [HarmonyPatch(typeof(TruckScreenText), "Update")] private class TruckScreenTextPatch { private static void Prefix(TruckScreenText __instance) { allowMessage = (isDead ? ChatForDead : ChatForAlive); if (!allowMessage) { playerSentMessage = ""; } else if (playerSentMessage != "" && allowMessage) { PlayerAvatar val = SemiFunc.PlayerGetFromSteamID(PlayerController.instance.playerSteamID); __instance.MessageSendCustom(val.playerName, playerSentMessage, 0); LogDebug("Message sent!"); playerSentMessage = ""; } } } [HarmonyPatch(typeof(ChatManager), "MessageSend")] private class LobbyChatUIPatch { private static void Prefix(ChatManager __instance) { if (!(__instance.chatMessage == "") && __instance.spamTimer <= 0f) { playerSentMessage = __instance.chatMessage; } } } [HarmonyPatch(typeof(PlayerHealth), "Update")] private class PlayerHealthPatch { private static void Prefix(PlayerHealth __instance) { if (__instance.health <= 0) { isDead = true; } else { isDead = false; } } } public class NetworkTestRPC : MonoBehaviourPunCallbacks { [PunRPC] public void SyncConfigsRPC(bool chatForDead, bool chatForAlive) { LogDebug($"Sync RPC Received! ChatForDead: {chatForDead}, ChatForAlive: {chatForAlive} on {PhotonNetwork.LocalPlayer.NickName}"); ChatForDead = chatForDead; ChatForAlive = chatForAlive; } [PunRPC] public void RequestConfigSyncRPC(int actorNumber, string requesterName) { if (SemiFunc.IsMasterClient()) { LogDebug($"RequestConfigSyncRPC called by {requesterName} with actorNumber {actorNumber}!"); Player player = PhotonNetwork.CurrentRoom.GetPlayer(actorNumber, false); localPlayerAvatar.photonView.RPC("SyncConfigsRPC", player, new object[2] { ChatForDead, ChatForAlive }); } } } public static string playerSentMessage = ""; public static bool isDead; public static bool ChatForDead; public static bool ChatForAlive; private static PlayerAvatar? localPlayerAvatar; public static bool allowMessage; public static ConfigEntry<bool>? toggleChatForDeadPlayers; public static ConfigEntry<bool>? toggleChatForLivingPlayers; public static ConfigEntry<bool>? toggleDebugLogs; internal static SemiBotChat Instance { get; private set; } = null; internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } public void InitConfigs() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown toggleChatForDeadPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("Host Settings", "Enable Chat for Dead Players (Host only)", true, new ConfigDescription("Enables messages from Dead Players to be sent to the Truck Screen", (AcceptableValueBase)null, Array.Empty<object>())); toggleChatForLivingPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("Host Settings", "Enable Chat for Living Players (Host only)", true, new ConfigDescription("Enables messages from Living Players to be sent to the Truck Screen", (AcceptableValueBase)null, Array.Empty<object>())); toggleDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Debugging Logs (Client Side)", false, new ConfigDescription("Enables Debugging Logs", (AcceptableValueBase)null, Array.Empty<object>())); ChatForDead = toggleChatForDeadPlayers.Value; ChatForAlive = toggleChatForLivingPlayers.Value; toggleChatForDeadPlayers.SettingChanged += OnChatForDeadPlayersSettingChanged; toggleChatForLivingPlayers.SettingChanged += OnChatForLivingPlayersSettingChanged; LogDebug($"ChatForDeadPlayers.value: {toggleChatForDeadPlayers.Value}"); LogDebug($"ChatForLivingPlayers.value: {toggleChatForLivingPlayers.Value}"); LogDebug($"ChatForDead: {ChatForDead}"); LogDebug($"ChatForAlive: {ChatForAlive}"); } private static void LogDebug(string message) { ConfigEntry<bool>? obj = toggleDebugLogs; if (obj != null && obj.Value) { Logger.LogMessage((object)message); } } private static void LogError(string message) { ConfigEntry<bool>? obj = toggleDebugLogs; if (obj != null && obj.Value) { Logger.LogError((object)message); } } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); InitConfigs(); } internal void Patch() { //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_0020: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void OnChatForDeadPlayersSettingChanged(object sender, EventArgs e) { try { if (SemiFunc.IsMasterClientOrSingleplayer()) { ChatForDead = toggleChatForDeadPlayers.Value; ChatForAlive = toggleChatForLivingPlayers.Value; LogDebug($"ChatForDeadPlayers setting changed {ChatForDead}!"); if ((Object)(object)localPlayerAvatar.photonView != (Object)null && localPlayerAvatar.photonView.IsMine) { LogDebug("Sending Sync RPC"); localPlayerAvatar.photonView.RPC("SyncConfigsRPC", (RpcTarget)4, new object[2] { ChatForDead, ChatForAlive }); } } else { Logger.LogWarning((object)"Cant Change Config, not Host!"); } } catch { } } private void OnChatForLivingPlayersSettingChanged(object sender, EventArgs e) { try { if (SemiFunc.IsMasterClientOrSingleplayer()) { ChatForAlive = toggleChatForLivingPlayers.Value; ChatForDead = toggleChatForDeadPlayers.Value; LogDebug($"ChatForLivingPlayers setting changed to {ChatForAlive}!"); if ((Object)(object)localPlayerAvatar.photonView != (Object)null && localPlayerAvatar.photonView.IsMine) { LogDebug("Sending Sync RPC"); localPlayerAvatar.photonView.RPC("SyncConfigsRPC", (RpcTarget)4, new object[2] { ChatForDead, ChatForAlive }); } } else { Logger.LogWarning((object)"Cant Change Config, not Host!"); } } catch { } } private void Update() { } public static void FindLocalPlayerAvatar() { LogDebug("FindLocalPlayerAvatar called!"); PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>(); if (array.Length == 0) { LogDebug("No PlayerAvatars found!"); return; } LogDebug($"Found {array.Length} PlayerAvatars!"); PlayerAvatar[] array2 = array; foreach (PlayerAvatar val in array2) { if ((Object)(object)val.photonView == (Object)null) { LogDebug("PlayerAvatar has no PhotonView!"); continue; } if (val.photonView.Owner == null) { LogDebug("PlayerAvatar PhotonView has no Owner!"); continue; } LogDebug($"PlayerAvatar found: {val.photonView.Owner.NickName}\nViewID: {val.photonView.ViewID}\nIsMine: {val.photonView.IsMine}"); if ((Object)(object)((Component)val.photonView).GetComponent<NetworkTestRPC>() == (Object)null) { LogDebug($"Adding NetworkTestRPC to PlayerAvatar with ViewID: {val.photonView.ViewID}"); ((Component)val.photonView).gameObject.AddComponent<NetworkTestRPC>(); LogDebug($"NetworkTestRPC added: {(Object)(object)((Component)val.photonView).GetComponent<NetworkTestRPC>() != (Object)null}"); } if (val.photonView.IsMine) { localPlayerAvatar = val; LogDebug("Found local player avatar!"); } } if ((Object)(object)localPlayerAvatar == (Object)null) { LogDebug("Could not find local player avatar!"); } } } }