public async Task HelpAsync()
        {
            // Deletes the invoking message if it's not a direct message.
            if (!Context.IsPrivate)
            {
                await Context.Message.DeleteAsync();
            }

            var embed = new EmbedBuilder
            {
                Color       = new Color(47, 111, 146),
                Title       = "\u2753 Command Help",
                Description = $"A command can be invoked by prefixing its name with `{Program.COMMAND_PREFIX}`. To see usage " +
                              $"details for a command, use `{Program.COMMAND_PREFIX}help [command]`.\n\nThe following is a " +
                              "list of available commands:"
            };

            // Sorts modules alphabetically and adds a field for each one.
            foreach (ModuleInfo module in _commands.Modules.OrderBy(m => m.Name))
            {
                _help.AddModuleField(module, ref embed);
            }

            // Replies normally if a direct message fails.
            try
            {
                await Context.User.SendMessageAsync(string.Empty, false, embed.Build());
            }
            catch
            {
                await ReplyAsync(string.Empty, false, embed.Build());
            }

            await DataBaseUtil.AddCommandAsync("Help", Context);
        }
Beispiel #2
0
        public async Task CatFactAsync()
        {
            var catFact = "Did you know cats have big bushy tails?";
            var name    = "Cat Fact 0";

            // Gets a fact from the file.
            if (File.Exists(_dataService.CatFactPath))
            {
                string[] allLines   = File.ReadAllLines(_dataService.CatFactPath);
                int      lineNumber = _random.Next(0, allLines.Length);
                catFact = allLines[lineNumber];

                // Splits the name and the fact in the selected line.
                Match match = Regex.Match(catFact, @"^\w+ Fact \d*", RegexOptions.IgnoreCase);
                name    = match.Value;
                catFact = catFact.Substring(match.Length).Trim();
            }

            var embed = new EmbedBuilder
            {
                ThumbnailUrl = _dataService.GetRandomImgFromUrl("https://content.tophattwaffle.com/BotHATTwaffle/catfacts/"),
                Color        = new Color(230, 235, 240)
            };

            embed.WithAuthor("CAT FACTS!", Context.Message.Author.GetAvatarUrl());
            embed.WithFooter("This was cat facts, you cannot unsubscribe.");
            embed.AddField(name, catFact);

            await _dataService.ChannelLog($"{Context.Message.Author.Username.ToUpper()} JUST GOT HIT WITH A CAT FACT");

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("CatFact", Context);
        }
Beispiel #3
0
        public async Task TanookiFactAsync()
        {
            var tanookiFact = "Did you know Tanooki has a big bushy tail?";

            // Gets a fact from the file.
            if (File.Exists(_dataService.TanookiFactPath))
            {
                string[] allLines   = File.ReadAllLines(_dataService.TanookiFactPath);
                int      lineNumber = _random.Next(0, allLines.Length);
                tanookiFact = allLines[lineNumber];
            }

            var embed = new EmbedBuilder
            {
                ThumbnailUrl = _dataService.GetRandomImgFromUrl("https://content.tophattwaffle.com/BotHATTwaffle/tanookifacts/"),
                Color        = new Color(230, 235, 240),
                Description  = tanookiFact
            };

            embed.WithAuthor("TANOOKI FACTS!", Context.Message.Author.GetAvatarUrl());
            embed.WithFooter("This was Tanooki facts; you cannot unsubscribe.");

            await _dataService.ChannelLog($"{Context.Message.Author.Username.ToUpper()} JUST GOT HIT WITH A TANOOKI FACT");

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("TanookiFact", Context);
        }
Beispiel #4
0
        public async Task MuteAsync(
            [Summary("The user to mute.")] SocketGuildUser user,
            [Summary("The duration, in minutes, of the mute.")]
            [RequireBoundaries(1, 43200)] int duration = 5,
            [Summary("The reason for the mute.")][Remainder]
            string reason = "No reason provided.")
        {
            if (user.Roles.Contains(_data.ModRole))
            {
                await Context.Channel.SendMessageAsync(string.Empty, embed :
                                                       new EmbedBuilder().WithAuthor("Mods don't mute other Mods...")
                                                       .WithDescription("Now you 2 need to learn to play nice and get along."));

                return;
            }

            if (await _mute.MuteAsync(user, (SocketGuildUser)Context.User, duration == 0 ? default(int?) : duration, reason))
            {
                await Context.Channel.SendMessageAsync($"Successfully muted {user}.");
            }
            else
            {
                await Context.Channel.SendMessageAsync($"{user} is already muted!");
            }

            await DataBaseUtil.AddCommandAsync("Mute", Context);
        }
