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 LethalChat v1.1.0
LethalWorkingConditions.dll
Decompiled 2 years 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.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using LethalWorkingConditions.Classes.ChatCommand; using LethalWorkingConditions.Classes.ChatCommand.Commands; using LethalWorkingConditions.Helpers; using LethalWorkingConditions.Patches; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("LethalWorkingCondition")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LethalWorkingCondition")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6efab151-7ff3-4bb1-a345-7f43604d9c10")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace LethalWorkingConditions { public class LWCConfig { public readonly string Name = "LethalChat"; public static readonly bool PlayerControllerUnlimitedSprintDefault = false; public static ConfigEntry<bool> PlayerControllerUnlimitedSprint; public static readonly string TerminalCommandPrefixDefault = "----"; public static ConfigEntry<string> TerminalCommandPrefix; public static readonly bool TerminalCommandDisableChatDefault = false; public static ConfigEntry<bool> TerminalCommandDisableChat; public static readonly bool AllowSpawnCommandIfNotHostDefault = false; public static ConfigEntry<bool> AllowSpawnCommandIfNotHost; public static readonly bool MonsterEventsEnabledDefault = false; public static ConfigEntry<bool> MonsterEventsEnabled; public LWCConfig(ConfigFile cfg) { AllowSpawnCommandIfNotHost = cfg.Bind<bool>(Name, "AllowSpawnCommandIfNotHost", AllowSpawnCommandIfNotHostDefault, "If enabled, you can use the spawn command even when you are not the host"); } } internal class Content { private static LWCLogger logger = new LWCLogger("Content"); public static AssetBundle MainAssetsBundle; private static readonly string mainAssetBundleName = "lethalworkingconditions"; public static Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>(); private static void TryLoadAssets() { MainAssetsBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), mainAssetBundleName)); if ((Object)(object)MainAssetsBundle != (Object)null) { logger.LogInfo("AssetBundle " + mainAssetBundleName + " loaded successfully"); } else { logger.LogError("Could not load AssetBundle from " + mainAssetBundleName); } } private static void LoadPatches() { LethalWorkingConditions.harmony.PatchAll(typeof(RoundManagerBPatch)); LethalWorkingConditions.harmony.PatchAll(typeof(HUDManagerBPatch)); logger.LogInfo("Done loading patches"); } private static void LoadEnemies() { } private static void LoadEnemy(string name, int rarity, LevelTypes levelType, SpawnType spawnType) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) logger.LogInfo("Loading enemy " + name); EnemyType val = MainAssetsBundle.LoadAsset<EnemyType>(name); TerminalNode val2 = MainAssetsBundle.LoadAsset<TerminalNode>(name + "TN"); TerminalKeyword val3 = MainAssetsBundle.LoadAsset<TerminalKeyword>(name + "TK"); NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); Enemies.RegisterEnemy(val, rarity, levelType, spawnType, val2, val3); logger.LogInfo("Loaded " + name); } public static void Load() { LethalWorkingConditions.harmony.PatchAll(typeof(LethalWorkingConditions)); LoadPatches(); foreach (KeyValuePair<string, GameObject> prefab in Prefabs) { GameObject value = prefab.Value; string key = prefab.Key; AudioSource[] componentsInChildren = value.GetComponentsInChildren<AudioSource>(); if (componentsInChildren.Length != 0) { AudioSource[] array = componentsInChildren; foreach (AudioSource val in array) { val.volume *= 1f; } } } logger.LogInfo("Content loaded"); } } [BepInPlugin("Trebossa.LethalChat", "Lethal Chat", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LethalWorkingConditions : BaseUnityPlugin { public const string modGUID = "Trebossa.LethalChat"; public const string modName = "Lethal Chat"; public const string modVersion = "1.1.0"; public static readonly Harmony harmony = new Harmony("Trebossa.LethalChat"); public static LethalWorkingConditions Instance; private static LWCLogger logger; public static LWCConfig Config { get; internal set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } Config = new LWCConfig(((BaseUnityPlugin)this).Config); LWCLogger.Init(); logger = new LWCLogger("LWC"); Content.Load(); logger.LogInfo("Done loading config"); AllowNetworkPrefabs(); } private void AllowNetworkPrefabs() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } } namespace LethalWorkingConditions.Patches { [HarmonyPatch(typeof(HUDManager))] internal class HUDManagerBPatch { private static bool chatDisabled = LWCConfig.TerminalCommandDisableChat.Value; [HarmonyPatch("SubmitChat_performed")] [HarmonyPrefix] private static bool HUDManager_SubmitChat_performed_Prefix(ref HUDManager __instance) { string text = __instance.chatTextField.text; if (!text.ToLower().StartsWith(ChatCommand.CommandPrefix) && !chatDisabled) { return true; } CommandStatus commandStatus = HandleCommandLogic(text, ref __instance); CleanupGUI(ref __instance); if (commandStatus == CommandStatus.NOT_SET && !chatDisabled) { return true; } return false; } private static CommandStatus HandleCommandLogic(string text, ref HUDManager __instance) { CommandStatus result = CommandStatus.NOT_SET; if (text.ToLower().StartsWith(ChatCommand.CommandPrefix + "spawn")) { SpawnCommand spawnCommand = new SpawnCommand(ref __instance); result = spawnCommand.ExecuteCommand(); } return result; } private static void CleanupGUI(ref HUDManager __instance) { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; localPlayerController.isTypingChat = false; __instance.chatTextField.text = ""; EventSystem.current.SetSelectedGameObject((GameObject)null); __instance.PingHUDElement(__instance.Chat, 2f, 1f, 0.2f); ((Behaviour)__instance.typingIndicator).enabled = false; } } [HarmonyPatch(typeof(RoundManager))] internal class RoundManagerBPatch { internal static bool isHost; internal static RoundManager currentRound; internal static SelectableLevel currentLevel; internal static EnemyVent[] currentLevelVents; [HarmonyPatch("Start")] [HarmonyPrefix] private static void RoundManagerBPatch_Start_Prefix(ref float ___mapSizeMultiplier) { ___mapSizeMultiplier = 2f; isHost = ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost; } [HarmonyPatch("AdvanceHourAndSpawnNewBatchOfEnemies")] [HarmonyPrefix] private static void RoundManagerBPatch_AdvanceHourAndSpawnNewBatchOfEnemies_Prefix(ref EnemyVent[] ___allEnemyVents, ref SelectableLevel ___currentLevel) { currentLevel = ___currentLevel; currentLevelVents = ___allEnemyVents; } [HarmonyPatch("LoadNewLevel")] [HarmonyPrefix] private static void RoundManagerBPatch_LoadNewLevel_Prefix(ref SelectableLevel newLevel) { currentRound = RoundManager.Instance; } } } namespace LethalWorkingConditions.Helpers { internal class LWCLogger { public static ManualLogSource mls; public readonly string source; public LWCLogger(string source) { this.source = source; } public static void Init() { mls = Logger.CreateLogSource("Trebossa.LethalChat"); } public void LogInfo(string message) { if (mls != null) { mls.LogInfo((object)("[" + source + "] " + message)); } } public void LogWarning(string message) { if (mls != null) { mls.LogWarning((object)("[" + source + "] " + message)); } } public void LogError(string message) { if (mls != null) { mls.LogError((object)("[" + source + "] " + message)); } } } internal class ObjectFinder { public static List<T> FindObjectsInRadius<T>(Transform transform, float radius) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) List<T> list = new List<T>(); Collider[] array = Physics.OverlapSphere(transform.position, radius); Collider[] array2 = array; foreach (Collider val in array2) { T component = ((Component)val).GetComponent<T>(); if (component != null) { list.Add(component); } } return list; } public static T[] FindObjectsOfType<T>() where T : Object { return Object.FindObjectsOfType<T>(); } } } namespace LethalWorkingConditions.Classes { internal enum EnemySpawnLocation { Auto, Inside, Outside } internal class EnemySpawner { private static LWCLogger logger = new LWCLogger("EnemySpawner"); public static List<SpawnableEnemyWithRarity> EnemiesInside => RoundManagerBPatch.currentLevel.Enemies; public static List<SpawnableEnemyWithRarity> EnemiesOutside => RoundManagerBPatch.currentLevel.OutsideEnemies; public static bool SpawnEnemy(SpawnableEnemyWithRarity enemy, int amount, EnemySpawnLocation spawnLocation = EnemySpawnLocation.Auto) { if (!RoundManagerBPatch.isHost) { logger.LogInfo("Could not spawn enemies because user is not host"); return false; } switch (spawnLocation) { case EnemySpawnLocation.Auto: if (FindEnemy(EnemiesInside, enemy.enemyType.enemyName) != null) { return SpawnEnemyAtRandomVent(enemy, amount); } return SpawnEnemyAtRandomOutsidePosition(enemy, amount); case EnemySpawnLocation.Inside: return SpawnEnemyAtRandomVent(enemy, amount); case EnemySpawnLocation.Outside: return SpawnEnemyAtRandomOutsidePosition(enemy, amount); default: return false; } } private static bool SpawnEnemyAtRandomVent(SpawnableEnemyWithRarity enemy, int amount) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) try { int num = RoundManagerBPatch.currentLevel.Enemies.IndexOf(enemy); for (int i = 0; i < amount; i++) { int num2 = Random.Range(0, RoundManagerBPatch.currentRound.allEnemyVents.Length); Vector3 position = RoundManagerBPatch.currentRound.allEnemyVents[num2].floorNode.position; float y = RoundManagerBPatch.currentRound.allEnemyVents[i].floorNode.eulerAngles.y; RoundManagerBPatch.currentRound.SpawnEnemyOnServer(position, y, RoundManagerBPatch.currentLevel.Enemies.IndexOf(enemy)); } } catch (Exception ex) { logger.LogError("Failed to spawn enemies: " + ex.ToString()); return false; } return true; } private static bool SpawnEnemyAtRandomOutsidePosition(SpawnableEnemyWithRarity enemy, int amount) { //IL_0054: 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_005e: Unknown result type (might be due to invalid IL or missing references) try { for (int i = 0; i < amount - 1; i++) { GameObject val = Object.Instantiate<GameObject>(RoundManagerBPatch.currentLevel.OutsideEnemies[RoundManagerBPatch.currentLevel.OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab, GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length - 1)].transform.position, Quaternion.Euler(Vector3.zero)); val.gameObject.GetComponentInChildren<NetworkObject>().Spawn(true); } } catch (Exception ex) { logger.LogError("Failed to spawn enemies: " + ex.ToString()); return false; } return true; } public static SpawnableEnemyWithRarity FindEnemy(List<SpawnableEnemyWithRarity> list, string search) { return list.Find((SpawnableEnemyWithRarity e) => e.enemyType.enemyName.ToLower().Contains(search.ToLower())); } } } namespace LethalWorkingConditions.Classes.ChatCommand { public enum CommandStatus { NOT_SET, PREQUISITES_NOT_MET, PARAMS_INCOMPLETE, OK } internal abstract class ChatCommand { protected LWCLogger logger; public static string CommandPrefix = LWCConfig.TerminalCommandPrefix.Value ?? LWCConfig.TerminalCommandPrefixDefault; protected HUDManager hudManager; protected readonly string text; protected string[] parameters; protected string commandName = "N/A"; protected string noticeTitle => "Command: " + CommandPrefix + commandName; protected virtual string GetFullCommandSyntax() { return CommandPrefix + commandName; } protected virtual void OnInterception() { } protected abstract bool CanBeCalled(); protected abstract bool ParseParameters(); protected abstract void Execute(); public ChatCommand(string commandname, ref HUDManager hudManager) { this.hudManager = hudManager; commandName = commandname; logger = new LWCLogger(commandName ?? ""); text = hudManager.chatTextField.text; parameters = text.Split(new char[1] { ' ' }).Skip(1).ToArray(); } protected void IssueNotification(string message, bool isWarning = false) { HUDManager.Instance.DisplayTip(noticeTitle, message, isWarning, false, "LC_Tip1"); logger.LogInfo(noticeTitle + ": " + message); } protected void IssueCommandSyntax() { IssueNotification("Wrong Syntax: " + GetFullCommandSyntax()); } public CommandStatus ExecuteCommand() { if (!CanBeCalled()) { return CommandStatus.PREQUISITES_NOT_MET; } if (!ParseParameters()) { IssueCommandSyntax(); return CommandStatus.PARAMS_INCOMPLETE; } Execute(); return CommandStatus.OK; } } } namespace LethalWorkingConditions.Classes.ChatCommand.Commands { internal class SpawnCommand : ChatCommand { private string targetEnemyNameParam = ""; private int targetEnemyAmountParam = 1; private EnemySpawnLocation spawnLocation = EnemySpawnLocation.Auto; private bool targetEnemyFound = false; private string targetEnemyName; private string creaturesAvailableString => string.Join("|", EnemySpawner.EnemiesInside.Select((SpawnableEnemyWithRarity e) => e.enemyType.enemyName).ToArray()) + "|" + string.Join("|", EnemySpawner.EnemiesOutside.Select((SpawnableEnemyWithRarity e) => e.enemyType.enemyName).ToArray()); public SpawnCommand(ref HUDManager hudManager) : base("Spawn", ref hudManager) { } protected override string GetFullCommandSyntax() { return base.GetFullCommandSyntax() + " <" + creaturesAvailableString + "> [amount=1] [inside|outside]"; } protected override bool CanBeCalled() { if (!RoundManagerBPatch.isHost) { IssueNotification("Only the host is allowed to use this comand"); return false; } try { List<SpawnableEnemyWithRarity> enemiesOutside = EnemySpawner.EnemiesOutside; List<SpawnableEnemyWithRarity> enemiesInside = EnemySpawner.EnemiesInside; if (enemiesOutside.Count <= 0 || enemiesInside.Count <= 0) { throw new Exception(); } } catch { IssueNotification("You need to start the game before spawning enemies"); return false; } return true; } protected override bool ParseParameters() { if (parameters.Length < 1) { return false; } targetEnemyNameParam = parameters[0].ToLower(); if (parameters.Length > 1) { int.TryParse(parameters[1], out targetEnemyAmountParam); } if (parameters.Length > 2) { string text = parameters[2].ToLower(); if (text.StartsWith("in")) { spawnLocation = EnemySpawnLocation.Inside; } if (text.StartsWith("out")) { spawnLocation = EnemySpawnLocation.Outside; } } return true; } protected override void Execute() { List<SpawnableEnemyWithRarity> outsideEnemies = RoundManagerBPatch.currentLevel.OutsideEnemies; List<SpawnableEnemyWithRarity> enemies = RoundManagerBPatch.currentLevel.Enemies; List<SpawnableEnemyWithRarity> availableEnemies = outsideEnemies.Concat(enemies).ToList(); HandleSpawnEnemies(availableEnemies); if (!targetEnemyFound) { IssueCommandSyntax(); } } private void HandleSpawnEnemies(List<SpawnableEnemyWithRarity> availableEnemies) { foreach (SpawnableEnemyWithRarity availableEnemy in availableEnemies) { if (!targetEnemyFound && availableEnemy.enemyType.enemyName.ToLower().Contains(targetEnemyNameParam)) { targetEnemyFound = true; targetEnemyName = availableEnemy.enemyType.enemyName; if (EnemySpawner.SpawnEnemy(availableEnemy, targetEnemyAmountParam, spawnLocation)) { IssueNotification($"Spawned {targetEnemyAmountParam} {targetEnemyName}"); } else { IssueNotification("Could not spawn enemies because an unknown error occured. Check console"); } } } } } }