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 }
public async Task CommandAsync() { #region help var builder = new ComponentBuilder() .WithButton("Go to help!", $"id.0|{Context.User.Id}", ButtonStyle.Primary) .WithButton("Become a voter!", $"id.voter|{Context.User.Id}", ButtonStyle.Primary) .WithButton("Our website", null, ButtonStyle.Link, null, "https://terrariabuilders.com/"); var modules = _Commands.Modules.Where(x => !string.IsNullOrWhiteSpace(x.Summary)); var emb = new EmbedBuilder(); emb.WithAuthor("Type !help (module) for all commands covering respective modules", $"{Utils.BotUser.GetAvatarUrl()}"); foreach (var module in modules) { bool success = false; foreach (var command in module.Commands) { var result = await command.CheckPreconditionsAsync(Context, _Provider); if (result.IsSuccess) { success = true; break; } } if (!success) { continue; } emb.AddField(module.Name, module.Summary); emb.WithColor(Color.Blue); } if (emb.Fields.Count <= 0) { await ReplyAsync("Module information cannot be found, please try again later.", false, null, null, new AllowedMentions() { MentionRepliedUser = true }, new MessageReference(Context.Message.Id), builder.Build()); await Utils.SendLog(Context.Message.Content, Context.User); } else { await ReplyAsync("", false, emb.Build(), null, new AllowedMentions() { MentionRepliedUser = true }, new MessageReference(Context.Message.Id), builder.Build()); await Utils.SendLog(Context.Message.Content, Context.User); } }
private async Task OnBumperNotifyAsync(BumpNotificationContainer container) { IMessageChannel channel = _client.GetChannel(_bumpChannelIDs[0]) as IMessageChannel; var builder = new EmbedBuilder() .WithColor(0xFF6E00) .WithDescription("Саме час **!bump**-нути :fire:"); if (container.UserCooldowns.Any()) { builder.Fields = new List <EmbedFieldBuilder> { new EmbedFieldBuilder { Name = "Кулдаун мають", Value = string.Join('\n', container.UserCooldowns.OrderBy(x => x.Value) .Select(user => $"<@{user.Key}> – {user.Value.ToString("HH:mm")}")) } } } ; var component = new ComponentBuilder() .WithButton("Підписатися на сповіщення", "BumpNotificationsSubscribe", ButtonStyle.Success) .WithButton("Відписатися від сповіщень", "BumpNotificationsUnsubscribe", ButtonStyle.Danger); await channel.SendMessageAsync(string.Join(' ', container.PingableUserIDs.Select(y => $"<@{y}>")), embed : builder.Build(), components : component.Build()); } }
/// <summary> /// Generates the message components for the given interaction /// </summary> /// <param name="type">The class type that handles the component interactions</param> /// <param name="channel">The channel the interaction will happen in</param> /// <param name="user">The user that triggered the interaction</param> /// <param name="message">The message that triggered the interaction</param> /// <returns>The message components to be sent to discord</returns> public async Task <MessageComponent> Components(Type type, IChannel channel, IUser user, IMessage?message) { if (!typeof(ComponentHandler).IsAssignableFrom(type)) { throw new ArgumentException($"Type does not implement `{nameof(ComponentHandler)}`", type.FullName); } var builder = new ComponentBuilder(); var methods = type.GetMethods(); foreach (var method in methods) { var compAtr = method.GetCustomAttribute <ComponentAttribute>(); if (compAtr == null) { continue; } if (compAtr is ButtonAttribute btn) { HandleButton(btn, method, builder); continue; } if (compAtr is not SelectMenuAttribute sm) { _logger.LogWarning($"Unknown `{nameof(ComponentAttribute)}`: {compAtr.GetType().Name}"); continue; } await HandleSelectMenu(sm, method, type, builder, channel, user, message); } return(builder.Build()); }
public async Task ClearAsync(SocketUserMessage message) { var componentBuilder = new ComponentBuilder(); await message.ModifyAsync(properties => properties.Components = componentBuilder.Build()); await RespondAsync($"Cleared role assignments for message: **{message.Id.ToString()}**."); }
protected virtual MessageComponent BuildComponents(IChannel channel, IUser user) { const ButtonStyle buttonStyle = ButtonStyle.Secondary; var builder = new ComponentBuilder() .WithButton(style: buttonStyle, emote: Options.First, customId: FirstId, disabled: _page <= 1) .WithButton(style: buttonStyle, emote: Options.Back, customId: PreviousId, disabled: _page <= 1) .WithButton(style: buttonStyle, emote: Options.Next, customId: NextId, disabled: _page >= _pages) .WithButton(style: buttonStyle, emote: Options.Last, customId: LastId, disabled: _page >= _pages); var manageMessages = (channel is IGuildChannel guildChannel) && (user as IGuildUser).GetPermissions(guildChannel).ManageMessages; if (Options.JumpDisplayOptions == JumpDisplayOptions.Always || (Options.JumpDisplayOptions == JumpDisplayOptions.WithManageMessages && manageMessages)) { builder.WithButton(style: buttonStyle, emote: Options.Jump, customId: JumpId); } builder.WithButton(style: buttonStyle, emote: new Emoji("🛑"), customId: StopId); if (Options.DisplayInformationIcon) { builder.WithButton(style: buttonStyle, emote: Options.Info, customId: InfoId); } return(builder.Build()); }
private static async Task <Message> GetLeaderboardMessageAsync(DatabaseContext dbContext, IConfigurationRoot configuration) { var users = await SharedLeaderboardManager.GetTopUsersAndTeams(dbContext, 20, configuration.GetValue <bool>("DynamicScoring")); var eb = new CustomEmbedBuilder(); eb.WithTitle("Leaderboard"); for (int i = 0; i < users.Count; i++) { if (users[i].IsTeam) { eb.Description += $"\n**{i + 1}. {users[i].TeamName}** (team) - {users[i].Score} points"; } else { eb.Description += $"\n**{i + 1}. {users[i].WebsiteUser?.UserName ?? users[i].DiscordUsername}** - {users[i].Score} points"; } } var builder = new ComponentBuilder().WithButton("Full Leaderboard", style: ButtonStyle.Link, url: "https://imaginaryctf.org/leaderboard"); return(new Message { Embed = eb.Build(), MessageComponent = builder.Build(), Ephemeral = true }); }
public async Task PingAsync(IIodemCommandContext context) { var cb = new ComponentBuilder(); cb.WithButton("Ping", "my_id"); await context.ReplyAsync(embed: new EmbedBuilder() .WithColor(Colors.Get("Iodem")) .WithDescription($"Pong! {Global.Client.Latency} ms") .Build(), component: cb.Build()); }
private MessageComponent CreateMessageComponents() { var builder = new ComponentBuilder() .WithButton("First", "first", ButtonStyle.Secondary, new Emoji("⏮️")) .WithButton("Previous", "previous", ButtonStyle.Secondary, new Emoji("⬅️")) .WithButton("Next", "next", ButtonStyle.Secondary, new Emoji("➡️")) .WithButton("Last", "last", ButtonStyle.Secondary, new Emoji("⏭️")); return(builder.Build()); }
public async Task PlayAsync(string searchQuery) { // Join if not playing. if (_lavaNode.HasPlayer(Context.Guild) is false) { await TryJoinAsync(); } var player = _lavaNode.GetPlayer(Context.Guild); if (Context.User is IVoiceState user && user.VoiceChannel != player.VoiceChannel) { await RespondAsync("You must be in the same voice channel."); return; } await DeferAsync(); // Play from url or search YouTube. var search = Uri.IsWellFormedUriString(searchQuery, UriKind.Absolute) ? await _lavaNode.SearchAsync(SearchType.Direct, searchQuery) : await _lavaNode.SearchYouTubeAsync(searchQuery); if (search.Status is SearchStatus.NoMatches or SearchStatus.LoadFailed) { await RespondAsync($"No matches found for query `{searchQuery.Truncate(100, "...")}`"); return; } // Generate select menu for search results. var selectMenu = new SelectMenuBuilder() .WithPlaceholder("Select a track") .WithCustomId($"tracks:{Context.Interaction.Id}") .WithMinValues(1) .WithMaxValues(1); foreach (var track in search.Tracks.Take(10)) { selectMenu.AddOption( track.Title, track.Url, track.Duration.ToString("c"), new Emoji("▶️")); } var components = new ComponentBuilder().WithSelectMenu(selectMenu); await Context.Interaction.ModifyOriginalResponseAsync(properties => { properties.Content = "Choose a track from the menu to play"; properties.Components = components.Build(); }); }
public MessageMetadata(Embed embed, Stream imageStream, bool imageIsSpoiler, string imageFileName, string message, bool success, bool hasMentions, ComponentBuilder componentBuilder) { Embed = embed; ImageStream = imageStream; ImageIsSpoiler = imageIsSpoiler; ImageFileName = imageFileName; Message = message; Success = success; HasMentions = hasMentions; Components = componentBuilder?.Build(); }
public async Task Buttons() { ComponentBuilder builder = new ComponentBuilder(); builder.WithButton("Test button 1", "btn1", ButtonStyle.Danger); builder.WithButton("Test button 2", "btn2", ButtonStyle.Danger); var msg = await ReplyAsync("Click button below", component : builder.Build()); var srv = Program.Services.GetRequiredService <MessageComponentService>(); srv.Register(msg, handleButton); }
//[Command("unpause")] //[Summary("Pauses the joining of the list.")] //[ModPermission] //public async Task Unpause() //{ // storage.IsPaused = false; // storage.Save(); // await UpdateReactionMessageAsync(waitingList, Context.Guild, storage); // await Context.Message.ReplyAsync("Waiting list has been unpaused"); //} public static async Task UpdatePublicMessageAsync(IWaitingList waitingList, IGuild guild, GuildData guildData) { var message = await GetMessageAsync(guild, guildData); if (message is not IUserMessage) { return; } var embedBuilder = new EmbedBuilder { Color = Color.Green, Title = $"Waiting list" }; var sortedList = await waitingList.GetPlayerListAsync(); var description = ""; int counter = 0; foreach (var player in sortedList) { description += $"**{++counter}.** {player.Name} ({GetMentionWithId(player.UserId)}) {(player.IsSub ? "(Sub) " : "")}"; if (player.PlayCount > 0) { description += $"(Played { player.PlayCount} time{ (player.PlayCount > 1 ? "s" : "")})"; } description += "\r\n"; } string url = "https://wl.pdelvo.com/WaitingList/" + guild.Id; embedBuilder.Description = description; embedBuilder.AddField("\u200B", "[View this list in real time](" + url + ")"); ComponentBuilder componentBuilder = new ComponentBuilder(); componentBuilder.WithButton("Join", customId: "join", disabled: guildData.IsPaused); componentBuilder.WithButton("Leave", customId: "leave"); // Waiting for an updated Discord.Net package for this to work componentBuilder.WithButton("Website", null, style: ButtonStyle.Link, url: url); Embed embed = embedBuilder.Build(); await message.ModifyAsync(p => { p.Content = $"Join the waiting list now!:"; p.Embed = embed; p.Components = componentBuilder.Build(); }); }
// TODO Handle Unhandled exception. Discord.Net.HttpException: The server responded with error 50007: Cannot send messages to this user public static async Task <bool> SaveMessage(SocketTextChannel socketTextChannel, SocketGuildUser user, IMessage message, bool byCommand) { var dmManager = DatabaseManager.Instance(); if (dmManager.IsSaveMessage(message.Id, user.Id)) { // dont allow double saves return(false); } string authorUsername = user.Username; // nickname? var link = $"https://discord.com/channels/{socketTextChannel.Guild.Id}/{socketTextChannel.Id}/{message.Id}"; // TODO create common place for button ids var builderComponent = new ComponentBuilder().WithButton("Delete Message", "delete-saved-message-id", ButtonStyle.Danger); EmbedBuilder builder = new EmbedBuilder(); builder.WithTitle($"Saved message from {authorUsername}"); builder.WithColor(0, 128, 255); builder.WithDescription(message.Content); builder.AddField("Guild", socketTextChannel.Guild.Name, true); builder.AddField("Channel", socketTextChannel.Name, true); builder.AddField("User", message?.Author?.Username ?? "N/A", true); builder.AddField("DirectLink", $"[Link to the message]({link})"); builder.WithAuthor(user); builder.WithCurrentTimestamp(); var messageSend = await user.SendMessageAsync("", false, builder.Build(), null, null, builderComponent.Build(), message.Embeds.Select(i => i as Embed).ToArray()); foreach (var item in message.Attachments) { await user.SendMessageAsync(item.Url, false, null, null, null, builderComponent.Build()); } dmManager.SaveMessage(message.Id, message?.Author?.Id ?? user.Id, user.Id, link, message.Content, byCommand, message.Id); if (!byCommand) { // TODO give hint to use the new way } return(true); }
private async Task OnActivityUpdatedAsync(ActivityContainer activity) { IMessageChannel channel = _client.GetChannel(activity.ChannelID) as IMessageChannel; var builder = ParseActivityContainer(activity); var componentBuilder = new ComponentBuilder() .WithButton(customId: "ActivitierSubscribe", style: ButtonStyle.Primary, emote: new Emoji("\U00002795")); await channel.ModifyMessageAsync(activity.ActivityID, msg => { msg.Content = string.Join(", ", _destinyRoleIDs.Select(x => $"<@&{x}>")); msg.Embed = builder.Build(); msg.Components = componentBuilder.Build(); }); }
public async Task Buttons() { try { ComponentBuilder builder = new ComponentBuilder(); builder.WithButton("Test button 1", "btn1", ButtonStyle.Danger); builder.WithButton("Test button 2", "btn2", ButtonStyle.Danger); var msg = await Interaction.RespondAsync("Click below", component : builder.Build()); var srv = Program.Services.GetRequiredService <MessageComponentService>(); srv.Register(msg, handleButton); } catch (Exception ex) { Program.LogError(ex, "EchoButtons"); } }
public static async Task LogErrorAsync(System.Exception e, ICommandContext ctx) { await LogAsync(new LogMessage(LogSeverity.Error, e.Source, e.Message, e)); if (ctx != null) { try { var id = Guid.NewGuid(); var button = new ComponentBuilder() .WithButton("More information", $"error-{id}"); StaticObjects.Errors.Add($"error-{id}", e); var embed = new EmbedBuilder { Color = Color.Red, Title = "An error occured", Description = "The error was automatically reported. If the error persist, please contact the bot owner." }.Build(); await ctx.ReplyAsync(embed : embed, components : button.Build()); } catch (System.Exception ex) { // TODO: Couldn't send error in channel } if (SentrySdk.IsEnabled) { SentrySdk.CaptureException(new System.Exception($"Command {ctx} failed", e)); } } else { if (SentrySdk.IsEnabled) { SentrySdk.CaptureException(e); } } await StaticObjects.Db.AddErrorAsync(e); }
public async Task Github() { //response embed: var embed = new Discord.EmbedBuilder(); embed.Title = "GitHub"; embed.Url = "https://github.com/bman46/InstagramEmbedDiscordBot"; embed.Description = "View the source code, download code to host your own version, contribute to the bot, and file issues for improvements or bugs. [Github](https://github.com/bman46/InstagramEmbedDiscordBot)"; embed.WithColor(new Color(131, 58, 180)); ButtonBuilder buttonGithub = new ButtonBuilder(); buttonGithub.Label = "GitHub"; buttonGithub.Style = ButtonStyle.Link; buttonGithub.Url = "https://github.com/bman46/InstagramEmbedDiscordBot"; ComponentBuilder component = new ComponentBuilder().WithButton(buttonGithub); await RespondAsync(embed : embed.Build(), ephemeral : true, components : component.Build()); }
public async Task RemoveAsync(SocketUserMessage message, IRole role) { var componentBuilder = new ComponentBuilder(); // Rebuild components without the role. IList <ActionRowBuilder> rows = message.Components .Select(row => row.Components .Where(component => component.CustomId != $"{Prefix}-{message.Id}-{role.Id}").ToList()) .Where(components => components.Count > 0) .Select(components => new ActionRowBuilder().WithComponents(components)) .ToList(); componentBuilder.WithRows(rows); await message.ModifyAsync(properties => properties.Components = componentBuilder.Build()); await RespondAsync($"Removed role {role.Mention} to message: **{message.Id.ToString()}**.", ephemeral : true); }
// This is not the recommended way to write a bot - consider // reading over the Commands Framework sample. private async Task MessageReceivedAsync(SocketMessage message) { // The bot should never respond to itself. if (message.Author.Id == _client.CurrentUser.Id) { return; } if (message.Content == "!ping") { // Create a new componentbuilder, in which dropdowns & buttons can be created. var cb = new ComponentBuilder() .WithButton("Click me!", "unique-id", ButtonStyle.Primary); // Send a message with content 'pong', including a button. // This button needs to be build by calling .Build() before being passed into the call. await message.Channel.SendMessageAsync("pong!", components : cb.Build()); } }
/// <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)); } }
public async Task HelpAsync() { var ct = new ComponentBuilder().WithButton("Previous page", $"id.0|{Context.User.Id}", ButtonStyle.Danger, null, null, true).WithButton("Next page", $"id.2|{Context.User.Id}", ButtonStyle.Success).WithButton("Our website", null, ButtonStyle.Link, null, "https://terrariabuilders.com/").WithButton("Become a voter!", $"id.voter|{Context.User.Id}", ButtonStyle.Primary); var eb = new EmbedBuilder() { Color = Color.Blue, Description = $"The Grand Design has been developed by the Terraria Builders Community to bring utility in Terraria and Discord to new heights!", Author = new EmbedAuthorBuilder() { IconUrl = $"{Utils.BotUser.GetAvatarUrl()}", Name = "TGD Help | Scroll through pages with the buttons below.", }, Footer = new EmbedFooterBuilder() { Text = $"Page 1 • The Grand Design!", }, Fields = { new EmbedFieldBuilder() { Name = "Commands", Value = "All commands are featured in the `!commands` command. Check it out!TGD also introduces slashcommands for a more fleshed out experience. type '/' to get a preview of all commands!" }, new EmbedFieldBuilder() { Name = "DM Support", Value = "To get into contact with the staff of this server in an easy way, DM this bot and recieve answer!" }, new EmbedFieldBuilder() { Name = "About TBC", Value = "A large amount of information about the Terraria Builders Community is provided in pages beyond where you currently are. Use the buttons to navigate through pages!" } } }; await ReplyAsync("", false, eb.Build(), null, null, null, ct.Build()); await Utils.SendLog(Context.Message.Content, Context.User); }
public static async Task <(Embed Embed, MessageComponent Components)> GetSettingsDisplayAsync(IGuild guild) { var subs = await StaticObjects.GetSubscriptionsAsync(guild.Id); var mySubs = subs?.Select(x => $"**{Utils.ToWordCase(x.Key)}**: {(x.Value == null ? "None" : x.Value.Mention)}"); var button = new ComponentBuilder(); if (subs != null) { foreach (var sub in subs) { if (sub.Value != null) { button.WithButton($"Remove {sub.Key} subscription", $"delSub-{sub.Key}", style: ButtonStyle.Danger); } } } button.WithButton("Database dump", "dump", style: ButtonStyle.Secondary); button.WithButton("Toggle translation from flags", "flag", style: ButtonStyle.Secondary); return(new EmbedBuilder { Title = guild.ToString(), Color = Color.Purple, Fields = new List <EmbedFieldBuilder> { new EmbedFieldBuilder { Name = "Translation from flags", Value = StaticObjects.Db.GetGuild(guild.Id).TranslateUsingFlags ? "Enabled" : "Disabled" }, new EmbedFieldBuilder { Name = "Subscriptions", Value = subs == null ? "Not yet initialized" : (mySubs.Any() ? string.Join("\n", mySubs) : "None") } } }.Build(), button.Build()); }
public async Task Delete(string userID) { var button = new ComponentBuilder() .WithButton(Translator.T().CmdUndoButtonsPublicNotification(), $"unban-conf-delete:1,{userID}", ButtonStyle.Primary) .WithButton(Translator.T().CmdUndoButtonsNoPublicNotification(), $"unban-conf-delete:0,{userID}", ButtonStyle.Secondary) .WithButton(Translator.T().CmdUndoButtonsCancel(), "unban-cancel", ButtonStyle.Danger); var castInteraction = Context.Interaction as SocketMessageComponent; var embed = castInteraction.Message.Embeds.FirstOrDefault().ToEmbedBuilder().WithColor(Color.Red); embed.Fields = new() { new EmbedFieldBuilder().WithName(Translator.T().CmdUndoResultTitle()).WithValue(Translator.T().CmdUndoResultWaiting()), new EmbedFieldBuilder().WithName(Translator.T().CmdUndoPublicNotificationTitle()).WithValue(Translator.T().CmdUndoPublicNotificationDescription()) }; await castInteraction.UpdateAsync(message => { message.Embed = embed.Build(); message.Components = button.Build(); }); }
public async Task Start() { var message = await GetMessageAsync(Context.Guild, guildData); if (message != null) { await Context.Message.ReplyAsync("Waiting list is already open"); return; } waitingList.ClearUsers(); var waitingListChannel = Context.Guild.GetTextChannel(guildData.WaitingListChannelId); message = await waitingListChannel.SendMessageAsync("Join the waiting list now!"); guildData.PublicMessageId = message.Id; guildData.IsEnabled = true; guildData.IsPaused = false; dataContext.Update(guildData); dataContext.SaveChanges(); // await message.AddReactionAsync(storage.ReactionEmote); await UpdatePublicMessageAsync(waitingList, Context.Guild, guildData); var modMessage = await Context.Message.ReplyAsync("Waiting list has been started"); ComponentBuilder componentBuilder = new ComponentBuilder(); componentBuilder.WithButton("Clear counters", customId: "clearcounters"); await modMessage.ModifyAsync(p => { p.Components = componentBuilder.Build(); }); }
public async Task Unmute([Summary("user", "User to unmute")] IUser user) { ModCaseRepository repo = ModCaseRepository.CreateDefault(ServiceProvider, CurrentIdentity); List <ModCase> modCases = (await repo.GetCasesForGuildAndUser(Context.Guild.Id, user.Id)) .Where(x => x.PunishmentActive && x.PunishmentType == PunishmentType.Mute).ToList(); if (modCases.Count == 0) { await Context.Interaction.RespondAsync(Translator.T().CmdUndoNoCases()); return; } StringBuilder interactionString = new(); interactionString.AppendLine(Translator.T().CmdUndoUnmuteFoundXCases(modCases.Count)); foreach (ModCase modCase in modCases.Take(5)) { int truncate = 50; if (modCase.PunishedUntil != null) { truncate = 30; } interactionString.Append($"- [#{modCase.CaseId} - {modCase.Title.Truncate(truncate)}]"); interactionString.Append($"({Config.GetBaseUrl()}/guilds/{modCase.GuildId}/cases/{modCase.CaseId})"); if (modCase.PunishedUntil != null) { interactionString.Append($" {Translator.T().Until()} {modCase.PunishedUntil.Value.ToDiscordTS()}"); } interactionString.AppendLine(); } if (modCases.Count > 5) { interactionString.AppendLine(Translator.T().AndXMore(modCases.Count - 5)); } EmbedBuilder embed = new EmbedBuilder() .WithTitle(user.Username) .WithDescription(interactionString.ToString()) .WithColor(Color.Orange); embed.AddField(Translator.T().CmdUndoResultTitle(), Translator.T().CmdUndoResultWaiting()); var button = new ComponentBuilder() .WithButton(Translator.T().CmdUndoUnmuteButtonsDelete(), $"unmute-delete:{user.Id}", ButtonStyle.Primary) .WithButton(Translator.T().CmdUndoUnmuteButtonsDeactivate(), $"unmute-deactivate:{user.Id}", ButtonStyle.Secondary) .WithButton(Translator.T().CmdUndoButtonsCancel(), "unmute-cancel", ButtonStyle.Danger); await Context.Interaction.RespondAsync(embed : embed.Build(), components : button.Build()); IMessage responseMessage = await Context.Interaction.GetOriginalResponseAsync(); }
public Solved Solve(State state) { result = new List <ActionBase>(); BoosterMaster.CreatePalka(state, result, 1); var map = state.Map; MinFreeY = Enumerable.Repeat(int.MaxValue, state.Map.SizeX).ToArray(); for (int x = 0; x < map.SizeX; x++) { for (int y = 0; y < map.SizeY; y++) { if (map[new V(x, y)] == CellState.Void) { MinFreeY[x] = Math.Min(MinFreeY[x], y); } } } state.OnWrap = v => { if (v.Y == MinFreeY[v.X]) { MinFreeY[v.X] = int.MaxValue; for (int y = v.Y + 1; y < map.SizeY; y++) { if (map[new V(v.X, y)] == CellState.Void) { MinFreeY[v.X] = y; break; } } } }; int palkaDown = -state.SingleWorker.Manipulators.Min(m => m.Y); while (state.UnwrappedLeft > 0) { if (result.Count == 213) #pragma warning disable 1717 { palkaDown = palkaDown; } #pragma warning restore 1717 for (int check = 0; check < 2; check++) { var me = state.SingleWorker; var pathBuilder = new PathBuilder(map, me.Position, MinFreeY, palkaDown, check == 0); V best = null; var bestDist = int.MaxValue; var bestY = int.MaxValue; var bestSize = double.MaxValue; var(comp, csize) = ComponentBuilder.Build(map, me.Position); for (int y = 0; y < map.SizeY; y++) { for (int x = 0; x < map.SizeX; x++) { if (map[new V(x, y)] != CellState.Void) { continue; } var dist = pathBuilder.Distance(new V(x, y)); var size = csize[comp[new V(x, y)]]; if (dist == int.MaxValue) { continue; } if (check == 0 && (size < bestSize || size == bestSize && dist < bestDist) || check == 1 && (dist < bestDist && bestY >= y || bestY > y)) { bestDist = dist; bestY = y; bestSize = size; best = new V(x, y); } } } if (best == null) { continue; } var actions = pathBuilder.GetActions(best).ToList(); state.ApplyRange(actions); result.AddRange(actions); break; } } return(new Solved { Actions = new List <List <ActionBase> > { result } }); }
public async Task EmoteSearch(string search, bool debug = false) { if (!CommonHelper.AllowedToRun(BotPermissionType.EnableType2Commands, Context.Message.Channel.Id, Context.Message.Author.Id)) { return; } Stopwatch watch = new Stopwatch(); watch.Start(); var author = Context.Message.Author; if (search.Length < 2 && author.Id != Program.ApplicationSetting.Owner) { await Context.Channel.SendMessageAsync($"Search term needs to be atleast 2 characters long", false); // to prevent from db overload return; } var emoteResult = DiscordHelper.SearchEmote(search, Context.Guild.Id, 0, debug); watch.Stop(); int page = 0; string desc = $"**Available({page * emoteResult.PageSize}-{Math.Min((page + 1) * emoteResult.PageSize, emoteResult.TotalEmotesFound)}/{emoteResult.TotalEmotesFound}) '{search}' emojis to use (Usage .<name>)**" + Environment.NewLine; EmbedBuilder builder = new EmbedBuilder() { ImageUrl = emoteResult.Url, Description = desc, Color = Color.DarkRed, Title = "Image full size", Footer = new EmbedFooterBuilder() { Text = $"{search}, Page: {page}, Debug: {debug}" }, ThumbnailUrl = "https://cdn.battlerush.dev/bot_xmas.png", Timestamp = DateTimeOffset.Now, Url = emoteResult.Url, }; builder.WithAuthor(Context.User); //foreach (var item in emoteResult.Fields) // builder.AddField(item.Key, item.Value); try { // TODO create common place for button ids var builderComponent = new ComponentBuilder() .WithButton("Prev <", $"emote-get-prev-page-{search}-{page}-{debug}", ButtonStyle.Danger, null, null, page == 0) .WithButton("> Next", $"emote-get-next-page-{search}-{page}-{debug}", ButtonStyle.Success, null, null, (page + 1) * emoteResult.PageSize > emoteResult.TotalEmotesFound); // TODO properly calc max page //.WithButton("Row 1", "emote-get-row-1", ButtonStyle.Secondary, null, null, false, 1) //.WithButton("Row 2", "emote-get-row-2", ButtonStyle.Secondary, null, null, false, 1) //.WithButton("Row 3", "emote-get-row-3", ButtonStyle.Secondary, null, null, false, 1) //.WithButton("Row 4", "emote-get-row-4", ButtonStyle.Secondary, null, null, false, 1) //.WithButton("Row 5", "emote-get-row-5", ButtonStyle.Secondary, null, null, false, 1); var msg2 = await Context.Channel.SendMessageAsync(emoteResult.textBlock, false, builder.Build(), null, null, null, builderComponent.Build()); } catch (Exception ex) { } }
public async Task EmoteFavourite(string search, bool secondTry = false) { int rows = 4; int columns = 5; if (!CommonHelper.AllowedToRun(BotPermissionType.EnableType2Commands, Context.Message.Channel.Id, Context.Message.Author.Id)) { return; } Stopwatch watch = new Stopwatch(); watch.Start(); var author = Context.Message.Author; if (search.Length < 2 && author.Id != Program.ApplicationSetting.Owner) { await Context.Channel.SendMessageAsync($"Search term needs to be atleast 2 characters long", false); // to prevent from db overload return; } var emoteResult = DiscordHelper.SearchEmote(search, Context.Guild.Id, 0, false, rows, columns); watch.Stop(); int page = 0; string desc = $"**Available({page * emoteResult.PageSize}-{Math.Min((page + 1) * emoteResult.PageSize, emoteResult.TotalEmotesFound)}/{emoteResult.TotalEmotesFound}) '{search}' emojis to use (Usage .<name>)**" + Environment.NewLine; try { EmbedBuilder builder = new EmbedBuilder() { ImageUrl = emoteResult.Url, Description = desc, Color = Color.DarkRed, Title = "Image full size", Footer = new EmbedFooterBuilder() { Text = search + " Page: " + page }, ThumbnailUrl = "https://cdn.battlerush.dev/bot_xmas.png", Timestamp = DateTimeOffset.Now, Url = emoteResult.Url, }; builder.WithAuthor(Context.User); //foreach (var item in emoteResult.Fields) // builder.AddField(item.Key, item.Value); // TODO create common place for button ids var builderComponent = new ComponentBuilder(); int row = 0; int col = 0; foreach (var emote in emoteResult.EmoteList) { if (emoteResult.valid.Skip(row * columns + col).First()) { builderComponent.WithButton(emote.Value, $"emote-fav-{emote.Key}", ButtonStyle.Primary, Emote.Parse($"<:{emote.Value}:{emote.Key}>"), null, false, row); } else { builderComponent.WithButton(emote.Value, $"emote-fav-{emote.Key}", ButtonStyle.Primary, null, null, false, row); } col++; if (col == columns) { row++; col = 0; } } // Start fresh row for paging if (col > 0) { row++; } builderComponent.WithButton("Prev <", $"emote-fav-get-prev-page-{search}-{page}", ButtonStyle.Danger, null, null, page == 0, row); builderComponent.WithButton("> Next", $"emote-fav-get-next-page-{search}-{page}", ButtonStyle.Success, null, null, (page + 1) * emoteResult.PageSize > emoteResult.TotalEmotesFound, row); var msg2 = await Context.Channel.SendMessageAsync("", false, builder.Build(), null, null, null, builderComponent.Build()); } catch (HttpException ex) { foreach (var error in ex.Errors) { if (error.Errors.Any(i => i.Code == "BUTTON_COMPONENT_INVALID_EMOJI")) { var parts = error.Path.Split('.'); int error_row = Convert.ToInt32(Regex.Replace(parts[0], "[^0-9]", "")); int error_column = Convert.ToInt32(Regex.Replace(parts[1], "[^0-9]", "")); var brokenEmote = emoteResult.EmoteList.Skip(error_row * columns + error_column).First(); EmoteDBManager.Instance().ChangeValidStatus(brokenEmote.Key, false); } } // call yourself again to retry -> if (secondTry == false) { await EmoteFavourite(search, true); } // Some emotes may no lonver be valid -> db entry to invalidate the emote } catch (Exception ex) { await Context.Channel.SendMessageAsync(ex.ToString(), false); } }
public async Task ViewFavouriteEmotes() { var userFavEmotes = DatabaseManager.EmoteDatabaseManager.GetFavouriteEmotes(Context.User.Id); var emotes = DatabaseManager.EmoteDatabaseManager.GetDiscordEmotes(userFavEmotes.Select(i => i.DiscordEmoteId).ToList()); string fileName = $"emote_fav_{new Random().Next(int.MaxValue)}.png"; // Show the user specified emote name foreach (var emote in emotes) { emote.EmoteName = userFavEmotes.SingleOrDefault(i => i.DiscordEmoteId == emote.DiscordEmoteId)?.Name ?? "N/A"; } // TODO List guild emotes var emoteDrawing = DiscordHelper.DrawPreviewImage(emotes, new List <GuildEmote>(), 10, 10); DrawingHelper.SaveToDisk(Path.Combine(Program.ApplicationSetting.CDNPath, fileName), emoteDrawing.Bitmap); EmbedBuilder builder = new EmbedBuilder() { ImageUrl = $"https://cdn.battlerush.dev/{fileName}", Description = "Your Favourited emotes", Color = Color.DarkRed, Title = "Image full size", Footer = new EmbedFooterBuilder() { Text = "" + " Page: " + -1 }, ThumbnailUrl = "https://cdn.battlerush.dev/bot_xmas.png", Timestamp = DateTimeOffset.Now, Url = $"https://cdn.battlerush.dev/{fileName}", }; builder.WithAuthor(Context.User); // COPY OF OTHER FAV FUNCTION var builderComponent = new ComponentBuilder(); int rows = 4; int columns = 5; int row = 0; int col = 0; foreach (var emote in emotes) { if (emote.IsValid && false) { builderComponent.WithButton(emote.EmoteName, $"emote-del-{emote.DiscordEmoteId}", ButtonStyle.Primary, Emote.Parse($"<:{emote.EmoteName}:{emote.DiscordEmoteId}>"), null, false, row); } else { builderComponent.WithButton(emote.EmoteName, $"emote-del-{emote.DiscordEmoteId}", ButtonStyle.Danger, null, null, false, row); } col++; if (col == columns) { row++; col = 0; } } // Start fresh row for paging if (col > 0) { row++; } //builderComponent.WithButton("Prev <", $"emote-fav-get-prev-page-{search}-{page}", ButtonStyle.Danger, null, null, page == 0, row); //builderComponent.WithButton("> Next", $"emote-fav-get-next-page-{search}-{page}", ButtonStyle.Success, null, null, (page + 1) * emoteResult.PageSize > emoteResult.TotalEmotesFound, row); var msg2 = await Context.Channel.SendMessageAsync("", false, builder.Build(), null, null, null, builderComponent.Build()); }