Ejemplo n.º 1
0
        public async Task Ping([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "ping", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                string response;
                if (Context.Guild != null)
                {
                    var language = statecollection.GetLanguage(Context.Guild, database);

                    // make sure that the user has the right permissions
                    if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Public, database))
                    {
                        await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                        return;
                    }

                    response = statecollection.GetLanguage(Context.Guild, database).GetString("command.ping");
                }
                else
                {
                    response = "pong";
                }
                await Context.Channel.SendMessageAsync(response);
            }
        }
Ejemplo n.º 2
0
        public async Task unset_notification([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "unset notification", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                // apply change and report to user
                GuildTB gtb      = statecollection.GetGuildEntry(Context.Guild, database);
                var     language = statecollection.GetLanguage(Context.Guild, database, gtb);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Owner, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                gtb.Notification = null;
                statecollection.SetGuildEntry(gtb, database);
                await Context.Channel.SendMessageAsync(language.GetString("command.unset.notification"));
            }
        }
Ejemplo n.º 3
0
        public async Task StopApplication([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "application stop", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                StringConverter language = statecollection.GetLanguage(Context.Guild, database);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Admin, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                // make sure that applications are taking place
                ApplicationTB appentry = statecollection.GetApplicationEntry(Context.Guild, database);
                if (appentry == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstop.noapp"));

                    return;
                }

                // stop the applications
                await statecollection.StopApplication(Context.Guild, database, appentry);

                await Context.Channel.SendMessageAsync(language.GetString("command.appstop.success"));
            }
        }
Ejemplo n.º 4
0
 private void Init()
 { //There, we have to load the commands from JSON file
     me = this;
     cm = gameObject.AddComponent<CommandMethods>();
     _text = new GUIStyle("label") { wordWrap = true, richText = true };
     Debug.isGamingEnabled = !m_disableDebug;
 }
Ejemplo n.º 5
0
        public async Task set_language(string newlang)
        {
            using (var database = new GuildDB())
            {
                // log execution
                CommandMethods.LogExecution(logger, "set language", Context);

                // indicate that the command is being worked on
                await Context.Channel.TriggerTypingAsync();

                // grab the guild language
                GuildTB gtb      = statecollection.GetGuildEntry(Context.Guild, database);
                var     language = statecollection.GetLanguage(Context.Guild, database, gtb);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Admin, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                // set the language
                if (!statecollection.SetLanguage(Context.Guild, newlang, database, gtb))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nolanguage"));

                    return;
                }

                // indicate success
                language = statecollection.GetLanguage(Context.Guild, database, gtb);
                await Context.Channel.SendMessageAsync(language.GetString("command.set.language"));
            }
        }
Ejemplo n.º 6
0
        public async Task set_permission(SocketRole role, string permissionstr, [Remainder] string rest = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "set permission", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                GuildTB         gtb      = statecollection.GetGuildEntry(Context.Guild, database);
                StringConverter language = statecollection.GetLanguage(Context.Guild, database, gtb);

                byte permission        = PermissionHelper.StringToPermission(permissionstr);
                byte target_permission = PermissionHelper.GetRolePermission(role, database);

                // make sure that the calling user has the right permission to perform this command
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, Math.Max(permission, target_permission), database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                // execute the command
                PermissionHelper.SetRolePermission(role, permission, database, gtb);

                // return success
                await Context.Channel.SendMessageAsync(language.GetString("command.set.permission"));
            }
        }
Ejemplo n.º 7
0
        public async Task set_timezones([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "set timezones", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                var language = statecollection.GetLanguage(Context.Guild, database);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Admin, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                await Context.Channel.SendMessageAsync(language.GetString("command.set.timezones.wait"));

                // find all the current roles in the guild
                IEnumerable <SocketRole> present = from role in Context.Guild.Roles
                                                   where DateTimeMethods.IsTimezone(role.Name)
                                                   select role;

                // add all the timezones that are not present already
                foreach (string t in DateTimeMethods.Timezones())
                {
                    if (!present.Any(x => x.Name == t))
                    {
                        var role = await Context.Guild.CreateRoleAsync(t, isHoisted : false, permissions : constants.RolePermissions);

                        await role.ModifyAsync(x =>
                        {
                            x.Mentionable = false;
                        });
                    }
                }

                // update the roles of the timezones that áre present
                foreach (SocketRole sr in present)
                {
                    await sr.ModifyAsync((x) =>
                    {
                        x.Permissions = constants.RolePermissions;
                        x.Mentionable = false;
                    });
                }

                // return success to the user
                await Context.Channel.TriggerTypingAsync();

                await Context.Channel.SendMessageAsync(statecollection.GetLanguage(Context.Guild, database).GetString("command.set.timezones.done"));
            }
        }
Ejemplo n.º 8
0
        public async Task Events(EventSpecifier eventSpecifier, [Remainder] string rest = null)
        {
            using (var database = new GuildDB())
            {
                // log execution
                CommandMethods.LogExecution(logger, "get event", Context);

                // indicate that the command is being worked on
                await Context.Channel.TriggerTypingAsync();

                GuildTB         gtb      = statecollection.GetGuildEntry(Context.Guild, database);
                StringConverter language = statecollection.GetLanguage(Context.Guild, database, gtb);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Member, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                var events = agenda.GetEvents(Context.Guild, database);

                // make sure that the agenda is not empty
                if (events.Count() == 0)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.event.empty"));

                    return;
                }

                // create an embed
                EmbedBuilder eb = new EmbedBuilder()
                                  .WithColor(Color.DarkRed);

                switch (eventSpecifier)
                {
                case EventSpecifier.All:
                    eb.Title = $":calendar_spiral: All events for '{Context.Guild.Name}'";
                    foreach (EventTB e in events)
                    {
                        eb.AddField(e.Name, e.Date.ToString(@"dd MMMM \a\t hh:mm tt UTC"));
                    }
                    break;

                case EventSpecifier.First:
                    eb.Title = $":calendar_spiral: First event for '{Context.Guild.Name}'";
                    EventTB ev = events.First();
                    eb.AddField(ev.Name, ev.Date.ToString(@"dd MMMM \a\t hh:mm tt UTC"));
                    break;
                }

                Embed embed = eb.Build();
                await Context.Channel.SendMessageAsync(language.GetString("present"), embed : embed);
            }
        }