Beispiel #5
0
        public async Task AnnounceAsync(
            [Summary("A format string or the input for the interactive builder's current prompt.")][Remainder]
            string input = null)
        {
            await Context.Message.DeleteAsync();

            if (input != null)
            {
                // Builds the embed from a supplied formatting string.
                var   builder = new QuickBuilder(Context);
                Embed embed   = builder.Build(input);

                if (!string.IsNullOrWhiteSpace(builder.Errors))
                {
                    await ReplyAndDeleteAsync($"```{builder.Errors}```", timeout : TimeSpan.FromSeconds(15));
                }

                if (embed == null)
                {
                    return;                // Builder was cancelled.
                }
                await SendEmbedAsync(embed, await builder.ParseChannels());
            }
            else
            {
                // No formatting string given; interactively builds the embed by prompting the user.
                var   builder = new InteractiveBuilder(Context, Interactive);
                Embed embed   = await builder.BuildAsync();

                if (embed == null)
                {
                    return;                // Builder was cancelled or timed out.
                }
                await SendEmbedAsync(embed, await builder.PromptDestinationAsync(Context));
            }

            // Helper function the send the embed to all given channels.
            async Task SendEmbedAsync(Embed embed, IReadOnlyCollection <SocketTextChannel> channels)
            {
                if (!channels.Any())
                {
                    await ReplyAndDeleteAsync("```No channel mentions were found.```", timeout : TimeSpan.FromSeconds(15));

                    return;
                }

                foreach (SocketTextChannel channel in channels)
                {
                    await channel.SendMessageAsync(string.Empty, false, embed);
                }

                await _data.ChannelLog(
                    $"Embed created by {Context.User} was sent to {string.Join(", ", channels.Select(c => c.Name))}.");

                await _data.LogChannel.SendMessageAsync(string.Empty, false, embed);
            }

            await DataBaseUtil.AddCommandAsync("Announce", Context);
        }
Beispiel #6
0
        public async Task StatsAsync(
            [Summary("The user for which to retrieve statistics. If no user is specified, the invoking user is used.")]
            SocketUser user = null)
        {
            user = user ?? Context.User;

            CommandUse[] commands = await DataBaseUtil.GetCommandsAsync(user.Id);

            Shitpost[] shitposts = await DataBaseUtil.GetShitpostsAsync(user.Id);

            Mute[] mutes = await DataBaseUtil.GetMutesAsync(user.Id);

            EmbedBuilder embed = new EmbedBuilder().WithAuthor($"Stats for {user}", user.GetAvatarUrl());

            if (commands.Any())
            {
                string fav      = commands.GroupBy(r => r.command).OrderByDescending(g => g.Count()).Select(g => g.Key).First();
                int    favCount = commands.Count(c => c.command == fav);

                embed.AddField("Command Usage", $"Total: `{commands.Length}`\nFavorite: `{fav}` ({favCount})");
            }

            if (shitposts.Any())
            {
                string fav      = shitposts.GroupBy(r => r.shitpost).OrderByDescending(g => g.Count()).Select(g => g.Key).First();
                int    favCount = shitposts.Count(c => c.shitpost == fav);

                embed.AddField("Shitpost Usage", $"Total: `{shitposts.Length}`\nFavorite: `{fav}` ({favCount})");
            }

            if (mutes.Any())
            {
                Mute   mute  = mutes.First();
                string value = $"Total: {mutes.Length}\nTimestamp: `{mute.Timestamp:yyyy-MM-ddTHH:mm:ssZ}`\nDuration: `";

                if (mute.Duration.HasValue)
                {
                    value += mute.Duration + (mute.Duration == 1 ? "` minute" : "` minutes");
                }
                else
                {
                    value += "indefinite`";
                }

                if (mute.Reason != null)
                {
                    value += $"\nReason: `{mute.Reason}`";
                }

                embed.AddField("Latest Mute Information", value);
            }

            await ReplyAsync(string.Empty, embed : embed.Build());

            await DataBaseUtil.AddCommandAsync("Stats", Context);
        }
