diff --git a/JetKarmaBot/ChatCommandRouter.cs b/JetKarmaBot/ChatCommandRouter.cs index 5f20d0d..71961d0 100644 --- a/JetKarmaBot/ChatCommandRouter.cs +++ b/JetKarmaBot/ChatCommandRouter.cs @@ -14,44 +14,46 @@ namespace JetKarmaBot { public class ChatCommandRouter : ICommandRouter { - public Telegram.Bot.Types.User Me { get; private set; } + public Telegram.Bot.Types.User Me { get; set; } [Inject] private Logger log; [Inject] private TelegramBotClient Client { get; set; } - public string Prefix => "/"; + public string Prefix => SuperRouter == null ? "/" : SuperRouter.Prefix + SuperCommand + " "; + public ICommandRouter SuperRouter { get; set; } + public string SuperCommand { get; set; } - public async Task Start() - { - Me = await Client.GetMeAsync(); - } - - public Task Execute(object sender, MessageEventArgs args) + public Task Execute(CommandString cs, MessageEventArgs args) { log.Debug("Message received"); var text = args.Message.Text; - if (CommandString.TryParse(text, out var cmd)) + CommandString ncs; + if (cs == null) { - if (cmd.UserName != null && cmd.UserName != Me.Username) + if (!CommandString.TryParse(text, out ncs)) + return Task.FromResult(false); + if (ncs.UserName != null && ncs.UserName != Me.Username) { // directed not at us! log.Debug("Message not directed at us"); return Task.FromResult(false); } + } + else + ncs = new CommandString(cs.Parameters[0], cs.Parameters.Skip(1).ToArray()); - try + try + { + if (commands.ContainsKey(ncs.Command)) { - if (commands.ContainsKey(cmd.Command)) - { - log.Debug($"Handling message via {commands[cmd.Command].GetType().Name}"); - return commands[cmd.Command].Execute(this, cmd, args); - } - } - catch (Exception e) - { - log.Error($"Error while handling command {cmd.Command}!"); - log.Error(e); + log.Debug($"Handling message via {commands[ncs.Command].GetType().Name}"); + return commands[ncs.Command].Execute(ncs, args); } } + catch (Exception e) + { + log.Error($"Error while handling command {ncs.Command}!"); + log.Error(e); + } return Task.FromResult(false); } @@ -59,6 +61,8 @@ namespace JetKarmaBot public void Add(IChatCommand c) { log.ConditionalTrace($"Adding command {c.GetType().Name}"); + c.Router = this; + c.OnMount(); foreach (var name in c.Names) { log.ConditionalTrace($"Mounting {c.GetType().Name} to {name}"); @@ -77,9 +81,9 @@ namespace JetKarmaBot List names = c.Names.ToList(); for (int i = 0; i < names.Count - 1; i++) { - build = build + "/" + names[i] + "\n"; + build = build + Prefix + names[i] + "\n"; } - build += "/" + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " " + getLocalizedCMDDesc(c, loc) + ""; + build += Prefix + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " " + getLocalizedCMDDesc(c, loc) + ""; pieces.Add(build); } return string.Join("\n", pieces); @@ -92,9 +96,9 @@ namespace JetKarmaBot List names = c.Names.ToList(); for (int i = 0; i < names.Count - 1; i++) { - build = build + "/" + names[i] + "\n"; + build = build + Prefix + names[i] + "\n"; } - build += "/" + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " " + getLocalizedCMDDesc(c, loc) + "\n"; + build += Prefix + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " " + getLocalizedCMDDesc(c, loc) + "\n"; build += string.Join("\n", c.Arguments.Select(ca => (!ca.Required ? "[" : "") + ca.Name + (!ca.Required ? "]" : "") + ": " + getLocalizedCMDArgDesc(ca, loc) + "")); return build; } diff --git a/JetKarmaBot/Commands/AwardCommand.cs b/JetKarmaBot/Commands/AwardCommand.cs index 49c7066..260f8b2 100644 --- a/JetKarmaBot/Commands/AwardCommand.cs +++ b/JetKarmaBot/Commands/AwardCommand.cs @@ -18,7 +18,7 @@ namespace JetKarmaBot.Commands [Inject] private Logger log; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { @@ -78,7 +78,7 @@ namespace JetKarmaBot.Commands return true; } - if (CommandRouter.Me.Id == recipientId) + if (Router.Me.Id == recipientId) { await Client.SendTextMessageAsync( args.Message.Chat.Id, @@ -161,7 +161,6 @@ namespace JetKarmaBot.Commands [Inject] KarmaContextFactory Db { get; set; } [Inject] TelegramBotClient Client { get; set; } [Inject] Localization Locale { get; set; } - [Inject] ChatCommandRouter CommandRouter { get; set; } public string Description => "Awards/revokes an award to a user."; public string DescriptionID => "jetkarmabot.award.help"; @@ -182,5 +181,7 @@ namespace JetKarmaBot.Commands DescriptionID="jetkarmabot.award.tohelp" } }; + + public ICommandRouter Router { get; set; } } } diff --git a/JetKarmaBot/Commands/AwardTypeCommand.cs b/JetKarmaBot/Commands/AwardTypeCommand.cs index b21111e..d40a6ba 100644 --- a/JetKarmaBot/Commands/AwardTypeCommand.cs +++ b/JetKarmaBot/Commands/AwardTypeCommand.cs @@ -15,19 +15,22 @@ namespace JetKarmaBot.Commands public string DescriptionID => "jetkarmabot.at.help"; - public VerbCommandRouter Router; + public ChatCommandRouter VerbRouter; [Inject] TelegramBotClient Client { get; set; } [Inject] Localization Locale { get; set; } [Inject] KarmaContextFactory Db { get; set; } + [Inject] IContainer C { get; set; } - public AwardTypeCommand(IContainer c, VerbCommandRouter r) + public void OnMount() { - Router = r; - Router.SuperCommand = "at"; - r.Add(c.GetInstance()); - r.Add(c.GetInstance()); - r.Add(c.GetInstance()); - r.Add(c.GetInstance()); + VerbRouter = C.ResolveObject(new ChatCommandRouter()); + VerbRouter.SuperCommand = "at"; + VerbRouter.SuperRouter = Router; + VerbRouter.Me = Router.Me; + VerbRouter.Add(C.GetInstance()); + VerbRouter.Add(C.GetInstance()); + VerbRouter.Add(C.GetInstance()); + VerbRouter.Add(C.GetInstance()); } public IReadOnlyCollection Arguments => new[] { @@ -40,13 +43,15 @@ namespace JetKarmaBot.Commands } }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public ICommandRouter Router { get; set; } + + public async Task Execute(CommandString cmd, MessageEventArgs args) { - Router.SuperRouter = route; + VerbRouter.SuperRouter = Router; using (var db = Db.GetContext()) { var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; - if (!await Router.Process(route, cmd, args)) + if (!await VerbRouter.Execute(cmd, args)) { await Client.SendTextMessageAsync( args.Message.Chat.Id, diff --git a/JetKarmaBot/Commands/AwardTypeManage/CreateCommand.cs b/JetKarmaBot/Commands/AwardTypeManage/CreateCommand.cs index aafd8eb..99008b2 100644 --- a/JetKarmaBot/Commands/AwardTypeManage/CreateCommand.cs +++ b/JetKarmaBot/Commands/AwardTypeManage/CreateCommand.cs @@ -60,7 +60,9 @@ namespace JetKarmaBot.Commands.AwardTypeManage } }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public ICommandRouter Router { get; set; } + + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { diff --git a/JetKarmaBot/Commands/AwardTypeManage/RemoveCommand.cs b/JetKarmaBot/Commands/AwardTypeManage/RemoveCommand.cs index 088241b..f7bacfb 100644 --- a/JetKarmaBot/Commands/AwardTypeManage/RemoveCommand.cs +++ b/JetKarmaBot/Commands/AwardTypeManage/RemoveCommand.cs @@ -33,7 +33,9 @@ namespace JetKarmaBot.Commands.AwardTypeManage } }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public ICommandRouter Router { get; set; } + + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { diff --git a/JetKarmaBot/Commands/AwardTypeManage/SetParameterCommand.cs b/JetKarmaBot/Commands/AwardTypeManage/SetParameterCommand.cs index 1782f8c..619fa80 100644 --- a/JetKarmaBot/Commands/AwardTypeManage/SetParameterCommand.cs +++ b/JetKarmaBot/Commands/AwardTypeManage/SetParameterCommand.cs @@ -46,7 +46,10 @@ namespace JetKarmaBot.Commands.AwardTypeManage DescriptionID="jetkarmabot.at.set.valuehelp" } }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + + public ICommandRouter Router { get; set; } + + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { diff --git a/JetKarmaBot/Commands/ChangeLocaleCommand.cs b/JetKarmaBot/Commands/ChangeLocaleCommand.cs index 51ef36b..e25758c 100644 --- a/JetKarmaBot/Commands/ChangeLocaleCommand.cs +++ b/JetKarmaBot/Commands/ChangeLocaleCommand.cs @@ -15,7 +15,7 @@ namespace JetKarmaBot.Commands [Inject] private Logger log; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { @@ -92,5 +92,7 @@ namespace JetKarmaBot.Commands DescriptionID="jetkarmabot.changelocale.localehelp" } }; + + public ICommandRouter Router { get; set; } } } diff --git a/JetKarmaBot/Commands/CurrenciesCommand.cs b/JetKarmaBot/Commands/CurrenciesCommand.cs index 21d5073..222d006 100644 --- a/JetKarmaBot/Commands/CurrenciesCommand.cs +++ b/JetKarmaBot/Commands/CurrenciesCommand.cs @@ -23,7 +23,9 @@ namespace JetKarmaBot.Commands public IReadOnlyCollection Arguments => new ChatCommandArgument[] { }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public ICommandRouter Router { get; set; } + + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { diff --git a/JetKarmaBot/Commands/HelpCommand.cs b/JetKarmaBot/Commands/HelpCommand.cs index 4999f50..07b1f2e 100644 --- a/JetKarmaBot/Commands/HelpCommand.cs +++ b/JetKarmaBot/Commands/HelpCommand.cs @@ -28,7 +28,9 @@ namespace JetKarmaBot.Commands } }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public ICommandRouter Router { get; set; } + + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { @@ -37,7 +39,7 @@ namespace JetKarmaBot.Commands { await Client.SendTextMessageAsync( args.Message.Chat.Id, - route.GetHelpText(currentLocale), + Router.GetHelpText(currentLocale), replyToMessageId: args.Message.MessageId, parseMode: ParseMode.Html); return true; @@ -46,7 +48,7 @@ namespace JetKarmaBot.Commands { await Client.SendTextMessageAsync( args.Message.Chat.Id, - route.GetHelpTextFor(cmd.Parameters[0], currentLocale), + Router.GetHelpTextFor(cmd.Parameters[0], currentLocale), replyToMessageId: args.Message.MessageId, parseMode: ParseMode.Html); return true; diff --git a/JetKarmaBot/Commands/IChatCommand.cs b/JetKarmaBot/Commands/IChatCommand.cs index 0d147fa..f3dce93 100644 --- a/JetKarmaBot/Commands/IChatCommand.cs +++ b/JetKarmaBot/Commands/IChatCommand.cs @@ -10,8 +10,10 @@ namespace JetKarmaBot.Commands string Description { get; } string DescriptionID { get; } IReadOnlyCollection Arguments { get; } + ICommandRouter Router { get; set; } - Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs messageEventArgs); + Task Execute(CommandString cmd, MessageEventArgs messageEventArgs); + void OnMount() { } } public struct ChatCommandArgument diff --git a/JetKarmaBot/Commands/LeaderboardCommand.cs b/JetKarmaBot/Commands/LeaderboardCommand.cs index 349c466..26cc031 100644 --- a/JetKarmaBot/Commands/LeaderboardCommand.cs +++ b/JetKarmaBot/Commands/LeaderboardCommand.cs @@ -17,7 +17,7 @@ namespace JetKarmaBot.Commands { public IReadOnlyCollection Names => new[] { "leaderboard" }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { @@ -77,5 +77,7 @@ namespace JetKarmaBot.Commands DescriptionID= "jetkarmabot.leaderboard.awardtypehelp" } }; + + public ICommandRouter Router { get; set; } } } diff --git a/JetKarmaBot/Commands/StatusCommand.cs b/JetKarmaBot/Commands/StatusCommand.cs index 9b493e5..56db65e 100644 --- a/JetKarmaBot/Commands/StatusCommand.cs +++ b/JetKarmaBot/Commands/StatusCommand.cs @@ -17,7 +17,7 @@ namespace JetKarmaBot.Commands { public IReadOnlyCollection Names => new[] { "status" }; - public async Task Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args) + public async Task Execute(CommandString cmd, MessageEventArgs args) { using (var db = Db.GetContext()) { @@ -100,5 +100,7 @@ namespace JetKarmaBot.Commands DescriptionID= "jetkarmabot.status.awardtypehelp" } }; + + public ICommandRouter Router { get; set; } } } diff --git a/JetKarmaBot/ICommandRouter.cs b/JetKarmaBot/ICommandRouter.cs index 956df8e..f45df32 100644 --- a/JetKarmaBot/ICommandRouter.cs +++ b/JetKarmaBot/ICommandRouter.cs @@ -4,6 +4,7 @@ namespace JetKarmaBot { public interface ICommandRouter { + Telegram.Bot.Types.User Me { get; set; } string GetHelpText(Locale loc); string GetHelpTextFor(string commandname, Locale loc); void Add(IChatCommand c); diff --git a/JetKarmaBot/JetKarmaBot.cs b/JetKarmaBot/JetKarmaBot.cs index c1da837..4cb2f9b 100644 --- a/JetKarmaBot/JetKarmaBot.cs +++ b/JetKarmaBot/JetKarmaBot.cs @@ -65,7 +65,7 @@ namespace JetKarmaBot db.Chats.Add(new Models.Chat { ChatId = messageEventArgs.Message.Chat.Id }); await db.SaveChangesAsync(); } - await Commands.Execute(sender, messageEventArgs); + await Commands.Execute(null, messageEventArgs); }); } @@ -84,8 +84,8 @@ namespace JetKarmaBot async Task InitCommands(IContainer c) { - Commands = c.GetInstance(); - await Commands.Start(); + Commands = c.ResolveObject(new ChatCommandRouter()); + Commands.Me = await Client.GetMeAsync(); Commands.Add(c.GetInstance()); Commands.Add(c.GetInstance()); Commands.Add(c.GetInstance()); diff --git a/JetKarmaBot/VerbCommandRouter.cs b/JetKarmaBot/VerbCommandRouter.cs deleted file mode 100644 index 8bfe55c..0000000 --- a/JetKarmaBot/VerbCommandRouter.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using JetKarmaBot.Commands; -using NLog; -using Perfusion; -using Telegram.Bot.Args; - -namespace JetKarmaBot -{ - public class VerbCommandRouter : ICommandRouter - { - Dictionary commands = new Dictionary(); - [Inject] private Logger log; - public string SuperCommand { get; set; } - public string Prefix => SuperRouter.Prefix + SuperCommand + " "; - public ICommandRouter SuperRouter { get; set; } - - public Task Process(ICommandRouter route, CommandString cs, MessageEventArgs args) - { - log.Debug($"(verb for {SuperCommand}) Processing verb"); - if (cs.Parameters.Length < 1) - { - log.Debug($"(verb for {SuperCommand}) too few arguments"); - return Task.FromResult(false); - } - CommandString ncs = new CommandString(cs.Parameters[0], cs.Parameters.Skip(1).ToArray()); - try - { - if (commands.ContainsKey(ncs.Command)) - { - log.Debug($"(verb for {SuperCommand}) Handling via {commands[ncs.Command].GetType().Name}"); - return commands[ncs.Command].Execute(this, ncs, args); - } - } - catch (Exception e) - { - log.Error($"(verb for {SuperCommand}) Error while handling verb {ncs.Command}!"); - log.Error(e); - return Task.FromResult(true); //Don't trigger message - } - - return Task.FromResult(false); - } - - public void Add(IChatCommand c) - { - log.ConditionalTrace($"(verb for {SuperCommand}) Adding command {c.GetType().Name}"); - foreach (var name in c.Names) - { - log.ConditionalTrace($"(verb for {SuperCommand}) Mounting {c.GetType().Name} to {name}"); - if (commands.ContainsKey(name)) - throw new Exception($"command collision for name {name}, commands {commands[name].GetType()} and {c.GetType()}"); - commands[name] = c; - } - } - - public string GetHelpText(Locale loc) - { - List pieces = new List(); - foreach (IChatCommand c in commands.Values.Distinct()) - { - string build = ""; - List names = c.Names.ToList(); - for (int i = 0; i < names.Count - 1; i++) - { - build = build + Prefix + names[i] + "\n"; - } - build += "" + Prefix + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " " + getLocalizedCMDDesc(c, loc) + ""; - pieces.Add(build); - } - return string.Join("\n", pieces); - } - - public string GetHelpTextFor(string commandname, Locale loc) - { - IChatCommand c = commands[commandname]; - string build = ""; - List names = c.Names.ToList(); - for (int i = 0; i < names.Count - 1; i++) - { - build = build + Prefix + names[i] + "\n"; - } - build += Prefix + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " " + getLocalizedCMDDesc(c, loc) + "\n"; - build += string.Join("\n", c.Arguments.Select(ca => (!ca.Required ? "[" : "") + ca.Name + (!ca.Required ? "]" : "") + ": " + getLocalizedCMDArgDesc(ca, loc) + "")); - return build; - } - private string getLocalizedCMDDesc(IChatCommand cmd, Locale loc) - { - if (loc.ContainsKey(cmd.DescriptionID)) return loc[cmd.DescriptionID]; - else return cmd.Description; - } - private string getLocalizedCMDArgDesc(ChatCommandArgument arg, Locale loc) - { - if (loc.ContainsKey(arg.DescriptionID)) return loc[arg.DescriptionID]; - else return arg.Description; - } - } -} \ No newline at end of file