Ejemplo n.º 9
0
        //////////////////////////////////////////////////////////////////////
        // scan args for a command to run or just check usage

        private bool parse_args(string[] command_line, bool run_commands)
        {
            int    functions_called = 0;
            string s = string.Join(" ", command_line);

            char[]   semicolon  = new char[] { ';' };
            char[]   whitespace = new char[] { ' ', '\t' };
            string[] p          = s.Split(semicolon, StringSplitOptions.RemoveEmptyEntries);
            foreach (string a in p)
            {
                string[] argv = a.Split(whitespace, StringSplitOptions.RemoveEmptyEntries);
                if (argv.Length != 0)
                {
                    List <int> param_counts = new List <int>();
                    bool       name_match   = false;
                    bool       args_match   = false;

                    foreach (MethodInfo method in CommandMethods.Where(x => string.Compare(argv[0], x.Name, StringComparison.OrdinalIgnoreCase) == 0))
                    {
                        name_match = true;
                        ParameterInfo[] parameters = method.GetParameters();
                        param_counts.Add(parameters.Length);
                        if (parameters.Length == argv.Length - 1)
                        {
                            args_match        = true;
                            functions_called += 1;
                            run(method, argv, run_it: run_commands);
                        }
                    }
                    if (!name_match)
                    {
                        throw new UsageError($"Unknown command {argv[0]}");
                    }
                    if (!args_match)
                    {
                        throw new UsageError($"Wrong number of arguments for command '{argv[0]}' - expected {string.Join(" or ", param_counts)}, got {argv.Length - 1}");
                    }
                }
            }
            if (functions_called == 0 && run_commands)
            {
                MethodInfo m = DefaultMethod;
                if (m != null)
                {
                    try
                    {
                        m.Invoke(this, null);
                    }
                    catch (TargetInvocationException e)
                    {
                        ExceptionDispatchInfo.Capture(e.InnerException).Throw();
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 10
0
 internal static void ExecuteCommand(string command)
 {
     if (command.IndexOf(' ') >= 0)
         command = Regex.Replace(command, @"\s+", " "); //Remove repeated chars, for example: "Hello,   how are  you? " into "Hello, how are you?"
     if (command.EndsWith(" "))
         command = command.Substring(0, command.Length - 1); //Look for last char as space, to rem it
     string gettedCommand = command.IndexOf(' ') >= 0 ? command.Substring(0, command.IndexOf(' ')) : command, //Get command name
            commandParams = command.IndexOf(' ') >= 0 ? command.Substring(gettedCommand.Length + 1) : ""; //Get the command params
     UnityEngine.Debug.Log("Searching for command /" + gettedCommand);
     Command c = null;
     Param[] set = null;
     foreach (Command cm in me.commandList)
     {
         if (cm.command == gettedCommand)
         {
             c = cm;
             break;
         }
         bool br = false;
         foreach (string al in cm.aliases)
             if (al == gettedCommand)
             {
                 c = cm;
                 br = true;
                 break;
             }
         if (br)
             break;
     }
     if (c == null)
     {
         AddMessage("Command not found!"); //There would be recomendable to send suggested commands (I have to).
         return;
     }
     if (commandParams.Length > 0 && c.paramSets.Length > 0)
     {
         int posUsed = -1;
         if (c.ParseParams(commandParams, ref set, ref posUsed))
             CommandMethods.ProcessCommand(c.linkedMethod, c, set, posUsed);
         else
         {
             AddMessage("Command form not recognized! Showing help below:");
             c.DisplayHelp();
         }
     }
     else
         CommandMethods.ProcessCommand(c.linkedMethod, c, null, -1);
 }
Ejemplo n.º 11
0
        public static int Main(string[] args)
        {
            try
            {
                var command = args.FirstOrDefault()?.ToLower() ?? "default";

                var method = CommandMethods
                             .SingleOrDefault(m => string.Equals(m.Name, command, StringComparison.CurrentCultureIgnoreCase));

                if (method == null)
                {
                    if (command == "help")
                    {
                        DefaultHelp();
                    }
                    else
                    {
                        throw new Exception("Unknown command: " + command);
                    }

                    return(Failure);
                }

                method.Invoke(new Commands(), Parameters(method, args.Skip(1).ToArray()));

                using (Foreground.Green)
                {
                    WriteLine();
                    WriteLine("Build Succeeded!");
                }

                return(Success);
            }
            catch (Exception exception)
            {
                using (Foreground.DarkRed)
                {
                    WriteLine();
                    WriteLine(exception.Message);
                    WriteLine();
                    WriteLine("Build Failed!");
                }

                return(Failure);
            }
        }
Ejemplo n.º 12
0
        public async Task Cancel([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "cancel", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                var language = statecollection.GetLanguage(Context.Guild, database);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Member, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                // make sure that the input is not empty
                if (input == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.cancel.empty"));

                    return;
                }

                // try to remove event with given name from the agenda
                if (!agenda.Cancel(Context.Guild, database, input))
                {
                    // return failure to the user
                    await Context.Channel.SendMessageAsync(language.GetString("command.cancel.notplanned"));

                    return;
                }

                // return success to the user
                await Context.Channel.SendMessageAsync(language.GetString("command.cancel.success", new SentenceContext()
                                                                          .Add("title", input)));
            }
        }
Ejemplo n.º 13
0
        public async Task Restart()
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "restart", Context);

                if (Context.Guild != null)
                {
                    StringConverter language = statecollection.GetLanguage(Context.Guild, database);
                    await Context.Channel.SendMessageAsync(language.GetString("command.restart"));
                }
                else
                {
                    await Context.Channel.SendMessageAsync("Restarting now...");
                }

                bot.Stop(true);
            }
        }
Ejemplo n.º 14
0
        public async Task unset_timezones([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "unset timezones", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                var language = statecollection.GetLanguage(Context.Guild, database);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Owner, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                await Context.Channel.SendMessageAsync(language.GetString("command.unset.timezones.wait"));

                // find all the current roles in the guild
                IEnumerable <KeyValuePair <string, ulong> > roles = Context.Guild.Roles.Select(r => new KeyValuePair <string, ulong>(r.Name, r.Id));

                // delete all the roles that are timezones
                foreach (var t in roles)
                {
                    if (DateTimeMethods.IsTimezone(t.Key))
                    {
                        await Context.Guild.GetRole(t.Value).DeleteAsync();
                    }
                }

                await Context.Channel.TriggerTypingAsync();

                await Context.Channel.SendMessageAsync(language.GetString("command.unset.timezones.done"));
            }
        }
Ejemplo n.º 15
0
        public async Task Status([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log execution
                CommandMethods.LogExecution(logger, "get status", Context);

                // indicate that the command is being worked on
                await Context.Channel.TriggerTypingAsync();

                GuildTB         gtb      = statecollection.GetGuildEntry(Context.Guild, database);
                StringConverter language = statecollection.GetLanguage(Context.Guild, database, gtb);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Admin, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                // get all the data from the database
                ApplicationTB     apptb = statecollection.GetApplicationEntry(Context.Guild, database);
                SocketTextChannel pc    = statecollection.GetPublicChannel(Context.Guild, database, gtb);
                SocketTextChannel nc    = statecollection.GetNotificationChannel(Context.Guild, database, gtb);

                EmbedBuilder eb = new EmbedBuilder()
                                  .WithColor(Color.Gold)
                                  .WithTitle($":clipboard: Status information for '{gtb.Name}'");

                eb.AddField("Language", gtb.Language);
                eb.AddField("Public channel", (pc != null ? pc.Mention : "Undefined"));
                eb.AddField("Notification channel", (nc != null ? nc.Mention : "Undefined"));
                eb.AddField("Application", (apptb != null ? $"ends on: {apptb.Deadline.ToString("dd MMMM a\\t hh:mm tt UTC")}" : "No active application"));

                await Context.Channel.SendMessageAsync(statecollection.GetLanguage(Context.Guild, database, gtb).GetString("present"), embed : eb.Build());
            }
        }
Ejemplo n.º 16
0
        public async Task Guilds()
        {
            using (var database = new GuildDB())
            {
                // log execution
                CommandMethods.LogExecution(logger, "get guilds", Context);

                // indicate that the command is being worked on
                await Context.Channel.TriggerTypingAsync();

                // get all the guilds from the database
                var dbresult = (from g in database.Guilds
                                orderby g.Name
                                select g.Name).ToArray();

                // display all guilds in an embed
                EmbedBuilder eb = new EmbedBuilder()
                                  .WithColor(Color.Gold);

                eb.AddField("Guilds", dbresult.Aggregate((x, y) => $"{x}\n{y}"));

                await Context.Channel.SendMessageAsync("", embed : eb.Build());
            }
        }
Ejemplo n.º 17
0
        public async Task Languages()
        {
            using (var database = new GuildDB())
            {
                // log execution
                CommandMethods.LogExecution(logger, "get languages", Context);

                // indicate that the bot is working on the answer
                await Context.Channel.TriggerTypingAsync();

                GuildTB gtb      = statecollection.GetGuildEntry(Context.Guild, database);
                var     language = statecollection.GetLanguage(Context.Guild, database, gtb);

                // make sure that caller has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Admin, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                EmbedBuilder eb = new EmbedBuilder()
                                  .WithTitle(":speech_balloon: Languages")
                                  .WithColor(Color.DarkBlue);

                // get the current language
                eb.AddField("Current Language", gtb.Language);

                // find all available languages
                IEnumerable <string> languages = Directory.GetFiles(constants.PathToLanguages(), "*.lang").Select(x => Path.GetFileNameWithoutExtension(x)).OrderBy(x => x);
                eb.AddField("Available Languages", languages.Aggregate((x, y) => $"{x}\n{y}"));

                // send feedback to caller
                await Context.Channel.SendMessageAsync(language.GetString("present"), embed : eb.Build());
            }
        }
Ejemplo n.º 18
0
        public async Task Plan([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "plan", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                var language = statecollection.GetLanguage(Context.Guild, database);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Member, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                //make sure that user has a timezone assigned
                TimeZoneInfo timezone = DateTimeMethods.UserToTimezone(Context.User);
                if (timezone == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.time.notimezone"));

                    return;
                }

                // make sure that the command is not empty
                if (input == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.plan.empty"));

                    return;
                }

                // make sure that a valid input has been provided
                DateTimeMethods.StringToAppointment(input, out DateTime? date, out string title);
                if (!date.HasValue)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.plan.error"));

                    return;
                }

                // make sure that the provided date is in the future
                var dateutc = TimeZoneInfo.ConvertTimeToUtc(date.Value, timezone);
                if (dateutc < DateTime.UtcNow)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.plan.past"));

                    return;
                }

                // build an embed that displays the event
                EmbedBuilder eb = new EmbedBuilder()
                                  .WithColor(Color.DarkGreen)
                                  .WithTitle($":calendar_spiral: Event");

                eb.AddField("Title", title);
                eb.AddField("Date", dateutc.ToString("dd MMMM a\\t hh:mm tt UTC"));

                // put the plan in the agenda
                agenda.Plan(Context.Guild, database, title, dateutc, notifications: constants.EventNotifications);

                // return success to the user
                await Context.Channel.SendMessageAsync(language.GetString("command.plan.success"), embed : eb.Build());
            }
        }
