Initial commit
Enjoy
This commit is contained in:
585
NadekoBot/Modules/Conversations.cs
Normal file
585
NadekoBot/Modules/Conversations.cs
Normal file
@ -0,0 +1,585 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Timers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
class Conversations : DiscordModule
|
||||
{
|
||||
private string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥";
|
||||
public Conversations() : base()
|
||||
{
|
||||
commands.Add(new CopyCommand());
|
||||
}
|
||||
|
||||
private CommandBuilder CreateCommand(CommandGroupBuilder cbg, string txt)
|
||||
{
|
||||
CommandBuilder cb = cbg.CreateCommand(txt);
|
||||
return AliasCommand(cb, txt);
|
||||
}
|
||||
|
||||
private CommandBuilder AliasCommand(CommandBuilder cb, string txt)
|
||||
{
|
||||
return cb.Alias(new string[] { "," + txt, "-" + txt });
|
||||
}
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
Random rng = new Random();
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
var client = manager.Client;
|
||||
|
||||
cgb.CreateCommand("\\o\\")
|
||||
.Description("Nadeko replies with /o/")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + "/o/");
|
||||
});
|
||||
|
||||
cgb.CreateCommand("/o/")
|
||||
.Description("Nadeko replies with \\o\\")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + "\\o\\");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
manager.CreateCommands(NadekoBot.botMention, cgb =>
|
||||
{
|
||||
var client = manager.Client;
|
||||
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
CreateCommand(cgb, "do you love me")
|
||||
.Description("Replies with positive answer only to the bot owner.")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + ", Of course I do, my Master.");
|
||||
else
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + ", Don't be silly.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "die")
|
||||
.Description("Works only for the owner. Shuts the bot down.")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
Timer t = new Timer();
|
||||
t.Interval = 2000;
|
||||
t.Elapsed += (s, ev) => { Environment.Exit(0); };
|
||||
t.Start();
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + ", Yes, my love.");
|
||||
}
|
||||
else
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + ", No.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "how are you")
|
||||
.Description("Replies positive only if bot owner is online.")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " I am great as long as you are here.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var kw = client.GetUser(e.Server, NadekoBot.OwnerID);
|
||||
if (kw != null && kw.Status == UserStatus.Online)
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " I am great as long as " + Mention.User(kw) + " is with me.");
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " I am sad. My Master is not with me.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "insult")
|
||||
.Parameter("mention", ParameterType.Required)
|
||||
.Description("Only works for owner. Insults @X person.\nUsage: @NadekoBot insult @X.")
|
||||
.Do(async e =>
|
||||
{
|
||||
List<string> insults = new List<string> { " you are a poop.", " you jerk.", " i will eat you when i get my powers back." };
|
||||
Random r = new Random();
|
||||
var u = e.Message.MentionedUsers.Last();
|
||||
if (u.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "I would never insult my master <3");
|
||||
}
|
||||
else if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(u) + insults[r.Next(0, insults.Count)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " Eww, why would i do that for you ?!");
|
||||
}
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "praise")
|
||||
.Description("Only works for owner. Praises @X person.\nUsage: @NadekoBot insult @X.")
|
||||
.Parameter("mention", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
List<string> praises = new List<string> { " You are cool.", " You are nice... But don't get any wrong ideas.", " You did a good job." };
|
||||
Random r = new Random();
|
||||
var u = e.Message.MentionedUsers.First();
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
if (u.Id != NadekoBot.OwnerID)
|
||||
await client.SendMessage(e.Channel, Mention.User(u) + praises[r.Next(0, praises.Count)]);
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(u) + " No need, you know I love you <3");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (u.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " I don't need your permission to praise my beloved Master <3");
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " Yeah... No.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "are you real")
|
||||
.Description("Useless.")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " I will be soon.");
|
||||
});
|
||||
|
||||
cgb.CreateCommand("are you there")
|
||||
.Description("Checks if nadeko is operational.")
|
||||
.Alias(new string[] { "!", "?", "??", "???", "!!", "!!!" })
|
||||
.Do(SayYes());
|
||||
|
||||
CreateCommand(cgb, "draw")
|
||||
.Description("Nadeko instructs you to type $draw. Gambling functions start with $")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Sorry i dont gamble, type $draw for that function.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "uptime")
|
||||
.Description("Shows how long is Nadeko running for.")
|
||||
.Do(async e =>
|
||||
{
|
||||
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||
string str = "I am online for " + time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
||||
await client.SendMessage(e.Channel, str);
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "fire")
|
||||
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire.\nUsage: @NadekoBot fire [x]")
|
||||
.Parameter("times", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
int count = 0;
|
||||
if (e.Args?.Length > 0)
|
||||
int.TryParse(e.Args[0], out count);
|
||||
|
||||
if (count < 1)
|
||||
count = 1;
|
||||
else if (count > 12)
|
||||
count = 12;
|
||||
string str = "";
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
str += firestr;
|
||||
}
|
||||
await client.SendMessage(e.Channel, str);
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "rip")
|
||||
.Description("Shows a grave image.Optional parameter [@X] instructs her to put X's name on the grave.\nUsage: @NadekoBot rip [@X]")
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
if (e.Message.MentionedUsers.Count() == 1)
|
||||
{
|
||||
await client.SendFile(e.Channel, @"images\rip.png");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (User u in e.Message.MentionedUsers)
|
||||
{
|
||||
if (u.Name == "NadekoBot") continue;
|
||||
RipName(u.Name);
|
||||
await client.SendFile(e.Channel, @"images\ripnew.png");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("j")
|
||||
.Description("Joins a server using a code. Obsolete, since nadeko will autojoin any valid code in chat.")
|
||||
.Parameter("id", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await client.AcceptInvite(client.GetInvite(e.Args[0]).Result);
|
||||
await client.SendMessage(e.Channel, "I got in!");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Invalid code.");
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("i")
|
||||
.Description("Pulls a first image using a search parameter.\nUsage: @NadekoBot img Multiword_search_parameter")
|
||||
.Alias("img")
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var httpClient = new System.Net.Http.HttpClient();
|
||||
string str = e.Args[0];
|
||||
|
||||
var r = httpClient.GetAsync("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" + Uri.EscapeDataString(str) + "&start=0").Result;
|
||||
|
||||
dynamic obj = JObject.Parse(r.Content.ReadAsStringAsync().Result);
|
||||
if (obj.responseData.results.Count == 0)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "No results found for that keyword :\\");
|
||||
return;
|
||||
}
|
||||
string s = Searches.ShortenUrl(obj.responseData.results[0].url.ToString());
|
||||
await client.SendMessage(e.Channel, s);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("ir")
|
||||
.Description("Pulls a random image using a search parameter.\nUsage: @NadekoBot img Multiword_search_parameter")
|
||||
.Alias("imgrandom")
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
var httpClient = new System.Net.Http.HttpClient();
|
||||
string str = e.Args[0];
|
||||
var r = httpClient.GetAsync("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" + Uri.EscapeDataString(str) + "&start=" + rng.Next(0, 30)).Result;
|
||||
dynamic obj = JObject.Parse(r.Content.ReadAsStringAsync().Result);
|
||||
if (obj.responseData.results.Count == 0)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "No results found for that keyword :\\");
|
||||
return;
|
||||
}
|
||||
int rnd = rng.Next(0, obj.responseData.results.Count);
|
||||
string s = Searches.ShortenUrl(obj.responseData.results[rnd].url.ToString());
|
||||
await client.SendMessage(e.Channel, s);
|
||||
});
|
||||
|
||||
|
||||
AliasCommand(CreateCommand(cgb, "save"), "s")
|
||||
.Description("Saves something for the owner in a file.")
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
string m = "";
|
||||
try
|
||||
{
|
||||
FileStream f = File.OpenWrite("saves.txt");
|
||||
m = e.Args[0];
|
||||
byte[] b = Encoding.ASCII.GetBytes(m + "\n");
|
||||
f.Seek(f.Length, SeekOrigin.Begin);
|
||||
f.Write(b, 0, b.Length);
|
||||
f.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Error saving. Sorry :(");
|
||||
}
|
||||
if (m.Length > 0)
|
||||
await client.SendMessage(e.Channel, "I saved this for you: " + Environment.NewLine + "```" + m + "```");
|
||||
else
|
||||
await client.SendMessage(e.Channel, "No point in saving empty message...");
|
||||
}
|
||||
else await client.SendMessage(e.Channel, "Not for you, only my Master <3");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "ls")
|
||||
.Description("Shows all saved items.")
|
||||
.Do(async e =>
|
||||
{
|
||||
FileStream f = File.OpenRead("saves.txt");
|
||||
if (f.Length == 0)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Saves are empty.");
|
||||
return;
|
||||
}
|
||||
byte[] b = new byte[f.Length / sizeof(byte)];
|
||||
f.Read(b, 0, b.Length);
|
||||
f.Close();
|
||||
string str = Encoding.ASCII.GetString(b);
|
||||
await client.SendPrivateMessage(e.User, "```" + (str.Length < 1950 ? str : str.Substring(0, 1950)) + "```");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "cs")
|
||||
.Description("Deletes all saves")
|
||||
.Do(async e =>
|
||||
{
|
||||
File.Delete("saves.txt");
|
||||
await client.SendMessage(e.Channel, "Cleared all saves.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "bb")
|
||||
.Description("Says bye to someone.\nUsage: @NadekoBot bb @X")
|
||||
.Parameter("ppl", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
string str = "Bye";
|
||||
foreach (var u in e.Message.MentionedUsers)
|
||||
{
|
||||
str += " " + Mention.User(u);
|
||||
}
|
||||
await client.SendMessage(e.Channel, str);
|
||||
});
|
||||
|
||||
AliasCommand(CreateCommand(cgb, "req"), "request")
|
||||
.Description("Requests a feature for nadeko.\nUsage: @NadekoBot req Mutliword_feature_request")
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
string str = e.Args[0];
|
||||
|
||||
try
|
||||
{
|
||||
StatsCollector.SaveRequest(e, str);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Something went wrong.");
|
||||
return;
|
||||
}
|
||||
await client.SendMessage(e.Channel, "Thank you for your request.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "lr")
|
||||
.Description("PMs the user all current nadeko requests.")
|
||||
.Do(async e =>
|
||||
{
|
||||
string str = StatsCollector.GetRequests();
|
||||
if (str.Trim().Length > 110)
|
||||
await client.SendPrivateMessage(e.User, str);
|
||||
else
|
||||
await client.SendPrivateMessage(e.User, "No requests atm.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "dr")
|
||||
.Description("Deletes a request. Only owner is able to do this.")
|
||||
.Parameter("reqNumber", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StatsCollector.DeleteRequest(int.Parse(e.Args[0])))
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " Request deleted.");
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, "No request on that number.");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Error deleting request, probably NaN error.");
|
||||
}
|
||||
}
|
||||
else await client.SendMessage(e.Channel, "You don't have permission to do that.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "rr")
|
||||
.Description("Resolves a request. Only owner is able to do this.")
|
||||
.Parameter("reqNumber", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.User.Id == NadekoBot.OwnerID)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sc = StatsCollector.ResolveRequest(int.Parse(e.Args[0]));
|
||||
if (sc != null)
|
||||
{
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " Request resolved, notice sent.");
|
||||
await client.SendPrivateMessage(client.GetUser(client.GetServer(sc.ServerId), sc.Id), "**This request of yours has been resolved:**\n" + sc.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, "No request on that number.");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Error resolving request, probably NaN error.");
|
||||
}
|
||||
}
|
||||
else await client.SendMessage(e.Channel, "You don't have permission to do that.");
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "clr")
|
||||
.Description("Clears some of nadeko's messages from the current channel.")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.Channel.Messages.Count() < 50)
|
||||
{
|
||||
await client.DownloadMessages(e.Channel, 100);
|
||||
}
|
||||
|
||||
await client.DeleteMessages(e.Channel.Messages.Where(msg => msg.User.Id == client.CurrentUser.Id));
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "I cant do it :(");
|
||||
}
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "call")
|
||||
.Description("Useless. Writes calling @X to chat.\nUsage: @NadekoBot call @X ")
|
||||
.Parameter("who", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Calling " + e.Args[0] + "...");
|
||||
});
|
||||
|
||||
cgb.CreateCommand("cid")
|
||||
.Description("Shows current channel id")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, "This channel's id is " + e.Channel.Id);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("sid")
|
||||
.Description("Shows current server id")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, "This server's id is " + e.Server.Id);
|
||||
});
|
||||
CreateCommand(cgb, "hide")
|
||||
.Description("Hides nadeko in plain sight!11!!")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
using (Image img = Image.FromFile("images/hidden.png"))
|
||||
{
|
||||
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
||||
|
||||
await client.EditProfile("", null, null, null, ms, ImageType.Png);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatsCollector.DEBUG_LOG(ex.ToString());
|
||||
}
|
||||
});
|
||||
|
||||
CreateCommand(cgb, "unhide")
|
||||
.Description("Hides nadeko in plain sight!11!!")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
using (Image img = Image.FromFile("images/nadeko.jpg"))
|
||||
{
|
||||
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||
|
||||
await client.EditProfile("", null, null, null,ms, ImageType.Jpeg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatsCollector.DEBUG_LOG(ex.ToString());
|
||||
}
|
||||
});
|
||||
CreateCommand(cgb, "stats")
|
||||
.Description("Shows some basic stats for nadeko")
|
||||
.Do(async e =>
|
||||
{
|
||||
int serverCount = client.AllServers.Count();
|
||||
int uniqueUserCount = client.AllUsers.Count();
|
||||
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||
string uptime = " " + time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
||||
|
||||
await client.SendMessage(e.Channel, String.Format("```Servers: {0}\nUnique Users: {1}\nUptime: {2}\nMy id is: {3}```", serverCount, uniqueUserCount, uptime, client.CurrentUserId));
|
||||
});
|
||||
|
||||
|
||||
//TODO add eval
|
||||
/*
|
||||
cgb.CreateCommand(">")
|
||||
.Parameter("code", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.Message.User.Id == NadekoBot.OwnerId)
|
||||
{
|
||||
var result = await CSharpScript.EvaluateAsync(e.Args[0]);
|
||||
await client.SendMessage(e.Channel, result?.ToString() ?? "null");
|
||||
return;
|
||||
}
|
||||
});*/
|
||||
});
|
||||
}
|
||||
|
||||
public void RipName(string name)
|
||||
{
|
||||
Bitmap bm = new Bitmap(Image.FromFile(@"images\rip.png"));
|
||||
|
||||
int offset = name.Length * 5;
|
||||
|
||||
int fontSize = 20;
|
||||
|
||||
if (name.Length > 10)
|
||||
{
|
||||
fontSize -= (name.Length - 10) / 2;
|
||||
}
|
||||
|
||||
//TODO use measure string
|
||||
Graphics g = Graphics.FromImage(bm);
|
||||
g.DrawString(name, new Font("Comic Sans MS", fontSize, FontStyle.Bold), Brushes.Black, 100 - offset, 200);
|
||||
g.DrawString("? - " + DateTime.Now.Year, new Font("Consolas", 12, FontStyle.Bold), Brushes.Black, 80, 235);
|
||||
g.Flush();
|
||||
g.Dispose();
|
||||
|
||||
bm.Save(@"images\ripnew.png");
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> SayYes()
|
||||
{
|
||||
return async e =>
|
||||
{
|
||||
await NadekoBot.client.SendMessage(e.Channel, "Yes. :)");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
20
NadekoBot/Modules/DiscordModule.cs
Normal file
20
NadekoBot/Modules/DiscordModule.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Discord.Modules;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
abstract class DiscordModule : IModule
|
||||
{
|
||||
public List<DiscordCommand> commands;
|
||||
|
||||
protected DiscordModule() {
|
||||
commands = new List<DiscordCommand>();
|
||||
}
|
||||
|
||||
public abstract void Install(ModuleManager manager);
|
||||
}
|
||||
}
|
23
NadekoBot/Modules/Gambling.cs
Normal file
23
NadekoBot/Modules/Gambling.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
class Gambling : DiscordModule
|
||||
{
|
||||
|
||||
public Gambling() {
|
||||
commands.Add(new DrawCommand());
|
||||
commands.Add(new FlipCoinCommand());
|
||||
commands.Add(new DiceRollCommand());
|
||||
}
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
commands.ForEach(com => com.Init(cgb));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
24
NadekoBot/Modules/Games.cs
Normal file
24
NadekoBot/Modules/Games.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Modules;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
class Games : DiscordModule
|
||||
{
|
||||
public Games() : base() {
|
||||
commands.Add(new Trivia());
|
||||
}
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
230
NadekoBot/Modules/Music.cs
Normal file
230
NadekoBot/Modules/Music.cs
Normal file
@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Modules;
|
||||
using Discord.Commands;
|
||||
using System.IO;
|
||||
using Discord;
|
||||
using Discord.Audio;
|
||||
using System.Collections.Concurrent;
|
||||
using VideoLibrary;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
class Music : DiscordModule
|
||||
{
|
||||
private static bool exit = true;
|
||||
|
||||
public static bool NextSong = false;
|
||||
public static IDiscordVoiceClient Voice;
|
||||
public static Channel VoiceChannel;
|
||||
public static bool Pause = false;
|
||||
public static List<YouTubeVideo> SongQueue = new List<YouTubeVideo>();
|
||||
|
||||
public static YouTubeVideo CurrentSong;
|
||||
|
||||
public static bool Exit
|
||||
{
|
||||
get { return exit; }
|
||||
set { exit = value;} // if i set this to true, break the song and exit the main loop
|
||||
}
|
||||
|
||||
public Music() : base() {
|
||||
//commands.Add(new PlayMusic());
|
||||
}
|
||||
|
||||
//m r,radio - init
|
||||
//m n,next - next in que
|
||||
//m p,pause - pauses, call again to unpause
|
||||
//m yq [key_words] - queue from yt by keywords
|
||||
//m s,stop - stop
|
||||
//m sh - shuffle songs
|
||||
//m pl - current playlist
|
||||
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
var client = NadekoBot.client;
|
||||
manager.CreateCommands("!m", cgb =>
|
||||
{
|
||||
//queue all more complex commands
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand("n")
|
||||
.Alias("next")
|
||||
.Description("Goes to the next song in the queue.")
|
||||
.Do(e =>
|
||||
{
|
||||
if (Voice != null && Exit == false)
|
||||
{
|
||||
NextSong = true;
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("s")
|
||||
.Alias("stop")
|
||||
.Description("Completely stops the music and unbinds the bot from the channel.")
|
||||
.Do(e =>
|
||||
{
|
||||
if (Voice != null && Exit == false)
|
||||
{
|
||||
Exit = true;
|
||||
SongQueue = new List<YouTubeVideo>();
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("p")
|
||||
.Alias("pause")
|
||||
.Description("Pauses the song")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (Voice != null && Exit == false && CurrentSong != null)
|
||||
{
|
||||
Pause = !Pause;
|
||||
if (Pause)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Pausing. Run the command again to resume.");
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Resuming...");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("q")
|
||||
.Alias("yq")
|
||||
.Description("Queue a song using a multi/single word name.\nUsage: `!m q Dream Of Venice`")
|
||||
.Parameter("Query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var youtube = YouTube.Default;
|
||||
var video = youtube.GetAllVideos(Searches.FindYoutubeUrlByKeywords(e.Args[0]))
|
||||
.Where(v => v.AdaptiveKind == AdaptiveKind.Audio)
|
||||
.OrderByDescending(v => v.AudioBitrate).FirstOrDefault();
|
||||
|
||||
if (video?.Uri != "" && video.Uri != null)
|
||||
{
|
||||
SongQueue.Add(video);
|
||||
await client.SendMessage(e.Channel, "**Queued** " + video.FullName);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("lq")
|
||||
.Alias("ls").Alias("lp")
|
||||
.Description("Lists up to 10 currently queued songs.")
|
||||
.Do(async e =>
|
||||
{
|
||||
await client.SendMessage(e.Channel, SongQueue.Count + " videos currently queued.");
|
||||
await client.SendMessage(e.Channel, string.Join("\n", SongQueue.Select(v => v.FullName).Take(10)));
|
||||
});
|
||||
|
||||
cgb.CreateCommand("sh")
|
||||
.Description("Shuffles the current playlist.")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (SongQueue.Count < 2)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Not enough songs in order to perform the shuffle.");
|
||||
return;
|
||||
}
|
||||
|
||||
SongQueue.Shuffle();
|
||||
await client.SendMessage(e.Channel, "Songs shuffled!");
|
||||
});
|
||||
|
||||
cgb.CreateCommand("radio")
|
||||
.Alias("music")
|
||||
.Description("Binds to a voice and text channel in order to play music.")
|
||||
.Parameter("ChannelName", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (Voice != null) return;
|
||||
VoiceChannel = client.FindChannels(e.Server, e.GetArg("ChannelName").Trim(), ChannelType.Voice).FirstOrDefault();
|
||||
Voice = await client.JoinVoiceServer(VoiceChannel);
|
||||
Exit = false;
|
||||
NextSong = false;
|
||||
Pause = false;
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (Exit) break;
|
||||
if (SongQueue.Count == 0 || Pause) { Thread.Sleep(100); continue; }
|
||||
if (!LoadNextSong()) break;
|
||||
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
if (Exit)
|
||||
{
|
||||
Voice = null;
|
||||
Exit = false;
|
||||
await client.SendMessage(e.Channel, "Exiting...");
|
||||
return;
|
||||
}
|
||||
int blockSize = 1920;
|
||||
byte[] buffer = new byte[1920];
|
||||
//float multiplier = 1.0f / 48000 / 2;
|
||||
|
||||
var msg = await client.SendMessage(e.Channel, "Playing " + Music.CurrentSong.FullName + " [00:00]");
|
||||
int counter = 0;
|
||||
int byteCount;
|
||||
using (var stream = GetAudioFileStream(Music.CurrentSong.Uri))
|
||||
{
|
||||
while ((byteCount = stream.Read(buffer, 0, blockSize)) > 0)
|
||||
{
|
||||
Voice.SendVoicePCM(buffer, byteCount);
|
||||
counter += blockSize;
|
||||
if (NextSong)
|
||||
{
|
||||
NextSong = false;
|
||||
break;
|
||||
}
|
||||
if (Exit)
|
||||
{
|
||||
Exit = false;
|
||||
return;
|
||||
}
|
||||
while (Pause) Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
await Voice.WaitVoice();
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
|
||||
await client.LeaveVoiceServer(VoiceChannel.Server);
|
||||
Voice = null;
|
||||
VoiceChannel = null;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private Stream GetAudioFileStream(string file)
|
||||
{
|
||||
Process p = Process.Start(new ProcessStartInfo()
|
||||
{
|
||||
FileName = "ffmpeg",
|
||||
Arguments = "-i \"" + Uri.EscapeUriString(file) + "\" -f s16le -ar 48000 -af volume=1 -ac 1 pipe:1 ",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true
|
||||
});
|
||||
return p.StandardOutput.BaseStream;
|
||||
}
|
||||
|
||||
private bool LoadNextSong()
|
||||
{
|
||||
if (SongQueue.Count == 0) {
|
||||
CurrentSong = null;
|
||||
return false;
|
||||
}
|
||||
CurrentSong = SongQueue[0];
|
||||
SongQueue.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
197
NadekoBot/Modules/Searches.cs
Normal file
197
NadekoBot/Modules/Searches.cs
Normal file
@ -0,0 +1,197 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Modules;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
class Searches : DiscordModule
|
||||
{
|
||||
public Searches() : base()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
var client = NadekoBot.client;
|
||||
|
||||
manager.CreateCommands("",cgb =>
|
||||
{
|
||||
cgb.CreateCommand("~av")
|
||||
.Parameter("mention", Discord.Commands.ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (e.Message.MentionedUsers.Count() == 0) {
|
||||
await client.SendMessage(e.Channel, "You need to mention a person");
|
||||
return;
|
||||
}
|
||||
string av = e.Message.MentionedUsers.First().AvatarUrl;
|
||||
await client.SendMessage(e.Channel, ShortenUrl("http://www.discordapp.com/api/" + av));
|
||||
|
||||
});
|
||||
cgb.CreateCommand("~yt")
|
||||
.Parameter("query",Discord.Commands.ParameterType.Unparsed)
|
||||
.Description("Queries youtubes and embeds the first result")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
|
||||
|
||||
var str = ShortenUrl(FindYoutubeUrlByKeywords(e.GetArg("query")));
|
||||
if (str == null || str.Trim().Length < 5)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Query failed");
|
||||
return;
|
||||
}
|
||||
await client.SendMessage(e.Channel, str);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("~ani")
|
||||
.Alias("~anime").Alias("~aq")
|
||||
.Parameter("query", Discord.Commands.ParameterType.Unparsed)
|
||||
.Description("Queries anilist for an anime and shows the first result.")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
|
||||
|
||||
var result = GetAnimeQueryResultLink(e.GetArg("query"));
|
||||
if (result == null) {
|
||||
await client.SendMessage(e.Channel, "Failed to find that anime.");
|
||||
return;
|
||||
}
|
||||
|
||||
await client.SendMessage(e.Channel,result.ToString());
|
||||
});
|
||||
|
||||
cgb.CreateCommand("~mang")
|
||||
.Alias("~manga").Alias("~mq")
|
||||
.Parameter("query", Discord.Commands.ParameterType.Unparsed)
|
||||
.Description("Queries anilist for a manga and shows the first result.")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
|
||||
|
||||
var result = GetMangaQueryResultLink(e.GetArg("query"));
|
||||
if (result == null)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Failed to find that anime.");
|
||||
return;
|
||||
}
|
||||
await client.SendMessage(e.Channel, result.ToString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private string token = "";
|
||||
private AnimeResult GetAnimeQueryResultLink(string query)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cl = new RestSharp.RestClient("https://anilist.co/api");
|
||||
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
|
||||
|
||||
RefreshToken();
|
||||
|
||||
rq = new RestSharp.RestRequest("/anime/search/" + Uri.EscapeUriString(query));
|
||||
rq.AddParameter("access_token", token);
|
||||
|
||||
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
|
||||
|
||||
rq = new RestSharp.RestRequest("anime/" + smallObj["id"]);
|
||||
rq.AddParameter("access_token", token);
|
||||
return JsonConvert.DeserializeObject<AnimeResult>(cl.Execute(rq).Content);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private MangaResult GetMangaQueryResultLink(string query)
|
||||
{
|
||||
try
|
||||
{
|
||||
RefreshToken();
|
||||
|
||||
var cl = new RestSharp.RestClient("https://anilist.co/api");
|
||||
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
|
||||
rq = new RestSharp.RestRequest("/manga/search/"+Uri.EscapeUriString(query));
|
||||
rq.AddParameter("access_token", token);
|
||||
|
||||
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
|
||||
|
||||
rq = new RestSharp.RestRequest("manga/" + smallObj["id"]);
|
||||
rq.AddParameter("access_token", token);
|
||||
return JsonConvert.DeserializeObject<MangaResult> (cl.Execute(rq).Content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshToken()
|
||||
{
|
||||
var cl = new RestSharp.RestClient("https://anilist.co/api");
|
||||
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
|
||||
rq.AddParameter("grant_type", "client_credentials");
|
||||
rq.AddParameter("client_id", "kwoth-w0ki9");
|
||||
rq.AddParameter("client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z");
|
||||
token = JObject.Parse(cl.Execute(rq).Content)["access_token"].ToString();
|
||||
}
|
||||
|
||||
private static async Task<bool> ValidateQuery(Discord.Channel ch,string query) {
|
||||
if (query == null || query.Trim().Length == 0)
|
||||
{
|
||||
await NadekoBot.client.SendMessage(ch, "Please specify search parameters.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string FindYoutubeUrlByKeywords(string v)
|
||||
{
|
||||
WebRequest wr = WebRequest.Create("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=" + Uri.EscapeDataString(v) + "&key=" + NadekoBot.GoogleAPIKey);
|
||||
|
||||
var sr = new StreamReader(wr.GetResponse().GetResponseStream());
|
||||
|
||||
dynamic obj = JObject.Parse(sr.ReadToEnd());
|
||||
return "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString();
|
||||
}
|
||||
|
||||
public static string ShortenUrl(string url)
|
||||
{
|
||||
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey);
|
||||
httpWebRequest.ContentType = "application/json";
|
||||
httpWebRequest.Method = "POST";
|
||||
|
||||
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
||||
{
|
||||
string json = "{\"longUrl\":\"" + url + "\"}";
|
||||
streamWriter.Write(json);
|
||||
}
|
||||
try
|
||||
{
|
||||
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
|
||||
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
|
||||
{
|
||||
var responseText = streamReader.ReadToEnd();
|
||||
string MATCH_PATTERN = @"""id"": ?""(?<id>.+)""";
|
||||
return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user