Beispiel #7
0
        public async Task ActiveAsync([Summary("User to give role to")] SocketGuildUser user)
        {
            await _data.ChannelLog($"{user} has been given {_data.ActiveRole.Mention} by {Context.User}");

            await ReplyAsync($"{user.Mention} has been given {_data.ActiveRole.Mention}!\n\nThanks for being an active member in our community!");

            await((IGuildUser)user).AddRoleAsync(_data.ActiveRole);

            await DataBaseUtil.AddCommandAsync("Active", Context);
        }
Beispiel #8
0
        public async Task SearchAsync(
            [Summary("The series in which to search.")]
            string series,
            [Summary("The term for which to search in the series.")][Remainder]
            string term)
        {
            IUserMessage wait = await ReplyAsync(
                $":eyes: Searching for **{term}** in **{series}**. This may take a moment! :eyes:");

            bool isPrivate = Context.IsPrivate;
            List <List <string> > results = await _dataService.Search(series, term, isPrivate); // Peforms a search.

            await _dataService.ChannelLog($"{Context.User} ran a search", $"Series: {series}\nSearch Term: {term}");

            // Notifies the user of a lack of search results.
            if (!results.Any())
            {
                results.Add(
                    new List <string>
                {
                    "Try a different search term",
                    "http://tophattwaffle.com/faq",
                    "I could not locate anything for the search term you provided. Please try a different search term.",
                    null
                });
            }

            foreach (List <string> r in results)
            {
                var embed = new EmbedBuilder
                {
                    Author = new EmbedAuthorBuilder
                    {
                        Name    = r[0],
                        IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                    },
                    Title        = "Click Here",
                    Url          = r[1],
                    ThumbnailUrl = r[3],
                    Color        = new Color(243, 128, 72),
                    Description  = r[2]
                };

                await ReplyAsync(string.Empty, false, embed.Build());
            }

            if (!isPrivate)
            {
                await wait.DeleteAsync();
            }

            await DataBaseUtil.AddCommandAsync("Search", Context);
        }
Beispiel #9
0
        public async Task TanookiLookAsync()
        {
            var embed = new EmbedBuilder
            {
                ImageUrl = _dataService.GetRandomImgFromUrl("https://content.tophattwaffle.com/BotHATTwaffle/kimjongillookingatthings/"),
                Color    = new Color(138, 43, 226)
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("TanookiIRL", Context);
        }
Beispiel #10
0
        public async Task PingAsync()
        {
            var builder = new EmbedBuilder
            {
                Color       = new Color(47, 111, 146),
                Description = $"*Do you like waffles?*\nIt took me **{_client.Latency} ms** to reach the Discord API."
            };

            await ReplyAsync(string.Empty, false, builder.Build());

            await DataBaseUtil.AddCommandAsync("Ping", Context);
        }
Beispiel #11
0
        public async Task ShutdownAsync()
        {
            await DataBaseUtil.AddCommandAsync("Shutdown", Context);

            await Context.Message.DeleteAsync();

            await _data.ChannelLog($"{Context.Message.Author} is shutting down the bot.");

            await Context.Client.SetStatusAsync(UserStatus.Invisible); // Workaround for an issue with StopAsync.

            await Context.Client.StopAsync();

            await Task.Delay(2000); // Without the delay, the bot never logs the shutdown.

            Environment.Exit(0);
        }
Beispiel #12
0
        public async Task ClearReservationsAsync(
            [Summary("The three-letter code which identifies the server to clear.")]
            string serverCode = null)
        {
            if (serverCode == null)
            {
                await _playtesting.ClearServerReservations();
            }
            else
            {
                await _playtesting.ClearServerReservations(serverCode);
            }

            await ReplyAsync(string.Empty, false, _playtesting.DisplayServerReservations());

            await DataBaseUtil.AddCommandAsync("ClearReservations", Context);
        }
Beispiel #13
0
        public async Task SearchAsync(
            [Summary("The term for which to search.")][Remainder]
            string term)
        {
            await Context.Channel.TriggerTypingAsync();

            term = term.Replace(' ', '+');
            string builtUrl = $"https://developer.valvesoftware.com/w/index.php?search={term}&title=Special%3ASearch&go=Go";
            string siteTitle;

            // Download web page title and store to string.
            using (var client = new WebClient())
            {
                siteTitle = client.DownloadString(builtUrl);
            }

            var regex = new Regex(@"(?<=<title.*>)([\s\S]*)(?=</title>)", RegexOptions.IgnoreCase);

            siteTitle = regex.Match(siteTitle).Value.Trim();

            // Defaults the URL if it isn't properly formatted.
            if (!Uri.IsWellFormedUriString(builtUrl, UriKind.Absolute))
            {
                builtUrl = "https://developer.valvesoftware.com/wiki/Main_Page";
                term     = "Valve Developer Community";
            }

            var builder = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = $"This is what I was able to find for {term}",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title       = "Search Results",
                Url         = builtUrl,
                ImageUrl    = "https://developer.valvesoftware.com/w/skins/valve/images-valve/logo.png",
                Color       = new Color(71, 126, 159),
                Description = siteTitle
            };

            await ReplyAsync(string.Empty, false, builder.Build());

            await DataBaseUtil.AddCommandAsync("VDC", Context);
        }
        public async Task AboutAsync()
        {
            DateTime buildDate = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime.ToUniversalTime();

            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "About BotHATTwaffle",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Url          = "https://www.tophattwaffle.com/",
                ThumbnailUrl = _client.CurrentUser.GetAvatarUrl(),
                Color        = new Color(130, 171, 206),
                Description  = "BotHATTwaffle was started to centralize Source Engine Discord server functions that were " +
                               "fractured between multiple bots. This bot was my first attempt at a real C# program that other " +
                               "people would interact with.\n\nPlease let me know if you have any suggests or find bugs!"
            };

            embed.AddInlineField("Author", "[TopHATTwaffle](https://github.com/tophattwaffle)");
            embed.AddInlineField(
                "Contributors",
                "[BenBlodgi](https://github.com/BenVlodgi)\n" +
                "[Mark](https://github.com/MarkKoz)\n" +
                "[JimWood](https://github.com/JamesT-W)");
            embed.AddInlineField(
                "Build Date",
                $"{buildDate:yyyy-MM-ddTHH:mm:ssK}\n[Changelog](https://github.com/tophattwaffle/BotHATTwaffle/commits/master)");
            embed.AddInlineField(
                "Libraries",
                "[Discord.net V1.0.2](https://github.com/RogueException/Discord.Net)\n" +
                "[CoreRCON](https://github.com/ScottKaye/CoreRCON)\n" +
                "[Html Agility Pack](http://html-agility-pack.net/)\n" +
                "[Newtonsoft Json.NET](https://www.newtonsoft.com/json)\n" +
                "[SSH.NET](https://github.com/sshnet/SSH.NET/)\n" +
                "[FluentFTP](https://github.com/robinrodricks/FluentFTP)\n" +
                "[EF Core](https://docs.microsoft.com/en-us/ef/core/)");

            embed.WithFooter("Build date");
            embed.WithTimestamp(buildDate);

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("About", Context);
        }