Ejemplo n.º 19
0
        public async Task StartApplications([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "application start", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                GuildTB dbentry = statecollection.GetGuildEntry(Context.Guild, database);

                var language = statecollection.GetLanguage(Context.Guild, database, dbentry);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Admin, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                // allow only 1 application per guild
                if (statecollection.GetApplicationEntry(Context.Guild, database) != null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstart.isactive"));

                    return;
                }

                // command must have input
                if (input == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstart.empty"));

                    return;
                }

                // user must have a timezone
                TimeZoneInfo usertimezone = DateTimeMethods.UserToTimezone(Context.User);
                if (usertimezone == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstart.notimezone"));

                    return;
                }

                // given deadline must be in proper format
                DateTime?localdeadline = DateTimeMethods.StringToDatetime(input);
                if (!localdeadline.HasValue)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstart.error"));

                    return;
                }
                DateTime utcdeadline = TimeZoneInfo.ConvertTimeToUtc(localdeadline.Value, usertimezone);

                // deadline must be in the future
                if (utcdeadline < DateTime.UtcNow)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstart.past"));

                    return;
                }

                // creation must succeed
                IInviteMetadata invite = await statecollection.StartApplication(Context.Guild, database, utcdeadline, dbentry);

                if (invite == null)
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.appstart.error"));

                    return;
                }

                // return success to the user
                await Context.Channel.SendMessageAsync(language.GetString("command.appstart.success", new SentenceContext()
                                                                          .Add("url", invite.Url)));
            }
        }
        public string Execute(string input = null)
        {
            // It's perfectly valid to call it without passing anything in. This assumes that a command will acquire text somehow.
            if (input == null)
            {
                input = String.Empty;
            }

            // If there's nothing to do, just send the same string back...
            if (!commands.Any())
            {
                return(input);
            }

            foreach (TextFilterCommand command in commands)
            {
                // Are we writing to a variable?
                if (command.NormalizedCommandName == WRITE_TO_VARIABLE_COMMAND)
                {
                    string variableName = command.CommandArgs.First().Value;

                    if (variables.ContainsKey(variableName))
                    {
                        variables.Remove(variableName);
                    }

                    variables.Add(variableName, input);

                    continue;
                }

                // Are we reading from a variable?
                if (command.NormalizedCommandName == READ_FROM_VARIABLE_COMMAND)
                {
                    string variableName = command.CommandArgs.First().Value;

                    if (variables.ContainsKey(variableName))
                    {
                        input = variables[variableName].ToString();
                    }
                    else
                    {
                        // Do we have a default argument as the second argument?
                        if (command.CommandArgs.Count > 1)
                        {
                            // Yes, use it
                            input = command.CommandArgs[1];
                        }
                        else
                        {
                            throw new Exception("Variable name \"" + variableName + "\" not found.");
                        }
                    }

                    continue;
                }


                // If it doesn't contain a dot, then put it in the "core" category
                if (!command.NormalizedCommandName.Contains("."))
                {
                    command.CommandName = String.Concat("core.", command.CommandName);
                }

                // Do we have such a command?
                if (!CommandMethods.ContainsKey(command.NormalizedCommandName))
                {
                    throw new Exception("No command method found for \"" + command.CommandName + "\"");
                }

                // Set a pipeline reference
                command.Pipeline = this;

                // Execute
                MethodInfo method = CommandMethods[command.NormalizedCommandName];
                try
                {
                    // This is where we make the method call
                    var result = (string)method.Invoke(null, new object[] { input, command });

                    if (!String.IsNullOrWhiteSpace(command.VariableName))
                    {
                        WriteToVariable(command.VariableName, result);
                    }
                    else
                    {
                        // If we're not writing to a variable, then we're changing the active text
                        input = result;
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(String.Concat(
                                            method.Name,
                                            ". ",
                                            Environment.NewLine,
                                            e.GetBaseException().Message,
                                            Environment.NewLine,
                                            e.GetBaseException().StackTrace));
                }
            }

            return(input);
        }
Ejemplo n.º 21
0
 private MethodInfo MethodByCmdName(string cmd)
 {
     return(CommandMethods.Where(cm => GetAttribute(cm).Command == cmd).FirstOrDefault());
 }
Ejemplo n.º 22
0
 private void Awake()
 {
     me = GetComponent<CommandMethods>();
 }
Ejemplo n.º 23
0
        public string Execute(string input = null)
        {
            // Clear the debug data
            LogEntries.Clear();

            // Have any commandFactories been defined?
            if (commandFactories != null)
            {
                // We need to execute any command factories and modify the command list
                // We can't do a foreach, because we're going to modify this list
                // Also: _this does not account for recursion or circular inclusions!!!!_
                // The GetLogicHashCode method can be used to compare command logic to ensure uniqueness

                for (var i = 0; i < commands.Count(); i++)
                {
                    var thisCommand    = commands[i];
                    var factoryCommand = commandFactories.FirstOrDefault(c => Regex.IsMatch(thisCommand.NormalizedCommandName, StringUtilities.ConvertWildcardToRegex(c.Key), RegexOptions.IgnoreCase));

                    if (factoryCommand.Value != null) // This test is a little weird. KeyValue is a struct, so a normal null check doesn't work, so I do the null check against the Value...
                    {
                        // Run the factory, passing the entire command
                        var commandsToInclude = factoryCommand.Value(thisCommand);

                        // Include the source, for logging
                        commandsToInclude.ToList().ForEach(c =>
                        {
                            c.CommandFactorySource = thisCommand.OriginalText;
                        });

                        // Insert these commands AFTER the factory command
                        commands.InsertRange(i + 1, commandsToInclude);

                        // Delete the factory command
                        commands.Remove(thisCommand);

                        // Inserted commands will also be processed for command factories, since the next iteration of this loop will pickup at the first inserted command
                    }
                }
            }
            // At this point, all command factories should be resolved for this and subsequent executions

            // Add a pass-through command at the end just to hold a label called "end".
            if (commands.Any(c => c.Label == FINAL_COMMAND_LABEL))
            {
                commands.Remove(commands.First(c => c.Label == FINAL_COMMAND_LABEL));
            }
            commands.Add(
                new PipelineCommand()
            {
                FullyQualifiedCommandName = LABEL_COMMAND,
                Label       = FINAL_COMMAND_LABEL,
                CommandArgs = new Dictionary <object, string>()
                {
                    { 0, FINAL_COMMAND_LABEL }
                }
            }
                );

            // We set the global variable to the incoming string. It will be modified and eventually returned from this variable slot.
            SetVariable(GLOBAL_VARIABLE_NAME, input);

            // We're going to set up a linked list of commands. Each command holds a reference to the next command in its SendToLabel property. The last command is NULL.
            var commandQueue = new Dictionary <string, PipelineCommand>();

            for (var index = 0; index < commands.Count; index++)
            {
                var thisCommand = commands[index];

                // If this is a "Label" command, then we need to get the label "out" to a property
                if (thisCommand.NormalizedCommandName == LABEL_COMMAND)
                {
                    thisCommand.Label = thisCommand.DefaultArgument;
                }

                // If (1) this command doesn't already have a SendToLabel (it...shouldn't...I don't think), and (2) we're not on the last command, then set the SendToLabel of this command to the Label of the next command
                if (thisCommand.SendToLabel == null && index < commands.Count - 1)
                {
                    thisCommand.SendToLabel = commands[index + 1].Label;
                }

                // Add this command to the queue, keyed to its Label
                commandQueue.Add(thisCommand.Label.ToLower(), thisCommand);
            }

            // We're going to stay in this loop, resetting "command" each iteration, until SendToLabel is NULL
            NextCommandLabel = commandQueue.First().Value.Label;
            while (true)
            {
                // Do we have a next command?
                if (NextCommandLabel == null)
                {
                    // Stick a fork in us, we're done
                    break;
                }

                // Does the specified next command exist?
                if (!commandQueue.ContainsKey(NextCommandLabel.ToLower()))
                {
                    throw new Exception(string.Format("Specified command label \"{0}\" does not exist in the command queue.", NextCommandLabel));
                }

                // Get the next command
                var command = commandQueue[NextCommandLabel.ToLower()];

                // Create the debug entry
                var executionLog = new ExecutionLog(command, Variables);

                // Are we writing to a variable?
                if (command.NormalizedCommandName == WRITE_TO_VARIABLE_COMMAND)
                {
                    // Get the active text and copy it to a different variable
                    SetVariable(command.OutputVariable, GetVariable(GLOBAL_VARIABLE_NAME));
                    NextCommandLabel = command.SendToLabel;
                    continue;
                }

                // Are we reading from a variable?
                if (command.NormalizedCommandName == READ_FROM_VARIABLE_COMMAND)
                {
                    // Get the variable and copy it into the active text
                    SetVariable(GLOBAL_VARIABLE_NAME, GetVariable(command.InputVariable));
                    NextCommandLabel = command.SendToLabel;
                    continue;
                }

                // Is this a label?
                if (command.NormalizedCommandName == LABEL_COMMAND)
                {
                    NextCommandLabel = command.SendToLabel;
                    continue;
                }

                // Note that the above commands will never actually execute. This is why their methods are just empty shells...

                // Do we a method for this command?
                if (!CommandMethods.ContainsKey(command.NormalizedCommandName))
                {
                    // This command doesn't exist. We're going to try to be helpful and let the user know if it's becaue of a missing dependency.
                    var errorString = hiddenCommandMethods.ContainsKey(command.NormalizedCommandName)
                        ? string.Format(hiddenCommandMethods[command.NormalizedCommandName])  // This should be the reason the command is hidden
                        : string.Format(@"No command loaded for ""{0}""", command.FullyQualifiedCommandName);

                    throw new DeninaException(errorString);
                }

                // Set a pipeline reference which can be accessed inside the filter method
                command.Pipeline = this;

                // Resolve any arguments that are actually variable names
                command.ResolveArguments();

                // Execute
                var method = CommandMethods[command.NormalizedCommandName];
                try
                {
                    timer.Reset();
                    timer.Start();

                    // Get the input from the designated variable
                    var filterInput = (string)GetVariable(command.InputVariable);

                    // Process the input through the event
                    var executingFilterEventArgs = new FilterEventArgs(command, filterInput, null);
                    OnFilterExecuting(executingFilterEventArgs);
                    filterInput = executingFilterEventArgs.Input;
                    command     = executingFilterEventArgs.Command; // I'm not sure I need to do this, but just to be explicit...

                    // TO DO: How do we track changes made to the input in an event?
                    executionLog.InputValue = GetVariable(command.InputVariable).ToString();

                    // This is where we make the actual method call. We get the text out of the InputVariable slot, and we put it back into the OutputVariable slot. (These are usually the same slot...)
                    // We create a delete so that we can use anonymous functions. Since non-anonymous functions are static, and anonymous functions aren't static, we have to create a
                    // delegate so we can handle both
                    var filter       = (FilterDelegate)Delegate.CreateDelegate(typeof(FilterDelegate), null, method);
                    var filterOutput = filter(filterInput, command, executionLog);

                    // Process the output through the event
                    var executedFilterEventArgs = new FilterEventArgs(command, null, filterOutput);
                    OnFilterExecuted(executedFilterEventArgs);
                    filterOutput = executedFilterEventArgs.Output;

                    // TO DO: How do we track changes made to the output in an event?
                    executionLog.OutputValue = filterOutput.ToString();

                    // If we're appending, tack this onto what was passed in (really, prepend was was passed in)
                    if (command.AppendToOutput)
                    {
                        filterOutput = string.Concat(GetVariable(command.OutputVariable), filterOutput);
                    }

                    // We're going to "SafeSet" this, so they can't pipe output to a read-only variable
                    SafeSetVariable(command.OutputVariable, filterOutput);

                    executionLog.ElapsedTime = timer.ElapsedMilliseconds;

                    // If we got here with no exception
                    executionLog.SuccessfullyExecuted = true;
                }
                catch (DeninaException e)
                {
                    e.CurrentCommandText = command.OriginalText;
                    e.CurrentCommandName = command.NormalizedCommandName;
                    throw;
                }
                // We are not going to handle a non-DeninaException. We'll just let that bubble up to the implementation's error handler

                // Set the pointer to the next command
                NextCommandLabel = command.SendToLabel;

                LogEntries.Add(executionLog);
            }

            var finalOutput = GetVariable(GLOBAL_VARIABLE_NAME).ToString();

            // Raise the PipelineCompleted event
            var eventArgs = new PipelineEventArgs(this, finalOutput);

            OnPipelineComplete(eventArgs);
            finalOutput = eventArgs.Value;

            return(finalOutput);
        }
Ejemplo n.º 24
0
        public string Execute(string input = null)
        {
            // Clear the debug data
            DebugData.Clear();

            // Add a pass-through command at the end just to hold a label called "end".
            if (commands.Any(c => c.Label == FINAL_COMMAND_LABEL))
            {
                commands.Remove(commands.First(c => c.Label == FINAL_COMMAND_LABEL));
            }
            commands.Add(
                new PipelineCommand()
            {
                CommandName = LABEL_COMMAND,
                Label       = FINAL_COMMAND_LABEL,
                CommandArgs = new Dictionary <object, string>()
                {
                    { 0, FINAL_COMMAND_LABEL }
                }
            }
                );

            // We set the global variable to the incoming string. It will be modified and eventually returned from this variable slot.
            SetVariable(GLOBAL_VARIABLE_NAME, input);

            // We're going to set up a linked list of commands. Each command holds a reference to the next command in its SendToLabel property. The last command is NULL.
            var commandQueue = new Dictionary <string, PipelineCommand>();

            for (var index = 0; index < commands.Count; index++)
            {
                var thisCommand = commands[index];

                // If this is a "Label" command, then we need to get the label "out" to a property
                if (thisCommand.NormalizedCommandName == LABEL_COMMAND)
                {
                    thisCommand.Label = thisCommand.DefaultArgument;
                }

                // If (1) this command doesn't already have a SendToLabel (it...shouldn't...I don't think), and (2) we're not on the last command, then set the SendToLabel of this command to the Label of the next command
                if (thisCommand.SendToLabel == null && index < commands.Count - 1)
                {
                    thisCommand.SendToLabel = commands[index + 1].Label;
                }

                // Add this command to the queue, keyed to its Label
                commandQueue.Add(thisCommand.Label.ToLower(), thisCommand);
            }

            // We're going to stay in this loop, resetting "command" each iteration, until SendToLabel is NULL
            NextCommandLabel = commandQueue.First().Value.Label;
            while (true)
            {
                // Do we have a next command?
                if (NextCommandLabel == null)
                {
                    // Stick a fork in us, we're done
                    break;
                }

                // Does the specified next command exist?
                if (!commandQueue.ContainsKey(NextCommandLabel.ToLower()))
                {
                    throw new Exception(string.Format("Specified command label \"{0}\" does not exist in the command queue.", NextCommandLabel));
                }

                // Get the next command
                var command = commandQueue[NextCommandLabel.ToLower()];

                // Create the debug entry
                var debugData = new DebugEntry(command);

                // Are we writing to a variable?
                if (command.NormalizedCommandName == WRITE_TO_VARIABLE_COMMAND)
                {
                    // Get the active text and copy it to a different variable
                    SetVariable(command.OutputVariable, GetVariable(GLOBAL_VARIABLE_NAME));
                    NextCommandLabel = command.SendToLabel;
                    continue;
                }

                // Are we reading from a variable?
                if (command.NormalizedCommandName == READ_FROM_VARIABLE_COMMAND)
                {
                    // Get the variable and copy it into the active text
                    SetVariable(GLOBAL_VARIABLE_NAME, GetVariable(command.InputVariable));
                    NextCommandLabel = command.SendToLabel;
                    continue;
                }

                // Is this a label?
                if (command.NormalizedCommandName == LABEL_COMMAND)
                {
                    NextCommandLabel = command.SendToLabel;
                    continue;
                }

                // Note that the above commands will never actually execute. This is why their methods are just empty shells...

                // Do we a method for this command?
                if (!CommandMethods.ContainsKey(command.NormalizedCommandName))
                {
                    // This command doesn't exist. We're going to try to be helpful and let the user know if it's becaue of a missing dependency.
                    var errorString = hiddenCommandMethods.ContainsKey(command.NormalizedCommandName)
                        ? string.Format(hiddenCommandMethods[command.NormalizedCommandName])  // This should be the reason the command is hidden
                        : string.Format(@"No command loaded for ""{0}""", command.CommandName);

                    throw new DeninaException(errorString);
                }

                // Set a pipeline reference which can be accessed inside the filter method
                command.Pipeline = this;

                // Resolve any arguments that are actually variable names
                command.ResolveArguments();

                // Execute
                var method = CommandMethods[command.NormalizedCommandName];
                try
                {
                    timer.Reset();
                    timer.Start();

                    // This is where we make the actual method call. We get the text out of the InputVariable slot, and we put it back into the OutputVariable slot. (These are usually the same slot...)
                    // We're going to "SafeSet" this, so they can't pipe output to a read-only variable
                    debugData.InputValue = GetVariable(command.InputVariable).ToString();
                    var output = method.Invoke(null, new[] { GetVariable(command.InputVariable), command });
                    debugData.OutputValue = output.ToString();

                    // If we're appending, tack this onto what was passed in (really, prepend was was passed in)
                    if (command.AppendToLast)
                    {
                        output = string.Concat(GetVariable(command.InputVariable), output);
                    }

                    SafeSetVariable(command.OutputVariable, output);

                    command.ElapsedTime = timer.ElapsedMilliseconds;
                }
                catch (Exception e)
                {
                    if (e.InnerException is DeninaException)
                    {
                        // Since this was reflected, the "outer" exception is "an exception was thrown by the target of an invocation"
                        // Hence, the "real" exception is the inner exception
                        var exception = (DeninaException)e.InnerException;

                        exception.CurrentCommandText = command.OriginalText;
                        exception.CurrentCommandName = command.NormalizedCommandName;
                        throw exception;
                    }
                    else
                    {
                        throw;
                    }
                }

                // Set the pointer to the next command
                NextCommandLabel = command.SendToLabel;

                DebugData.Add(debugData);
            }

            var finalOutput = GetVariable(GLOBAL_VARIABLE_NAME).ToString();

            // Raise the PipelineCompleted event
            var eventArgs = new PipelineEventArgs(this, finalOutput);

            OnPipelineComplete(eventArgs);
            finalOutput = eventArgs.Value;

            return(finalOutput);
        }
        private void RegisterCommands(Type t, ulong?guildid)
        {
            CommandMethod[]   InternalCommandMethods   = Array.Empty <CommandMethod>();
            GroupCommand[]    InternalGroupCommands    = Array.Empty <GroupCommand>();
            SubGroupCommand[] InternalSubGroupCommands = Array.Empty <SubGroupCommand>();

            Client.Ready += (s, e) =>
            {
                _ = Task.Run(async() =>
                {
                    try
                    {
                        List <CommandCreatePayload> ToUpdate = new List <CommandCreatePayload>();

                        var ti = t.GetTypeInfo();

                        var classes = ti.DeclaredNestedTypes;
                        foreach (var tti in classes.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null))
                        {
                            var groupatt   = tti.GetCustomAttribute <SlashCommandGroupAttribute>();
                            var submethods = tti.DeclaredMethods;
                            var subclasses = tti.DeclaredNestedTypes;
                            if (subclasses.Any(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null) && submethods.Any(x => x.GetCustomAttribute <SlashCommandAttribute>() != null))
                            {
                                throw new ArgumentException("Slash command groups cannot have both subcommands and subgroups!");
                            }
                            var payload = new CommandCreatePayload
                            {
                                Name        = groupatt.Name,
                                Description = groupatt.Description
                            };
                            var commandmethods = new Dictionary <string, MethodInfo>();
                            foreach (var submethod in submethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null))
                            {
                                var commandattribute = submethod.GetCustomAttribute <SlashCommandAttribute>();
                                var subpayload       = new DiscordApplicationCommandOption(commandattribute.Name, commandattribute.Description);

                                var parameters = submethod.GetParameters();
                                if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
                                {
                                    throw new ArgumentException($"The first argument must be an InteractionContext!");
                                }
                                parameters = parameters.Skip(1).ToArray();
                                foreach (var parameter in parameters)
                                {
                                    var optionattribute = parameter.GetCustomAttribute <OptionAttribute>();
                                    if (optionattribute == null)
                                    {
                                        throw new ArgumentException("Arguments must have the Option attribute!");
                                    }

                                    var type = parameter.ParameterType;
                                    ApplicationCommandOptionType parametertype;
                                    if (ReferenceEquals(type, typeof(string)))
                                    {
                                        parametertype = ApplicationCommandOptionType.String;
                                    }
                                    else if (ReferenceEquals(type, typeof(long)))
                                    {
                                        parametertype = ApplicationCommandOptionType.Integer;
                                    }
                                    else if (ReferenceEquals(type, typeof(bool)))
                                    {
                                        parametertype = ApplicationCommandOptionType.Boolean;
                                    }
                                    else if (ReferenceEquals(type, typeof(DiscordChannel)))
                                    {
                                        parametertype = ApplicationCommandOptionType.Channel;
                                    }
                                    else if (ReferenceEquals(type, typeof(DiscordUser)))
                                    {
                                        parametertype = ApplicationCommandOptionType.User;
                                    }
                                    else if (ReferenceEquals(type, typeof(DiscordRole)))
                                    {
                                        parametertype = ApplicationCommandOptionType.Role;
                                    }
                                    else
                                    {
                                        throw new ArgumentException("Cannot convert type! Argument types must be string, long, bool, DiscordChannel, DiscordUser or DiscordRole.");
                                    }

                                    DiscordApplicationCommandOptionChoice[] choices = null;
                                    var choiceattributes = parameter.GetCustomAttributes <ChoiceAttribute>();
                                    if (choiceattributes.Any())
                                    {
                                        choices = Array.Empty <DiscordApplicationCommandOptionChoice>();
                                        foreach (var att in choiceattributes)
                                        {
                                            choices = choices.Append(new DiscordApplicationCommandOptionChoice(att.Name, att.Value)).ToArray();
                                        }
                                    }

                                    var list = subpayload.Options?.ToList() ?? new List <DiscordApplicationCommandOption>();

                                    list.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description)
                                    {
                                        Required = !parameter.IsOptional,
                                        Type     = parametertype,
                                        Choices  = choices
                                    });

                                    subpayload.Options = list;
                                }

                                commandmethods.Add(commandattribute.Name, submethod);

                                payload.Options.Add(new DiscordApplicationCommandOption(commandattribute.Name, commandattribute.Description)
                                {
                                    Required = null,
                                    Options  = subpayload.Options,
                                    Type     = ApplicationCommandOptionType.SubCommand
                                });

                                InternalGroupCommands = InternalGroupCommands.Append(new GroupCommand {
                                    Name = groupatt.Name, ParentClass = tti, Methods = commandmethods
                                }).ToArray();
                            }
                            foreach (var subclass in subclasses.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null))
                            {
                                var subgroupatt   = subclass.GetCustomAttribute <SlashCommandGroupAttribute>();
                                var subsubmethods = subclass.DeclaredMethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null);

                                var command = new SubGroupCommand {
                                    Name = groupatt.Name
                                };

                                var subpayload = new DiscordApplicationCommandOption(subgroupatt.Name, subgroupatt.Description)
                                {
                                    Required = null,
                                    Type     = ApplicationCommandOptionType.SubCommandGroup,
                                    Options  = new List <DiscordApplicationCommandOption>()
                                };

                                foreach (var subsubmethod in subsubmethods)
                                {
                                    var commatt       = subsubmethod.GetCustomAttribute <SlashCommandAttribute>();
                                    var subsubpayload = new DiscordApplicationCommandOption(commatt.Name, commatt.Description)
                                    {
                                        Type = ApplicationCommandOptionType.SubCommand,
                                    };
                                    var parameters = subsubmethod.GetParameters();
                                    if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
                                    {
                                        throw new ArgumentException($"The first argument must be an InteractionContext!");
                                    }
                                    parameters = parameters.Skip(1).ToArray();
                                    foreach (var parameter in parameters)
                                    {
                                        var optionattribute = parameter.GetCustomAttribute <OptionAttribute>();
                                        if (optionattribute == null)
                                        {
                                            throw new ArgumentException("Arguments must have the Option attribute!");
                                        }

                                        var type = parameter.ParameterType;
                                        ApplicationCommandOptionType parametertype;
                                        if (ReferenceEquals(type, typeof(string)))
                                        {
                                            parametertype = ApplicationCommandOptionType.String;
                                        }
                                        else if (ReferenceEquals(type, typeof(long)))
                                        {
                                            parametertype = ApplicationCommandOptionType.Integer;
                                        }
                                        else if (ReferenceEquals(type, typeof(bool)))
                                        {
                                            parametertype = ApplicationCommandOptionType.Boolean;
                                        }
                                        else if (ReferenceEquals(type, typeof(DiscordChannel)))
                                        {
                                            parametertype = ApplicationCommandOptionType.Channel;
                                        }
                                        else if (ReferenceEquals(type, typeof(DiscordUser)))
                                        {
                                            parametertype = ApplicationCommandOptionType.User;
                                        }
                                        else if (ReferenceEquals(type, typeof(DiscordRole)))
                                        {
                                            parametertype = ApplicationCommandOptionType.Role;
                                        }
                                        else
                                        {
                                            throw new ArgumentException("Cannot convert type! Argument types must be string, long, bool, DiscordChannel, DiscordUser or DiscordRole.");
                                        }

                                        DiscordApplicationCommandOptionChoice[] choices = null;
                                        var choiceattributes = parameter.GetCustomAttributes <ChoiceAttribute>();
                                        if (choiceattributes.Any())
                                        {
                                            choices = Array.Empty <DiscordApplicationCommandOptionChoice>();
                                            foreach (var att in choiceattributes)
                                            {
                                                choices = choices.Append(new DiscordApplicationCommandOptionChoice(att.Name, att.Value)).ToArray();
                                            }
                                        }

                                        var list = subsubpayload.Options?.ToList() ?? new List <DiscordApplicationCommandOption>();

                                        list.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description)
                                        {
                                            Required = !parameter.IsOptional,
                                            Type     = parametertype,
                                            Choices  = choices
                                        });

                                        subsubpayload.Options = list;
                                    }
                                    subpayload.Options = subpayload.Options.ToArray().Append(subsubpayload).ToList();
                                    commandmethods.Add(commatt.Name, subsubmethod);
                                }
                                command.SubCommands.Add(new GroupCommand {
                                    Name = subgroupatt.Name, ParentClass = subclass, Methods = commandmethods
                                });
                                InternalSubGroupCommands = InternalSubGroupCommands.Append(command).ToArray();
                                payload.Options.Add(subpayload);
                            }
                            ToUpdate.Add(payload);
                        }

                        var methods = ti.DeclaredMethods;
                        foreach (var method in methods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null))
                        {
                            var commandattribute = method.GetCustomAttribute <SlashCommandAttribute>();
                            var payload          = new CommandCreatePayload
                            {
                                Name        = commandattribute.Name,
                                Description = commandattribute.Description
                            };

                            var parameters = method.GetParameters();
                            if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
                            {
                                throw new ArgumentException($"The first argument must be an InteractionContext!");
                            }
                            parameters = parameters.Skip(1).ToArray();
                            foreach (var parameter in parameters)
                            {
                                var optionattribute = parameter.GetCustomAttribute <OptionAttribute>();
                                if (optionattribute == null)
                                {
                                    throw new ArgumentException("Arguments must have the SlashOption attribute!");
                                }

                                var type = parameter.ParameterType;
                                ApplicationCommandOptionType parametertype;
                                if (ReferenceEquals(type, typeof(string)))
                                {
                                    parametertype = ApplicationCommandOptionType.String;
                                }
                                else if (ReferenceEquals(type, typeof(long)))
                                {
                                    parametertype = ApplicationCommandOptionType.Integer;
                                }
                                else if (ReferenceEquals(type, typeof(bool)))
                                {
                                    parametertype = ApplicationCommandOptionType.Boolean;
                                }
                                else if (ReferenceEquals(type, typeof(DiscordChannel)))
                                {
                                    parametertype = ApplicationCommandOptionType.Channel;
                                }
                                else if (ReferenceEquals(type, typeof(DiscordUser)))
                                {
                                    parametertype = ApplicationCommandOptionType.User;
                                }
                                else if (ReferenceEquals(type, typeof(DiscordRole)))
                                {
                                    parametertype = ApplicationCommandOptionType.Role;
                                }
                                else
                                {
                                    throw new ArgumentException($"Cannot convert type! Argument types must be string, long, bool, DiscordChannel, DiscordUser or DiscordRole.");
                                }

                                DiscordApplicationCommandOptionChoice[] choices = null;
                                var choiceattributes = parameter.GetCustomAttributes <ChoiceAttribute>();
                                if (choiceattributes.Any())
                                {
                                    choices = Array.Empty <DiscordApplicationCommandOptionChoice>();
                                    foreach (var att in choiceattributes)
                                    {
                                        choices = choices.Append(new DiscordApplicationCommandOptionChoice(att.Name, att.Value)).ToArray();
                                    }
                                }

                                payload.Options.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description)
                                {
                                    Required = !parameter.IsOptional,
                                    Type     = parametertype,
                                    Choices  = choices
                                });
                            }
                            InternalCommandMethods = InternalCommandMethods.Append(new CommandMethod {
                                Method = method, Name = commandattribute.Name, ParentClass = t
                            }).ToArray();
                            ToUpdate.Add(payload);
                        }

                        var commands = await BulkCreateCommandsAsync(ToUpdate, guildid);
                        foreach (var command in commands)
                        {
                            if (InternalCommandMethods.Any(x => x.Name == command.Name))
                            {
                                InternalCommandMethods.First(x => x.Name == command.Name).Id = command.Id;
                            }

                            else if (InternalGroupCommands.Any(x => x.Name == command.Name))
                            {
                                InternalGroupCommands.First(x => x.Name == command.Name).Id = command.Id;
                            }

                            else if (InternalSubGroupCommands.Any(x => x.Name == command.Name))
                            {
                                InternalSubGroupCommands.First(x => x.Name == command.Name).Id = command.Id;
                            }
                        }
                        CommandMethods.AddRange(InternalCommandMethods);
                        GroupCommands.AddRange(InternalGroupCommands);
                        SubGroupCommands.AddRange(InternalSubGroupCommands);
                    }
                    catch (Exception ex)
                    {
                        Client.Logger.LogError(ex, $"There was an error registering slash commands");
                        Environment.Exit(-1);
                    }
                });

                return(Task.CompletedTask);
            };
        }
        //Handler
        internal Task InteractionHandler(DiscordClient client, InteractionCreateEventArgs e)
        {
            _ = Task.Run(async() =>
            {
                InteractionContext context = new InteractionContext
                {
                    Interaction            = e.Interaction,
                    Channel                = e.Interaction.Channel,
                    Guild                  = e.Interaction.Guild,
                    User                   = e.Interaction.User,
                    Client                 = client,
                    SlashCommandsExtension = this,
                    CommandName            = e.Interaction.Data.Name,
                    InteractionId          = e.Interaction.Id,
                    Token                  = e.Interaction.Token
                };

                try
                {
                    var methods   = CommandMethods.Where(x => x.Id == e.Interaction.Data.Id);
                    var groups    = GroupCommands.Where(x => x.Id == e.Interaction.Data.Id);
                    var subgroups = SubGroupCommands.Where(x => x.Id == e.Interaction.Data.Id);
                    if (!methods.Any() && !groups.Any() && !subgroups.Any())
                    {
                        throw new SlashCommandNotFoundException("An interaction was created, but no command was registered for it");
                    }
                    if (methods.Any())
                    {
                        var method = methods.First();

                        List <object> args = new List <object> {
                            context
                        };
                        var parameters = method.Method.GetParameters().Skip(1);

                        for (int i = 0; i < parameters.Count(); i++)
                        {
                            var parameter = parameters.ElementAt(i);
                            if (parameter.IsOptional && (e.Interaction.Data.Options == null || e.Interaction.Data.Options?.ElementAtOrDefault(i) == default))
                            {
                                args.Add(parameter.DefaultValue);
                            }
                            else
                            {
                                var option = e.Interaction.Data.Options.ElementAt(i);

                                if (ReferenceEquals(parameter.ParameterType, typeof(string)))
                                {
                                    args.Add(option.Value.ToString());
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(long)))
                                {
                                    args.Add((long)option.Value);
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(bool)))
                                {
                                    args.Add((bool)option.Value);
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordUser)))
                                {
                                    if (e.Interaction.Data.Resolved.Members.TryGetValue((ulong)option.Value, out var member))
                                    {
                                        args.Add(member);
                                    }
                                    else if (e.Interaction.Data.Resolved.Users.TryGetValue((ulong)option.Value, out var user))
                                    {
                                        args.Add(user);
                                    }
                                    else
                                    {
                                        args.Add(await Client.GetUserAsync((ulong)option.Value));
                                    }
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordChannel)))
                                {
                                    if (e.Interaction.Data.Resolved.Channels.TryGetValue((ulong)option.Value, out var channel))
                                    {
                                        args.Add(channel);
                                    }
                                    else
                                    {
                                        args.Add(e.Interaction.Guild.GetChannel((ulong)option.Value));
                                    }
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordRole)))
                                {
                                    if (e.Interaction.Data.Resolved.Roles.TryGetValue((ulong)option.Value, out var role))
                                    {
                                        args.Add(role);
                                    }
                                    else
                                    {
                                        args.Add(e.Interaction.Guild.GetRole((ulong)option.Value));
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException($"How on earth did that happen");
                                }
                            }
                        }
                        var classinstance = Activator.CreateInstance(method.ParentClass);
                        var task          = (Task)method.Method.Invoke(classinstance, args.ToArray());
                        await task;
                    }
                    else if (groups.Any())
                    {
                        var command = e.Interaction.Data.Options.First();
                        var method  = groups.First().Methods.First(x => x.Key == command.Name).Value;

                        List <object> args = new List <object> {
                            context
                        };
                        var parameters = method.GetParameters().Skip(1);

                        for (int i = 0; i < parameters.Count(); i++)
                        {
                            var parameter = parameters.ElementAt(i);
                            if (parameter.IsOptional && (command.Options == null || command.Options?.ElementAtOrDefault(i) == default))
                            {
                                args.Add(parameter.DefaultValue);
                            }
                            else
                            {
                                var option = command.Options.ElementAt(i);

                                if (ReferenceEquals(parameter.ParameterType, typeof(string)))
                                {
                                    args.Add(option.Value.ToString());
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(long)))
                                {
                                    args.Add((long)option.Value);
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(bool)))
                                {
                                    args.Add((bool)option.Value);
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordUser)))
                                {
                                    if (e.Interaction.Data.Resolved.Members.TryGetValue((ulong)option.Value, out var member))
                                    {
                                        args.Add(member);
                                    }
                                    else if (e.Interaction.Data.Resolved.Users.TryGetValue((ulong)option.Value, out var user))
                                    {
                                        args.Add(user);
                                    }
                                    else
                                    {
                                        args.Add(await Client.GetUserAsync((ulong)option.Value));
                                    }
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordChannel)))
                                {
                                    if (e.Interaction.Data.Resolved.Channels.TryGetValue((ulong)option.Value, out var channel))
                                    {
                                        args.Add(channel);
                                    }
                                    else
                                    {
                                        args.Add(e.Interaction.Guild.GetChannel((ulong)option.Value));
                                    }
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordRole)))
                                {
                                    if (e.Interaction.Data.Resolved.Roles.TryGetValue((ulong)option.Value, out var role))
                                    {
                                        args.Add(role);
                                    }
                                    else
                                    {
                                        args.Add(e.Interaction.Guild.GetRole((ulong)option.Value));
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException($"How on earth did that happen");
                                }
                            }
                        }
                        var classinstance = Activator.CreateInstance(groups.First().ParentClass);
                        var task          = (Task)method.Invoke(classinstance, args.ToArray());
                        await task;
                    }
                    else if (subgroups.Any())
                    {
                        var command = e.Interaction.Data.Options.First();
                        var group   = subgroups.First(x => x.SubCommands.Any(y => y.Name == command.Name)).SubCommands.First(x => x.Name == command.Name);

                        var method = group.Methods.First(x => x.Key == command.Options.First().Name).Value;

                        List <object> args = new List <object> {
                            context
                        };
                        var parameters = method.GetParameters().Skip(1);

                        for (int i = 0; i < parameters.Count(); i++)
                        {
                            var parameter = parameters.ElementAt(i);
                            if (parameter.IsOptional && (command.Options == null || command.Options?.ElementAtOrDefault(i) == default))
                            {
                                args.Add(parameter.DefaultValue);
                            }
                            else
                            {
                                var option = command.Options.ElementAt(i);

                                if (ReferenceEquals(parameter.ParameterType, typeof(string)))
                                {
                                    args.Add(option.Value.ToString());
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(long)))
                                {
                                    args.Add((long)option.Value);
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(bool)))
                                {
                                    args.Add((bool)option.Value);
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordUser)))
                                {
                                    if (e.Interaction.Data.Resolved.Members.TryGetValue((ulong)option.Value, out var member))
                                    {
                                        args.Add(member);
                                    }
                                    else if (e.Interaction.Data.Resolved.Users.TryGetValue((ulong)option.Value, out var user))
                                    {
                                        args.Add(user);
                                    }
                                    else
                                    {
                                        args.Add(await Client.GetUserAsync((ulong)option.Value));
                                    }
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordChannel)))
                                {
                                    if (e.Interaction.Data.Resolved.Channels.TryGetValue((ulong)option.Value, out var channel))
                                    {
                                        args.Add(channel);
                                    }
                                    else
                                    {
                                        args.Add(e.Interaction.Guild.GetChannel((ulong)option.Value));
                                    }
                                }
                                else if (ReferenceEquals(parameter.ParameterType, typeof(DiscordRole)))
                                {
                                    if (e.Interaction.Data.Resolved.Roles.TryGetValue((ulong)option.Value, out var role))
                                    {
                                        args.Add(role);
                                    }
                                    else
                                    {
                                        args.Add(e.Interaction.Guild.GetRole((ulong)option.Value));
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException($"How on earth did that happen");
                                }
                            }
                        }
                        var classinstance = Activator.CreateInstance(group.ParentClass);
                        var task          = (Task)method.Invoke(classinstance, args.ToArray());
                        await task;
                    }

                    await _executed.InvokeAsync(this, new SlashCommandExecutedEventArgs {
                        Context = context
                    });
                }
                catch (Exception ex)
                {
                    await _error.InvokeAsync(this, new SlashCommandErrorEventArgs {
                        Context = context, Exception = ex
                    });
                }
            });
            return(Task.CompletedTask);
        }
