Example #1
0
        public async Task BotInfoAsync(ICommandContext ctx)
        {
            var embed = new EmbedBuilder
            {
                Title = "Status",
                Color = Color.Purple
            };

            embed.AddField("Latest version", Utils.ToDiscordTimestamp(new FileInfo(Assembly.GetEntryAssembly().Location).LastWriteTimeUtc, Utils.TimestampInfo.None), true);
            embed.AddField("Last command received", Utils.ToDiscordTimestamp(StaticObjects.LastMessage, Utils.TimestampInfo.TimeAgo), true);
            embed.AddField("Uptime", Utils.ToDiscordTimestamp(StaticObjects.Started, Utils.TimestampInfo.TimeAgo), true);
            embed.AddField("Guild count", StaticObjects.Client.Guilds.Count, true);

            var options = new ComponentBuilder();

            if (StaticObjects.IsBotOwner(ctx.User))
            {
                options.WithSelectMenu("delCache", StaticObjects.AllGameNames.Select(x => new SelectMenuOptionBuilder(x, StaticObjects.Db.GetCacheName(x))).ToList(), placeholder: "Select a game cache to delete (require bot restart)");
            }
            options.WithButton("Show Global Stats", "globalStats");

            await ctx.ReplyAsync(embed : embed.Build(), components : options.Build(), ephemeral : true);

            embed.AddField("Useful links",
#if NSFW_BUILD
                           " - [Source Code](https://github.com/Xwilarg/Sanara)\n" +
                           " - [Website](https://sanara.zirk.eu/)\n" +
#endif
                           " - [Invitation Link](https://discord.com/api/oauth2/authorize?client_id=" + StaticObjects.ClientId + "&scope=bot%20applications.commands)\n"
#if NSFW_BUILD
                           +
                           " - [Support Server](https://discordapp.com/invite/H6wMRYV)\n" +
                           " - [Top.gg](https://discordbots.org/bot/329664361016721408)"
#endif
                           );
            embed.AddField("Credits",
                           "Programming: [Zirk#0001](https://zirk.eu/)\n" +
                           "With the help of [TheIndra](https://theindra.eu/)\n"
#if NSFW_BUILD
                           +
                           "Profile Picture: [Uikoui](https://www.pixiv.net/en/users/11608780)"
#endif // TODO: Can prob use current pfp for SFW version
                           );

#if NSFW_BUILD
            // Get latests commits
            StringBuilder str  = new();
            var           json = JsonConvert.DeserializeObject <JArray>(await StaticObjects.HttpClient.GetStringAsync("https://api.github.com/repos/Xwilarg/Sanara/commits?per_page=5"));
            foreach (var elem in json)
            {
                var time = Utils.ToDiscordTimestamp(DateTime.ParseExact(elem["commit"]["author"]["date"].Value <string>(), "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture), Utils.TimestampInfo.None);
                str.AppendLine($"{time}: [{elem["commit"]["message"].Value<string>()}](https://github.com/Xwilarg/Sanara/commit/{elem["sha"].Value<string>()})");
            }
            embed.AddField("Latest changes", str.ToString());

            await ctx.ReplyAsync(embed : embed.Build(), components : options.Build());
#endif
        }
Example #2
0
        /// <summary>
        /// Handles adding <see cref="SelectMenuComponent"/> to the given interaction
        /// </summary>
        /// <param name="sm">The <see cref="SelectMenuAttribute"/> that represents the select menu handler</param>
        /// <param name="method">The method that will be triggered when handling the interaction</param>
        /// <param name="type">The type of the class that will handle the interaction</param>
        /// <param name="builder">The <see cref="ComponentBuilder"/></param>
        /// <param name="channel">The channel the interaction happened in</param>
        /// <param name="user">The user that triggered the interaction</param>
        /// <param name="message">The message that triggered the interaction</param>
        /// <returns>A task representing the completion of the request</returns>
        /// <exception cref="ArgumentException">Thrown when the min or max values field on the select menu are less than 1</exception>
        public async Task HandleSelectMenu(SelectMenuAttribute sm, MethodInfo method, Type type, ComponentBuilder builder, IChannel channel, IUser user, IMessage?message)
        {
            if (sm.MinValues < 1 || sm.MaxValues < 1)
            {
                throw new ArgumentException("Min/Max values for Select Menu must be 1 or greater.", "(Max/Min)Values");
            }

            var id      = _handlers.IdFromMethod(method);
            var options = new List <SelectMenuOptionBuilder>();

            if (!string.IsNullOrEmpty(sm.OptionsMethod))
            {
                options.AddRange(await MenuOptionsFromMethod(sm.OptionsMethod, type, channel, user, message));
            }

            options.AddRange(MenuOptionsFromAttributes(method));

            builder.WithSelectMenu(id, options, sm.Placeholder, sm.MinValues, sm.MaxValues, sm.Disabled, sm.Row);
        }
        /// <summary>
        /// Precondition to disable the source of an interaction.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="commandInfo"></param>
        /// <param name="services"></param>
        /// <returns></returns>
        public override async Task <PreconditionResult> CheckRequirementsAsync(IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services)
        {
            if (context.Interaction is not IComponentInteraction messageComponent)
            {
                return(PreconditionResult.FromError("This attribute does not work for application commands!"));
            }

            var builder = new ComponentBuilder();

            var rows = ComponentBuilder.FromMessage(messageComponent.Message).ActionRows;

            for (int i = 0; i < rows.Count; i++)
            {
                foreach (var component in rows[i].Components)
                {
                    switch (component)
                    {
                    case ButtonComponent button:
                        builder.WithButton(button.ToBuilder()
                                           .WithDisabled(!button.CustomId.StartsWith("delete-message-")), i);
                        break;

                    case SelectMenuComponent menu:
                        builder.WithSelectMenu(menu.ToBuilder()
                                               .WithDisabled(true), i);
                        break;
                    }
                }
            }

            try
            {
                await messageComponent.Message.ModifyAsync(x => x.Components = builder.Build());

                return(PreconditionResult.FromSuccess());
            }
            catch (Exception ex)
            {
                return(PreconditionResult.FromError(ex));
            }
        }