Beispiel #15
0
        public async Task SuppressAsync(int input = 0)
        {
            if (input == 0)
            {
                await ReplyAsync($"```True means this alert will not be fired until the announcement " +
                                 $"message has changed.\n\nCurrent Alert Flags:\n{_playtesting.GetAnnounceFlags()}```");

                return;
            }

            _playtesting.SuppressAnnounce(input);

            await ReplyAsync($"```True means this alert will not be fired until the announcement " +
                             $"message has changed.\n\nCurrent Alert Flags:\n{_playtesting.GetAnnounceFlags()}```");

            await _data.ChannelLog($"{Context.User} changed playtest alert flag suppression", _playtesting.GetAnnounceFlags());

            await DataBaseUtil.AddCommandAsync("Suppress", Context);
        }
Beispiel #16
0
        public async Task ShadersAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Shader Resources",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Fields =
                {
                    new EmbedFieldBuilder
                    {
                        Name  = "General",
                        Value = "[Shader](https://developer.valvesoftware.com/wiki/Shader)\n" +
                                "[Shader Authoring](https://developer.valvesoftware.com/wiki/Shader_Authoring)\n" +
                                "[Guide to Shaders](http://www.bit-tech.net/reviews/tech/guide_to_shaders/1/)\n" +
                                "[Introduction to Shaders](http://www.moddb.com/games/half-life-2/tutorials/introduction-to-shaders)\n" +
                                "[Post Process Shaders](http://www.moddb.com/games/half-life-2/tutorials/post-process-shader)",
                        IsInline = false
                    },
                    new EmbedFieldBuilder
                    {
                        Name     = "Language",
                        Value    = "[High-Level Shader Language](https://en.wikipedia.org/wiki/High-Level_Shading_Language)",
                        IsInline = false
                    },
                    new EmbedFieldBuilder
                    {
                        Name  = "Types",
                        Value = "[Vertex](https://developer.valvesoftware.com/wiki/Shader#Vertex_shaders)\n" +
                                "[Pixel](https://developer.valvesoftware.com/wiki/Shader#Pixel_shaders)",
                        IsInline = false
                    }
                },
                Color       = new Color(240, 235, 230),
                Description = "Here are lists of popular shader resources:"
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("Shaders", Context);
        }
