diff --git a/JetKarmaBot/CommandRouter.cs b/JetKarmaBot/CommandRouter.cs index 53edf69..f65d5ee 100644 --- a/JetKarmaBot/CommandRouter.cs +++ b/JetKarmaBot/CommandRouter.cs @@ -9,7 +9,7 @@ using Telegram.Bot.Types; namespace JetKarmaBot { - class ChatCommandRouter + public class ChatCommandRouter { User BotUser { get; } [Inject] @@ -52,6 +52,7 @@ namespace JetKarmaBot return false; } + public void Add(IChatCommand c) { log.ConditionalTrace($"Adding command {c.GetType().Name}"); @@ -64,6 +65,48 @@ namespace JetKarmaBot } } + internal 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 + "/" + names[i] + "\n"; + } + build += "/" + 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); + } + + internal 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 + "/" + 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 += 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; + } + Dictionary commands = new Dictionary(); } } diff --git a/JetKarmaBot/Commands/AwardCommand.cs b/JetKarmaBot/Commands/AwardCommand.cs index 44d321e..517be3e 100644 --- a/JetKarmaBot/Commands/AwardCommand.cs +++ b/JetKarmaBot/Commands/AwardCommand.cs @@ -104,6 +104,19 @@ namespace JetKarmaBot.Commands [Inject] Localization Locale { get; set; } User Me { get; } + public string Description => "Awards/revokes an award to a user."; + public string DescriptionID => "jetkarmabot.award.help"; + + public IReadOnlyCollection Arguments => new ChatCommandArgument[] { + new ChatCommandArgument() { + Name="awardtype", + Required=false, + Type=ChatCommandArgumentType.String, + Description="The award to grant to/strip of the specified user", + DescriptionID="jetkarmabot.award.awardtypehelp" + } + }; + public AwardCommand(User me) { Me = me; diff --git a/JetKarmaBot/Commands/ChangeLocaleCommand.cs b/JetKarmaBot/Commands/ChangeLocaleCommand.cs index a60455e..7d8c82c 100644 --- a/JetKarmaBot/Commands/ChangeLocaleCommand.cs +++ b/JetKarmaBot/Commands/ChangeLocaleCommand.cs @@ -67,5 +67,18 @@ namespace JetKarmaBot.Commands [Inject] KarmaContextFactory Db { get; set; } [Inject] TelegramBotClient Client { get; set; } [Inject] Localization Locale { get; set; } + + public string Description => "Switches current chat locale to [locale]"; + public string DescriptionID => "jetkarmabot.changelocale.help"; + + public IReadOnlyCollection Arguments => new ChatCommandArgument[] { + new ChatCommandArgument() { + Name="locale", + Required=false, + Type=ChatCommandArgumentType.String, + Description="The locale to switch to. Can be \"list\" to list all possible locales. Also can be empty to get current locale.", + DescriptionID="jetkarmabot.changelocale.localehelp" + } + }; } } diff --git a/JetKarmaBot/Commands/HelpCommand.cs b/JetKarmaBot/Commands/HelpCommand.cs new file mode 100644 index 0000000..1e455f7 --- /dev/null +++ b/JetKarmaBot/Commands/HelpCommand.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using Telegram.Bot.Args; +using Perfusion; +using JetKarmaBot.Services; +using Telegram.Bot; +using Telegram.Bot.Types.Enums; + +namespace JetKarmaBot.Commands +{ + public class HelpCommand : IChatCommand + { + [Inject] KarmaContextFactory Db; + [Inject] TelegramBotClient Client { get; set; } + [Inject] Localization Locale { get; set; } + ChatCommandRouter Router; + public IReadOnlyCollection Names => new[] { "help" }; + + public string Description => "Displays help text for all(one) command(s)"; + public string DescriptionID => "jetkarmabot.help.help"; + + public IReadOnlyCollection Arguments => new ChatCommandArgument[] { + new ChatCommandArgument() { + Name="command", + Required=false, + Type=ChatCommandArgumentType.String, + Description="The command to return help text for. If empty shows all commands.", + DescriptionID="jetkarmabot.help.commandhelp" + } + }; + + public bool Execute(CommandString cmd, MessageEventArgs args) + { + using (var db = Db.GetContext()) + { + var currentLocale = Locale[db.Chats.Find(args.Message.Chat.Id).Locale]; + if (cmd.Parameters.Length < 1) + { + Client.SendTextMessageAsync( + args.Message.Chat.Id, + Router.GetHelpText(currentLocale), + replyToMessageId: args.Message.MessageId, + parseMode: ParseMode.Html); + return true; + } + else + { + Client.SendTextMessageAsync( + args.Message.Chat.Id, + Router.GetHelpTextFor(cmd.Parameters[0], currentLocale), + replyToMessageId: args.Message.MessageId, + parseMode: ParseMode.Html); + return true; + } + } + } + public HelpCommand(ChatCommandRouter router) + { + Router = router; + } + } +} diff --git a/JetKarmaBot/Commands/IChatCommand.cs b/JetKarmaBot/Commands/IChatCommand.cs index ebfacc0..436f789 100644 --- a/JetKarmaBot/Commands/IChatCommand.cs +++ b/JetKarmaBot/Commands/IChatCommand.cs @@ -6,7 +6,26 @@ namespace JetKarmaBot.Commands public interface IChatCommand { IReadOnlyCollection Names { get; } + string Description { get; } + string DescriptionID { get; } + IReadOnlyCollection Arguments { get; } + bool Execute(CommandString cmd, MessageEventArgs messageEventArgs); } + public struct ChatCommandArgument + { + public string Name; + public bool Required; + public ChatCommandArgumentType Type; + public string Description; + public string DescriptionID; + } + + public enum ChatCommandArgumentType + { + Boolean, + String, + Integer, + } } diff --git a/JetKarmaBot/Commands/StartCommand.cs b/JetKarmaBot/Commands/StartCommand.cs deleted file mode 100644 index fd52cbe..0000000 --- a/JetKarmaBot/Commands/StartCommand.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using Telegram.Bot.Args; -using Perfusion; -using JetKarmaBot.Services; - -namespace JetKarmaBot.Commands -{ - public class StartCommand : IChatCommand - { - [Inject] KarmaContextFactory Db; - - public IReadOnlyCollection Names => new[] { "start" }; - - public bool Execute(CommandString cmd, MessageEventArgs args) - { - using (var db = Db.GetContext()) - { - db.Chats.Add(new Models.Chat { ChatId = args.Message.Chat.Id }); - db.Users.Add(new Models.User { UserId = args.Message.From.Id }); - db.SaveChanges(); - return true; - } - } - } -} diff --git a/JetKarmaBot/Commands/StatusCommand.cs b/JetKarmaBot/Commands/StatusCommand.cs index c095595..db45e3b 100644 --- a/JetKarmaBot/Commands/StatusCommand.cs +++ b/JetKarmaBot/Commands/StatusCommand.cs @@ -67,5 +67,17 @@ namespace JetKarmaBot.Commands [Inject] TelegramBotClient Client { get; set; } [Inject] Localization Locale { get; set; } + public string Description => "Shows the amount of awards that you have"; + public string DescriptionID => "jetkarmabot.status.help"; + + public IReadOnlyCollection Arguments => new ChatCommandArgument[] { + new ChatCommandArgument(){ + Name="awardtype", + Required=false, + Type=ChatCommandArgumentType.String, + Description="The awardtype to show. If empty shows everything.", + DescriptionID= "jetkarmabot.status.awardtypehelp" + } + }; } } diff --git a/JetKarmaBot/JetKarmaBot.cs b/JetKarmaBot/JetKarmaBot.cs index 642bb4f..044b0a9 100644 --- a/JetKarmaBot/JetKarmaBot.cs +++ b/JetKarmaBot/JetKarmaBot.cs @@ -73,7 +73,7 @@ namespace JetKarmaBot void InitCommands(Container c) { Commands = c.ResolveObject(new ChatCommandRouter(Me)); - Commands.Add(c.ResolveObject(new StartCommand())); + Commands.Add(c.ResolveObject(new HelpCommand(Commands))); Commands.Add(c.ResolveObject(new AwardCommand(Me))); Commands.Add(c.ResolveObject(new StatusCommand())); Commands.Add(c.ResolveObject(new LocaleCommand())); diff --git a/JetKarmaBot/lang/be-BY.json b/JetKarmaBot/lang/be-BY.json index c112c0f..66c2527 100644 --- a/JetKarmaBot/lang/be-BY.json +++ b/JetKarmaBot/lang/be-BY.json @@ -13,14 +13,22 @@ "jetkarmabot.award.awardmessage": "Ўручыў \"{0}\" {1}!", "jetkarmabot.award.revokemessage": "Адабраў \"{0}\" у {1}!", "jetkarmabot.award.statustext": "У {0} цяпер {1}{2}.", + "jetkarmabot.award.help": "", + "jetkarmabot.award.awardtypehelp": "", "jetkarmabot.status.listalltext": "У вас :", "jetkarmabot.status.listspecifictext": "У вас зараз {0}{1}.", "jetkarmabot.status.havenothing": "У вас пакуль нічога няма.", + "jetkarmabot.status.help": "", + "jetkarmabot.status.awardtypehelp": "", "jetkarmabot.changelocale.justchanged": "Так дакладна.", "jetkarmabot.changelocale.getlocale": "Я зараз кажу па-беларускай.", "jetkarmabot.changelocale.listalltext": "Я ведаю:", "jetkarmabot.changelocale.errorall": "Мне б хацелася гаварыць на ўсіх мовах у той жа самы час, але з-за абмежаванняў сусвету, мне гэта не дазваляецца.", "jetkarmabot.changelocale.beforenote": "Увага: ", + "jetkarmabot.changelocale.help": "", + "jetkarmabot.changelocale.localehelp": "", + "jetkarmabot.help.help": "", + "jetkarmabot.help.commandhelp": "", "jetkarmabot.awardtypes.star": "Зорачка", "jetkarmabot.awardtypes.pie": "з паліцы піражок", "jetkarmabot.awardtypes.dream": "Мара", diff --git a/JetKarmaBot/lang/en-US.json b/JetKarmaBot/lang/en-US.json index c8bd514..aabbf12 100644 --- a/JetKarmaBot/lang/en-US.json +++ b/JetKarmaBot/lang/en-US.json @@ -12,14 +12,22 @@ "jetkarmabot.award.awardmessage": "Awarded a {0} to {1}!", "jetkarmabot.award.revokemessage": "Revoked a {0} from {1}!", "jetkarmabot.award.statustext": "{0} is at {1}{2} now.", + "jetkarmabot.award.help": "Awards/revokes an award to a user.", + "jetkarmabot.award.awardtypehelp": "The award to grant to/strip of the specified user", "jetkarmabot.status.listalltext": "Your badges report:", "jetkarmabot.status.listspecifictext": "You are at {0}{1} now.", "jetkarmabot.status.havenothing": "You don't have anything yet.", + "jetkarmabot.status.help": "Shows the amount of awards that you have", + "jetkarmabot.status.awardtypehelp": "The awardtype to show. If empty shows everything.", "jetkarmabot.changelocale.justchanged": "Roger that.", "jetkarmabot.changelocale.getlocale": "I'm currently speaking English.", "jetkarmabot.changelocale.listalltext": "I know:", "jetkarmabot.changelocale.errorall": "I would like to speak all languages at once, but because of the rules of the universe, I am not allowed to do that.", "jetkarmabot.changelocale.beforenote": "Warning: ", + "jetkarmabot.changelocale.help": "Switches current chat locale to [locale]", + "jetkarmabot.changelocale.localehelp": "The locale to switch to. Can be \"list\" to list all possible locales. Also can be empty to get current locale", + "jetkarmabot.help.help": "Displays help text for all(one) command(s)", + "jetkarmabot.help.commandhelp": "The command to return help text for. If empty shows all commands.", "jetkarmabot.awardtypes.star": "Star", "jetkarmabot.awardtypes.pie": "a pie from the shelf", "jetkarmabot.awardtypes.dream": "Dream", diff --git a/JetKarmaBot/lang/ru-RU.json b/JetKarmaBot/lang/ru-RU.json index e0f15e7..e599e8c 100644 --- a/JetKarmaBot/lang/ru-RU.json +++ b/JetKarmaBot/lang/ru-RU.json @@ -12,14 +12,22 @@ "jetkarmabot.award.awardmessage": "Вручил \"{0}\" {1}!", "jetkarmabot.award.revokemessage": "Отнял \"{0}\" у {1}!", "jetkarmabot.award.statustext": "У {0} теперь {1}{2}.", + "jetkarmabot.award.help": "Поручает/лишает награду от ползователя/пользователю.", + "jetkarmabot.award.awardtypehelp": "Награду которую поручить/лишить от пользователя", "jetkarmabot.status.listalltext": "У вас :", "jetkarmabot.status.listspecifictext": "У вас сейчас {0}{1}.", "jetkarmabot.status.havenothing": "У вас пока ничего нет.", + "jetkarmabot.status.help": "", + "jetkarmabot.status.awardtypehelp": "", "jetkarmabot.changelocale.justchanged": "Так точно.", "jetkarmabot.changelocale.getlocale": "Я сейчас говорю по-русски.", "jetkarmabot.changelocale.listalltext": "Я знаю:", "jetkarmabot.changelocale.errorall": "Мне бы хотелось говорить на всех языках в то же самое время, но из-за ограничений вселенной, мне это не позволяется.", "jetkarmabot.changelocale.beforenote": "Внимание: ", + "jetkarmabot.changelocale.help": "", + "jetkarmabot.changelocale.localehelp": "", + "jetkarmabot.help.help": "", + "jetkarmabot.help.commandhelp": "", "jetkarmabot.awardtypes.star": "Звездочка", "jetkarmabot.awardtypes.pie": "с полки пирожок", "jetkarmabot.awardtypes.dream": "Мечта",