Ejemplo n.º 27
0
        private void RegisterCommands(Type[] types, ulong?guildid)
        {
            CommandMethod[]   InternalCommandMethods   = Array.Empty <CommandMethod>();
            GroupCommand[]    InternalGroupCommands    = Array.Empty <GroupCommand>();
            SubGroupCommand[] InternalSubGroupCommands = Array.Empty <SubGroupCommand>();
            List <DiscordApplicationCommand> ToUpdate  = new List <DiscordApplicationCommand>();

            _ = Task.Run(async() =>
            {
                foreach (var t in types)
                {
                    try
                    {
                        var ti = t.GetTypeInfo();

                        var classes = ti.DeclaredNestedTypes;
                        foreach (var tti in classes.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null))
                        {
                            var groupatt   = tti.GetCustomAttribute <SlashCommandGroupAttribute>();
                            var submethods = tti.DeclaredMethods;
                            var subclasses = tti.DeclaredNestedTypes;
                            if (subclasses.Any(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null) && submethods.Any(x => x.GetCustomAttribute <SlashCommandAttribute>() != null))
                            {
                                throw new ArgumentException("Slash command groups cannot have both subcommands and subgroups!");
                            }
                            var payload = new DiscordApplicationCommand(groupatt.Name, groupatt.Description);


                            var commandmethods = new Dictionary <string, MethodInfo>();
                            foreach (var submethod in submethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null))
                            {
                                var commandattribute = submethod.GetCustomAttribute <SlashCommandAttribute>();


                                var parameters = submethod.GetParameters();
                                if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
                                {
                                    throw new ArgumentException($"The first argument must be an InteractionContext!");
                                }
                                parameters = parameters.Skip(1).ToArray();

                                var options = ParseParameters(parameters);

                                var subpayload = new DiscordApplicationCommandOption(commandattribute.Name, commandattribute.Description, ApplicationCommandOptionType.SubCommand, null, null, options);

                                commandmethods.Add(commandattribute.Name, submethod);

                                payload = new DiscordApplicationCommand(payload.Name, payload.Description, payload.Options != null ? payload.Options.ToArray().Append(subpayload) : new DiscordApplicationCommandOption[] { subpayload });

                                InternalGroupCommands = InternalGroupCommands.Append(new GroupCommand {
                                    Name = groupatt.Name, ParentClass = tti, Methods = commandmethods
                                }).ToArray();
                            }
                            foreach (var subclass in subclasses.Where(x => x.GetCustomAttribute <SlashCommandGroupAttribute>() != null))
                            {
                                var subgroupatt   = subclass.GetCustomAttribute <SlashCommandGroupAttribute>();
                                var subsubmethods = subclass.DeclaredMethods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null);

                                var command = new SubGroupCommand {
                                    Name = groupatt.Name
                                };

                                var options = new List <DiscordApplicationCommandOption>();

                                foreach (var subsubmethod in subsubmethods)
                                {
                                    var suboptions = new List <DiscordApplicationCommandOption>();
                                    var commatt    = subsubmethod.GetCustomAttribute <SlashCommandAttribute>();
                                    var parameters = subsubmethod.GetParameters();
                                    if (!ReferenceEquals(parameters.First().ParameterType, typeof(InteractionContext)))
                                    {
                                        throw new ArgumentException($"The first argument must be an InteractionContext!");
                                    }
                                    parameters = parameters.Skip(1).ToArray();
                                    options    = options.Concat(ParseParameters(parameters)).ToList();

                                    var subsubpayload = new DiscordApplicationCommandOption(commatt.Name, commatt.Description, ApplicationCommandOptionType.SubCommand, null, null, suboptions);
                                    options.Add(subsubpayload);
                                    commandmethods.Add(commatt.Name, subsubmethod);
                                }

                                var subpayload = new DiscordApplicationCommandOption(subgroupatt.Name, subgroupatt.Description, ApplicationCommandOptionType.SubCommandGroup, null, null, options);
                                command.SubCommands.Add(new GroupCommand {
                                    Name = subgroupatt.Name, ParentClass = subclass, Methods = commandmethods
                                });
                                InternalSubGroupCommands = InternalSubGroupCommands.Append(command).ToArray();
                                payload = new DiscordApplicationCommand(payload.Name, payload.Description, payload.Options != null ? payload.Options.ToArray().Append(subpayload) : new DiscordApplicationCommandOption[] { subpayload });
                            }
                            ToUpdate.Add(payload);
                        }

                        var methods = ti.DeclaredMethods;
                        foreach (var method in methods.Where(x => x.GetCustomAttribute <SlashCommandAttribute>() != null))
                        {
                            var commandattribute = method.GetCustomAttribute <SlashCommandAttribute>();

                            var options = new List <DiscordApplicationCommandOption>();

                            var parameters = method.GetParameters();
                            if (parameters.Length == 0 || parameters == null || !ReferenceEquals(parameters.FirstOrDefault()?.ParameterType, typeof(InteractionContext)))
                            {
                                throw new ArgumentException($"The first argument must be an InteractionContext!");
                            }
                            parameters = parameters.Skip(1).ToArray();
                            foreach (var parameter in parameters)
                            {
                                var optionattribute = parameter.GetCustomAttribute <OptionAttribute>();
                                if (optionattribute == null)
                                {
                                    throw new ArgumentException("Arguments must have the SlashOption attribute!");
                                }

                                var type = parameter.ParameterType;
                                ApplicationCommandOptionType parametertype = GetParameterType(type);

                                DiscordApplicationCommandOptionChoice[] choices = GetChoiceAttributesFromParameter(parameter.GetCustomAttributes <ChoiceAttribute>());

                                options.Add(new DiscordApplicationCommandOption(optionattribute.Name, optionattribute.Description, parametertype, !parameter.IsOptional, choices));
                            }
                            InternalCommandMethods = InternalCommandMethods.Append(new CommandMethod {
                                Method = method, Name = commandattribute.Name, ParentClass = t
                            }).ToArray();

                            var payload = new DiscordApplicationCommand(commandattribute.Name, commandattribute.Description, options);
                            ToUpdate.Add(payload);
                        }
                    }
                    catch (Exception ex)
                    {
                        Client.Logger.LogError(ex, $"There was an error registering slash commands");
                        Environment.Exit(-1);
                    }
                }
                try
                {
                    IEnumerable <DiscordApplicationCommand> commands;
                    if (guildid == null)
                    {
                        commands = await Client.BulkOverwriteGlobalApplicationCommandsAsync(ToUpdate);
                    }
                    else
                    {
                        commands = await Client.BulkOverwriteGuildApplicationCommandsAsync(guildid.Value, ToUpdate);
                    }
                    foreach (var command in commands)
                    {
                        if (InternalCommandMethods.Any(x => x.Name == command.Name))
                        {
                            InternalCommandMethods.First(x => x.Name == command.Name).Id = command.Id;
                        }

                        else if (InternalGroupCommands.Any(x => x.Name == command.Name))
                        {
                            InternalGroupCommands.First(x => x.Name == command.Name).Id = command.Id;
                        }

                        else if (InternalSubGroupCommands.Any(x => x.Name == command.Name))
                        {
                            InternalSubGroupCommands.First(x => x.Name == command.Name).Id = command.Id;
                        }
                    }
                    CommandMethods.AddRange(InternalCommandMethods);
                    GroupCommands.AddRange(InternalGroupCommands);
                    SubGroupCommands.AddRange(InternalSubGroupCommands);
                }
                catch (Exception ex)
                {
                    Client.Logger.LogError(ex, $"There was an error registering slash commands");
                    Environment.Exit(-1);
                }
            });
        }