Beispiel #17
0
        public async Task DumpSettingsAsync()
        {
            await Context.Message.DeleteAsync();

            string reply = string.Join("\n", _data.Config.Select(kvp => $"{kvp.Key}: {kvp.Value}"));

            reply = reply.Replace(_data.Config["botToken"], "[REDACTED]");

            try
            {
                await Context.Message.Author.SendMessageAsync($"```{reply}```");
            }
            catch
            {
                // Do nothing if the user doesn't accept DMs.
            }

            await _data.ChannelLog($"{Context.User} dumped the settings.");

            await DataBaseUtil.AddCommandAsync("DumpSettings", Context);
        }
        public async Task WallWormAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Check out Wall Worm",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title        = "Click Here",
                Url          = "https://dev.wallworm.com/",
                ThumbnailUrl = "https://content.tophattwaffle.com/BotHATTwaffle/worm_logo.png",
                Color        = new Color(21, 21, 21),
                Description  = "Wall Worm tools enable developers to design assets and level in Autodesk's 3ds Max and export " +
                               "them into the Source Engine. It's the best thing to ever happen to Source Engine modelling."
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("WallWorm", Context);
        }
        public async Task PlaytesterAsync()
        {
            var user = Context.User as SocketGuildUser;

            if (user.Roles.Contains(_dataService.PlayTesterRole))
            {
                await _dataService.ChannelLog($"{Context.User} has unsubscribed from playtest notifications!");
                await ReplyAsync($"Sorry to see you go from playtest notifications {Context.User.Mention}!");

                await((IGuildUser)user).RemoveRoleAsync(_dataService.PlayTesterRole);
            }
            else
            {
                await _dataService.ChannelLog($"{Context.User} has subscribed to playtest notifications!");
                await ReplyAsync($"Thanks for subscribing to playtest notifications {Context.User.Mention}!");

                await((IGuildUser)user).AddRoleAsync(_dataService.PlayTesterRole);
            }

            await DataBaseUtil.AddCommandAsync("Playtester", Context);
        }
        public async Task BspSourceAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Download BSPSource",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title        = "Click Here",
                Url          = "https://www.tophattwaffle.com/downloads/bspsource/",
                ThumbnailUrl = "https://content.tophattwaffle.com/BotHATTwaffle/BSPSource_icon.png",
                Color        = new Color(84, 137, 71),
                Description  = "BSPSource is a tool for decompiling Source's BSP (Binary Space Partition) files into VMF " +
                               "(Valve Map Format) files that can be opened with Hammer. It is a great tool to see how things " +
                               "are done in a map. It should not be used to steal content."
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("BSPSource", Context);
        }
        public async Task LogCheckerAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Interlopers Compile Log Checker",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title        = "Click Here",
                Url          = "http://www.interlopers.net/errors",
                ThumbnailUrl = "https://www.tophattwaffle.com/wp-content/uploads/2017/12/selectall.jpg",
                Color        = new Color(84, 137, 71),
                Description  = "The compile log checker on Interlopers is a web tool which analyses compile logs of maps to " +
                               "detect compilation issues and propose solutions. Simply copy and paste an entire log or a " +
                               "section with an error and click the button to have the log checked."
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("Log", Context);
        }
        public async Task VmtEditorAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Download VMT Editor",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title        = "Click Here",
                Url          = "https://gira-x.github.io/VMT-Editor/",
                ThumbnailUrl = "https://content.tophattwaffle.com/BotHATTwaffle/vmteditor.png",
                Color        = new Color(50, 50, 50),
                Description  = "VMT Editor is, hands down, one of the best VMT (Valve Material Type) creation tools that " +
                               "exists for the Source engine. It quickly became a standard tool for most designers that " +
                               "regularly create VMT files. Created by Yanzl over at MapCore."
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("VMTEditor", Context);
        }
        public async Task VtfEditAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Download VTFEdit",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title        = "Click Here",
                Url          = "https://www.tophattwaffle.com/downloads/vtfedit/",
                ThumbnailUrl = "https://content.tophattwaffle.com/BotHATTwaffle/vtfedit.png",
                Color        = new Color(255, 206, 199),
                Description  = "VTFEdit is a lightweight tool used to convert images into Valve's proprietary format - VTF " +
                               "(Valve Texture Format). Because it has a GUI, it is substantially easier to use than Valve's " +
                               "own CLI tool, VTEX (Valve Texture Tool)."
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("VTFEdit", Context);
        }
        public async Task VideAsync()
        {
            var embed = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name    = "Download VIDE",
                    IconUrl = _client.Guilds.FirstOrDefault()?.IconUrl
                },
                Title        = "Click Here",
                Url          = "https://www.tophattwaffle.com/downloads/vide/",
                ThumbnailUrl = "https://content.tophattwaffle.com/BotHATTwaffle/vide.png",
                Color        = new Color(50, 50, 50),
                Description  = "VIDE (Valve Integrated Development Environment) is a 3rd-party program which contains various " +
                               "tools. It is popular for its pakfile lump editor (packing assets into a level), but it can do " +
                               "so much more than that."
            };

            await ReplyAsync(string.Empty, false, embed.Build());

            await DataBaseUtil.AddCommandAsync("VIDE", Context);
        }
