using System.Diagnostics; using Optionals; using RevoltSharp.Commands; using RevoltSharp; using System.Reflection; using Newtonsoft.Json.Linq; using System.Globalization; using Microsoft.Extensions.Configuration; class Program { public static RevoltClient Client; public static async Task Start() { IConfiguration Configuration = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("config.json") .Build(); string token = Configuration["RevoltConfig:Token"]; string apiUrl = Configuration["RevoltConfig:ApiUrl"]; Client = new RevoltClient(token, ClientMode.WebSocket, new ClientConfig { ApiUrl = apiUrl }); await Client.StartAsync(); await Client.CurrentUser.ModifySelfAsync(statusText: new Option("Always Evolving!")); await Client.CurrentUser.ModifySelfAsync(statusType: new Option(UserStatusType.Focus)); CommandHandler CommandHandler = new CommandHandler(Client); CommandHandler.LoadCommands(); await Task.Delay(-1); } static void Main(string[] args) { Start().GetAwaiter().GetResult(); } } // CommandHandler public class CommandHandler { public CommandHandler(RevoltClient client) { Client = client; Client.OnMessageRecieved += Client_OnMessageRecieved; Service.OnCommandExecuted += Service_OnCommandExecuted; } private RevoltClient Client; private CommandService Service = new CommandService(); // Here you can change the prefix Default one is "?" public const string Prefix = "?"; public async Task LoadCommands() { await Service.AddModulesAsync(Assembly.GetEntryAssembly(), null); } private void Client_OnMessageRecieved(Message msg) { UserMessage Message = msg as UserMessage; if (Message == null || Message.Author.IsBot) return; int argPos = 0; if (!(Message.HasCharPrefix('?', ref argPos) || Message.HasMentionPrefix(Client.CurrentUser, ref argPos))) return; CommandContext context = new CommandContext(Client, Message); Service.ExecuteAsync(context, argPos, null); } private void Service_OnCommandExecuted(Optional commandinfo, CommandContext context, IResult result) { if (result.IsSuccess) Console.WriteLine("Success command: " + commandinfo.Value.Name); else { if (!commandinfo.HasValue) return; context.Channel.SendMessageAsync("Error: " + result.ErrorReason); } } // Only god and the dude behing RevoltSharp know what's going on here. } public class Commands : ModuleBase { // Help commands: // Basic Help Command. [Command("help")] public async Task Help() { var helpMessage = "### List of available commands:\n\n" + "### Practical Commands: \n" + "`?help` - Displays this command.\n" + "`?source` - Links to the bots source code. \n" + "`?credits` - Displays bot's credit.\n" + "`?test` - Simple test command you say test bot will response.\n" + "`?invite` - Send a link to invite this bot to your server! \n" + "`?calculate` {num} {+, - , / , * } {num} - A very simple calculator. \n" + "`?mod-help` - Displays a list of available mod commands. \n " + "`?ping` - tests the bot ping. \n" + "`?nsfw-help` - Sends a list of all aviable nsfw commands. \n " + "### Fun Commands: \n" + "`?dice` - Rolls a random number between 1 and 6.\n" + "`?say` - says what the user told it to say!. \n" + "`?dm` - Just DMs the user Hi :3. \n" + "`?rps {paper,rock,scissors}` - Simple Rock paper scissors game.\n" + "`?dogfact` - Gives a random dogfact using the Dogfact API!. \n" + "`?catfact` - Gives a random Catfact using cat fact API (Currently somewhat bugged with the []. \n" + "`?joke` - Very simple command just gives a joke using the Joke API. \n " + "`?flipcoin` - a Command so easy a child could do it. \n " + "`?fact` - Gives a random useless fact. \n " + "`?urban + {word}` - uses the urban dictionary the search for the word. \n" + "`?shitpost` - Sends a random shitpost. (The shitpost API is broken.) \n " + "`?cat` - Cat :3 \n " + "`?neko` - Neko command \n " + "`?advice` - Gives the user a life Advice \n " + "`?quote` - Gives a random quote using yet another API. \n " + "`?gif {term}` - Allows the user to search for gifs using giphy (Beta) \n" + "`?avatar` - Sends the user Avatar (Beta) \n "; await ReplyAsync(helpMessage); } // Mod Help command [Command("mod-help")] public async Task modhelp() { await ReplyAsync( "## List Of Available mod commands. \n `?kick {Mention}` - Kicks the user \n `?ban {mentions}` - Bans the User \n `?unban {mention}` - Unbans the user. \n"); } // NSFW Help command: [Command("nsfw-help")] public async Task nsfwhelp() { await ReplyAsync("### Here are all the available NSFW commands: \n `?r34 {search}` - Searches rule34.xxx \n `?hentai` - Grabs a random hentai image \n "); } // End of the help command Section // Dm Commands (commands that dm the user in some way.): // Invite Command - Sends a invite in the DM [Command("invite")] public async Task Invite() { DMChannel DM = await Context.User.GetDMChannelAsync(); if (DM == null) { await ReplyAsync("Could not open DM :( wich means no invite :((("); return; } await DM.SendMessageAsync("## Invite me! \n" + "If you on app.haydar.dev use this link: \n" + "https://app.haydar.dev/bot/01HA55V3K8B26T87TBKMZMWRKJ \n" + "but if you on nightly.haydar.dev use this link \n" + "https://nightly.haydar.dev/bot/01HA55V3K8B26T87TBKMZMWRKJ \n" + "If you find any bugs report them to the bots creator. thank you bai"); } // End of DM commands. // Debug commands. // Very Simple test Command [Command("test")] public async Task Test() { await ReplyAsync("Ig it works :tm:"); } // Ping command. [Command("ping")] public async Task PingCommand() { var stopwatch = new Stopwatch(); stopwatch.Start(); await ReplyAsync("Ping..."); stopwatch.Stop(); var latency = stopwatch.ElapsedMilliseconds; await ReplyAsync($"Pong! (Latency: {latency}ms)"); } // End of the Debug commands. // Fun commands: // Gif command [Command("gif")] public async Task GifCommand([Remainder] string keyword) { using (HttpClient client = new HttpClient()) { IConfiguration Configuration = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("giphy.json") .Build(); string apiKey = Configuration["GiphyApiKey"]; string apiUrl = $"https://api.giphy.com/v1/gifs/search?api_key={apiKey}&q={keyword}&limit=1"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string gifJson = await response.Content.ReadAsStringAsync(); JObject gifObject = JObject.Parse(gifJson); string gifUrl = gifObject["data"][0]["images"]["original"]["url"]?.ToString(); if (!string.IsNullOrEmpty(gifUrl)) { await Context.Channel.SendMessageAsync(gifUrl); } else { await Context.Channel.SendMessageAsync("Sorry, I couldn't find a GIF for that keyword."); } } else { await Context.Channel.SendMessageAsync("Sorry, I couldn't fetch a GIF at the moment. Please try again later."); } } } // A Rock paper Scicors command. [Command("rps")] public async Task Rps([Remainder] string userChoice = null) { string[] options = { "rock", "paper", "scissors" }; Random random = new Random(); string botChoice = options[random.Next(options.Length)]; if (userChoice == null) { await ReplyAsync("You need to provide a choice! Please choose from: rock, paper, scissors"); return; } userChoice = userChoice.ToLower(); if (Array.Exists(options, option => option == userChoice)) { if (userChoice == botChoice) { await ReplyAsync($"It's a tie! I chose {botChoice} too."); } else if ((userChoice == "rock" && botChoice == "scissors") || (userChoice == "paper" && botChoice == "rock") || (userChoice == "scissors" && botChoice == "paper")) { await ReplyAsync($"You win! I chose {botChoice}."); } else { await ReplyAsync($"You lose! I chose {botChoice}."); } } else { await ReplyAsync($"Invalid choice. Please choose from: {string.Join(", ", options)}"); } } // Roll command roles a random number between 1 - 6 (Perfect for bets :troll") [Command("dice")] public async Task dice() { var random = new Random(); var result = random.Next(1, 7); await ReplyAsync($"You rolled a {result}!"); } // Very simple very say command. private List blacklist = new List { "nigga", "nigger", "n i g g a", "fuck", "shit", "piss", "cunt", "dick", "fag", "faggot", "kys", "ky$", // Blacklist for the say command }; [Command("say")] public async Task Say([Remainder] string text) { var user = Context.User.Username; foreach (var word in blacklist) { if (text.ToLower().Contains(word)) { text = text.Replace(word, new string('*', word.Length)); } } await ReplyAsync($"{user} said: {text}"); } // Haydar. [Command("miau")] public async Task miau() { await ReplyAsync("<@01H4H8M7E20HJAD6DXKDMXVKXF> Miau???"); } // The flip a coin command. [Command("flipcoin")] public async Task FlipCoin() { Random random = new Random(); int result = random.Next(2); string side = (result == 0) ? "Heads" : "Tails"; await ReplyAsync($"It's {side}!"); } // End of the Fun commands. // Api commands // Advice command. [Command("advice")] public async Task Advice() { using (HttpClient client = new HttpClient()) { string apiUrl = "https://api.adviceslip.com/advice"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string adviceJson = await response.Content.ReadAsStringAsync(); JObject adviceObject = JObject.Parse(adviceJson); string advice = adviceObject["slip"]["advice"]?.ToString(); if (!string.IsNullOrEmpty(advice)) { await ReplyAsync($"Advice: {advice}"); } else { await ReplyAsync("Sorry, I couldn't fetch advice at the moment. Please try again later."); } } else { await ReplyAsync("Sorry, I couldn't fetch advice at the moment. Please try again later."); } } } // Dog fact command very simple very fun [Command("dogfact")] public async Task DogFact() { using (HttpClient client = new HttpClient()) { string apiUrl = "http://dog-api.kinduff.com/api/facts"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string factsJson = await response.Content.ReadAsStringAsync(); JObject factsObject = JObject.Parse(factsJson); if (factsObject["facts"] is JArray factsArray && factsArray.Count > 0) { Random random = new Random(); int randomIndex = random.Next(factsArray.Count); string randomFact = factsArray[randomIndex].ToString(); await ReplyAsync(randomFact); } else { await ReplyAsync("Sorry, I couldn't fetch a dog fact at the moment. Please try again later."); } } else { await ReplyAsync("Sorry, I couldn't fetch a dog fact at the moment. Please try again later."); } } } // Cat fact command very simple very fun [Command("catfact")] public async Task CatFact() { using (HttpClient client = new HttpClient()) { string apiUrl = "http://meowfacts.herokuapp.com/"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string factJson = await response.Content.ReadAsStringAsync(); JObject factObject = JObject.Parse(factJson); if (factObject["data"] != null) { string fact = factObject["data"].ToString(); await ReplyAsync(fact); } else { await ReplyAsync("Sorry, I couldn't fetch a cat fact at the moment. Please try again later."); } } else { await ReplyAsync("Sorry, I couldn't fetch a cat fact at the moment. Please try again later."); } } } // Joke command [Command("joke")] public async Task Joke() { using (HttpClient client = new HttpClient()) { string apiUrl = "https://v2.jokeapi.dev/joke/Any?type=twopart"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string jokeJson = await response.Content.ReadAsStringAsync(); JObject jokeObject = JObject.Parse(jokeJson); string setup = jokeObject["setup"]?.ToString(); string punchline = jokeObject["delivery"]?.ToString(); if (!string.IsNullOrEmpty(setup) && !string.IsNullOrEmpty(punchline)) { await ReplyAsync($"{setup}\n{punchline}"); } else { await ReplyAsync("Sorry, I couldn't fetch a joke at the moment. Please try again later."); } } else { await ReplyAsync("Sorry, I couldn't fetch a joke at the moment. Please try again later."); } } } // Simple quote command [Command("quote")] public async Task Quote() { using (HttpClient client = new HttpClient()) { string apiUrl = "https://api.quotable.io/random"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string quoteJson = await response.Content.ReadAsStringAsync(); dynamic quoteObject = Newtonsoft.Json.JsonConvert.DeserializeObject(quoteJson); string content = quoteObject.content; string author = quoteObject.author; await ReplyAsync($"\"{content}\" - {author}"); } else { await ReplyAsync("Sorry, I couldn't fetch a quote at the moment. Please try again later."); } } } // Fact command [Command("fact")] public async Task Fact() { using (HttpClient client = new HttpClient()) { string apiUrl = "https://uselessfacts.jsph.pl/random.json?language=en"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string factJson = await response.Content.ReadAsStringAsync(); dynamic factObject = Newtonsoft.Json.JsonConvert.DeserializeObject(factJson); string fact = factObject.text; await ReplyAsync(fact); } else { await ReplyAsync("Sorry, I couldn't fetch a fact at the moment. Please try again later."); } } } // Urban Dictionary [Command("urban")] public async Task Urban([Remainder] string term) { using (HttpClient client = new HttpClient()) { string apiUrl = $"https://api.urbandictionary.com/v0/define?term={term}"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string urbanJson = await response.Content.ReadAsStringAsync(); dynamic urbanObject = Newtonsoft.Json.JsonConvert.DeserializeObject(urbanJson); if (urbanObject.list.Count > 0) { string definition = urbanObject.list[0].definition; await ReplyAsync($"**Term:** {term}\n**Definition:** {definition}"); } else { await ReplyAsync("Sorry, I couldn't find a definition for that term."); } } else { await ReplyAsync("Sorry, I couldn't fetch a definition at the moment. Please try again later."); } } } // Shitpost command [Command("shitpost")] public async Task shitpost() { using (HttpClient client = new HttpClient()) { string apiUrl = "https://api.thedailyshitpost.net/random"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string memeJson = await response.Content.ReadAsStringAsync(); dynamic memeObject = Newtonsoft.Json.JsonConvert.DeserializeObject(memeJson); string title = memeObject.title; string imageUrl = memeObject.url; await ReplyAsync($"{imageUrl}"); } else { await ReplyAsync("Sorry, I couldn't fetch a meme at the moment. Please try again later."); } } } // Cat. [Command("cat")] public async Task Cat() { using (HttpClient client = new HttpClient()) { string apiUrl = "https://api.thecatapi.com/v1/images/search"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string catJson = await response.Content.ReadAsStringAsync(); dynamic catObject = Newtonsoft.Json.JsonConvert.DeserializeObject(catJson); string imageUrl = catObject[0].url; await ReplyAsync(imageUrl); } else { await ReplyAsync("Sorry, I couldn't fetch a cat image at the moment. Please try again later."); } } } // Neko command [Command("neko")] public async Task Neko() { try { using (HttpClient client = new HttpClient()) { string apiUrl = "https://nekos.life/api/v2/img/neko"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string nekoJson = await response.Content.ReadAsStringAsync(); JObject nekoObject = JObject.Parse(nekoJson); string imageUrl = nekoObject["url"]?.ToString(); if (!string.IsNullOrEmpty(imageUrl)) { await ReplyAsync(imageUrl); } else { await ReplyAsync("Sorry, I couldn't fetch a neko at the moment. Please try again later."); } } else { await ReplyAsync("Sorry, I couldn't fetch a neko at the moment. Please try again later."); } } } catch (Exception ex) { Console.WriteLine($"Error in Neko command: {ex.Message}"); await ReplyAsync("An error occurred while fetching the neko. Please try again later."); } } // End of neko command // The End of the API commands. // Misc Commands: // Give the credits of the bot [Command("credits")] public async Task Credits() { await ReplyAsync("This bot is made using revoltsharp by Purplebored known as Kniaż Jarema on nightly"); } // Avatar command [Command("avatar")] public async Task AvatarCommand() { var user = Context.Message.Author.GetAvatarUrl(); var avatarUrl = $"{user}"; await Context.Channel.SendMessageAsync($"Your avatar: {avatarUrl}"); } // End of the misc commands // Calculate command [Command("calculate")] public async Task Calculate(string num1String, string operation, string num2String) { if (!double.TryParse(num1String, NumberStyles.Any, CultureInfo.InvariantCulture, out double num1) || !double.TryParse(num2String, NumberStyles.Any, CultureInfo.InvariantCulture, out double num2)) { await ReplyAsync("Error: Invalid input. Please provide valid numbers."); return; } double result = 0; switch (operation) { case "+": result = num1 + num2; break; case "-": result = num1 - num2; break; case "*": result = num1 * num2; break; case "/": if (num2 != 0) // Check for division by zero { result = num1 / num2; } else { await ReplyAsync("Error: Division by zero is not allowed."); return; } break; default: await ReplyAsync("Invalid operation. Please use +, -, *, or /."); return; } await ReplyAsync($"Result: {result}"); } // Moderation commands. from Darkly Bot // Stuff neded to make these commands work. private string RemoveMention(string mention) { return mention.Replace("<@", "").Replace(">", ""); } private RevoltClient Client; // Stats command [Command("stats")] public async Task GetStats() { IReadOnlyCollection result1 = await Context.Server.GetMembersAsync(); int num2 = 0; foreach (ServerMember serverMember in result1) ++num2; IReadOnlyCollection result2 = await Context.Server.GetMembersAsync(true); int num3 = 0; foreach (ServerMember serverMember in result2) ++num3; await ReplyAsync($"### Stats:\n \n ### Member count: {num2}\n ### Online member count: {num3}\n"); } // Ban Command [Command("ban")] public async Task BanUser([Remainder] string args) { try { string userId = RemoveMention(args); await Context.Server.BanMemberAsync(userId, "Banned via command."); await ReplyAsync("### Ban\n whomp whomp."); } catch { await ReplyAsync("### ERROR \n Invalid Mention or Bot Perms."); } } // Unban Command [Command("unban")] public async Task UnbanUser([Remainder] string args) { try { string userId = RemoveMention(args); await Context.Server.UnBanMemberAsync(userId); await ReplyAsync("### Unbanned \n Very sadly a mod had a change of his heart."); } catch { await ReplyAsync("### ERROR \n Invalid Mention or Bot Perms."); } } // Kick Command [Command("kick")] public async Task KickUser([Remainder] string args) { try { string userId = RemoveMention(args); await Context.Server.KickMemberAsync(userId); await ReplyAsync("### Kicked \n And he gone."); } catch { await ReplyAsync("### ERROR \\n Invalid Mention or Bot Perms."); } } // NSFW COMMANDS // R34 command. [Command("r34")] public async Task ExampleCommand([Remainder] string query = null) { if (string.IsNullOrWhiteSpace(query)) { await Context.Channel.SendMessageAsync("Please provide a search query. Usage: ?r34 {searchquery}"); return; } if (!(Context.Channel is TextChannel textChannel) || !textChannel.IsNsfw) { await Context.Channel.SendMessageAsync( "This command is only allowed in NSFW channels. So go to a NSFW channel to get your NSFW smh"); return; } using (HttpClient httpClient = new HttpClient()) { string apiUrl = $"https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&limit=1&json=1&tags={query}"; HttpResponseMessage response = await httpClient.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string jsonResult = await response.Content.ReadAsStringAsync(); dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonResult); if (data != null && data.Count > 0 && data[0].file_url != null) { string imageUrl = data[0].file_url; await Context.Channel.SendMessageAsync(imageUrl); } else { await Context.Channel.SendMessageAsync("No images found."); } } else { await Context.Channel.SendMessageAsync( "Sorry, I couldn't fetch an image at the moment. Please try again later."); } } } // Hentai command. [Command("hentai")] public async Task hentai() { if (!(Context.Channel is TextChannel textChannel) || !textChannel.IsNsfw) { await Context.Channel.SendMessageAsync( "This command is only allowed in NSFW channels. So go to a NSFW channel to get your NSFW smh"); return; } using (HttpClient client = new HttpClient()) { string apiUrl = "https://nekobot.xyz/api/image?type=hneko"; HttpResponseMessage response = await client.GetAsync(apiUrl); if (response.IsSuccessStatusCode) { string nekoJson = await response.Content.ReadAsStringAsync(); dynamic nekoObject = Newtonsoft.Json.JsonConvert.DeserializeObject(nekoJson); string imageUrl = nekoObject["message"]; await ReplyAsync(imageUrl); } else { await ReplyAsync("Sorry, I couldn't fetch a neko image at the moment. Please try again later."); } } } }