using TGServiceInterface; using System; using System.Collections.Generic; using System.Threading; namespace TGServerService.ChatCommands { /// /// Metadata about the currently running /// sealed class CommandInfo { /// /// If the was invoked by an admin /// public bool IsAdmin { get; set; } /// /// If the was invoked from an admin chat channel /// public bool IsAdminChannel { get; set; } /// /// The name of the invoker /// public string Speaker { get; set; } /// /// A reference to the that runs the that heard the /// public ServerInstance Server { get; set; } } /// /// A command heard by a /// abstract class ChatCommand : Command { /// /// for the /// public static ThreadLocal CommandInfo { get; private set; } = new ThreadLocal(); /// /// If set to , the cannot be invoked by a non-admin or outside an admin chat channel /// public bool RequiresAdmin { get; protected set; } /// /// Shorthand for accessing /// protected ServerInstance Instance { get { return CommandInfo.Value.Server; } } /// public override ExitCode DoRun(IList parameters) { if (RequiresAdmin) { var Info = CommandInfo.Value; if (!Info.IsAdmin) { OutputProc("You are not authorized to use that command!"); return ExitCode.BadCommand; } if (!Info.IsAdminChannel) { OutputProc("Use this command in an admin channel!"); return ExitCode.BadCommand; } } return base.DoRun(parameters); } } /// /// s generated by DreamDaemon via the API /// sealed class ServerChatCommand : ChatCommand { /// /// The help text for the /// readonly string HelpText; /// /// Construct a /// /// The invocation of the /// The help text of the /// If set to , the cannot be invoked by a non-admin or outside an admin chat channel /// The number of parameters the requires public ServerChatCommand(string name, string helpText, bool adminOnly, int requiredParameters) { Keyword = name; RequiresAdmin = adminOnly; HelpText = helpText; RequiredParameters = requiredParameters; } /// public override string GetHelpText() { return HelpText; } /// protected override ExitCode Run(IList parameters) { var res = Instance.SendCommand(String.Format("{0};sender={1};custom={2}", Keyword, CommandInfo.Value.Speaker, Program.SanitizeTopicString(String.Join(" ", parameters)))); if (res != "SUCCESS" && !String.IsNullOrWhiteSpace(res)) OutputProc(res); return ExitCode.Normal; } } /// /// The main root chat command /// sealed class RootChatCommand : RootCommand { /// /// Construct a /// /// List of s supplied by DreamDaemon public RootChatCommand(List serverCommands) { var tmp = new List { new PRsCommand(), new VersionCommand(), new RevisionCommand(), new ByondCommand(), new KekCommand() }; if (serverCommands != null) tmp.AddRange(serverCommands); Children = tmp.ToArray(); serverCommands = new List(); PrintHelpList = true; } } /// /// Retrieves the git SHA of the live DreamDaemon code /// sealed class RevisionCommand : ChatCommand { /// /// Construct a /// public RevisionCommand() { Keyword = "revision"; } /// protected override ExitCode Run(IList parameters) { var res = Instance.LiveSha(); if (res == "UNKNOWN") { OutputProc(res); return ExitCode.ServerError; } OutputProc(String.Format("^{0}", res)); return ExitCode.Normal; } /// public override string GetHelpText() { return "Prints the current code revision of the repository (not the server)"; } } /// /// Retrieve the installed, staged, or latest availab /// sealed class ByondCommand : ChatCommand { /// /// Construct a /// public ByondCommand() { Keyword = "byond"; } /// protected override ExitCode Run(IList parameters) { var type = ByondVersion.Installed; if (parameters.Count > 0) if (parameters[0].ToLower() == "--staged") type = ByondVersion.Staged; else if (parameters[0].ToLower() == "--latest") type = ByondVersion.Latest; OutputProc(Instance.GetVersion(type) ?? "None"); return ExitCode.Normal; } /// public override string GetHelpText() { return "Gets the specified BYOND version"; } /// public override string GetArgumentString() { return "[--staged|--latest]"; } } /// /// Retrieve the current service version /// sealed class VersionCommand : ChatCommand { /// /// Construct a /// public VersionCommand() { Keyword = "version"; } /// protected override ExitCode Run(IList parameters) { OutputProc(Instance.Version()); return ExitCode.Normal; } /// public override string GetHelpText() { return "Gets the running service version"; } } /// /// kek /// sealed class KekCommand : ChatCommand { /// /// Construct a /// public KekCommand() { Keyword = "kek"; } /// protected override ExitCode Run(IList parameters) { OutputProc("kek"); return ExitCode.Normal; } /// public override string GetHelpText() { return "kek"; } } /// /// Retrieve the list of test-merged github pull requests /// sealed class PRsCommand : ChatCommand { /// /// Construct a /// public PRsCommand() { Keyword = "prs"; } /// protected override ExitCode Run(IList parameters) { var PRs = Instance.MergedPullRequests(out string res); if (PRs == null) { OutputProc(res); return ExitCode.ServerError; } if (PRs.Count == 0) OutputProc("None!"); else { res = ""; foreach (var I in PRs) res += "#" + I.Number + " "; OutputProc(res); } return ExitCode.Normal; } /// public override string GetHelpText() { return "Gets the currently merged pull requests in the repository"; } } }