Beispiel #25
0
        public async Task UnmuteAsync(
            [Summary("The user to unmute.")] SocketGuildUser user = null,
            [Summary("The reason for the unmute.")][Remainder]
            string reason = "A moderator has taken mercy on you by lifting the mute.")
        {
            if (user != null)
            {
                if (await _mute.UnmuteAsync(user, (SocketGuildUser)Context.User, reason))
                {
                    await ReplyAsync($"Unmuted {user}.");
                }
                else
                {
                    await ReplyAsync($"Failed to unmute {user} because the user isn't muted.");
                }
            }
            else
            {
                string reply = null;

                foreach (Mute mute in await DataBaseUtil.GetActiveMutesAsync())
                {
                    //TODO: Move this to >MuteHistory. It is only here because I'm too lazy and this was easier...
                    reply += $"Name: {mute.Username}\nMuted at: {mute.Timestamp:yyyy-MM-ddTHH:mm:ssZ}\n" +
                             $"Duration: {mute.Duration?.ToString() ?? "indefinite"}\nReason: {mute.Reason ?? "None"}\n" +
                             $"Expires at: {mute.Timestamp.AddMinutes(mute.Duration ?? 0)}";
                }

                if (reply == null)
                {
                    reply = "No mutes found!";
                }

                await ReplyAsync($"Current Mutes: {reply}");
            }

            await DataBaseUtil.AddCommandAsync("Unmute", Context);
        }
Beispiel #26
0
        public async Task ReloadAsync()
        {
            try
            {
                await _data.DeserialiseConfig(true);

                _timer.Stop();
                _timer.Start();

                await ReplyAsync("```Successfully reloaded settings.```");

                await _data.ChannelLog($"{Context.User} successfully reloaded the settings.");
            }
            catch (InvalidOperationException e)
            {
                await _data.ChannelLog($"{Context.User} failed to reload the settings.", e.Message);

                await Context.Channel.SendMessageAsync(
                    $"An error occurred reloading the config. Reverting to the previous config. ```{e.Message}```");
            }

            await DataBaseUtil.AddCommandAsync("Reload", Context);
        }
        public async Task ReleasePublicTestCommandAsync([Remainder] string command = null)
        {
            Server server = null;

            if (!_playtesting.CanReserve)
            {
                await ReplyAsync($"```Servers cannot be reserved at this time." +
                                 $"\nServer reservation is blocked 1 hour before a scheduled test, and resumes once the calendar event has passed.```");

                return;
            }
            bool hasServer = false;

            foreach (UserData u in _playtesting.UserData)
            {
                if (u.User != Context.Message.Author)
                {
                    continue;
                }
                server    = u.ReservedServer;
                hasServer = true;
            }

            if (hasServer)
            {
                await ReplyAsync("```Releasing Server reservation.```");

                await _playtesting.ClearServerReservations(server.name);
            }
            else
            {
                await ReplyAsync("```I could not locate a server reservation for your account.```");
            }

            await DataBaseUtil.AddCommandAsync("ReleaseServer", Context);
        }