Ejemplo n.º 28
0
        public async Task ConvertTime([Remainder] string input = null)
        {
            using (var database = new GuildDB())
            {
                // log command execution
                CommandMethods.LogExecution(logger, "time", Context);

                // indicate that the bot is working on the command
                await Context.Channel.TriggerTypingAsync();

                StringConverter language = statecollection.GetLanguage(Context.Guild, database);

                // make sure that the user has the right permissions
                if (!PermissionHelper.UserHasPermission(Context.User as SocketGuildUser, PermissionHelper.Member, database))
                {
                    await Context.Channel.SendMessageAsync(language.GetString("command.nopermission"));

                    return;
                }

                TimeZoneInfo sourcetz;
                DateTime     time;

                if (input != null)
                {
                    // parse the input
                    Match m = timerx.Match(input);
                    if (!m.Success)
                    {
                        await Context.Channel.SendMessageAsync(language.GetString("command.time.error"));

                        return;
                    }

                    // find out which timezone is desired
                    GroupCollection g = m.Groups;
                    TimeLocale      tl;
                    if (g["locale"].Success)
                    {
                        if (!Enum.TryParse <TimeLocale>(g["locale"].Value, true, out tl))
                        {
                            await Context.Channel.SendMessageAsync(language.GetString("command.time.error"));

                            return;
                        }
                    }
                    else
                    {
                        tl = TimeLocale.local;
                    }

                    // find the desired timezone info
                    if (tl == TimeLocale.local)
                    {
                        sourcetz = DateTimeMethods.UserToTimezone(Context.User);
                        if (sourcetz == null)
                        {
                            await Context.Channel.SendMessageAsync(language.GetString("command.time.notimezone"));

                            return;
                        }
                    }
                    else
                    {
                        sourcetz = TimeZoneInfo.Utc;
                    }

                    // find the time
                    time = TimeZoneInfo.ConvertTime(DateTime.Now, sourcetz);
                    TimeSpan?ts = DateTimeMethods.StringToTime(g["time"].Value, true);
                    if (!ts.HasValue)
                    {
                        // signal error if not
                        await Context.Channel.SendMessageAsync(language.GetString("command.time.error"));

                        return;
                    }
                    time = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0, time.Kind) + ts.Value;
                }
                else
                {
                    sourcetz = TimeZoneInfo.Utc;
                    time     = DateTime.UtcNow;
                }

                // construct a timetable and present it to the user
                string result = DateTimeMethods.TimetableToString(DateTimeMethods.LocalTimeToTimetable(time, sourcetz, Context.Guild));
                await Context.Channel.SendMessageAsync(language.GetString("present"));

                await Context.Channel.TriggerTypingAsync();

                await Context.Channel.SendMessageAsync(result);
            }
        }
