using 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 Alpha; using Alpha.Core.Command; using Alpha.Core.Util; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Chalky.Core.Commands; using Chalky.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using PurrNet; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AndrewLin")] [assembly: AssemblyConfiguration("Publish")] [assembly: AssemblyDescription("Chalky: Enlarge chalk and save/load chalkboard. Use /chalkyhelp for commands.")] [assembly: AssemblyFileVersion("1.2.9.0")] [assembly: AssemblyInformationalVersion("1.2.9+6d8ff45e787a49ad993a6bf3e2e6d91d41bd5c79")] [assembly: AssemblyProduct("AndrewLin.Chalky")] [assembly: AssemblyTitle("AndrewLin.Chalky")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/andrewlimforfun/ot-mods")] [assembly: AssemblyVersion("1.2.9.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace Chalky { public static class BuildInfo { public const string Version = "1.2.9"; } [BepInPlugin("com.andrewlin.ontogether.chalky", "Chalky", "1.2.9")] public class ChalkyPlugin : BaseUnityPlugin { public static readonly string DefaultChatLogPath = Path.Combine(Paths.BepInExRootPath, "on_together_chat_log.txt"); public static int chalkySize = 2; public static Color? chalkyColor = null; public const string ModGUID = "com.andrewlin.ontogether.chalky"; public const string ModName = "Chalky"; public const string ModVersion = "1.2.9"; public static ConfigEntry? EnableFeature { get; private set; } public static ConfigEntry? ShowCommand { get; private set; } public static ConfigEntry? EnableHostRelay { get; private set; } public static ConfigEntry? BoardSaveDirectory { get; private set; } public static string SaveDir { get; private set; } = ""; public static string? PlayerId { get; private set; } private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)"Chalky v1.2.9 is loaded!"); InitConfig(); Harmony val = new Harmony("com.andrewlin.ontogether.chalky"); val.PatchAll(typeof(QuadPainterGPUPatch)); ChatCommandManager commandManager = AlphaPlugin.CommandManager; if (commandManager != null) { commandManager.Register((IChatCommand)(object)new ChalkyGetBoardsCommand()); } ChatCommandManager commandManager2 = AlphaPlugin.CommandManager; if (commandManager2 != null) { commandManager2.Register((IChatCommand)(object)new ChalkyLoadBoardCommand()); } ChatCommandManager commandManager3 = AlphaPlugin.CommandManager; if (commandManager3 != null) { commandManager3.Register((IChatCommand)(object)new ChalkySaveBoardCommand()); } ChatCommandManager commandManager4 = AlphaPlugin.CommandManager; if (commandManager4 != null) { commandManager4.Register((IChatCommand)(object)new ChalkySetSize()); } ChatCommandManager commandManager5 = AlphaPlugin.CommandManager; if (commandManager5 != null) { commandManager5.Register((IChatCommand)(object)new ChalkyToggleCommand()); } ChatCommandManager commandManager6 = AlphaPlugin.CommandManager; if (commandManager6 != null) { commandManager6.Register((IChatCommand)(object)new ChalkyHostRelayCommand()); } } private void InitConfig() { EnableFeature = ((BaseUnityPlugin)this).Config.Bind("General", "EnableFeature", true, "Enable or disable the mod feature."); ShowCommand = ((BaseUnityPlugin)this).Config.Bind("General", "ShowCommand", false, "Show the command in chat when used."); EnableHostRelay = ((BaseUnityPlugin)this).Config.Bind("General", "EnableHostRelay", true, "If true, the host will relay board state received from a non-host client to all other connected players."); BoardSaveDirectory = ((BaseUnityPlugin)this).Config.Bind("Boards", "BoardSaveDirectory", "~/on-together/chalkboard", "Directory where chalkboard saves are stored. '~' expands to your home folder."); SaveDir = ResolvePath(BoardSaveDirectory.Value); Directory.CreateDirectory(SaveDir); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Board save directory: " + SaveDir)); } public static string ResolvePath(string path) { if (path.StartsWith("~")) { path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + path.Substring(1); } return Path.GetFullPath(path); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "AndrewLin.Chalky"; public const string PLUGIN_NAME = "AndrewLin.Chalky"; public const string PLUGIN_VERSION = "1.2.9"; } } namespace Chalky.Patches { [HarmonyPatch(typeof(QuadPainterGPU))] public class QuadPainterGPUPatch { private static ManualLogSource _log = Logger.CreateLogSource("Chalky.QPGPUP"); private static readonly FieldInfo _pixelsField = typeof(QuadPainterGPU).GetField("_pixelsToUpdate", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo _previousUVField = typeof(QuadPainterGPU).GetField("previousUV", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo _fillTheBlanksMethod = typeof(QuadPainterGPU).GetMethod("FillTheBlanks", BindingFlags.Instance | BindingFlags.NonPublic); [HarmonyPatch("Update")] [HarmonyPrefix] public static bool UpdatePrefix(QuadPainterGPU __instance) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0278: 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) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) if (ChalkyPlugin.EnableFeature == null || !ChalkyPlugin.EnableFeature.Value) { return true; } int chalkySize = ChalkyPlugin.chalkySize; if (chalkySize <= 2) { return true; } if (!__instance.IsActive || (!MonoSingleton.I.IsHaveChalk() && !MonoSingleton.I.IsEraser)) { return false; } if (MonoSingleton.I.IsEraser) { return true; } Vector2 val = (Vector2)_previousUVField.GetValue(__instance); if (Input.GetMouseButton(0)) { Ray item = MonoSingleton.I.GetMousePosRay().Item1; RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(item, ref val2, 10f, 1 << LayerMask.NameToLayer("Drawing")) || (Object)(object)((Component)((RaycastHit)(ref val2)).collider).gameObject != (Object)(object)((Component)__instance).gameObject) { return false; } Vector2 textureCoord = ((RaycastHit)(ref val2)).textureCoord; Vector2Int gridSize = __instance.gridSize; float num = 2f / (float)((Vector2Int)(ref gridSize)).x; float num2 = 2f / (float)((Vector2Int)(ref gridSize)).y; int num3 = Mathf.CeilToInt((float)chalkySize / 2f); int chalkIndex = MonoSingleton.I.ChalkIndex; Vector2 val3 = default(Vector2); for (int i = 0; i < num3; i++) { for (int j = 0; j < num3; j++) { ((Vector2)(ref val3))..ctor(textureCoord.x + (float)i * num, textureCoord.y + (float)j * num2); Vector2 val4 = (Vector2)((val.x > 0f) ? new Vector2(val.x + (float)i * num, val.y + (float)j * num2) : val); __instance.FillTheBlanksRPC(val3, val4, chalkIndex, false, false, default(RPCInfo)); _fillTheBlanksMethod.Invoke(__instance, new object[6] { val3, val4, chalkIndex, false, false, true }); } } _previousUVField.SetValue(__instance, textureCoord); } if (Input.GetMouseButtonUp(0)) { Vector2 val5 = val; val5.x = -1f; _previousUVField.SetValue(__instance, val5); } return false; } [HarmonyPatch("GetQuadImage_Original_1")] [HarmonyPostfix] public static void RelayGetQuadImage(QuadPainterGPU __instance, RPCInfo rpcInfo) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) if (ChalkyPlugin.EnableFeature == null || !ChalkyPlugin.EnableFeature.Value || ChalkyPlugin.EnableHostRelay == null || !ChalkyPlugin.EnableHostRelay.Value || !((NetworkIdentity)__instance).isServer) { return; } PlayerID sender = rpcInfo.sender; if (sender == ((NetworkIdentity)__instance).localPlayerForced || sender == default(PlayerID)) { return; } PlayerDetail val = PlayerUtils.FindPlayer((Func)((string _steamId, PlayerID _pid, PlayerIDInfo _info, NetworkTransform _transform) => _pid == sender)); string text = ((val != null) ? val.UserNameClean : null) ?? "(unknown)"; string text2 = val?.SteamID ?? "?"; NetworkID? id = ((NetworkIdentity)__instance).id; string text3 = (id.HasValue ? ((object)id.GetValueOrDefault()/*cast due to .constrained prefix*/).ToString() : null) ?? "?"; ChatUtils.AddGlobalNotification("Chalky relay from " + text + " (" + text2 + ") [board " + text3 + "]"); _log.LogInfo((object)("[Relay] Host received board state update from " + text + " (" + text2 + ") on board " + text3 + ", relaying to other players...")); List playerIDs = NetworkSingleton.I.PlayerIDs; int num = 0; foreach (PlayerID item in playerIDs) { if (!(item == sender) && !(item == ((NetworkIdentity)__instance).localPlayerForced)) { __instance.GetQuadImage(item, __instance.PaintColors, default(RPCInfo)); num++; } } _log.LogInfo((object)$"[BoardIO relay] Host relayed board state to {num} other player(s)."); } } } namespace Chalky.Core { public static class BoardIO { private static readonly ManualLogSource _log = Logger.CreateLogSource("Chalky.BIO"); public static List ListSavedBoards() { if (!Directory.Exists(ChalkyPlugin.SaveDir)) { _log.LogWarning((object)("Save directory not found: " + ChalkyPlugin.SaveDir)); return new List(); } string[] files = Directory.GetFiles(ChalkyPlugin.SaveDir, "*.chalkboard.json"); return files.Select((string f) => Path.GetFileNameWithoutExtension(f).Replace(".chalkboard", "")).ToList(); } public static int ResolveBoard(string? indexArg) { DrawingManager i = MonoSingleton.I; if ((Object)(object)i == (Object)null) { _log.LogError((object)"DrawingManager not found."); return -1; } int result; int num = ((string.IsNullOrEmpty(indexArg) || !int.TryParse(indexArg, out result)) ? ((int)AccessTools.Field(typeof(DrawingManager), "_boardIndex").GetValue(i)) : result); if (num < 0 || num >= i.QuadPainterGPUS.Count) { _log.LogError((object)($"Invalid board index {num}. " + $"Valid range: 0-{i.QuadPainterGPUS.Count - 1}. " + "Interact with a board first, or pass an explicit index.")); return -1; } return num; } public static void SaveBoard(int index, string name) { DrawingManager i = MonoSingleton.I; if ((Object)(object)i == (Object)null || index < 0 || index >= i.QuadPainterGPUS.Count) { _log.LogError((object)$"SaveBoard: invalid state or index {index}"); return; } QuadPainterGPU val = i.QuadPainterGPUS[index]; int[][] array = val.PaintColors.Select((IntList col) => col.Ints.ToArray()).ToArray(); string text = Path.Combine(ChalkyPlugin.SaveDir, name + ".chalkboard.json"); File.WriteAllText(text, JsonConvert.SerializeObject((object)array)); _log.LogInfo((object)$"Board {index} saved to {text}"); SavePreview(val, name); } public static void LoadBoard(int index, string name) { DrawingManager i = MonoSingleton.I; if ((Object)(object)i == (Object)null || index < 0 || index >= i.QuadPainterGPUS.Count) { _log.LogError((object)$"LoadBoard: invalid state or index {index}"); return; } QuadPainterGPU val = i.QuadPainterGPUS[index]; if (!((NetworkIdentity)val).isServer) { ChatUtils.AddGlobalNotification("Relaying board to other players via the host..."); } string text = Path.Combine(ChalkyPlugin.SaveDir, name + ".chalkboard.json"); if (!File.Exists(text)) { ChatUtils.AddGlobalNotification("Board file not found: " + name + ".chalkboard.json"); _log.LogError((object)("File not found: " + text)); return; } int[][] array = JsonConvert.DeserializeObject(File.ReadAllText(text)); for (int j = 0; j < val.PaintColors.Length && j < array.Length; j++) { for (int k = 0; k < val.PaintColors[j].Ints.Count && k < array[j].Length; k++) { val.PaintColors[j].Ints[k] = array[j][k]; } } _log.LogInfo((object)("PaintColors restored from " + text)); RebuildRenderTexture(val, i); BroadcastToPlayers(val); _log.LogInfo((object)$"Board {index} loaded and synced to all players."); } private static void SavePreview(QuadPainterGPU board, string name) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) RenderTexture value = Traverse.Create((object)board).Field("_rt").GetValue(); if ((Object)(object)value == (Object)null) { _log.LogWarning((object)"_rt is null - skipping PNG preview."); return; } Texture2D val = new Texture2D(((Texture)value).width, ((Texture)value).height, (TextureFormat)5, false); RenderTexture active = RenderTexture.active; RenderTexture.active = value; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)value).width, (float)((Texture)value).height), 0, 0); val.Apply(); RenderTexture.active = active; string text = Path.Combine(ChalkyPlugin.SaveDir, name + ".chalkboard.png"); File.WriteAllBytes(text, ImageConversion.EncodeToPNG(val)); Object.Destroy((Object)(object)val); _log.LogInfo((object)("Preview saved to " + text)); } private static void RebuildRenderTexture(QuadPainterGPU board, DrawingManager dm) { //IL_0046: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Traverse val = Traverse.Create((object)board); RenderTexture value = val.Field("_rt").GetValue(); if ((Object)(object)value == (Object)null) { _log.LogError((object)"_rt is null - cannot rebuild render texture."); return; } RenderTexture active = RenderTexture.active; RenderTexture.active = value; GL.Clear(true, true, Color.clear); RenderTexture.active = active; board.GetQuadImage_Original_1(default(PlayerID), board.PaintColors, default(RPCInfo)); _log.LogInfo((object)"RenderTexture rebuilt from PaintColors."); } private static void BroadcastToPlayers(QuadPainterGPU board) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0068: Unknown result type (might be due to invalid IL or missing references) List playerIDs = NetworkSingleton.I.PlayerIDs; if (((NetworkIdentity)board).isServer) { BroadcastToAllPlayers(board); return; } PlayerID? val = PlayerUtils.GetHost()?.PlayerID; if (val.HasValue) { board.GetQuadImage(val.Value, board.PaintColors, default(RPCInfo)); _log.LogInfo((object)"Sent board state to host for relay."); } else { _log.LogWarning((object)"Could not find host player in PlayerIDs."); ChatUtils.AddGlobalNotification("Could not find host player to relay board. Broadcast to everyone"); BroadcastToAllPlayers(board); } } private static void BroadcastToAllPlayers(QuadPainterGPU board) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) List playerIDs = NetworkSingleton.I.PlayerIDs; int num = 0; foreach (PlayerID item in playerIDs) { if (!(item == ((NetworkIdentity)board).localPlayerForced)) { board.GetQuadImage(item, board.PaintColors, default(RPCInfo)); num++; } } _log.LogInfo((object)$"Broadcast to {num} player(s)."); } } } namespace Chalky.Core.Commands { public class ChalkyGetBoardsCommand : IChatCommand, IComparable { public const string CMD = "chalkygetboards"; public string Name => "chalkygetboards"; public string ShortName => "cgb"; public string Description => "List all saved chalkboards. Usage: /chalkygetboards."; public string Namespace => "chalky"; public void Execute(string[] args) { List list = BoardIO.ListSavedBoards(); if (list.Count == 0) { ChatUtils.AddGlobalNotification("No saved chalkboards found."); return; } string text = string.Join(", ", list); ChatUtils.AddGlobalNotification("Saved chalkboards: " + text); } } public class ChalkyHostRelayCommand : IChatCommand, IComparable { public const string CMD = "chalkyhostrelay"; public string Name => "chalkyhostrelay"; public string ShortName => "chr"; public string Description => "Toggle Chalky host relay on/off."; public string Namespace => "chalky"; public void Execute(string[] args) { if (ChalkyPlugin.EnableHostRelay != null) { ChalkyPlugin.EnableHostRelay.Value = !ChalkyPlugin.EnableHostRelay.Value; ChatUtils.AddGlobalNotification("Chalky host relay is now " + (ChalkyPlugin.EnableHostRelay.Value ? "enabled" : "disabled") + "."); } } } public class ChalkyLoadBoardCommand : IChatCommand, IComparable { public const string CMD = "chalkyloadboard"; public string Name => "chalkyloadboard"; public string ShortName => "clb"; public string Description => "Load a chalkboard from disk and sync to all players (HOST only feature). Usage: /chalkyloadboard [name] [index]. Omit [index] to use the currently active board."; public string Namespace => "chalky"; public void Execute(string[] args) { string name = ((args.Length >= 1) ? args[0] : "default"); string indexArg = ((args.Length >= 2) ? args[1] : null); int num = BoardIO.ResolveBoard(indexArg); if (num < 0) { ChatUtils.AddGlobalNotification("Could not determine board index. Interact with a board first, or pass an explicit index. e.g. /chalkyloadboard rat_king 1"); } else { BoardIO.LoadBoard(num, name); } } } public class ChalkySaveBoardCommand : IChatCommand, IComparable { public const string CMD = "chalkysaveboard"; public string Name => "chalkysaveboard"; public string ShortName => "csb"; public string Description => "Save a chalkboard to disk. Usage: /chalkysaveboard [name] [index]. Omit [index] to use the currently active board."; public string Namespace => "chalky"; public void Execute(string[] args) { string text = ((args.Length >= 1) ? args[0] : "default"); string indexArg = ((args.Length >= 2) ? args[1] : null); int num = BoardIO.ResolveBoard(indexArg); if (num < 0) { ChatUtils.AddGlobalNotification("Could not determine board index. Interact with a board first, or pass an explicit index. e.g. /chalkysaveboard rat_king 1"); return; } BoardIO.SaveBoard(num, text); ChatUtils.AddGlobalNotification($"Board {num} saved as '{text}' in {ChalkyPlugin.SaveDir}"); } } public class ChalkySetSize : IChatCommand, IComparable { public const string CMD = "chalkysetsize"; public string Name => "chalkysetsize"; public string ShortName => "css"; public string Description => "Set the size of the chalk. Not persistent, will reset to default on game restart. Game Default: 2. Usage: /chalkysetsize [size]"; public string Namespace => "chalky"; public void Execute(string[] args) { if (ChalkyPlugin.EnableFeature == null) { return; } int result; if (args.Length == 0) { ChalkyPlugin.chalkySize = 2; ChatUtils.AddGlobalNotification("Reset chalk size."); } else if (int.TryParse(args[0], out result)) { if (result < 1) { ChatUtils.AddGlobalNotification("Invalid size value. Please provide an integer value of 1 or greater."); return; } if (result == 1) { ChatUtils.AddGlobalNotification("Sorry! ): Size 1 is not possible atm. Please choose a size of 2 or greater. \nP.S. if you figure out how to do size 1 please let me know!"); return; } ChalkyPlugin.chalkySize = result; ChatUtils.AddGlobalNotification($"Chalk size is now set to {ChalkyPlugin.chalkySize}."); } else { ChatUtils.AddGlobalNotification("Invalid size value. Please provide a valid integer."); } } } public class ChalkyToggleCommand : IChatCommand, IComparable { public const string CMD = "chalkytoggle"; public string Name => "chalkytoggle"; public string ShortName => "ct"; public string Description => "Toggle Chalky feature on/off. "; public string Namespace => "chalky"; public void Execute(string[] args) { if (ChalkyPlugin.EnableFeature != null) { ChalkyPlugin.EnableFeature.Value = !ChalkyPlugin.EnableFeature.Value; ChatUtils.AddGlobalNotification("Chalky feature is now " + (ChalkyPlugin.EnableFeature.Value ? "enabled" : "disabled") + "."); } } } }