Beispiel #28
0
        public async Task MuteHistoryAsync(
            [Summary("The user for which to retrieve mute history.")] SocketGuildUser user,
            [RequireBoundaries(1, 25)] int quantity = 10)
        {
            Mute[] mutes = await DataBaseUtil.GetMutesAsync(user.Id, quantity);

            int total = mutes.Length;
            var pages = new List <EmbedBuilder>();

            await DataBaseUtil.AddCommandAsync("MuteHistory", Context);

            if (mutes.Any())
            {
                await BuildPage();
            }
            else
            {
                var embed = new EmbedBuilder
                {
                    ThumbnailUrl = user.GetAvatarUrl(),
                    Color        = new Color(243, 128, 72)
                };

                embed.WithAuthor($"No mutes for {user}!");
                embed.Description = "Who knew we have users that could behave!";

                await ReplyAsync(string.Empty, embed : embed.Build());

                return;
            }

            async Task BuildPage(EmbedFieldBuilder firstField = null)
            {
                var embed = new EmbedBuilder
                {
                    ThumbnailUrl = user.GetAvatarUrl(),
                    Color        = new Color(243, 128, 72)
                };

                embed.WithAuthor($"{user}'s Most Recent Mutes");

                if (firstField != null)
                {
                    embed.AddField(firstField);
                }

                foreach (Mute mute in mutes)
                {
                    string timestamp = mute.Timestamp.ToString("yyyy-MM-ddTHH:mm:ssZ");
                    string value     = $"Muted by: `{mute.MuterName}`";
                    string valueEnd;

                    if (mute.Duration.HasValue)
                    {
                        string         units   = mute.Duration > 1 ? "minutes" : "minute";
                        DateTimeOffset unmuted = mute.Timestamp.AddMinutes(mute.Duration.Value);
                        valueEnd = $"\nDuration: `{mute.Duration}` {units}\nUnmuted at: `{unmuted:yyyy-MM-ddTHH:mm:ssZ}`";
                    }
                    else
                    {
                        valueEnd = "\nDuration: `indefinite`";
                    }

                    string reason = null;

                    if (mute.Reason != null)
                    {
                        value   += "\nReason: `";
                        valueEnd = "`" + valueEnd;
                        reason   = mute.Reason.Truncate(1024 - value.Length - valueEnd.Length, true);
                    }

                    embed.AddField(timestamp, value + reason + valueEnd);

                    if (embed.Length() > 6000 - 26)                   // Total char limit - maximum possible footer length.
                    {
                        EmbedFieldBuilder field = embed.Fields.Pop(); // Re-use the field in the next embed.
                        pages.Add(embed);

                        mutes = mutes.Skip(embed.Fields.Count + 1).ToArray(); // Skips already processed records.
                        await BuildPage(field);                               // Process the remaining records.

                        return;
                    }
                }

                pages.Add(embed);
            }

            // Sets the footer text and sends each embed.
            if (pages.Count > 1)
            {
                for (var i = 0; i < pages.Count;)
                {
                    EmbedBuilder embed = pages[i];
                    embed.WithFooter($"{total} Results | Page {++i} of {pages.Count}");

                    await ReplyAsync(string.Empty, embed : embed.Build());
                }
            }
            else
            {
                await ReplyAsync(string.Empty, embed : pages.Single().Build());
            }
        }
        public async Task HelpAsync([Summary("The command for which to get help.")] string command)
        {
            // Deletes the invoking message if it's not a direct message.
            if (!Context.IsPrivate)
            {
                await Context.Message.DeleteAsync();
            }

            SearchResult result = _commands.Search(Context, command);

            if (!result.IsSuccess)
            {
                await ReplyAsync($"No commands matching **{command}** were found.");

                return;
            }

            // Iterates command search results.
            for (var i = 0; i < result.Commands.Count; ++i)
            {
                CommandInfo cmd = result.Commands[i].Command;

                string parameters  = _help.GetParameters(cmd.Parameters);
                string contexts    = _help.GetContexts(cmd.Preconditions);
                string permissions = _help.GetPermissions(cmd.Preconditions);
                string roles       = _help.GetRoles(cmd.Preconditions, Context);

                // Creates the embed.
                var embed = new EmbedBuilder
                {
                    Color       = new Color(47, 111, 146),
                    Title       = $"\u2753 `{cmd.Name}` Help",
                    Description = $"`{_help.GetUsage(cmd)}`\n{cmd.Summary}"
                };

                // Only includes result count if there's more than one.
                // Only includes message about optional parameters if the command has any.
                embed.WithFooter(
                    (result.Commands.Count > 1 ? $"Result {i + 1}/{result.Commands.Count}." : string.Empty) +
                    (cmd.Parameters.Any(p => p.IsOptional)
                        ? " Angle brackets and italics denote optional arguments/parameters."
                        : string.Empty));

                if (!string.IsNullOrWhiteSpace(cmd.Remarks))
                {
                    embed.AddField("Details", cmd.Remarks);
                }

                if (!string.IsNullOrWhiteSpace(parameters))
                {
                    embed.AddField("Parameters", parameters);
                }

                if (!string.IsNullOrWhiteSpace(contexts))
                {
                    embed.AddInlineField("Contexts", contexts);
                }

                if (!string.IsNullOrWhiteSpace(permissions))
                {
                    embed.AddInlineField("Permissions", permissions);
                }

                if (!string.IsNullOrWhiteSpace(roles))
                {
                    embed.AddInlineField("Roles", roles);
                }

                // Excludes the command's name from the aliases.
                if (cmd.Aliases.Count > 1)
                {
                    embed.AddInlineField(
                        "Aliases",
                        string.Join("\n", cmd.Aliases.Where(a => !a.Equals(cmd.Name, StringComparison.OrdinalIgnoreCase))));
                }

                // Replies normally if a direct message fails.
                try
                {
                    await Context.User.SendMessageAsync(string.Empty, false, embed.Build());
                }
                catch
                {
                    await ReplyAsync(string.Empty, false, embed.Build());
                }
            }
            await DataBaseUtil.AddCommandAsync("Help", Context);
        }