Ejemplo n.º 29
0
        //Handler
        private Task InteractionHandler(DiscordClient client, InteractionCreateEventArgs e)
        {
            _ = Task.Run(async() =>
            {
                InteractionContext context = new InteractionContext
                {
                    Interaction            = e.Interaction,
                    Channel                = e.Interaction.Channel,
                    Guild                  = e.Interaction.Guild,
                    User                   = e.Interaction.User,
                    Client                 = client,
                    SlashCommandsExtension = this,
                    CommandName            = e.Interaction.Data.Name,
                    InteractionId          = e.Interaction.Id,
                    Token                  = e.Interaction.Token,
                    Services               = _configuration?.Services
                };

                try
                {
                    var methods   = CommandMethods.Where(x => x.Id == e.Interaction.Data.Id);
                    var groups    = GroupCommands.Where(x => x.Id == e.Interaction.Data.Id);
                    var subgroups = SubGroupCommands.Where(x => x.Id == e.Interaction.Data.Id);
                    if (!methods.Any() && !groups.Any() && !subgroups.Any())
                    {
                        throw new Exception("An interaction was created, but no command was registered for it");
                    }
                    if (methods.Any())
                    {
                        var method = methods.First();

                        var args          = await ResloveInteractionCommandParameters(e, context, method.Method);
                        var classinstance = ActivatorUtilities.CreateInstance(_configuration?.Services, method.ParentClass);
                        var task          = (Task)method.Method.Invoke(classinstance, args.ToArray());
                        await task;
                    }
                    else if (groups.Any())
                    {
                        var command = e.Interaction.Data.Options.First();
                        var method  = groups.First().Methods.First(x => x.Key == command.Name).Value;

                        var args          = await ResloveInteractionCommandParameters(e, context, method);
                        var classinstance = ActivatorUtilities.CreateInstance(_configuration?.Services, groups.First().ParentClass);
                        var task          = (Task)method.Invoke(classinstance, args.ToArray());
                        await task;
                    }
                    else if (subgroups.Any())
                    {
                        var command = e.Interaction.Data.Options.First();
                        var group   = subgroups.First(x => x.SubCommands.Any(y => y.Name == command.Name)).SubCommands.First(x => x.Name == command.Name);

                        var method = group.Methods.First(x => x.Key == command.Options.First().Name).Value;

                        var args          = await ResloveInteractionCommandParameters(e, context, method);
                        var classinstance = ActivatorUtilities.CreateInstance(_configuration?.Services, group.ParentClass);
                        var task          = (Task)method.Invoke(classinstance, args.ToArray());
                        await task;
                    }

                    await _executed.InvokeAsync(this, new SlashCommandExecutedEventArgs {
                        Context = context
                    });
                }
                catch (Exception ex)
                {
                    await _error.InvokeAsync(this, new SlashCommandErrorEventArgs {
                        Context = context, Exception = ex
                    });
                }
            });
            return(Task.CompletedTask);
        }