Beispiel #30
0
        public async Task EditServers(string action = null, [Remainder] string values = null)
        {
            if (!_playtesting.CanReserve)
            {
                //Can't reserve, meaning we are close to a test. Don't want to edit fields.
                await ReplyAsync("You cannot edit servers this close to a playtest. Try again later.");

                return;
            }

            if (action.StartsWith("a", StringComparison.OrdinalIgnoreCase))
            {
                string[] vars = values.Split('|');

                if (vars.Length != 8)
                {
                    await ReplyAsync("You didn't provide all 8 parameters. Please provide all 8 and try again." +
                                     "\nYour message was deleted as it may have contained a password.");

                    await Context.Message.DeleteAsync();

                    return;
                }

                if (vars[0].Length != 3)
                {
                    //Enforce length during the add because SQLite does not support min/max lengths on TEXT fields.
                    await ReplyAsync("Server name must be 3 characters long. Please provide 3 characters as the name and try again." +
                                     "\nYour message was deleted as it may have contained a password.");

                    await Context.Message.DeleteAsync();

                    return;
                }

                //Validate FTP type before entry
                switch (vars[7])
                {
                case "ftp":
                    break;

                case "sftp":
                    break;

                case "ftps":
                    break;

                default:
                    await ReplyAsync("Invalid FTP type. Please provide `ftp`, `ftps`, or `sftp` and try again." +
                                     "\nYour message was deleted as it may have contained a password.");

                    await Context.Message.DeleteAsync();

                    return;
                }

                await DataBaseUtil.AddServerAsync(new Server()
                {
                    name          = vars[0],
                    description   = vars[1],
                    address       = vars[2],
                    rcon_password = vars[3],
                    ftp_path      = vars[4],
                    ftp_username  = vars[5],
                    ftp_password  = vars[6],
                    ftp_type      = vars[7]
                });

                await ReplyAsync("Server added! Your message was removed as it contained passwords.");

                await Context.Message.DeleteAsync();
            }
            else if (action.StartsWith("g", StringComparison.OrdinalIgnoreCase))
            {
                var server = await DataBaseUtil.GetServerAsync(values.Substring(0, 3));

                if (server != null)
                {
                    await ReplyAsync($"`{server.ToString()}`");
                }
                else
                {
                    await ReplyAsync($"I could not find a server with that name.");
                }
            }
            else if (action.StartsWith("r", StringComparison.OrdinalIgnoreCase))
            {
                Server removedServer = await DataBaseUtil.GetServerAsync(values.Substring(0, 3));

                if (removedServer != null)
                {
                    await ReplyAsync($"Removing server\n`{removedServer.ToString()}`");

                    await DataBaseUtil.RemoveServerAsync(removedServer);
                }
                else
                {
                    await ReplyAsync($"I could not find a server with that name.");

                    return;
                }
            }
            else
            {
                await ReplyAsync("Invalid command. Please see the help text.");
            }

            await DataBaseUtil.AddCommandAsync("EditServers", Context);
        }