Merge remote-tracking branch 'refs/remotes/Kwoth/1.0' into math
# Conflicts: # src/NadekoBot/project.json # src/NadekoBot/project.lock.json
This commit is contained in:
commit
3006ea1c48
@ -115,13 +115,13 @@ namespace NadekoBot
|
||||
HttpClient carbonClient = new HttpClient();
|
||||
private async Task SendUpdateToCarbon()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.CarbonKey))
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.CarbonKey))
|
||||
return;
|
||||
try
|
||||
{
|
||||
using (var content = new FormUrlEncodedContent(new Dictionary<string, string> {
|
||||
{ "servercount", NadekoBot.Client.Servers.Count().ToString() },
|
||||
{ "key", NadekoBot.Creds.CarbonKey }
|
||||
{ "key", NadekoBot.Credentials.CarbonKey }
|
||||
}))
|
||||
{
|
||||
content.Headers.Clear();
|
||||
@ -155,7 +155,7 @@ namespace NadekoBot
|
||||
sb.AppendLine($"`Bot Version: {BotVersion}`");
|
||||
sb.AppendLine($"`Bot id: {NadekoBot.Client.CurrentUser.Id}`");
|
||||
sb.Append("`Owners' Ids:` ");
|
||||
sb.AppendLine("`" + String.Join(", ", NadekoBot.Creds.OwnerIds) + "`");
|
||||
sb.AppendLine("`" + String.Join(", ", NadekoBot.Credentials.OwnerIds) + "`");
|
||||
sb.AppendLine($"`Uptime: {GetUptimeString()}`");
|
||||
sb.Append($"`Servers: {ServerCount}");
|
||||
sb.Append($" | TextChannels: {TextChannelsCount}");
|
||||
|
@ -147,14 +147,14 @@ namespace NadekoBot.Classes
|
||||
return $"https://www.youtube.com/watch?v={match.Groups["id"].Value}";
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey))
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey))
|
||||
throw new InvalidCredentialException("Google API Key is missing.");
|
||||
|
||||
var response = await GetResponseStringAsync(
|
||||
$"https://www.googleapis.com/youtube/v3/search?" +
|
||||
$"part=snippet&maxResults=1" +
|
||||
$"&q={Uri.EscapeDataString(keywords)}" +
|
||||
$"&key={NadekoBot.Creds.GoogleAPIKey}").ConfigureAwait(false);
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}").ConfigureAwait(false);
|
||||
JObject obj = JObject.Parse(response);
|
||||
|
||||
var data = JsonConvert.DeserializeObject<YoutubeVideoSearch>(response);
|
||||
@ -181,7 +181,7 @@ namespace NadekoBot.Classes
|
||||
$"https://www.googleapis.com/youtube/v3/search?" +
|
||||
$"part=snippet&maxResults={count}&type=video" +
|
||||
$"&relatedToVideoId={id}" +
|
||||
$"&key={NadekoBot.Creds.GoogleAPIKey}").ConfigureAwait(false);
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}").ConfigureAwait(false);
|
||||
JObject obj = JObject.Parse(response);
|
||||
|
||||
var data = JsonConvert.DeserializeObject<YoutubeVideoSearch>(response);
|
||||
@ -191,7 +191,7 @@ namespace NadekoBot.Classes
|
||||
|
||||
public static async Task<string> GetPlaylistIdByKeyword(string query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey))
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey))
|
||||
throw new ArgumentNullException(nameof(query));
|
||||
var match = new Regex("(?:youtu\\.be\\/|list=)(?<id>[\\da-zA-Z\\-_]*)").Match(query);
|
||||
if (match.Length > 1)
|
||||
@ -201,7 +201,7 @@ namespace NadekoBot.Classes
|
||||
var link = "https://www.googleapis.com/youtube/v3/search?part=snippet" +
|
||||
"&maxResults=1&type=playlist" +
|
||||
$"&q={Uri.EscapeDataString(query)}" +
|
||||
$"&key={NadekoBot.Creds.GoogleAPIKey}";
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}";
|
||||
|
||||
var response = await GetResponseStringAsync(link).ConfigureAwait(false);
|
||||
var data = JsonConvert.DeserializeObject<YoutubePlaylistSearch>(response);
|
||||
@ -212,7 +212,7 @@ namespace NadekoBot.Classes
|
||||
|
||||
public static async Task<IList<string>> GetVideoIDs(string playlist, int number = 50)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey))
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(playlist));
|
||||
}
|
||||
@ -231,7 +231,7 @@ namespace NadekoBot.Classes
|
||||
$"https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails" +
|
||||
$"&maxResults={toGet}" +
|
||||
$"&playlistId={playlist}" +
|
||||
$"&key={NadekoBot.Creds.GoogleAPIKey}";
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}";
|
||||
if (!string.IsNullOrWhiteSpace(nextPageToken))
|
||||
link += $"&pageToken={nextPageToken}";
|
||||
var response = await GetResponseStringAsync(link).ConfigureAwait(false);
|
||||
@ -245,12 +245,12 @@ namespace NadekoBot.Classes
|
||||
|
||||
public static async Task<string> ShortenUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey)) return url;
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey)) return url;
|
||||
try
|
||||
{
|
||||
var httpWebRequest =
|
||||
(HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" +
|
||||
NadekoBot.Creds.GoogleAPIKey);
|
||||
NadekoBot.Credentials.GoogleAPIKey);
|
||||
httpWebRequest.ContentType = "application/json";
|
||||
httpWebRequest.Method = "POST";
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Restart(IMessage imsg)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// await channel.SendMessageAsync("`Restarting in 2 seconds...`");
|
||||
// await Task.Delay(2000);
|
||||
@ -42,7 +42,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequirePermission(GuildPermission.ManageGuild)]
|
||||
//public async Task Delmsgoncmd(IMessage imsg)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// var conf = SpecificConfigurations.Default.Of(channel.Guild.Id);
|
||||
// conf.AutoDeleteMessagesOnCommand = !conf.AutoDeleteMessagesOnCommand;
|
||||
@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageRoles)]
|
||||
public async Task Setrole(IMessage imsg, IGuildUser usr, [Remainder] IRole role)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
try
|
||||
{
|
||||
await usr.AddRolesAsync(role).ConfigureAwait(false);
|
||||
@ -76,7 +76,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageRoles)]
|
||||
public async Task Removerole(IMessage imsg, IGuildUser usr, [Remainder] IRole role)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
try
|
||||
{
|
||||
await usr.RemoveRolesAsync(role).ConfigureAwait(false);
|
||||
@ -93,7 +93,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageRoles)]
|
||||
public async Task RenameRole(IMessage imsg, IRole roleToEdit, string newname)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
try
|
||||
{
|
||||
if (roleToEdit.Position > (await channel.Guild.GetCurrentUserAsync().ConfigureAwait(false)).Roles.Max(r => r.Position))
|
||||
@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageRoles)]
|
||||
public async Task RemoveAllRoles(IMessage imsg, [Remainder] IGuildUser user)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
try
|
||||
{
|
||||
@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageRoles)]
|
||||
public async Task CreateRole(IMessage imsg, [Remainder] string roleName = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(roleName))
|
||||
@ -154,7 +154,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageRoles)]
|
||||
public async Task RoleColor(IMessage imsg, params string[] args)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (args.Count() != 2 && args.Count() != 4)
|
||||
{
|
||||
@ -192,7 +192,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.BanMembers)]
|
||||
public async Task Ban(IMessage imsg, IGuildUser user)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var msg = "";
|
||||
|
||||
@ -219,7 +219,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.BanMembers)]
|
||||
public async Task Softban(IMessage imsg, IGuildUser user, [Remainder] string msg = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(msg))
|
||||
{
|
||||
@ -244,7 +244,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Kick(IMessage imsg, IGuildUser user, [Remainder] string msg = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
@ -273,7 +273,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.MuteMembers)]
|
||||
public async Task Mute(IMessage imsg, params IGuildUser[] users)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!users.Any())
|
||||
return;
|
||||
@ -296,7 +296,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.MuteMembers)]
|
||||
public async Task Unmute(IMessage imsg, params IGuildUser[] users)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!users.Any())
|
||||
return;
|
||||
@ -319,7 +319,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.DeafenMembers)]
|
||||
public async Task Deafen(IMessage imsg, params IGuildUser[] users)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!users.Any())
|
||||
return;
|
||||
@ -342,7 +342,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.DeafenMembers)]
|
||||
public async Task UnDeafen(IMessage imsg, params IGuildUser[] users)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!users.Any())
|
||||
return;
|
||||
@ -374,7 +374,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageChannels)]
|
||||
public async Task CreatVoiChanl(IMessage imsg, [Remainder] string channelName)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
//todo actually print info about created channel
|
||||
await channel.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Created voice channel **{channelName}**.").ConfigureAwait(false);
|
||||
@ -394,7 +394,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageChannels)]
|
||||
public async Task CreaTxtChanl(IMessage imsg, [Remainder] string channelName)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
//todo actually print info about created channel
|
||||
var txtCh = await channel.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Added text channel **{channelName}**.").ConfigureAwait(false);
|
||||
@ -405,7 +405,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageChannels)]
|
||||
public async Task SetTopic(IMessage imsg, [Remainder] string topic = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
topic = topic ?? "";
|
||||
await (channel as ITextChannel).ModifyAsync(c => c.Topic = topic);
|
||||
//await (channel).ModifyAsync(c => c).ConfigureAwait(false);
|
||||
@ -417,7 +417,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.ManageChannels)]
|
||||
public async Task SetChanlName(IMessage imsg, [Remainder] string name)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.ModifyAsync(c => c.Name = name).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync(":ok: **New channel name set.**").ConfigureAwait(false);
|
||||
@ -429,7 +429,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Prune(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var user = await channel.Guild.GetCurrentUserAsync();
|
||||
|
||||
@ -471,7 +471,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Die(IMessage imsg)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// await channel.SendMessageAsync("`Shutting down.`").ConfigureAwait(false);
|
||||
// await Task.Delay(2000).ConfigureAwait(false);
|
||||
@ -483,7 +483,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Setname(IMessage imsg, [Remainder] string newName = null)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
//}
|
||||
|
||||
@ -492,12 +492,12 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task NewAvatar(IMessage imsg, [Remainder] string img = null)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(e.GetArg("img")))
|
||||
// if (string.IsNullOrWhiteSpace(img))
|
||||
// return;
|
||||
// // Gather user provided URL.
|
||||
// var avatarAddress = e.GetArg("img");
|
||||
// var avatarAddress = img;
|
||||
// var imageStream = await SearchHelper.GetResponseStreamAsync(avatarAddress).ConfigureAwait(false);
|
||||
// var image = System.Drawing.Image.FromStream(imageStream);
|
||||
// await client.CurrentUser.Edit("", avatar: image.ToStream()).ConfigureAwait(false);
|
||||
@ -511,11 +511,11 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task SetGame(IMessage imsg, [Remainder] string game = null)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// game = game ?? "";
|
||||
|
||||
// client.SetGame(e.GetArg("set_game"));
|
||||
// client.SetGame(set_game);
|
||||
//}
|
||||
|
||||
////todo owner only
|
||||
@ -523,7 +523,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Send(IMessage imsg, string where, [Remainder] string msg = null)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(msg))
|
||||
// return;
|
||||
@ -569,9 +569,9 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Donadd(IMessage imsg, IUser donator, int amount)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var donator = channel.Guild.FindUsers(e.GetArg("donator")).FirstOrDefault();
|
||||
// var amount = int.Parse(e.GetArg("amount"));
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
// var donator = channel.Guild.FindUsers(donator).FirstOrDefault();
|
||||
// var amount = int.Parse(amount);
|
||||
// if (donator == null) return;
|
||||
// try
|
||||
// {
|
||||
@ -592,7 +592,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Announce(IMessage imsg, [Remainder] string message)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// foreach (var ch in (await _client.GetGuildsAsync().ConfigureAwait(false)).Select(async g => await g.GetDefaultChannelAsync().ConfigureAwait(false)))
|
||||
// {
|
||||
@ -607,7 +607,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task SaveChat(IMessage imsg, int cnt)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// ulong? lastmsgId = null;
|
||||
// var sb = new StringBuilder();
|
||||
@ -640,7 +640,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequirePermission(GuildPermission.MentionEveryone)]
|
||||
public async Task MentionRole(IMessage imsg, params IRole[] roles)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
string send = $"--{imsg.Author.Mention} has invoked a mention on the following roles--";
|
||||
foreach (var role in roles)
|
||||
@ -665,7 +665,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Donators(IMessage imsg)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// var rows = DbHandler.Instance.GetAllRows<Donator>();
|
||||
// var donatorsOrdered = rows.OrderByDescending(d => d.Amount);
|
||||
|
@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Administration
|
||||
//[RequirePermission(GuildPermission.ManageRoles)]
|
||||
//public async Task AutoAssignRole(IMessage imsg, IRole role)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
|
||||
|
@ -86,7 +86,7 @@
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// int token;
|
||||
// if (!int.TryParse(e.GetArg("token"), out token))
|
||||
// if (!int.TryParse(token, out token))
|
||||
// return;
|
||||
// HashSet<Channel> set;
|
||||
// if (!Subscribers.TryGetValue(token, out set))
|
||||
|
@ -456,7 +456,7 @@
|
||||
// {
|
||||
|
||||
// var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
// if (e.GetArg("all")?.ToLower() == "all")
|
||||
// if (all?.ToLower() == "all")
|
||||
// {
|
||||
// foreach (var voiceChannel in e.Server.VoiceChannels)
|
||||
// {
|
||||
|
@ -80,8 +80,8 @@
|
||||
// .AddCheck(SimpleCheckers.ManageMessages())
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var minutesStr = e.GetArg("minutes");
|
||||
// var msg = e.GetArg("msg");
|
||||
// var minutesStr = minutes;
|
||||
// var msg = msg;
|
||||
|
||||
// // if both null, disable
|
||||
// if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr))
|
||||
|
@ -109,7 +109,7 @@
|
||||
// .AddCheck(SimpleCheckers.OwnerOnly())
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var arg = e.GetArg("text");
|
||||
// var arg = text;
|
||||
// if (string.IsNullOrWhiteSpace(arg))
|
||||
// return;
|
||||
// await playingPlaceholderLock.WaitAsync().ConfigureAwait(false);
|
||||
@ -149,7 +149,7 @@
|
||||
// .AddCheck(SimpleCheckers.OwnerOnly())
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var arg = e.GetArg("number");
|
||||
// var arg = number;
|
||||
// int num;
|
||||
// string str;
|
||||
// await playingPlaceholderLock.WaitAsync().ConfigureAwait(false);
|
||||
|
@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
_client.MessageReceived += async (imsg) =>
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (channel == null || await imsg.IsAuthor())
|
||||
return;
|
||||
@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Slowmode(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
ConcurrentDictionary<ulong, DateTime> throwaway;
|
||||
if (RatelimitingChannels.TryRemove(channel.Id, out throwaway))
|
||||
|
@ -49,7 +49,7 @@
|
||||
// .AddCheck(SimpleCheckers.CanManageRoles)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var roleName = e.GetArg("role")?.Trim();
|
||||
// var roleName = role?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(roleName))
|
||||
// return;
|
||||
// var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
||||
@ -116,7 +116,7 @@
|
||||
// .Parameter("role", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var roleName = e.GetArg("role")?.Trim();
|
||||
// var roleName = role?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(roleName))
|
||||
// return;
|
||||
// var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
||||
@ -172,7 +172,7 @@
|
||||
// .Parameter("role", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var roleName = e.GetArg("role")?.Trim();
|
||||
// var roleName = role?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(roleName))
|
||||
// return;
|
||||
// var role = e.Server.FindRoles(roleName).FirstOrDefault();
|
||||
|
@ -24,7 +24,7 @@
|
||||
// [RequireContext(ContextType.Guild)]
|
||||
// public async Task Leave(IMessage imsg, [Remainder] string guildStr)
|
||||
// {
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// guildStr = guildStr.ToUpperInvariant();
|
||||
// var server = _client.GetGuilds().FirstOrDefault(g => g.Id.ToString() == guildStr) ?? _client.GetGuilds().FirstOrDefault(g => g.Name.ToUpperInvariant() == guildStr);
|
||||
|
@ -240,14 +240,14 @@
|
||||
// {
|
||||
// if (!imsg.Author.ServerPermissions.ManageServer) return;
|
||||
// var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
||||
// if (string.IsNullOrWhiteSpace(e.GetArg("msg")))
|
||||
// if (string.IsNullOrWhiteSpace(msg))
|
||||
// {
|
||||
// await channel.SendMessageAsync("`Current greet message:` " + ann.GreetText);
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// ann.GreetText = e.GetArg("msg");
|
||||
// ann.GreetText = msg;
|
||||
// await channel.SendMessageAsync("New greet message set.").ConfigureAwait(false);
|
||||
// if (!ann.Greet)
|
||||
// await channel.SendMessageAsync("Enable greet messsages by typing `.greet`").ConfigureAwait(false);
|
||||
@ -273,13 +273,13 @@
|
||||
// {
|
||||
// if (!imsg.Author.ServerPermissions.ManageServer) return;
|
||||
// var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
|
||||
// if (string.IsNullOrWhiteSpace(e.GetArg("msg")))
|
||||
// if (string.IsNullOrWhiteSpace(msg))
|
||||
// {
|
||||
// await channel.SendMessageAsync("`Current bye message:` " + ann.ByeText);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ann.ByeText = e.GetArg("msg");
|
||||
// ann.ByeText = msg;
|
||||
// await channel.SendMessageAsync("New bye message set.").ConfigureAwait(false);
|
||||
// if (!ann.Bye)
|
||||
// await channel.SendMessageAsync("Enable bye messsages by typing `.bye`.").ConfigureAwait(false);
|
||||
|
@ -40,7 +40,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task CreateWar(IMessage imsg, int size, [Remainder] string enemyClan = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels)
|
||||
return;
|
||||
@ -73,7 +73,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task StartWar(IMessage imsg, [Remainder] string number = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
int num = 0;
|
||||
int.TryParse(number, out num);
|
||||
@ -100,7 +100,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ListWar(IMessage imsg, [Remainder] string number = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if number is null, print all wars in a short way
|
||||
if (string.IsNullOrWhiteSpace(number))
|
||||
@ -143,7 +143,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Claim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var warsInfo = GetWarInfo(imsg, number);
|
||||
if (warsInfo == null || warsInfo.Item1.Count == 0)
|
||||
{
|
||||
@ -170,7 +170,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ClaimFinish1(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
await FinishClaim(imsg, number, baseNumber, other_name, 1);
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ClaimFinish2(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
await FinishClaim(imsg, number, baseNumber, other_name, 2);
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ClaimFinish(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
await FinishClaim(imsg, number, baseNumber, other_name);
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task EndWar(IMessage imsg, int number)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var warsInfo = GetWarInfo(imsg,number);
|
||||
if (warsInfo == null)
|
||||
@ -213,7 +213,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Unclaim(IMessage imsg, int number, [Remainder] string otherName = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var warsInfo = GetWarInfo(imsg, number);
|
||||
if (warsInfo == null || warsInfo.Item1.Count == 0)
|
||||
@ -239,7 +239,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
|
||||
private async Task FinishClaim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name, int stars = 3)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var warInfo = GetWarInfo(imsg, number);
|
||||
if (warInfo == null || warInfo.Item1.Count == 0)
|
||||
{
|
||||
@ -265,7 +265,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
|
||||
private static Tuple<List<ClashWar>, int> GetWarInfo(IMessage imsg, int num)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
//check if there are any wars
|
||||
List<ClashWar> wars = null;
|
||||
ClashWars.TryGetValue(channel.Guild.Id, out wars);
|
||||
|
@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Race(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var ar = new AnimalRace(channel.Guild.Id, channel);
|
||||
|
||||
@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task JoinRace(IMessage imsg, int amount = 0)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (amount < 0)
|
||||
amount = 0;
|
||||
|
@ -26,7 +26,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
// InternalRoll(imsg, arg, false);
|
||||
|
||||
//private async Task InternalRoll(IMessage imsg, string arg, bool ordered) {
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
// var r = new Random();
|
||||
// if (string.IsNullOrWhiteSpace(arg))
|
||||
// {
|
||||
@ -110,7 +110,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task NRoll(IMessage imsg, [Remainder] string range)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
|
||||
try
|
||||
|
@ -53,7 +53,7 @@
|
||||
// try
|
||||
// {
|
||||
// var num = 1;
|
||||
// var isParsed = int.TryParse(e.GetArg("count"), out num);
|
||||
// var isParsed = int.TryParse(count, out num);
|
||||
// if (!isParsed || num < 2)
|
||||
// {
|
||||
// var c = cards.DrawACard();
|
||||
|
@ -34,9 +34,9 @@
|
||||
// public Func<CommandEventArgs, Task> BetFlipCoinFunc() => async e =>
|
||||
// {
|
||||
|
||||
// var amountstr = e.GetArg("amount").Trim();
|
||||
// var amountstr = amount.Trim();
|
||||
|
||||
// var guessStr = e.GetArg("guess").Trim().ToUpperInvariant();
|
||||
// var guessStr = guess.Trim().ToUpperInvariant();
|
||||
// if (guessStr != "H" && guessStr != "T" && guessStr != "HEADS" && guessStr != "TAILS")
|
||||
// return;
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
// public Func<CommandEventArgs, Task> FlipCoinFunc() => async e =>
|
||||
// {
|
||||
|
||||
// if (e.GetArg("count") == "")
|
||||
// if (count == "")
|
||||
// {
|
||||
// if (rng.Next(0, 2) == 1)
|
||||
// await e.Channel.SendFile("heads.png", Properties.Resources.heads.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
@ -92,7 +92,7 @@
|
||||
// else
|
||||
// {
|
||||
// int result;
|
||||
// if (int.TryParse(e.GetArg("count"), out result))
|
||||
// if (int.TryParse(count, out result))
|
||||
// {
|
||||
// if (result > 10)
|
||||
// result = 10;
|
||||
|
@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Raffle(IMessage imsg, [Remainder] IRole role = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
role = role ?? channel.Guild.EveryoneRole;
|
||||
|
||||
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Cash(IMessage imsg, [Remainder] string arg)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// var usr = e.Message.MentionedUsers.FirstOrDefault() ?? imsg.Author;
|
||||
// var pts = GetUserFlowers(usr.Id);
|
||||
@ -52,7 +52,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Give(IMessage imsg, long amount, [Remainder] IUser receiver)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
// if (amount <= 0)
|
||||
// return;
|
||||
// var userFlowers = GetUserFlowers(imsg.Author.Id);
|
||||
@ -81,7 +81,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Award(IMessage imsg, long amount, [Remainder] ulong usrId)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if (amount <= 0)
|
||||
// return;
|
||||
@ -102,7 +102,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Take(IMessage imsg, long amount, [Remainder] ulong usrId)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
// if (amount <= 0)
|
||||
// return;
|
||||
|
||||
@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task BetRoll(IMessage imsg, int amount)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if (amount < 1)
|
||||
// return;
|
||||
@ -160,7 +160,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
// [RequireContext(ContextType.Guild)]
|
||||
// public async Task Leaderboard(IMessage imsg)
|
||||
// {
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// var richestTemp = DbHandler.Instance.GetTopRichest();
|
||||
// var richest = richestTemp as CurrencyState[] ?? richestTemp.ToArray();
|
||||
|
@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Leet(IMessage imsg, int level, [Remainder] string text = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
text = text.Trim();
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
|
@ -131,7 +131,7 @@
|
||||
// .Parameter("cd", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var cdStr = e.GetArg("cd");
|
||||
// var cdStr = cd;
|
||||
// int cd = 2;
|
||||
// if (!int.TryParse(cdStr, out cd) || cd < 0)
|
||||
// {
|
||||
|
@ -19,7 +19,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Poll(IMessage imsg, [Remainder] string arg = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels)
|
||||
return;
|
||||
@ -40,7 +40,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Pollend(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels)
|
||||
return;
|
||||
|
@ -181,11 +181,11 @@
|
||||
// .Parameter("text", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// if (!NadekoBot.IsOwner(imsg.Author.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
|
||||
// if (!NadekoBot.IsOwner(imsg.Author.Id) || string.IsNullOrWhiteSpace(text)) return;
|
||||
|
||||
// DbHandler.Instance.Connection.Insert(new TypingArticle
|
||||
// {
|
||||
// Text = e.GetArg("text"),
|
||||
// Text = text,
|
||||
// DateAdded = DateTime.Now
|
||||
// });
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Trivia(IMessage imsg, string[] args)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
TriviaGame trivia;
|
||||
if (!RunningTrivias.TryGetValue(channel.Guild.Id, out trivia))
|
||||
@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Tl(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
TriviaGame trivia;
|
||||
if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia))
|
||||
@ -61,7 +61,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Tq(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
TriviaGame trivia;
|
||||
if (RunningTrivias.TryRemove(channel.Guild.Id, out trivia))
|
||||
|
@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Choose(IMessage imsg, [Remainder] string list = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
if (string.IsNullOrWhiteSpace(list))
|
||||
return;
|
||||
var listArr = list.Split(';');
|
||||
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task _8Ball(IMessage imsg, [Remainder] string question = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(question))
|
||||
return;
|
||||
@ -52,7 +52,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Rps(IMessage imsg, string input)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
Func<int,string> GetRPSPick = (p) =>
|
||||
{
|
||||
@ -102,7 +102,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Linux(IMessage imsg, string guhnoo, string loonix)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendMessageAsync(
|
||||
$@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.
|
||||
|
@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Help
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Modules(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendMessageAsync("`List of modules:` \n• " + string.Join("\n• ", _commands.Modules.Select(m => m.Name)) + $"\n`Type \"-commands module_name\" to get a list of commands in that module.`")
|
||||
.ConfigureAwait(false);
|
||||
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Help
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Commands(IMessage imsg, [Remainder] string module = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
module = module?.Trim().ToUpperInvariant();
|
||||
if (string.IsNullOrWhiteSpace(module))
|
||||
@ -69,7 +69,7 @@ namespace NadekoBot.Modules.Help
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task H(IMessage imsg, [Remainder] string comToFind = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
comToFind = comToFind?.ToLowerInvariant();
|
||||
if (string.IsNullOrWhiteSpace(comToFind))
|
||||
@ -117,7 +117,7 @@ namespace NadekoBot.Modules.Help
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Guide(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendMessageAsync(
|
||||
@"**LIST OF COMMANDS**: <http://nadekobot.readthedocs.io/en/latest/Commands%20List/>
|
||||
@ -128,7 +128,7 @@ namespace NadekoBot.Modules.Help
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Donate(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendMessageAsync(
|
||||
$@"You can support the project on patreon. <https://patreon.com/nadekobot> or
|
||||
|
724
src/NadekoBot/Modules/Music/Music.cs
Normal file
724
src/NadekoBot/Modules/Music/Music.cs
Normal file
@ -0,0 +1,724 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Modules.Music.Classes;
|
||||
using System.Collections.Concurrent;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Services;
|
||||
using System.IO;
|
||||
using Discord;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Attributes;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Net.Http;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NadekoBot.Modules.Music
|
||||
{
|
||||
[Module("!!", AppendSpace = false)]
|
||||
public partial class Music : DiscordModule
|
||||
{
|
||||
public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers = new ConcurrentDictionary<ulong, MusicPlayer>();
|
||||
|
||||
public const string MusicDataPath = "data/musicdata";
|
||||
private IGoogleApiService _google;
|
||||
|
||||
public Music(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client, IGoogleApiService google) : base(loc, cmds, config, client)
|
||||
{
|
||||
//it can fail if its currenctly opened or doesn't exist. Either way i don't care
|
||||
try { Directory.Delete(MusicDataPath, true); } catch { }
|
||||
|
||||
Directory.CreateDirectory(MusicDataPath);
|
||||
|
||||
_google = google;
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Next(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
|
||||
if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)imsg.Author).VoiceChannel)
|
||||
musicPlayer.Next();
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Stop(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
{
|
||||
musicPlayer.Autoplay = false;
|
||||
musicPlayer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Destroy(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryRemove(channel.Guild.Id, out musicPlayer)) return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
musicPlayer.Destroy();
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Pause(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.TogglePause();
|
||||
if (musicPlayer.Paused)
|
||||
await channel.SendMessageAsync("🎵`Music Player paused.`").ConfigureAwait(false);
|
||||
else
|
||||
await channel.SendMessageAsync("🎵`Music Player unpaused.`").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Queue(IMessage imsg, [Remainder] string query)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, query).ConfigureAwait(false);
|
||||
if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await imsg.DeleteAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task SoundCloudQueue(IMessage imsg, [Remainder] string query)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false);
|
||||
if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await imsg.DeleteAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ListQueue(IMessage imsg, int page = 1)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
{
|
||||
await channel.SendMessageAsync("🎵 No active music player.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (page <= 0)
|
||||
return;
|
||||
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
if (currentSong == null)
|
||||
return;
|
||||
var toSend = $"🎵`Now Playing` {currentSong.PrettyName} " + $"{currentSong.PrettyCurrentTime()}\n";
|
||||
if (musicPlayer.RepeatSong)
|
||||
toSend += "🔂";
|
||||
else if (musicPlayer.RepeatPlaylist)
|
||||
toSend += "🔁";
|
||||
toSend += $" **{musicPlayer.Playlist.Count}** `tracks currently queued. Showing page {page}` ";
|
||||
if (musicPlayer.MaxQueueSize != 0 && musicPlayer.Playlist.Count >= musicPlayer.MaxQueueSize)
|
||||
toSend += "**Song queue is full!**\n";
|
||||
else
|
||||
toSend += "\n";
|
||||
const int itemsPerPage = 15;
|
||||
int startAt = itemsPerPage * (page - 1);
|
||||
var number = 1 + startAt;
|
||||
await channel.SendMessageAsync(toSend + string.Join("\n", musicPlayer.Playlist.Skip(startAt).Take(15).Select(v => $"`{number++}.` {v.PrettyName}"))).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task NowPlaying(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
if (currentSong == null)
|
||||
return;
|
||||
await channel.SendMessageAsync($"🎵`Now Playing` {currentSong.PrettyName} " +
|
||||
$"{currentSong.PrettyCurrentTime()}").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Volume(IMessage imsg, int val)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
if (val < 0)
|
||||
return;
|
||||
var volume = musicPlayer.SetVolume(val);
|
||||
await channel.SendMessageAsync($"🎵 `Volume set to {volume}%`").ConfigureAwait(false);
|
||||
}
|
||||
////todo DB
|
||||
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Defvol(IMessage imsg, [Remainder] int val)
|
||||
//{
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
// var arg = val;
|
||||
// float volume;
|
||||
// if (!float.TryParse(arg, out volume) || volume < 0 || volume > 100)
|
||||
// {
|
||||
// await channel.SendMessageAsync("Volume number invalid.").ConfigureAwait(false);
|
||||
// return;
|
||||
// }
|
||||
// var conf = SpecificConfigurations.Default.Of(channel.Guild.Id);
|
||||
// conf.DefaultMusicVolume = volume / 100;
|
||||
// await channel.SendMessageAsync($"🎵 `Default volume set to {volume}%`").ConfigureAwait(false);
|
||||
//}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Mute(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.SetVolume(0);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Max(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.SetVolume(100);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Shuffle(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
if (musicPlayer.Playlist.Count < 2)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Not enough songs in order to perform the shuffle.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
musicPlayer.Shuffle();
|
||||
await channel.SendMessageAsync("🎵 `Songs shuffled.`").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Playlist(IMessage imsg, [Remainder] string playlist)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var arg = playlist;
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel?.Guild != channel.Guild)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var plId = (await _google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault();
|
||||
if (plId == null)
|
||||
{
|
||||
await channel.SendMessageAsync("No search results for that query.");
|
||||
return;
|
||||
}
|
||||
var ids = await _google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false);
|
||||
if (!ids.Any())
|
||||
{
|
||||
await channel.SendMessageAsync($"🎵 `Failed to find any songs.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var idArray = ids as string[] ?? ids.ToArray();
|
||||
var count = idArray.Length;
|
||||
var msg =
|
||||
await channel.SendMessageAsync($"🎵 `Attempting to queue {count} songs".SnPl(count) + "...`").ConfigureAwait(false);
|
||||
foreach (var id in idArray)
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, id, true).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{ break; }
|
||||
catch { }
|
||||
}
|
||||
await msg.ModifyAsync(m => m.Content = "🎵 `Playlist queue complete.`").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task SoundCloudPl(IMessage imsg, [Remainder] string pl)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
pl = pl?.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(pl))
|
||||
return;
|
||||
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var scvids = JObject.Parse(await http.GetStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Credentials.SoundCloudClientId}").ConfigureAwait(false))["tracks"].ToObject<SoundCloudVideo[]>();
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false);
|
||||
|
||||
MusicPlayer mp;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out mp))
|
||||
return;
|
||||
|
||||
foreach (var svideo in scvids.Skip(1))
|
||||
{
|
||||
try
|
||||
{
|
||||
mp.AddSong(new Song(new Classes.SongInfo
|
||||
{
|
||||
Title = svideo.FullName,
|
||||
Provider = "SoundCloud",
|
||||
Uri = svideo.StreamLink,
|
||||
ProviderType = MusicType.Normal,
|
||||
Query = svideo.TrackLink,
|
||||
}), ((IGuildUser)imsg.Author).Username);
|
||||
}
|
||||
catch (PlaylistFullException) { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task LocalPl(IMessage imsg, [Remainder] string directory)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var arg = directory;
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var fileEnum = new DirectoryInfo(arg).GetFiles()
|
||||
.Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
|
||||
foreach (var file in fileEnum)
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
await channel.SendMessageAsync("🎵 `Directory queue complete.`").ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Radio(IMessage imsg, string radio_link)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel?.Guild != channel.Guild)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false);
|
||||
if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await imsg.DeleteAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Local(IMessage imsg, [Remainder] string path)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var arg = path;
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Move(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
var voiceChannel = ((IGuildUser)imsg.Author).VoiceChannel;
|
||||
if (voiceChannel == null || voiceChannel.Guild != channel.Guild || !MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
musicPlayer.MoveToVoiceChannel(voiceChannel);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Remove(IMessage imsg, int num)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
if (num <= 0 || num > musicPlayer.Playlist.Count)
|
||||
return;
|
||||
var song = (musicPlayer.Playlist as List<Song>)?[num - 1];
|
||||
musicPlayer.RemoveSongAt(num - 1);
|
||||
await channel.SendMessageAsync($"🎵**Track {song.PrettyName} at position `#{num}` has been removed.**").ConfigureAwait(false);
|
||||
}
|
||||
//todo fix
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Remove(IMessage imsg, string all)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (all.Trim().ToUpperInvariant() != "ALL")
|
||||
return;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
|
||||
musicPlayer.ClearQueue();
|
||||
await channel.SendMessageAsync($"🎵`Queue cleared!`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task MoveSong(IMessage imsg, [Remainder] string fromto)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
fromto = fromto?.Trim();
|
||||
var fromtoArr = fromto.Split('>');
|
||||
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
var playlist = musicPlayer.Playlist as List<Song> ?? musicPlayer.Playlist.ToList();
|
||||
|
||||
if (fromtoArr.Length != 2 || !int.TryParse(fromtoArr[0], out n1) ||
|
||||
!int.TryParse(fromtoArr[1], out n2) || n1 < 1 || n2 < 1 || n1 == n2 ||
|
||||
n1 > playlist.Count || n2 > playlist.Count)
|
||||
{
|
||||
await channel.SendMessageAsync("`Invalid input.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var s = playlist[n1 - 1];
|
||||
playlist.Insert(n2 - 1, s);
|
||||
var nn1 = n2 < n1 ? n1 : n1 - 1;
|
||||
playlist.RemoveAt(nn1);
|
||||
|
||||
await channel.SendMessageAsync($"🎵`Moved` {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task SetMaxQueue(IMessage imsg, uint size)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
musicPlayer.MaxQueueSize = size;
|
||||
await channel.SendMessageAsync($"🎵 `Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}`");
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ReptCurSong(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
if (currentSong == null)
|
||||
return;
|
||||
var currentValue = musicPlayer.ToggleRepeatSong();
|
||||
await channel.SendMessageAsync(currentValue ?
|
||||
$"🎵🔂`Repeating track:`{currentSong.PrettyName}" :
|
||||
$"🎵🔂`Current track repeat stopped.`")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task RepeatPl(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
var currentValue = musicPlayer.ToggleRepeatPlaylist();
|
||||
await channel.SendMessageAsync($"🎵🔁`Repeat playlist {(currentValue ? "enabled" : "disabled")}`").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
///
|
||||
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Save(IMessage imsg, [Remainder] string name)
|
||||
//{
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
//}
|
||||
|
||||
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Load(IMessage imsg, [Remainder] string name)
|
||||
//{
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
//}
|
||||
|
||||
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Playlists(IMessage imsg, [Remainder] string num)
|
||||
//{
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
//}
|
||||
|
||||
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task DeletePlaylist(IMessage imsg, [Remainder] string pl)
|
||||
//{
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
//}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Goto(IMessage imsg, int time)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
|
||||
if (time < 0)
|
||||
return;
|
||||
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
|
||||
if (currentSong == null)
|
||||
return;
|
||||
|
||||
//currentSong.PrintStatusMessage = false;
|
||||
var gotoSong = currentSong.Clone();
|
||||
gotoSong.SkipTo = time;
|
||||
musicPlayer.AddSong(gotoSong, 0);
|
||||
musicPlayer.Next();
|
||||
|
||||
var minutes = (time / 60).ToString();
|
||||
var seconds = (time % 60).ToString();
|
||||
|
||||
if (minutes.Length == 1)
|
||||
minutes = "0" + minutes;
|
||||
if (seconds.Length == 1)
|
||||
seconds = "0" + seconds;
|
||||
|
||||
await channel.SendMessageAsync($"`Skipped to {minutes}:{seconds}`").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task GetLink(IMessage imsg, int index = 0)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
|
||||
var selSong = musicPlayer.Playlist.DefaultIfEmpty(null).ElementAtOrDefault(index - 1);
|
||||
if (selSong == null)
|
||||
{
|
||||
await channel.SendMessageAsync("Could not select song, likely wrong index");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await channel.SendMessageAsync($"🎶`Selected song {selSong.SongInfo.Title}:` <{selSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var curSong = musicPlayer.CurrentSong;
|
||||
if (curSong == null)
|
||||
return;
|
||||
await channel.SendMessageAsync($"🎶`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Autoplay(IMessage imsg)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
|
||||
return;
|
||||
|
||||
if (!musicPlayer.ToggleAutoplay())
|
||||
await channel.SendMessageAsync("🎶`Autoplay disabled.`").ConfigureAwait(false);
|
||||
else
|
||||
await channel.SendMessageAsync("🎶`Autoplay enabled.`").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task QueueSong(IGuildUser queuer, ITextChannel textCh, IVoiceChannel voiceCh, string query, bool silent = false, MusicType musicType = MusicType.Normal)
|
||||
{
|
||||
if (voiceCh == null || voiceCh.Guild != textCh.Guild)
|
||||
{
|
||||
if (!silent)
|
||||
await textCh.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining.").ConfigureAwait(false);
|
||||
throw new ArgumentNullException(nameof(voiceCh));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(query) || query.Length < 3)
|
||||
throw new ArgumentException("💢 Invalid query for queue song.", nameof(query));
|
||||
|
||||
var musicPlayer = MusicPlayers.GetOrAdd(textCh.Guild.Id, server =>
|
||||
{
|
||||
//todo DB
|
||||
float vol = 100;// SpecificConfigurations.Default.Of(server.Id).DefaultMusicVolume;
|
||||
var mp = new MusicPlayer(voiceCh, vol);
|
||||
|
||||
|
||||
IMessage playingMessage = null;
|
||||
IMessage lastFinishedMessage = null;
|
||||
mp.OnCompleted += async (s, song) =>
|
||||
{
|
||||
if (song.PrintStatusMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (lastFinishedMessage != null)
|
||||
await lastFinishedMessage.DeleteAsync().ConfigureAwait(false);
|
||||
if (playingMessage != null)
|
||||
await playingMessage.DeleteAsync().ConfigureAwait(false);
|
||||
lastFinishedMessage = await textCh.SendMessageAsync($"🎵`Finished`{song.PrettyName}").ConfigureAwait(false);
|
||||
if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube")
|
||||
{
|
||||
await QueueSong(queuer.Guild.GetCurrentUser(), textCh, voiceCh, (await NadekoBot.Google.GetRelatedVideosAsync(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
mp.OnStarted += async (s, song) =>
|
||||
{
|
||||
if (song.PrintStatusMessage)
|
||||
{
|
||||
var sender = s as MusicPlayer;
|
||||
if (sender == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
var msgTxt = $"🎵`Playing`{song.PrettyName} `Vol: {(int)(sender.Volume * 100)}%`";
|
||||
playingMessage = await textCh.SendMessageAsync(msgTxt).ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
};
|
||||
return mp;
|
||||
});
|
||||
Song resolvedSong;
|
||||
try
|
||||
{
|
||||
musicPlayer.ThrowIfQueueFull();
|
||||
resolvedSong = await Song.ResolveSong(query, musicType).ConfigureAwait(false);
|
||||
|
||||
musicPlayer.AddSong(resolvedSong, queuer.Username);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
await textCh.SendMessageAsync($"🎵 `Queue is full at {musicPlayer.MaxQueueSize}/{musicPlayer.MaxQueueSize}.` ");
|
||||
throw;
|
||||
}
|
||||
if (!silent)
|
||||
{
|
||||
var queuedMessage = await textCh.SendMessageAsync($"🎵`Queued`{resolvedSong.PrettyName} **at** `#{musicPlayer.Playlist.Count + 1}`").ConfigureAwait(false);
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await queuedMessage.DeleteAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
}).ConfigureAwait(false);
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using System.Net;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Extensions;
|
||||
|
||||
namespace NadekoBot.Modules.NSFW
|
||||
{
|
||||
@ -25,7 +26,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Hentai(IMessage imsg, [Remainder] string tag = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
tag = tag?.Trim() ?? "";
|
||||
|
||||
@ -44,7 +45,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Danbooru(IMessage imsg, [Remainder] string tag = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
tag = tag?.Trim() ?? "";
|
||||
var link = await GetDanbooruImageLink(tag).ConfigureAwait(false);
|
||||
@ -58,7 +59,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Gelbooru(IMessage imsg, [Remainder] string tag = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
tag = tag?.Trim() ?? "";
|
||||
var link = await GetRule34ImageLink(tag).ConfigureAwait(false);
|
||||
@ -72,7 +73,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Rule34(IMessage imsg, [Remainder] string tag = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
tag = tag?.Trim() ?? "";
|
||||
var link = await GetGelbooruImageLink(tag).ConfigureAwait(false);
|
||||
@ -86,7 +87,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task E621(IMessage imsg, [Remainder] string tag = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
tag = tag?.Trim() ?? "";
|
||||
var link = await GetE621ImageLink(tag).ConfigureAwait(false);
|
||||
@ -100,7 +101,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Cp(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendMessageAsync("http://i.imgur.com/MZkY1md.jpg").ConfigureAwait(false);
|
||||
}
|
||||
@ -109,7 +110,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Boobs(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
try
|
||||
{
|
||||
JToken obj;
|
||||
@ -129,7 +130,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Butts(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
try
|
||||
{
|
||||
@ -173,9 +174,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
{
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
http.DefaultRequestHeaders.Clear();
|
||||
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1");
|
||||
http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
http.AddFakeHeaders();
|
||||
|
||||
var webpage = await http.GetStringAsync("http://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=100&tags="+ tag.Replace(" ", "_")).ConfigureAwait(false);
|
||||
var matches = Regex.Matches(webpage, "file_url=\"(?<url>.*?)\"");
|
||||
@ -211,9 +210,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
{
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
http.DefaultRequestHeaders.Clear();
|
||||
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1");
|
||||
http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
http.AddFakeHeaders();
|
||||
var data = await http.GetStreamAsync("http://e621.net/post/index.xml?tags=" + Uri.EscapeUriString(tags) + "%20order:random&limit=1");
|
||||
var doc = XDocument.Load(data);
|
||||
return doc.Descendants("file_url").FirstOrDefault().Value;
|
||||
|
@ -19,7 +19,7 @@ namespace NadekoBot.Modules.Games
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Poke(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// [RequireContext(ContextType.Guild)]
|
||||
// public async Task Anime(IMessage imsg, [Remainder] string query = null)
|
||||
// {
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
|
||||
// string result;
|
||||
@ -36,7 +36,7 @@
|
||||
// [RequireContext(ContextType.Guild)]
|
||||
// public async Task Manga(IMessage imsg, [Remainder] string query = null)
|
||||
// {
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
|
||||
// string result;
|
||||
|
@ -72,11 +72,11 @@
|
||||
// {
|
||||
// await e.Channel.SendIsTyping().ConfigureAwait(false);
|
||||
|
||||
// string from = e.GetArg("from-to").ToLowerInvariant().Split('>')[0];
|
||||
// string to = e.GetArg("from-to").ToLowerInvariant().Split('>')[1];
|
||||
// string from = from-to.ToLowerInvariant().Split('>')[0];
|
||||
// string to = from-to.ToLowerInvariant().Split('>')[1];
|
||||
|
||||
// float quantity = 1.0f;
|
||||
// if (!float.TryParse(e.GetArg("quantity"), out quantity))
|
||||
// if (!float.TryParse(quantity, out quantity))
|
||||
// {
|
||||
// quantity = 1.0f;
|
||||
// }
|
||||
|
@ -27,7 +27,7 @@
|
||||
// private CustomParser parser = new CustomParser();
|
||||
// private Func<CommandEventArgs, Task> EvalFunc() => async e =>
|
||||
// {
|
||||
// string expression = e.GetArg("expression")?.Trim();
|
||||
// string expression = expression?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(expression))
|
||||
// {
|
||||
// return;
|
||||
|
@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Yomama(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false);
|
||||
@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Randjoke(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
|
||||
@ -70,7 +70,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task ChuckNorris(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var response = await http.GetStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false);
|
||||
@ -82,7 +82,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task WowJoke(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!wowJokes.Any())
|
||||
{
|
||||
@ -94,7 +94,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task MagicItem(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var rng = new Random();
|
||||
var item = magicItems[rng.Next(0, magicItems.Count)].ToString();
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Lolban(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
|
||||
|
||||
@ -124,9 +124,9 @@ namespace NadekoBot.Modules.Searches
|
||||
// try
|
||||
// {
|
||||
// //get role
|
||||
// var role = ResolvePos(e.GetArg("position"));
|
||||
// var role = ResolvePos(position);
|
||||
// var resolvedRole = role;
|
||||
// var name = e.GetArg("champ").Replace(" ", "").ToLower();
|
||||
// var name = champ.Replace(" ", "").ToLower();
|
||||
// CachedChampion champ = null;
|
||||
|
||||
// if (CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ))
|
||||
@ -136,7 +136,7 @@ namespace NadekoBot.Modules.Searches
|
||||
// await e.Channel.SendFile("champ.png", champ.ImageStream).ConfigureAwait(false);
|
||||
// return;
|
||||
// }
|
||||
// var allData = JArray.Parse(await Classes.http.GetStringAsync($"http://api.champion.gg/champion/{name}?api_key={NadekoBot.Creds.LOLAPIKey}").ConfigureAwait(false));
|
||||
// var allData = JArray.Parse(await Classes.http.GetStringAsync($"http://api.champion.gg/champion/{name}?api_key={NadekoBot.Credentials.LOLAPIKey}").ConfigureAwait(false));
|
||||
// JToken data = null;
|
||||
// if (role != null)
|
||||
// {
|
||||
@ -177,7 +177,7 @@ namespace NadekoBot.Modules.Searches
|
||||
// roles[i] = ">" + roles[i] + "<";
|
||||
// }
|
||||
// var general = JArray.Parse(await http.GetStringAsync($"http://api.champion.gg/stats/" +
|
||||
// $"champs/{name}?api_key={NadekoBot.Creds.LOLAPIKey}")
|
||||
// $"champs/{name}?api_key={NadekoBot.Credentials.LOLAPIKey}")
|
||||
// .ConfigureAwait(false))
|
||||
// .FirstOrDefault(jt => jt["role"].ToString() == role)?["general"];
|
||||
// if (general == null)
|
||||
|
@ -19,7 +19,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Memelist(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(await http.GetStringAsync("http://memegen.link/templates/"))
|
||||
@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Memegen(IMessage imsg, string meme, string topText, string botText)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var top = Uri.EscapeDataString(topText.Replace(' ', '-'));
|
||||
var bot = Uri.EscapeDataString(botText.Replace(' ', '-'));
|
||||
|
@ -26,7 +26,7 @@ $@"`Title:` {WebUtility.HtmlDecode(Title)} {(string.IsNullOrEmpty(OriginalTitle)
|
||||
`Genre:` {GenresAsString}
|
||||
`Link:` <{ImdbURL}>
|
||||
`Plot:` {System.Net.WebUtility.HtmlDecode(Plot.TrimTo(500))}
|
||||
`img:` " + Poster.ShortenUrl().Result;
|
||||
`img:` " + Poster;
|
||||
public string GenresAsString =>
|
||||
string.Join(", ", Genres);
|
||||
}
|
||||
|
@ -1,269 +1,277 @@
|
||||
//using Discord.Commands;
|
||||
//using NadekoBot.Classes;
|
||||
//using Newtonsoft.Json.Linq;
|
||||
//using System;
|
||||
//using System.IO;
|
||||
//using System.Net;
|
||||
//using System.Text.RegularExpressions;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
//todo DI into partials
|
||||
//namespace NadekoBot.Modules.Searches
|
||||
//{
|
||||
// internal class OsuCommands : DiscordCommand
|
||||
// {
|
||||
// public OsuCommands(DiscordModule module) : base(module)
|
||||
// {
|
||||
// }
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
public partial class Searches
|
||||
{
|
||||
[Group]
|
||||
public class OsuCommands
|
||||
{
|
||||
private Logger _log;
|
||||
|
||||
// internal override void Init(CommandGroupBuilder cgb)
|
||||
// {
|
||||
// cgb.CreateCommand(Module.Prefix + "osu")
|
||||
// .Description($"Shows osu stats for a player. | `{Prefix}osu Name` or `{Prefix}osu Name taiko`")
|
||||
// .Parameter("usr", ParameterType.Required)
|
||||
// .Parameter("mode", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(e.GetArg("usr")))
|
||||
// return;
|
||||
public OsuCommands()
|
||||
{
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
}
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Osu(IMessage imsg, string usr, string mode)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// using (WebClient cl = new WebClient())
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// var m = 0;
|
||||
// if (!string.IsNullOrWhiteSpace(e.GetArg("mode")))
|
||||
// {
|
||||
// m = ResolveGameMode(e.GetArg("mode"));
|
||||
// }
|
||||
if (string.IsNullOrWhiteSpace(usr))
|
||||
return;
|
||||
|
||||
// cl.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
|
||||
// cl.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.2; Win64; x64)");
|
||||
// cl.DownloadDataAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ e.GetArg("usr") }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}"));
|
||||
// cl.DownloadDataCompleted += async (s, cle) =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// await e.Channel.SendFile($"{e.GetArg("usr")}.png", new MemoryStream(cle.Result)).ConfigureAwait(false);
|
||||
// await channel.SendMessageAsync($"`Profile Link:`https://osu.ppy.sh/u/{Uri.EscapeDataString(e.GetArg("usr"))}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
|
||||
// }
|
||||
// catch { }
|
||||
// };
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// await channel.SendMessageAsync("💢 Failed retrieving osu signature :\\").ConfigureAwait(false);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
using (HttpClient http = new HttpClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
var m = 0;
|
||||
if (!string.IsNullOrWhiteSpace(mode))
|
||||
{
|
||||
m = ResolveGameMode(mode);
|
||||
}
|
||||
http.AddFakeHeaders();
|
||||
var res = await http.GetStreamAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ usr }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}")).ConfigureAwait(false);
|
||||
|
||||
// cgb.CreateCommand(Module.Prefix + "osu b")
|
||||
// .Description($"Shows information about an osu beatmap. |`{Prefix}osu b` https://osu.ppy.sh/s/127712`")
|
||||
// .Parameter("map", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(NadekoBot.Creds.OsuAPIKey))
|
||||
// {
|
||||
// await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
|
||||
// return;
|
||||
// }
|
||||
res.Position = 0;
|
||||
await channel.SendFileAsync(res, $"{usr}.png").ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"`Profile Link:`https://osu.ppy.sh/u/{Uri.EscapeDataString(usr)}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Failed retrieving osu signature :\\").ConfigureAwait(false);
|
||||
_log.Warn(ex, "Osu command failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(e.GetArg("map")))
|
||||
// return;
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Osub(IMessage imsg, [Remainder] string map)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// try
|
||||
// {
|
||||
// var mapId = ResolveMap(e.GetArg("map"));
|
||||
// var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&{mapId}";
|
||||
// var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false))[0];
|
||||
// var sb = new System.Text.StringBuilder();
|
||||
// var starRating = Math.Round(Double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2);
|
||||
// var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss");
|
||||
// sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}");
|
||||
// sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}");
|
||||
// await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// await channel.SendMessageAsync("Something went wrong.");
|
||||
// }
|
||||
// });
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
|
||||
{
|
||||
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// cgb.CreateCommand(Module.Prefix + "osu top5")
|
||||
// .Description($"Displays a user's top 5 plays. |`{Prefix}osu top5 Name`")
|
||||
// .Parameter("usr", ParameterType.Required)
|
||||
// .Parameter("mode", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(NadekoBot.Creds.OsuAPIKey))
|
||||
// {
|
||||
// await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
|
||||
// return;
|
||||
// }
|
||||
if (string.IsNullOrWhiteSpace(map))
|
||||
return;
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(e.GetArg("usr")))
|
||||
// {
|
||||
// await channel.SendMessageAsync("💢 Please provide a username.").ConfigureAwait(false);
|
||||
// return;
|
||||
// }
|
||||
try
|
||||
{
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var mapId = ResolveMap(map);
|
||||
var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Credentials.OsuApiKey}&{mapId}";
|
||||
var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false))[0];
|
||||
var sb = new System.Text.StringBuilder();
|
||||
var starRating = Math.Round(Double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2);
|
||||
var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss");
|
||||
sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}");
|
||||
sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}");
|
||||
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went wrong.");
|
||||
_log.Warn(ex, "Osub command failed");
|
||||
}
|
||||
}
|
||||
|
||||
// try
|
||||
// {
|
||||
// var m = 0;
|
||||
// if (!string.IsNullOrWhiteSpace(e.GetArg("mode")))
|
||||
// {
|
||||
// m = ResolveGameMode(e.GetArg("mode"));
|
||||
// }
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Osu5(IMessage imsg, string user, [Remainder] string mode)
|
||||
{
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
|
||||
{
|
||||
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// var reqString = $"https://osu.ppy.sh/api/get_user_best?k={NadekoBot.Creds.OsuAPIKey}&u={Uri.EscapeDataString(e.GetArg("usr"))}&type=string&limit=5&m={m}";
|
||||
// var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false));
|
||||
// var sb = new System.Text.StringBuilder($"`Top 5 plays for {e.GetArg("usr")}:`\n```xl" + Environment.NewLine);
|
||||
// foreach (var item in obj)
|
||||
// {
|
||||
// var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&b={item["beatmap_id"]}";
|
||||
// var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0];
|
||||
// var pp = Math.Round(Double.Parse($"{item["pp"]}", CultureInfo.InvariantCulture), 2);
|
||||
// var acc = CalculateAcc(item, m);
|
||||
// var mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}"));
|
||||
// if (mods != "+")
|
||||
// sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"],-40}) | **{mods,-10}** | /b/{item["beatmap_id"]}");
|
||||
// else
|
||||
// sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"],-40}) | /b/{item["beatmap_id"]}");
|
||||
// }
|
||||
// sb.Append("```");
|
||||
// await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// await channel.SendMessageAsync("Something went wrong.");
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
if (string.IsNullOrWhiteSpace(user))
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Please provide a username.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
var m = 0;
|
||||
if (!string.IsNullOrWhiteSpace(mode))
|
||||
{
|
||||
m = ResolveGameMode(mode);
|
||||
}
|
||||
|
||||
// //https://osu.ppy.sh/wiki/Accuracy
|
||||
// private static Double CalculateAcc(JToken play, int mode)
|
||||
// {
|
||||
// if (mode == 0)
|
||||
// {
|
||||
// var hitPoints = Double.Parse($"{play["count50"]}") * 50 + Double.Parse($"{play["count100"]}") * 100 + Double.Parse($"{play["count300"]}") * 300;
|
||||
// var totalHits = Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countmiss"]}");
|
||||
// totalHits *= 300;
|
||||
// return Math.Round(hitPoints / totalHits * 100, 2);
|
||||
// }
|
||||
// else if (mode == 1)
|
||||
// {
|
||||
// var hitPoints = Double.Parse($"{play["countmiss"]}") * 0 + Double.Parse($"{play["count100"]}") * 0.5 + Double.Parse($"{play["count300"]}") * 1;
|
||||
// var totalHits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}");
|
||||
// hitPoints *= 300;
|
||||
// totalHits *= 300;
|
||||
// return Math.Round(hitPoints / totalHits * 100, 2);
|
||||
// }
|
||||
// else if (mode == 2)
|
||||
// {
|
||||
// var fruitsCaught = Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}");
|
||||
// var totalFruits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countkatu"]}");
|
||||
// return Math.Round(fruitsCaught / totalFruits * 100, 2);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var hitPoints = Double.Parse($"{play["count50"]}") * 50 + Double.Parse($"{play["count100"]}") * 100 + Double.Parse($"{play["countkatu"]}") * 200 + (Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countgeki"]}")) * 300;
|
||||
// var totalHits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["countkatu"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countgeki"]}");
|
||||
// totalHits *= 300;
|
||||
// return Math.Round(hitPoints / totalHits * 100, 2);
|
||||
// }
|
||||
// }
|
||||
var reqString = $"https://osu.ppy.sh/api/get_user_best?k={NadekoBot.Credentials.OsuApiKey}&u={Uri.EscapeDataString(user)}&type=string&limit=5&m={m}";
|
||||
var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false));
|
||||
var sb = new System.Text.StringBuilder($"`Top 5 plays for {user}:`\n```xl" + Environment.NewLine);
|
||||
foreach (var item in obj)
|
||||
{
|
||||
var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Credentials.OsuApiKey}&b={item["beatmap_id"]}";
|
||||
var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0];
|
||||
var pp = Math.Round(Double.Parse($"{item["pp"]}", CultureInfo.InvariantCulture), 2);
|
||||
var acc = CalculateAcc(item, m);
|
||||
var mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}"));
|
||||
if (mods != "+")
|
||||
sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"],-40}) | **{mods,-10}** | /b/{item["beatmap_id"]}");
|
||||
else
|
||||
sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"],-40}) | /b/{item["beatmap_id"]}");
|
||||
}
|
||||
sb.Append("```");
|
||||
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went wrong.");
|
||||
_log.Warn(ex, "Osu5 command failed");
|
||||
}
|
||||
|
||||
// private static string ResolveMap(string mapLink)
|
||||
// {
|
||||
// Match s = new Regex(@"osu.ppy.sh\/s\/", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
// Match b = new Regex(@"osu.ppy.sh\/b\/", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
// Match p = new Regex(@"osu.ppy.sh\/p\/", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
// Match m = new Regex(@"&m=", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
// if (s.Success)
|
||||
// {
|
||||
// var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3);
|
||||
// return $"s={mapId}";
|
||||
// }
|
||||
// else if (b.Success)
|
||||
// {
|
||||
// if (m.Success)
|
||||
// return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("/b/") + 3))}";
|
||||
// else
|
||||
// return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3)}";
|
||||
// }
|
||||
// else if (p.Success)
|
||||
// {
|
||||
// if (m.Success)
|
||||
// return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("?b=") + 3))}";
|
||||
// else
|
||||
// return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3)}";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return $"s={mapLink}"; //just a default incase an ID number was provided by itself (non-url)?
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// private static int ResolveGameMode(string mode)
|
||||
// {
|
||||
// switch (mode.ToLower())
|
||||
// {
|
||||
// case "std":
|
||||
// case "standard":
|
||||
// return 0;
|
||||
// case "taiko":
|
||||
// return 1;
|
||||
// case "ctb":
|
||||
// case "catchthebeat":
|
||||
// return 2;
|
||||
// case "mania":
|
||||
// case "osu!mania":
|
||||
// return 3;
|
||||
// default:
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
//https://osu.ppy.sh/wiki/Accuracy
|
||||
private static Double CalculateAcc(JToken play, int mode)
|
||||
{
|
||||
if (mode == 0)
|
||||
{
|
||||
var hitPoints = Double.Parse($"{play["count50"]}") * 50 + Double.Parse($"{play["count100"]}") * 100 + Double.Parse($"{play["count300"]}") * 300;
|
||||
var totalHits = Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countmiss"]}");
|
||||
totalHits *= 300;
|
||||
return Math.Round(hitPoints / totalHits * 100, 2);
|
||||
}
|
||||
else if (mode == 1)
|
||||
{
|
||||
var hitPoints = Double.Parse($"{play["countmiss"]}") * 0 + Double.Parse($"{play["count100"]}") * 0.5 + Double.Parse($"{play["count300"]}") * 1;
|
||||
var totalHits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}");
|
||||
hitPoints *= 300;
|
||||
totalHits *= 300;
|
||||
return Math.Round(hitPoints / totalHits * 100, 2);
|
||||
}
|
||||
else if (mode == 2)
|
||||
{
|
||||
var fruitsCaught = Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}");
|
||||
var totalFruits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countkatu"]}");
|
||||
return Math.Round(fruitsCaught / totalFruits * 100, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var hitPoints = Double.Parse($"{play["count50"]}") * 50 + Double.Parse($"{play["count100"]}") * 100 + Double.Parse($"{play["countkatu"]}") * 200 + (Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countgeki"]}")) * 300;
|
||||
var totalHits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["countkatu"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countgeki"]}");
|
||||
totalHits *= 300;
|
||||
return Math.Round(hitPoints / totalHits * 100, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// //https://github.com/ppy/osu-api/wiki#mods
|
||||
// private static string ResolveMods(int mods)
|
||||
// {
|
||||
// var modString = $"+";
|
||||
private static string ResolveMap(string mapLink)
|
||||
{
|
||||
Match s = new Regex(@"osu.ppy.sh\/s\/", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
Match b = new Regex(@"osu.ppy.sh\/b\/", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
Match p = new Regex(@"osu.ppy.sh\/p\/", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
Match m = new Regex(@"&m=", RegexOptions.IgnoreCase).Match(mapLink);
|
||||
if (s.Success)
|
||||
{
|
||||
var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3);
|
||||
return $"s={mapId}";
|
||||
}
|
||||
else if (b.Success)
|
||||
{
|
||||
if (m.Success)
|
||||
return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("/b/") + 3))}";
|
||||
else
|
||||
return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3)}";
|
||||
}
|
||||
else if (p.Success)
|
||||
{
|
||||
if (m.Success)
|
||||
return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("?b=") + 3))}";
|
||||
else
|
||||
return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"s={mapLink}"; //just a default incase an ID number was provided by itself (non-url)?
|
||||
}
|
||||
}
|
||||
|
||||
// if (IsBitSet(mods, 0))
|
||||
// modString += "NF";
|
||||
// if (IsBitSet(mods, 1))
|
||||
// modString += "EZ";
|
||||
// if (IsBitSet(mods, 8))
|
||||
// modString += "HT";
|
||||
private static int ResolveGameMode(string mode)
|
||||
{
|
||||
switch (mode.ToLower())
|
||||
{
|
||||
case "std":
|
||||
case "standard":
|
||||
return 0;
|
||||
case "taiko":
|
||||
return 1;
|
||||
case "ctb":
|
||||
case "catchthebeat":
|
||||
return 2;
|
||||
case "mania":
|
||||
case "osu!mania":
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// if (IsBitSet(mods, 3))
|
||||
// modString += "HD";
|
||||
// if (IsBitSet(mods, 4))
|
||||
// modString += "HR";
|
||||
// if (IsBitSet(mods, 6) && !IsBitSet(mods, 9))
|
||||
// modString += "DT";
|
||||
// if (IsBitSet(mods, 9))
|
||||
// modString += "NC";
|
||||
// if (IsBitSet(mods, 10))
|
||||
// modString += "FL";
|
||||
//https://github.com/ppy/osu-api/wiki#mods
|
||||
private static string ResolveMods(int mods)
|
||||
{
|
||||
var modString = $"+";
|
||||
|
||||
// if (IsBitSet(mods, 5))
|
||||
// modString += "SD";
|
||||
// if (IsBitSet(mods, 14))
|
||||
// modString += "PF";
|
||||
if (IsBitSet(mods, 0))
|
||||
modString += "NF";
|
||||
if (IsBitSet(mods, 1))
|
||||
modString += "EZ";
|
||||
if (IsBitSet(mods, 8))
|
||||
modString += "HT";
|
||||
|
||||
// if (IsBitSet(mods, 7))
|
||||
// modString += "RX";
|
||||
// if (IsBitSet(mods, 11))
|
||||
// modString += "AT";
|
||||
// if (IsBitSet(mods, 12))
|
||||
// modString += "SO";
|
||||
// return modString;
|
||||
// }
|
||||
if (IsBitSet(mods, 3))
|
||||
modString += "HD";
|
||||
if (IsBitSet(mods, 4))
|
||||
modString += "HR";
|
||||
if (IsBitSet(mods, 6) && !IsBitSet(mods, 9))
|
||||
modString += "DT";
|
||||
if (IsBitSet(mods, 9))
|
||||
modString += "NC";
|
||||
if (IsBitSet(mods, 10))
|
||||
modString += "FL";
|
||||
|
||||
// private static bool IsBitSet(int mods, int pos)
|
||||
// {
|
||||
// return (mods & (1 << pos)) != 0;
|
||||
// }
|
||||
if (IsBitSet(mods, 5))
|
||||
modString += "SD";
|
||||
if (IsBitSet(mods, 14))
|
||||
modString += "PF";
|
||||
|
||||
// }
|
||||
//}
|
||||
if (IsBitSet(mods, 7))
|
||||
modString += "RX";
|
||||
if (IsBitSet(mods, 11))
|
||||
modString += "AT";
|
||||
if (IsBitSet(mods, 12))
|
||||
modString += "SO";
|
||||
return modString;
|
||||
}
|
||||
|
||||
private static bool IsBitSet(int mods, int pos) =>
|
||||
(mods & (1 << pos)) != 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Pokemon(IMessage imsg, [Remainder] string pokemon = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
pokemon = pokemon?.Trim().ToUpperInvariant();
|
||||
if (string.IsNullOrWhiteSpace(pokemon))
|
||||
@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Searches
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task PokemonAbility(IMessage imsg, [Remainder] string ability = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
ability = ability?.Trim().ToUpperInvariant().Replace(" ", "");
|
||||
if (string.IsNullOrWhiteSpace(ability))
|
||||
|
@ -154,7 +154,7 @@
|
||||
// .AddCheck(SimpleCheckers.ManageServer())
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var stream = e.GetArg("username")?.Trim();
|
||||
// var stream = username?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(stream))
|
||||
// return;
|
||||
// try
|
||||
@ -183,7 +183,7 @@
|
||||
// .Parameter("username", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var stream = e.GetArg("username")?.Trim();
|
||||
// var stream = username?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(stream))
|
||||
// return;
|
||||
// try
|
||||
@ -212,7 +212,7 @@
|
||||
// .Parameter("username", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var stream = e.GetArg("username")?.Trim();
|
||||
// var stream = username?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(stream))
|
||||
// return;
|
||||
// try
|
||||
@ -241,7 +241,7 @@
|
||||
// .Parameter("username", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var username = e.GetArg("username")?.ToLower().Trim();
|
||||
// var username = username?.ToLower().Trim();
|
||||
// if (string.IsNullOrWhiteSpace(username))
|
||||
// return;
|
||||
|
||||
@ -298,7 +298,7 @@
|
||||
// private Func<CommandEventArgs, Task> TrackStream(StreamNotificationConfig.StreamType type) =>
|
||||
// async e =>
|
||||
// {
|
||||
// var username = e.GetArg("username")?.ToLowerInvariant();
|
||||
// var username = username?.ToLowerInvariant();
|
||||
// if (string.IsNullOrWhiteSpace(username))
|
||||
// return;
|
||||
|
||||
|
@ -8,7 +8,6 @@ using System.Net.Http;
|
||||
using NadekoBot.Services;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Net;
|
||||
using Discord.WebSocket;
|
||||
@ -20,17 +19,17 @@ namespace NadekoBot.Modules.Searches
|
||||
[Module("~", AppendSpace = false)]
|
||||
public partial class Searches : DiscordModule
|
||||
{
|
||||
private IYoutubeService _yt { get; }
|
||||
private IGoogleApiService _google { get; }
|
||||
|
||||
public Searches(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client, IYoutubeService youtube) : base(loc, cmds, config, client)
|
||||
public Searches(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client, IGoogleApiService youtube) : base(loc, cmds, config, client)
|
||||
{
|
||||
_yt = youtube;
|
||||
_google = youtube;
|
||||
}
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Weather(IMessage imsg, string city, string country)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
city = city.Replace(" ", "");
|
||||
country = city.Replace(" ", "");
|
||||
string response;
|
||||
@ -51,9 +50,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Youtube(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
|
||||
var result = (await _yt.FindVideosByKeywordsAsync(query, 1)).FirstOrDefault();
|
||||
var result = (await _google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault();
|
||||
if (string.IsNullOrWhiteSpace(result))
|
||||
{
|
||||
await channel.SendMessageAsync("No results found for that query.");
|
||||
@ -66,7 +65,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Imdb(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
|
||||
await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
|
||||
@ -90,7 +89,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task RandomCat(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
await channel.SendMessageAsync(JObject.Parse(
|
||||
@ -103,7 +102,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task RandomDog(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
await channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof").ConfigureAwait(false)).ConfigureAwait(false);
|
||||
@ -114,7 +113,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task I(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
return;
|
||||
@ -144,7 +143,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Ir(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
return;
|
||||
@ -176,13 +175,13 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Lmgtfy(IMessage imsg, [Remainder] string ffs = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ffs))
|
||||
return;
|
||||
|
||||
await channel.SendMessageAsync(await $"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>".ShortenUrl())
|
||||
await channel.SendMessageAsync(await _google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>"))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@ -190,7 +189,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Google(IMessage imsg, [Remainder] string terms = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
|
||||
terms = terms?.Trim();
|
||||
@ -204,8 +203,8 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Hearthstone(IMessage imsg, [Remainder] string name = null)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var arg = e.GetArg("name");
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
// var arg = name;
|
||||
// if (string.IsNullOrWhiteSpace(arg))
|
||||
// {
|
||||
// await channel.SendMessageAsync("💢 Please enter a card name to search for.").ConfigureAwait(false);
|
||||
@ -249,7 +248,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Ud(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var arg = query;
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
@ -269,7 +268,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine($"`Term:` {items["list"][0]["word"].ToString()}");
|
||||
sb.AppendLine($"`Definition:` {items["list"][0]["definition"].ToString()}");
|
||||
sb.Append($"`Link:` <{await items["list"][0]["permalink"].ToString().ShortenUrl().ConfigureAwait(false)}>");
|
||||
sb.Append($"`Link:` <{await _google.ShortenUrl(items["list"][0]["permalink"].ToString()).ConfigureAwait(false)}>");
|
||||
await channel.SendMessageAsync(sb.ToString());
|
||||
}
|
||||
catch
|
||||
@ -283,7 +282,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Hashtag(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var arg = query;
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
@ -305,7 +304,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
var items = JObject.Parse(res);
|
||||
var str = $@"`Hashtag:` {items["defs"]["def"]["hashtag"].ToString()}
|
||||
`Definition:` {items["defs"]["def"]["text"].ToString()}
|
||||
`Link:` <{await items["defs"]["def"]["uri"].ToString().ShortenUrl().ConfigureAwait(false)}>";
|
||||
`Link:` <{await _google.ShortenUrl(items["defs"]["def"]["uri"].ToString()).ConfigureAwait(false)}>";
|
||||
await channel.SendMessageAsync(str);
|
||||
}
|
||||
catch
|
||||
@ -318,7 +317,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Quote(IMessage imsg)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString();
|
||||
// await channel.SendMessageAsync(quote).ConfigureAwait(false);
|
||||
@ -328,7 +327,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Catfact(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
var response = await http.GetStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false);
|
||||
@ -342,7 +341,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Revav(IMessage imsg, [Remainder] string arg = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var usrStr = arg?.Trim().ToUpperInvariant();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(usrStr))
|
||||
@ -359,7 +358,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Revimg(IMessage imsg, [Remainder] string imageLink = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
imageLink = imageLink?.Trim() ?? "";
|
||||
|
||||
if (string.IsNullOrWhiteSpace(imageLink))
|
||||
@ -371,7 +370,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Safebooru(IMessage imsg, [Remainder] string tag = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
tag = tag?.Trim() ?? "";
|
||||
var link = await GetSafebooruImageLink(tag).ConfigureAwait(false);
|
||||
@ -385,7 +384,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Wiki(IMessage imsg, [Remainder] string query = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
query = query?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
@ -406,7 +405,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
//[RequireContext(ContextType.Guild)]
|
||||
//public async Task Clr(IMessage imsg, [Remainder] string color = null)
|
||||
//{
|
||||
// var channel = imsg.Channel as ITextChannel;
|
||||
// var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
// color = color?.Trim().Replace("#", "");
|
||||
// if (string.IsNullOrWhiteSpace((string)color))
|
||||
@ -431,7 +430,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Videocall(IMessage imsg, [Remainder] string arg = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
try
|
||||
{
|
||||
@ -454,7 +453,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Avatar(IMessage imsg, [Remainder] string mention = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
var usr = imsg.MentionedUsers.FirstOrDefault();
|
||||
if (usr == null)
|
||||
@ -462,7 +461,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
await channel.SendMessageAsync("Invalid user specified.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await channel.SendMessageAsync(await usr.AvatarUrl.ShortenUrl()).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync(await _google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<string> GetSafebooruImageLink(string tag)
|
||||
|
@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Translator
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Translate(IMessage imsg, string langs, [Remainder] string text = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
try
|
||||
{
|
||||
@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Translator
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Translangs(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => str, columns: 4);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
// TrelloConfiguration.Deserializer = serializer;
|
||||
// TrelloConfiguration.JsonFactory = new ManateeFactory();
|
||||
// TrelloConfiguration.RestClientProvider = new Manatee.Trello.WebApi.WebApiClientProvider();
|
||||
// TrelloAuthorization.Default.AppKey = NadekoBot.Creds.TrelloAppKey;
|
||||
// TrelloAuthorization.Default.AppKey = NadekoBot.Credentials.TrelloAppKey;
|
||||
// //TrelloAuthorization.Default.UserToken = "[your user token]";
|
||||
|
||||
// Discord.Channel bound = null;
|
||||
@ -80,7 +80,7 @@
|
||||
// try
|
||||
// {
|
||||
// bound = e.Channel;
|
||||
// board = new Board(e.GetArg("board_id").Trim());
|
||||
// board = new Board(board_id.Trim());
|
||||
// board.Refresh();
|
||||
// await channel.SendMessageAsync("Successfully bound to this channel and board " + board.Name);
|
||||
// t.Start();
|
||||
@ -121,15 +121,15 @@
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// if (!NadekoBot.IsOwner(imsg.Author.Id)) return;
|
||||
// if (bound == null || board == null || bound != e.Channel || e.GetArg("list_name") == null) return;
|
||||
// if (bound == null || board == null || bound != e.Channel || list_name == null) return;
|
||||
|
||||
// int num;
|
||||
// var success = int.TryParse(e.GetArg("list_name"), out num);
|
||||
// var success = int.TryParse(list_name, out num);
|
||||
// List list = null;
|
||||
// if (success && num <= board.Lists.Count() && num > 0)
|
||||
// list = board.Lists[num - 1];
|
||||
// else
|
||||
// list = board.Lists.FirstOrDefault(l => l.Name == e.GetArg("list_name"));
|
||||
// list = board.Lists.FirstOrDefault(l => l.Name == list_name);
|
||||
|
||||
|
||||
// if (list != null)
|
||||
|
@ -94,7 +94,7 @@
|
||||
// .Parameter("message", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var meorchStr = e.GetArg("meorchannel").ToUpperInvariant();
|
||||
// var meorchStr = meorchannel.ToUpperInvariant();
|
||||
// Channel ch;
|
||||
// bool isPrivate = false;
|
||||
// if (meorchStr == "ME")
|
||||
@ -117,7 +117,7 @@
|
||||
// return;
|
||||
// }
|
||||
|
||||
// var timeStr = e.GetArg("time");
|
||||
// var timeStr = time;
|
||||
|
||||
// var m = regex.Match(timeStr);
|
||||
|
||||
@ -167,7 +167,7 @@
|
||||
// ChannelId = (long)ch.Id,
|
||||
// IsPrivate = isPrivate,
|
||||
// When = time,
|
||||
// Message = e.GetArg("message"),
|
||||
// Message = message,
|
||||
// UserId = (long)imsg.Author.Id,
|
||||
// ServerId = (long)e.Server.Id
|
||||
// };
|
||||
@ -175,7 +175,7 @@
|
||||
|
||||
// reminders.Add(StartNewReminder(rem));
|
||||
|
||||
// await channel.SendMessageAsync($"⏰ I will remind \"{ch.Name}\" to \"{e.GetArg("message").ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false);
|
||||
// await channel.SendMessageAsync($"⏰ I will remind \"{ch.Name}\" to \"{message.ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false);
|
||||
// });
|
||||
// cgb.CreateCommand(Module.Prefix + "remindmsg")
|
||||
// .Description("Sets message for when the remind is triggered. " +
|
||||
@ -185,7 +185,7 @@
|
||||
// .AddCheck(SimpleCheckers.OwnerOnly())
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// var arg = e.GetArg("msg")?.Trim();
|
||||
// var arg = msg?.Trim();
|
||||
// if (string.IsNullOrWhiteSpace(arg))
|
||||
// return;
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Utility
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task WhoPlays(IMessage imsg, [Remainder] string game = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
game = game.Trim().ToUpperInvariant();
|
||||
if (string.IsNullOrWhiteSpace(game))
|
||||
return;
|
||||
@ -49,7 +49,7 @@ namespace NadekoBot.Modules.Utility
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(roles))
|
||||
return;
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
var arg = roles.Split(',').Select(r => r.Trim().ToUpperInvariant());
|
||||
string send = _l["`Here is a list of users in a specfic role:`"];
|
||||
foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str) && str != "@EVERYONE" && str != "EVERYONE"))
|
||||
@ -121,11 +121,11 @@ namespace NadekoBot.Modules.Utility
|
||||
var guild = (msg.Channel as ITextChannel).Guild;
|
||||
if (target != null)
|
||||
{
|
||||
await msg.Reply($"`List of roles for **{target.Username}**:` \n• " + string.Join("\n• ", target.Roles.Except(new[] { guild.EveryoneRole })));
|
||||
await msg.Reply($"`List of roles for **{target.Username}**:` \n• " + string.Join("\n• ", target.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => r.Position)));
|
||||
}
|
||||
else
|
||||
{
|
||||
await msg.Reply("`List of roles:` \n• " + string.Join("\n• ", (msg.Channel as ITextChannel).Guild.Roles.Except(new[] { guild.EveryoneRole })));
|
||||
await msg.Reply("`List of roles:` \n• " + string.Join("\n• ", (msg.Channel as ITextChannel).Guild.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r=>r.Position)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Utility
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Stats(IMessage imsg)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
var channel = (ITextChannel)imsg.Channel;
|
||||
|
||||
await channel.SendMessageAsync(await NadekoBot.Stats.Print());
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace NadekoBot
|
||||
public static Localization Localizer { get; private set; }
|
||||
public static BotCredentials Credentials { get; private set; }
|
||||
|
||||
private static YoutubeService Youtube { get; set; }
|
||||
public static GoogleApiService Google { get; set; }
|
||||
public static StatsService Stats { get; private set; }
|
||||
|
||||
public async Task RunAsync(string[] args)
|
||||
@ -43,7 +43,7 @@ namespace NadekoBot
|
||||
Commands = new CommandService();
|
||||
Config = new BotConfiguration();
|
||||
Localizer = new Localization();
|
||||
Youtube = new YoutubeService();
|
||||
Google = new GoogleApiService();
|
||||
Stats = new StatsService(Client);
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ namespace NadekoBot
|
||||
depMap.Add<IBotConfiguration>(Config);
|
||||
depMap.Add<DiscordSocketClient>(Client);
|
||||
depMap.Add<CommandService>(Commands);
|
||||
depMap.Add<IYoutubeService>(Youtube);
|
||||
depMap.Add<IGoogleApiService>(Google);
|
||||
|
||||
//connect
|
||||
await Client.LoginAsync(TokenType.Bot, Credentials.Token);
|
||||
|
134
src/NadekoBot/Resources/CommandStrings.Designer.cs
generated
134
src/NadekoBot/Resources/CommandStrings.Designer.cs
generated
@ -3734,27 +3734,27 @@ namespace NadekoBot.Resources {
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Queues all songs from a directory. **Bot Owner Only!**.
|
||||
/// </summary>
|
||||
public static string localplaylst_desc {
|
||||
public static string localpl_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("localplaylst_desc", resourceCulture);
|
||||
return ResourceManager.GetString("localpl_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `!!lopl C:/music/classical`.
|
||||
/// </summary>
|
||||
public static string localplaylst_summary {
|
||||
public static string localpl_summary {
|
||||
get {
|
||||
return ResourceManager.GetString("localplaylst_summary", resourceCulture);
|
||||
return ResourceManager.GetString("localpl_summary", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to localplaylst.
|
||||
/// </summary>
|
||||
public static string localplaylst_text {
|
||||
public static string localpl_text {
|
||||
get {
|
||||
return ResourceManager.GetString("localplaylst_text", resourceCulture);
|
||||
return ResourceManager.GetString("localpl_text", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4352,57 +4352,57 @@ namespace NadekoBot.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Shows information about an osu beatmap..
|
||||
/// </summary>
|
||||
public static string osubeatmap_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("osubeatmap_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `~osu b https://osu.ppy.sh/s/127712`.
|
||||
/// </summary>
|
||||
public static string osubeatmap_summary {
|
||||
get {
|
||||
return ResourceManager.GetString("osubeatmap_summary", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to osu b.
|
||||
/// </summary>
|
||||
public static string osubeatmap_text {
|
||||
get {
|
||||
return ResourceManager.GetString("osubeatmap_text", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Displays a user's top 5 plays..
|
||||
/// </summary>
|
||||
public static string osutop5_desc {
|
||||
public static string osu5_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("osutop5_desc", resourceCulture);
|
||||
return ResourceManager.GetString("osu5_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `~osu top5 Name`.
|
||||
/// </summary>
|
||||
public static string osutop5_summary {
|
||||
public static string osu5_summary {
|
||||
get {
|
||||
return ResourceManager.GetString("osutop5_summary", resourceCulture);
|
||||
return ResourceManager.GetString("osu5_summary", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to osu top5.
|
||||
/// Looks up a localized string similar to osu5.
|
||||
/// </summary>
|
||||
public static string osutop5_text {
|
||||
public static string osu5_text {
|
||||
get {
|
||||
return ResourceManager.GetString("osutop5_text", resourceCulture);
|
||||
return ResourceManager.GetString("osu5_text", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Shows information about an osu beatmap..
|
||||
/// </summary>
|
||||
public static string osub_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("osub_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `~osu b https://osu.ppy.sh/s/127712`.
|
||||
/// </summary>
|
||||
public static string osub_summary {
|
||||
get {
|
||||
return ResourceManager.GetString("osub_summary", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to osub.
|
||||
/// </summary>
|
||||
public static string osub_text {
|
||||
get {
|
||||
return ResourceManager.GetString("osub_text", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5189,6 +5189,33 @@ namespace NadekoBot.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue)..
|
||||
/// </summary>
|
||||
public static string repeatpl_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("repeatpl_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `!!rpl`.
|
||||
/// </summary>
|
||||
public static string repeatpl_summary {
|
||||
get {
|
||||
return ResourceManager.GetString("repeatpl_summary", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to rpeatplaylst.
|
||||
/// </summary>
|
||||
public static string repeatpl_text {
|
||||
get {
|
||||
return ResourceManager.GetString("repeatpl_text", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Toggles repeat of current song..
|
||||
/// </summary>
|
||||
@ -5594,33 +5621,6 @@ namespace NadekoBot.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue)..
|
||||
/// </summary>
|
||||
public static string rpeatplaylst_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("rpeatplaylst_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `!!rpl`.
|
||||
/// </summary>
|
||||
public static string rpeatplaylst_summary {
|
||||
get {
|
||||
return ResourceManager.GetString("rpeatplaylst_summary", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to rpeatplaylst.
|
||||
/// </summary>
|
||||
public static string rpeatplaylst_text {
|
||||
get {
|
||||
return ResourceManager.GetString("rpeatplaylst_text", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Play a game of rocket paperclip scissors with Nadeko..
|
||||
/// </summary>
|
||||
|
@ -1773,13 +1773,13 @@
|
||||
<data name="soundcloudpl_summary" xml:space="preserve">
|
||||
<value>`!!scpl soundcloudseturl`</value>
|
||||
</data>
|
||||
<data name="localplaylst_text" xml:space="preserve">
|
||||
<data name="localpl_text" xml:space="preserve">
|
||||
<value>localplaylst</value>
|
||||
</data>
|
||||
<data name="localplaylst_desc" xml:space="preserve">
|
||||
<data name="localpl_desc" xml:space="preserve">
|
||||
<value>Queues all songs from a directory. **Bot Owner Only!**</value>
|
||||
</data>
|
||||
<data name="localplaylst_summary" xml:space="preserve">
|
||||
<data name="localpl_summary" xml:space="preserve">
|
||||
<value>`!!lopl C:/music/classical`</value>
|
||||
</data>
|
||||
<data name="radio_text" xml:space="preserve">
|
||||
@ -1854,13 +1854,13 @@
|
||||
<data name="reptcursong_summary" xml:space="preserve">
|
||||
<value>`!!rcs`</value>
|
||||
</data>
|
||||
<data name="rpeatplaylst_text" xml:space="preserve">
|
||||
<data name="repeatpl_text" xml:space="preserve">
|
||||
<value>rpeatplaylst</value>
|
||||
</data>
|
||||
<data name="rpeatplaylst_desc" xml:space="preserve">
|
||||
<data name="repeatpl_desc" xml:space="preserve">
|
||||
<value>Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue).</value>
|
||||
</data>
|
||||
<data name="rpeatplaylst_summary" xml:space="preserve">
|
||||
<data name="repeatpl_summary" xml:space="preserve">
|
||||
<value>`!!rpl`</value>
|
||||
</data>
|
||||
<data name="save_text" xml:space="preserve">
|
||||
@ -2061,22 +2061,22 @@
|
||||
<data name="osu_summary" xml:space="preserve">
|
||||
<value>`~osu Name` or `~osu Name taiko`</value>
|
||||
</data>
|
||||
<data name="osubeatmap_text" xml:space="preserve">
|
||||
<data name="osub_text" xml:space="preserve">
|
||||
<value>osub</value>
|
||||
</data>
|
||||
<data name="osubeatmap_desc" xml:space="preserve">
|
||||
<data name="osub_desc" xml:space="preserve">
|
||||
<value>Shows information about an osu beatmap.</value>
|
||||
</data>
|
||||
<data name="osubeatmap_summary" xml:space="preserve">
|
||||
<data name="osub_summary" xml:space="preserve">
|
||||
<value>`~osu b https://osu.ppy.sh/s/127712`</value>
|
||||
</data>
|
||||
<data name="osutop5_text" xml:space="preserve">
|
||||
<value>osu top5</value>
|
||||
<data name="osu5_text" xml:space="preserve">
|
||||
<value>osu5</value>
|
||||
</data>
|
||||
<data name="osutop5_desc" xml:space="preserve">
|
||||
<data name="osu5_desc" xml:space="preserve">
|
||||
<value>Displays a user's top 5 plays.</value>
|
||||
</data>
|
||||
<data name="osutop5_summary" xml:space="preserve">
|
||||
<data name="osu5_summary" xml:space="preserve">
|
||||
<value>`~osu top5 Name`</value>
|
||||
</data>
|
||||
<data name="pokemon_text" xml:space="preserve">
|
||||
|
15
src/NadekoBot/Services/IGoogleApiService.cs
Normal file
15
src/NadekoBot/Services/IGoogleApiService.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
public interface IGoogleApiService
|
||||
{
|
||||
Task<IEnumerable<string>> GetVideosByKeywordsAsync(string keywords, int count = 1);
|
||||
Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1);
|
||||
Task<IEnumerable<string>> GetRelatedVideosAsync(string url, int count = 1);
|
||||
Task<IEnumerable<string>> GetPlaylistTracksAsync(string playlistId, int count = 50);
|
||||
|
||||
Task<string> ShortenUrl(string url);
|
||||
}
|
||||
}
|
@ -5,26 +5,29 @@ using System.Threading.Tasks;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.Services;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Diagnostics.Contracts;
|
||||
using Google.Apis.Urlshortener.v1;
|
||||
using Google.Apis.Urlshortener.v1.Data;
|
||||
|
||||
namespace NadekoBot.Services.Impl
|
||||
{
|
||||
public class YoutubeService : IYoutubeService
|
||||
public class GoogleApiService : IGoogleApiService
|
||||
{
|
||||
private YouTubeService yt;
|
||||
private UrlshortenerService sh;
|
||||
|
||||
public YoutubeService()
|
||||
public GoogleApiService()
|
||||
{
|
||||
var bcs = new BaseClientService.Initializer
|
||||
{
|
||||
yt = new YouTubeService(new BaseClientService.Initializer {
|
||||
ApplicationName = "Nadeko Bot",
|
||||
ApiKey = NadekoBot.Credentials.GoogleApiKey
|
||||
});
|
||||
}
|
||||
public async Task<IEnumerable<string>> FindPlaylistIdsByKeywordsAsync(string keywords, int count = 1)
|
||||
{
|
||||
//Contract.Requires<ArgumentNullException>(!string.IsNullOrWhiteSpace(keywords));
|
||||
//Contract.Requires<ArgumentOutOfRangeException>(count > 0);
|
||||
};
|
||||
|
||||
yt = new YouTubeService(bcs);
|
||||
sh = new UrlshortenerService(bcs);
|
||||
}
|
||||
public async Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keywords))
|
||||
throw new ArgumentNullException(nameof(keywords));
|
||||
|
||||
@ -43,7 +46,7 @@ namespace NadekoBot.Services.Impl
|
||||
return (await query.ExecuteAsync()).Items.Select(i => i.Id.PlaylistId);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> FindRelatedVideosAsync(string id, int count = 1)
|
||||
public async Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
@ -63,7 +66,7 @@ namespace NadekoBot.Services.Impl
|
||||
return (await query.ExecuteAsync()).Items.Select(i => "http://www.youtube.com/watch?v=" + i.Id.VideoId);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> FindVideosByKeywordsAsync(string keywords, int count = 1)
|
||||
public async Task<IEnumerable<string>> GetVideosByKeywordsAsync(string keywords, int count = 1)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keywords))
|
||||
throw new ArgumentNullException(nameof(keywords));
|
||||
@ -77,5 +80,46 @@ namespace NadekoBot.Services.Impl
|
||||
query.Type = "video";
|
||||
return (await query.ExecuteAsync()).Items.Select(i => "http://www.youtube.com/watch?v=" + i.Id.VideoId);
|
||||
}
|
||||
|
||||
public async Task<string> ShortenUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
|
||||
var response = await sh.Url.Insert(new Url { LongUrl = url }).ExecuteAsync();
|
||||
return response.Id;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetPlaylistTracksAsync(string playlistId, int count = 50)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(playlistId))
|
||||
throw new ArgumentNullException(nameof(playlistId));
|
||||
|
||||
if (count <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(count));
|
||||
|
||||
string nextPageToken = null;
|
||||
|
||||
List<string> toReturn = new List<string>(count);
|
||||
|
||||
do
|
||||
{
|
||||
var toGet = count > 50 ? 50 : count;
|
||||
count -= toGet;
|
||||
|
||||
var query = yt.PlaylistItems.List("contentDetails");
|
||||
query.MaxResults = count;
|
||||
query.PlaylistId = playlistId;
|
||||
query.PageToken = nextPageToken;
|
||||
|
||||
var data = await query.ExecuteAsync();
|
||||
|
||||
toReturn.AddRange(data.Items.Select(i => i.ContentDetails.VideoId));
|
||||
nextPageToken = data.NextPageToken;
|
||||
}
|
||||
while (count > 0 && !string.IsNullOrWhiteSpace(nextPageToken));
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@ -14,6 +15,15 @@ namespace NadekoBot.Extensions
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static void AddFakeHeaders(this HttpClient http)
|
||||
{
|
||||
http.DefaultRequestHeaders.Clear();
|
||||
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1");
|
||||
http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
}
|
||||
|
||||
public static double UnixTimestamp(this DateTime dt) => dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
||||
|
||||
public static async Task<IMessage> SendMessageAsync(this IGuildUser user, string message, bool isTTS = false) =>
|
||||
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false);
|
||||
|
||||
@ -81,39 +91,6 @@ namespace NadekoBot.Extensions
|
||||
return ch.SendTableAsync("", items, howToPrint, columns);
|
||||
}
|
||||
|
||||
public static async Task<string> ShortenUrl(this string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleApiKey)) return url;
|
||||
try
|
||||
{
|
||||
var httpWebRequest =
|
||||
(HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" +
|
||||
NadekoBot.Credentials.GoogleApiKey);
|
||||
httpWebRequest.ContentType = "application/json";
|
||||
httpWebRequest.Method = "POST";
|
||||
|
||||
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)))
|
||||
{
|
||||
var json = "{\"longUrl\":\"" + Uri.EscapeDataString(url) + "\"}";
|
||||
streamWriter.Write(json);
|
||||
}
|
||||
|
||||
var httpResponse = (await httpWebRequest.GetResponseAsync().ConfigureAwait(false)) as HttpWebResponse;
|
||||
var responseStream = httpResponse.GetResponseStream();
|
||||
using (var streamReader = new StreamReader(responseStream))
|
||||
{
|
||||
var responseText = await streamReader.ReadToEndAsync().ConfigureAwait(false);
|
||||
return Regex.Match(responseText, @"""id"": ?""(?<id>.+)""").Groups["id"].Value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Shortening of this url failed: " + url);
|
||||
Console.WriteLine(ex.ToString());
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns an IEnumerable with randomized element order
|
||||
/// </summary>
|
||||
|
@ -32,7 +32,7 @@ namespace NadekoBot.Modules.CustomReactions
|
||||
} },
|
||||
{new Regex("%mention%"), (e,m) => NadekoBot.BotMention },
|
||||
{new Regex("%user%"), (e,m) => imsg.Author.Mention },
|
||||
{new Regex("%target%"), (e,m) => e.GetArg("args")?.Trim() ?? "" },
|
||||
{new Regex("%target%"), (e,m) => args?.Trim() ?? "" },
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -1,131 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Music.Classes
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 💩
|
||||
/// </summary>
|
||||
public class PoopyBuffer
|
||||
{
|
||||
|
||||
private readonly byte[] ringBuffer;
|
||||
|
||||
public int WritePosition { get; private set; } = 0;
|
||||
public int ReadPosition { get; private set; } = 0;
|
||||
|
||||
public int ContentLength => (WritePosition >= ReadPosition ?
|
||||
WritePosition - ReadPosition :
|
||||
(BufferSize - ReadPosition) + WritePosition);
|
||||
|
||||
public int BufferSize { get; }
|
||||
|
||||
private readonly SemaphoreSlim readWriteLock = new SemaphoreSlim(1, 1);
|
||||
|
||||
public PoopyBuffer(int size)
|
||||
{
|
||||
if (size <= 0)
|
||||
throw new ArgumentException();
|
||||
BufferSize = size;
|
||||
ringBuffer = new byte[size];
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] buffer, int count)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
if (buffer.Length < count)
|
||||
throw new ArgumentException();
|
||||
//Console.WriteLine($"***\nRead: {ReadPosition}\nWrite: {WritePosition}\nContentLength:{ContentLength}\n***");
|
||||
await readWriteLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
//read as much as you can if you're reading too much
|
||||
if (count > ContentLength)
|
||||
count = ContentLength;
|
||||
//if nothing to read, return 0
|
||||
if (WritePosition == ReadPosition)
|
||||
return 0;
|
||||
// if buffer is in the "normal" state, just read
|
||||
if (WritePosition > ReadPosition)
|
||||
{
|
||||
Buffer.BlockCopy(ringBuffer, ReadPosition, buffer, 0, count);
|
||||
ReadPosition += count;
|
||||
//Console.WriteLine($"Read only normally1 {count}[{ReadPosition - count} to {ReadPosition}]");
|
||||
return count;
|
||||
}
|
||||
//else ReadPos <Writepos
|
||||
// buffer is in its inverted state
|
||||
// A: if i can read as much as possible without hitting the buffer.length, read that
|
||||
|
||||
if (count + ReadPosition <= BufferSize)
|
||||
{
|
||||
Buffer.BlockCopy(ringBuffer, ReadPosition, buffer, 0, count);
|
||||
ReadPosition += count;
|
||||
//Console.WriteLine($"Read only normally2 {count}[{ReadPosition - count} to {ReadPosition}]");
|
||||
return count;
|
||||
}
|
||||
// B: if i can't read as much, read to the end,
|
||||
var readNormaly = BufferSize - ReadPosition;
|
||||
Buffer.BlockCopy(ringBuffer, ReadPosition, buffer, 0, readNormaly);
|
||||
|
||||
//Console.WriteLine($"Read normaly {count}[{ReadPosition} to {ReadPosition + readNormaly}]");
|
||||
//then read the remaining amount from the start
|
||||
|
||||
var readFromStart = count - readNormaly;
|
||||
Buffer.BlockCopy(ringBuffer, 0, buffer, readNormaly, readFromStart);
|
||||
//Console.WriteLine($"Read From start {readFromStart}[{0} to {readFromStart}]");
|
||||
ReadPosition = readFromStart;
|
||||
return count;
|
||||
}
|
||||
finally { readWriteLock.Release(); }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public async Task WriteAsync(byte[] buffer, int count, CancellationToken cancelToken)
|
||||
{
|
||||
if (count > buffer.Length)
|
||||
throw new ArgumentException();
|
||||
while (ContentLength + count > BufferSize)
|
||||
{
|
||||
await Task.Delay(20, cancelToken).ConfigureAwait(false);
|
||||
if (cancelToken.IsCancellationRequested)
|
||||
return;
|
||||
}
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
//the while above assures that i cannot write past readposition with my write, so i don't have to check
|
||||
// *unless its multithreaded or task is not awaited
|
||||
await readWriteLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
// if i can just write without hitting buffer.length, do it
|
||||
if (WritePosition + count < BufferSize)
|
||||
{
|
||||
Buffer.BlockCopy(buffer, 0, ringBuffer, WritePosition, count);
|
||||
WritePosition += count;
|
||||
//Console.WriteLine($"Wrote only normally {count}[{WritePosition - count} to {WritePosition}]");
|
||||
return;
|
||||
}
|
||||
// otherwise, i have to write to the end, then write the rest from the start
|
||||
|
||||
var wroteNormaly = BufferSize - WritePosition;
|
||||
Buffer.BlockCopy(buffer, 0, ringBuffer, WritePosition, wroteNormaly);
|
||||
|
||||
//Console.WriteLine($"Wrote normally {wroteNormaly}[{WritePosition} to {BufferSize}]");
|
||||
|
||||
var wroteFromStart = count - wroteNormaly;
|
||||
Buffer.BlockCopy(buffer, wroteNormaly, ringBuffer, 0, wroteFromStart);
|
||||
|
||||
//Console.WriteLine($"and from start {wroteFromStart} [0 to {wroteFromStart}");
|
||||
|
||||
WritePosition = wroteFromStart;
|
||||
}
|
||||
finally { readWriteLock.Release(); }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,900 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.DataModels;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Music.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Music
|
||||
{
|
||||
internal class MusicModule : DiscordModule
|
||||
{
|
||||
public static ConcurrentDictionary<Server, MusicPlayer> MusicPlayers = new ConcurrentDictionary<Server, MusicPlayer>();
|
||||
|
||||
public const string MusicDataPath = "data/musicdata";
|
||||
|
||||
public MusicModule()
|
||||
{
|
||||
//it can fail if its currenctly opened or doesn't exist. Either way i don't care
|
||||
try { Directory.Delete(MusicDataPath, true); } catch { }
|
||||
|
||||
Directory.CreateDirectory(MusicDataPath);
|
||||
}
|
||||
|
||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Music;
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
var client = NadekoBot.Client;
|
||||
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "next")
|
||||
.Alias(Prefix + "n")
|
||||
.Alias(Prefix + "skip")
|
||||
.Description($"Goes to the next song in the queue. You have to be in the same voice channel as the bot. | `{Prefix}n`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) return;
|
||||
if (musicPlayer.PlaybackVoiceChannel == imsg.Author.VoiceChannel)
|
||||
musicPlayer.Next();
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "stop")
|
||||
.Alias(Prefix + "s")
|
||||
.Description($"Stops the music and clears the playlist. Stays in the channel. | `{Prefix}s`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) return;
|
||||
if (imsg.Author.VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
{
|
||||
musicPlayer.Autoplay = false;
|
||||
musicPlayer.Stop();
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "destroy")
|
||||
.Alias(Prefix + "d")
|
||||
.Description("Completely stops the music and unbinds the bot from the channel. " +
|
||||
$"(may cause weird behaviour) | `{Prefix}d`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryRemove(e.Server, out musicPlayer)) return;
|
||||
if (imsg.Author.VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
musicPlayer.Destroy();
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "pause")
|
||||
.Alias(Prefix + "p")
|
||||
.Description($"Pauses or Unpauses the song. | `{Prefix}p`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.TogglePause();
|
||||
if (musicPlayer.Paused)
|
||||
await channel.SendMessageAsync("🎵`Music Player paused.`").ConfigureAwait(false);
|
||||
else
|
||||
await channel.SendMessageAsync("🎵`Music Player unpaused.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "queue")
|
||||
.Alias(Prefix + "q")
|
||||
.Alias(Prefix + "yq")
|
||||
.Description("Queue a song using keywords or a link. Bot will join your voice channel." +
|
||||
$"**You must be in a voice channel**. | `{Prefix}q Dream Of Venice`")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, e.GetArg("query")).ConfigureAwait(false);
|
||||
if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "soundcloudqueue")
|
||||
.Alias(Prefix + "sq")
|
||||
.Description("Queue a soundcloud song using keywords. Bot will join your voice channel." +
|
||||
$"**You must be in a voice channel**. | `{Prefix}sq Dream Of Venice`")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, e.GetArg("query"), musicType: MusicType.Soundcloud).ConfigureAwait(false);
|
||||
if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "listqueue")
|
||||
.Alias(Prefix + "lq")
|
||||
.Description($"Lists 15 currently queued songs per page. Default page is 1. | `{Prefix}lq` or `{Prefix}lq 2`")
|
||||
.Parameter("page", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
{
|
||||
await channel.SendMessageAsync("🎵 No active music player.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int page;
|
||||
if (!int.TryParse(e.GetArg("page"), out page) || page <= 0)
|
||||
{
|
||||
page = 1;
|
||||
}
|
||||
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
if (currentSong == null)
|
||||
return;
|
||||
var toSend = $"🎵`Now Playing` {currentSong.PrettyName} " + $"{currentSong.PrettyCurrentTime()}\n";
|
||||
if (musicPlayer.RepeatSong)
|
||||
toSend += "🔂";
|
||||
else if (musicPlayer.RepeatPlaylist)
|
||||
toSend += "🔁";
|
||||
toSend += $" **{musicPlayer.Playlist.Count}** `tracks currently queued. Showing page {page}` ";
|
||||
if (musicPlayer.MaxQueueSize != 0 && musicPlayer.Playlist.Count >= musicPlayer.MaxQueueSize)
|
||||
toSend += "**Song queue is full!**\n";
|
||||
else
|
||||
toSend += "\n";
|
||||
const int itemsPerPage = 15;
|
||||
int startAt = itemsPerPage * (page - 1);
|
||||
var number = 1 + startAt;
|
||||
await channel.SendMessageAsync(toSend + string.Join("\n", musicPlayer.Playlist.Skip(startAt).Take(15).Select(v => $"`{number++}.` {v.PrettyName}"))).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "nowplaying")
|
||||
.Alias(Prefix + "np")
|
||||
.Description($"Shows the song currently playing. | `{Prefix}np`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
if (currentSong == null)
|
||||
return;
|
||||
await channel.SendMessageAsync($"🎵`Now Playing` {currentSong.PrettyName} " +
|
||||
$"{currentSong.PrettyCurrentTime()}").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "volume")
|
||||
.Alias(Prefix + "vol")
|
||||
.Description($"Sets the music volume 0-100% | `{Prefix}vol 50`")
|
||||
.Parameter("val", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
var arg = e.GetArg("val");
|
||||
int volume;
|
||||
if (!int.TryParse(arg, out volume))
|
||||
{
|
||||
await channel.SendMessageAsync("Volume number invalid.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
volume = musicPlayer.SetVolume(volume);
|
||||
await channel.SendMessageAsync($"🎵 `Volume set to {volume}%`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "defvol")
|
||||
.Alias(Prefix + "dv")
|
||||
.Description("Sets the default music volume when music playback is started (0-100)." +
|
||||
$" Persists through restarts. | `{Prefix}dv 80`")
|
||||
.Parameter("val", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("val");
|
||||
float volume;
|
||||
if (!float.TryParse(arg, out volume) || volume < 0 || volume > 100)
|
||||
{
|
||||
await channel.SendMessageAsync("Volume number invalid.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var conf = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
conf.DefaultMusicVolume = volume / 100;
|
||||
await channel.SendMessageAsync($"🎵 `Default volume set to {volume}%`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "mute")
|
||||
.Alias(Prefix + "min")
|
||||
.Description($"Sets the music volume to 0% | `{Prefix}min`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.SetVolume(0);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "max")
|
||||
.Description($"Sets the music volume to 100%. | `{Prefix}max`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.SetVolume(100);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "half")
|
||||
.Description($"Sets the music volume to 50%. | `{Prefix}half`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
musicPlayer.SetVolume(50);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "shuffle")
|
||||
.Alias(Prefix + "sh")
|
||||
.Description($"Shuffles the current playlist. | `{Prefix}sh`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
if (musicPlayer.Playlist.Count < 2)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Not enough songs in order to perform the shuffle.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
musicPlayer.Shuffle();
|
||||
await channel.SendMessageAsync("🎵 `Songs shuffled.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "playlist")
|
||||
.Alias(Prefix + "pl")
|
||||
.Description($"Queues up to 500 songs from a youtube playlist specified by a link, or keywords. | `{Prefix}pl playlist link or name`")
|
||||
.Parameter("playlist", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("playlist");
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel?.Server != e.Server)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var plId = await SearchHelper.GetPlaylistIdByKeyword(arg).ConfigureAwait(false);
|
||||
if (plId == null)
|
||||
{
|
||||
await channel.SendMessageAsync("No search results for that query.");
|
||||
return;
|
||||
}
|
||||
var ids = await SearchHelper.GetVideoIDs(plId, 500).ConfigureAwait(false);
|
||||
if (ids == null || ids.Count == 0)
|
||||
{
|
||||
await channel.SendMessageAsync($"🎵 `Failed to find any songs.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var idArray = ids as string[] ?? ids.ToArray();
|
||||
var count = idArray.Length;
|
||||
var msg =
|
||||
await channel.SendMessageAsync($"🎵 `Attempting to queue {count} songs".SnPl(count) + "...`").ConfigureAwait(false);
|
||||
foreach (var id in idArray)
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, id, true).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{ break; }
|
||||
catch { }
|
||||
}
|
||||
await msg.Edit("🎵 `Playlist queue complete.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "soundcloudpl")
|
||||
.Alias(Prefix + "scpl")
|
||||
.Description($"Queue a soundcloud playlist using a link. | `{Prefix}scpl https://soundcloud.com/saratology/sets/symphony`")
|
||||
.Parameter("pl", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var pl = e.GetArg("pl")?.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(pl))
|
||||
return;
|
||||
|
||||
var scvids = JObject.Parse(await http.GetStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Creds.SoundCloudClientID}").ConfigureAwait(false))["tracks"].ToObject<SoundCloudVideo[]>();
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false);
|
||||
|
||||
MusicPlayer mp;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out mp))
|
||||
return;
|
||||
|
||||
foreach (var svideo in scvids.Skip(1))
|
||||
{
|
||||
try
|
||||
{
|
||||
mp.AddSong(new Song(new Classes.SongInfo
|
||||
{
|
||||
Title = svideo.FullName,
|
||||
Provider = "SoundCloud",
|
||||
Uri = svideo.StreamLink,
|
||||
ProviderType = MusicType.Normal,
|
||||
Query = svideo.TrackLink,
|
||||
}), imsg.Author.Username);
|
||||
}
|
||||
catch (PlaylistFullException) { break; }
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "localplaylst")
|
||||
.Alias(Prefix + "lopl")
|
||||
.Description($"Queues all songs from a directory. **Bot Owner Only!** | `{Prefix}lopl C:/music/classical`")
|
||||
.Parameter("directory", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("directory");
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var fileEnum = new DirectoryInfo(arg).GetFiles()
|
||||
.Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
|
||||
foreach (var file in fileEnum)
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
await channel.SendMessageAsync("🎵 `Directory queue complete.`").ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "radio").Alias(Prefix + "ra")
|
||||
.Description($"Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf (Usage Video: <https://streamable.com/al54>) | `{Prefix}ra radio link here`")
|
||||
.Parameter("radio_link", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (imsg.Author.VoiceChannel?.Server != e.Server)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, e.GetArg("radio_link"), musicType: MusicType.Radio).ConfigureAwait(false);
|
||||
if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "local")
|
||||
.Alias(Prefix + "lo")
|
||||
.Description($"Queues a local file by specifying a full path. **Bot Owner Only!** | `{Prefix}lo C:/music/mysong.mp3`")
|
||||
.Parameter("path", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("path");
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
await QueueSong(imsg.Author, e.Channel, imsg.Author.VoiceChannel, e.GetArg("path"), musicType: MusicType.Local).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "move")
|
||||
.Alias(Prefix + "mv")
|
||||
.Description($"Moves the bot to your voice channel. (works only if music is already playing) | `{Prefix}mv`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
var voiceChannel = imsg.Author.VoiceChannel;
|
||||
if (voiceChannel == null || voiceChannel.Server != e.Server || !MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
musicPlayer.MoveToVoiceChannel(voiceChannel);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "remove")
|
||||
.Alias(Prefix + "rm")
|
||||
.Description($"Remove a song by its # in the queue, or 'all' to remove whole queue. | `{Prefix}rm 5`")
|
||||
.Parameter("num", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("num");
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
if (arg?.ToLower() == "all")
|
||||
{
|
||||
musicPlayer.ClearQueue();
|
||||
await channel.SendMessageAsync($"🎵`Queue cleared!`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
int num;
|
||||
if (!int.TryParse(arg, out num))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (num <= 0 || num > musicPlayer.Playlist.Count)
|
||||
return;
|
||||
var song = (musicPlayer.Playlist as List<Song>)?[num - 1];
|
||||
musicPlayer.RemoveSongAt(num - 1);
|
||||
await channel.SendMessageAsync($"🎵**Track {song.PrettyName} at position `#{num}` has been removed.**").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
//var msRegex = new Regex(@"(?<n1>\d+)>(?<n2>\d+)", RegexOptions.Compiled);
|
||||
cgb.CreateCommand(Prefix + "movesong")
|
||||
.Alias(Prefix + "ms")
|
||||
.Description($"Moves a song from one position to another. | `{Prefix} ms` 5>3")
|
||||
.Parameter("fromto")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var fromto = e.GetArg("fromto").Trim();
|
||||
var fromtoArr = fromto.Split('>');
|
||||
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
var playlist = musicPlayer.Playlist as List<Song> ?? musicPlayer.Playlist.ToList();
|
||||
|
||||
if (fromtoArr.Length != 2 || !int.TryParse(fromtoArr[0], out n1) ||
|
||||
!int.TryParse(fromtoArr[1], out n2) || n1 < 1 || n2 < 1 || n1 == n2 ||
|
||||
n1 > playlist.Count || n2 > playlist.Count)
|
||||
{
|
||||
await channel.SendMessageAsync("`Invalid input.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var s = playlist[n1 - 1];
|
||||
playlist.Insert(n2 - 1, s);
|
||||
var nn1 = n2 < n1 ? n1 : n1 - 1;
|
||||
playlist.RemoveAt(nn1);
|
||||
|
||||
await channel.SendMessageAsync($"🎵`Moved` {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false);
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "setmaxqueue")
|
||||
.Alias(Prefix + "smq")
|
||||
.Description($"Sets a maximum queue size. Supply 0 or no argument to have no limit. | `{Prefix}smq` 50 or `{Prefix}smq`")
|
||||
.Parameter("size", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sizeStr = e.GetArg("size")?.Trim();
|
||||
uint size = 0;
|
||||
if (string.IsNullOrWhiteSpace(sizeStr) || !uint.TryParse(sizeStr, out size))
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
|
||||
musicPlayer.MaxQueueSize = size;
|
||||
await channel.SendMessageAsync($"🎵 `Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}`");
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cleanup")
|
||||
.Description($"Cleans up hanging voice connections. **Bot Owner Only!** | `{Prefix}cleanup`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(e =>
|
||||
{
|
||||
foreach (var kvp in MusicPlayers)
|
||||
{
|
||||
var songs = kvp.Value.Playlist;
|
||||
var currentSong = kvp.Value.CurrentSong;
|
||||
if (songs.Count == 0 && currentSong == null)
|
||||
{
|
||||
MusicPlayer throwaway;
|
||||
MusicPlayers.TryRemove(kvp.Key, out throwaway);
|
||||
throwaway.Destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "reptcursong")
|
||||
.Alias(Prefix + "rcs")
|
||||
.Description($"Toggles repeat of current song. | `{Prefix}rcs`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
if (currentSong == null)
|
||||
return;
|
||||
var currentValue = musicPlayer.ToggleRepeatSong();
|
||||
await channel.SendMessageAsync(currentValue ?
|
||||
$"🎵🔂`Repeating track:`{currentSong.PrettyName}" :
|
||||
$"🎵🔂`Current track repeat stopped.`")
|
||||
.ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "rpeatplaylst")
|
||||
.Alias(Prefix + "rpl")
|
||||
.Description($"Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue). | `{Prefix}rpl`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
var currentValue = musicPlayer.ToggleRepeatPlaylist();
|
||||
await channel.SendMessageAsync($"🎵🔁`Repeat playlist {(currentValue ? "enabled" : "disabled")}`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "save")
|
||||
.Description($"Saves a playlist under a certain name. Name must be no longer than 20 characters and mustn't contain dashes. | `{Prefix}save classical1`")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var name = e.GetArg("name")?.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name) ||
|
||||
name.Length > 20 ||
|
||||
name.Contains("-"))
|
||||
return;
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
|
||||
//to avoid concurrency issues
|
||||
var currentPlaylist = new List<Song>(musicPlayer.Playlist);
|
||||
var curSong = musicPlayer.CurrentSong;
|
||||
if (curSong != null)
|
||||
currentPlaylist.Insert(0, curSong);
|
||||
|
||||
if (!currentPlaylist.Any())
|
||||
return;
|
||||
|
||||
|
||||
var songInfos = currentPlaylist.Select(s => new DataModels.SongInfo
|
||||
{
|
||||
Provider = s.SongInfo.Provider,
|
||||
ProviderType = (int)s.SongInfo.ProviderType,
|
||||
Title = s.SongInfo.Title,
|
||||
Uri = s.SongInfo.Uri,
|
||||
Query = s.SongInfo.Query,
|
||||
}).ToList();
|
||||
|
||||
var playlist = new MusicPlaylist
|
||||
{
|
||||
CreatorId = (long)imsg.Author.Id,
|
||||
CreatorName = imsg.Author.Username,
|
||||
Name = name.ToLowerInvariant(),
|
||||
};
|
||||
DbHandler.Instance.SaveAll(songInfos);
|
||||
DbHandler.Instance.Save(playlist);
|
||||
DbHandler.Instance.Connection.InsertAll(songInfos.Select(s => new PlaylistSongInfo
|
||||
{
|
||||
PlaylistId = playlist.Id.Value,
|
||||
SongInfoId = s.Id.Value
|
||||
}), typeof(PlaylistSongInfo));
|
||||
|
||||
await channel.SendMessageAsync($"🎵 `Saved playlist as {name}-{playlist.Id}`").ConfigureAwait(false);
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "load")
|
||||
.Description($"Loads a playlist under a certain name. | `{Prefix}load classical-1`")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var voiceCh = imsg.Author.VoiceChannel;
|
||||
var textCh = e.Channel;
|
||||
if (voiceCh == null || voiceCh.Server != textCh.Server)
|
||||
{
|
||||
await textCh.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var name = e.GetArg("name")?.Trim().ToLowerInvariant();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return;
|
||||
|
||||
var parts = name.Split('-');
|
||||
if (parts.Length != 2)
|
||||
return;
|
||||
var playlistName = parts[0];
|
||||
|
||||
int playlistNumber;
|
||||
if (!int.TryParse(parts[1], out playlistNumber))
|
||||
return;
|
||||
|
||||
var playlist = DbHandler.Instance.FindOne<MusicPlaylist>(
|
||||
p => p.Id == playlistNumber);
|
||||
|
||||
if (playlist == null)
|
||||
{
|
||||
await channel.SendMessageAsync("Can't find playlist under that name.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var psis = DbHandler.Instance.FindAll<PlaylistSongInfo>(psi =>
|
||||
psi.PlaylistId == playlist.Id);
|
||||
|
||||
var songInfos = psis.Select(psi => DbHandler.Instance
|
||||
.FindOne<DataModels.SongInfo>(si => si.Id == psi.SongInfoId));
|
||||
|
||||
await channel.SendMessageAsync($"`Attempting to load {songInfos.Count()} songs`").ConfigureAwait(false);
|
||||
foreach (var si in songInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(imsg.Author, textCh, voiceCh, si.Query, true, (MusicType)si.ProviderType).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed QueueSong in load playlist. {ex}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "playlists")
|
||||
.Alias(Prefix + "pls")
|
||||
.Description($"Lists all playlists. Paginated. 20 per page. Default page is 0. |`{Prefix}pls 1`")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(e =>
|
||||
{
|
||||
int num = 0;
|
||||
int.TryParse(e.GetArg("num"), out num);
|
||||
if (num < 0)
|
||||
return;
|
||||
var result = DbHandler.Instance.GetPlaylistData(num);
|
||||
if (result.Count == 0)
|
||||
channel.SendMessageAsync($"`No saved playlists found on page {num}`").ConfigureAwait(false);
|
||||
else
|
||||
channel.SendMessageAsync($"```js\n--- List of saved playlists ---\n\n" + string.Join("\n", result.Select(r => $"'{r.Name}-{r.Id}' by {r.Creator} ({r.SongCnt} songs)")) + $"\n\n --- Page {num} ---```").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "deleteplaylist")
|
||||
.Alias(Prefix + "delpls")
|
||||
.Description($"Deletes a saved playlist. Only if you made it or if you are the bot owner. | `{Prefix}delpls animu-5`")
|
||||
.Parameter("pl", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var pl = e.GetArg("pl").Trim().Split('-')[1];
|
||||
if (string.IsNullOrWhiteSpace(pl))
|
||||
return;
|
||||
var plnum = int.Parse(pl);
|
||||
if (NadekoBot.IsOwner(imsg.Author.Id))
|
||||
DbHandler.Instance.Delete<MusicPlaylist>(plnum);
|
||||
else
|
||||
DbHandler.Instance.DeleteWhere<MusicPlaylist>(mp => mp.Id == plnum && (long)imsg.Author.Id == mp.CreatorId);
|
||||
await channel.SendMessageAsync("`Ok.` :ok:").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "goto")
|
||||
.Description($"Goes to a specific time in seconds in a song. | `{Prefix}goto 30`")
|
||||
.Parameter("time")
|
||||
.Do(async e =>
|
||||
{
|
||||
var skipToStr = e.GetArg("time")?.Trim();
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
if (imsg.Author.VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
||||
return;
|
||||
int skipTo;
|
||||
if (!int.TryParse(skipToStr, out skipTo) || skipTo < 0)
|
||||
return;
|
||||
|
||||
var currentSong = musicPlayer.CurrentSong;
|
||||
|
||||
if (currentSong == null)
|
||||
return;
|
||||
|
||||
//currentSong.PrintStatusMessage = false;
|
||||
var gotoSong = currentSong.Clone();
|
||||
gotoSong.SkipTo = skipTo;
|
||||
musicPlayer.AddSong(gotoSong, 0);
|
||||
musicPlayer.Next();
|
||||
|
||||
var minutes = (skipTo / 60).ToString();
|
||||
var seconds = (skipTo % 60).ToString();
|
||||
|
||||
if (minutes.Length == 1)
|
||||
minutes = "0" + minutes;
|
||||
if (seconds.Length == 1)
|
||||
seconds = "0" + seconds;
|
||||
|
||||
await channel.SendMessageAsync($"`Skipped to {minutes}:{seconds}`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "getlink")
|
||||
.Alias(Prefix + "gl")
|
||||
.Description($"Shows a link to the song in the queue by index, or the currently playing song by default. | `{Prefix}gl`")
|
||||
.Parameter("index", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
int index;
|
||||
string arg = e.GetArg("index")?.Trim();
|
||||
if (!string.IsNullOrEmpty(arg) && int.TryParse(arg, out index))
|
||||
{
|
||||
|
||||
var selSong = musicPlayer.Playlist.DefaultIfEmpty(null).ElementAtOrDefault(index - 1);
|
||||
if (selSong == null)
|
||||
{
|
||||
await channel.SendMessageAsync("Could not select song, likely wrong index");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await channel.SendMessageAsync($"🎶`Selected song {selSong.SongInfo.Title}:` <{selSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var curSong = musicPlayer.CurrentSong;
|
||||
if (curSong == null)
|
||||
return;
|
||||
await channel.SendMessageAsync($"🎶`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "autoplay")
|
||||
.Alias(Prefix + "ap")
|
||||
.Description($"Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty) | `{Prefix}ap`")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
|
||||
if (!musicPlayer.ToggleAutoplay())
|
||||
await channel.SendMessageAsync("🎶`Autoplay disabled.`").ConfigureAwait(false);
|
||||
else
|
||||
await channel.SendMessageAsync("🎶`Autoplay enabled.`").ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task QueueSong(User queuer, Channel textCh, Channel voiceCh, string query, bool silent = false, MusicType musicType = MusicType.Normal)
|
||||
{
|
||||
if (voiceCh == null || voiceCh.Server != textCh.Server)
|
||||
{
|
||||
if (!silent)
|
||||
await textCh.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining.").ConfigureAwait(false);
|
||||
throw new ArgumentNullException(nameof(voiceCh));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(query) || query.Length < 3)
|
||||
throw new ArgumentException("💢 Invalid query for queue song.", nameof(query));
|
||||
|
||||
var musicPlayer = MusicPlayers.GetOrAdd(textCh.Server, server =>
|
||||
{
|
||||
float vol = SpecificConfigurations.Default.Of(server.Id).DefaultMusicVolume;
|
||||
var mp = new MusicPlayer(voiceCh, vol);
|
||||
|
||||
|
||||
Message playingMessage = null;
|
||||
Message lastFinishedMessage = null;
|
||||
mp.OnCompleted += async (s, song) =>
|
||||
{
|
||||
if (song.PrintStatusMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (lastFinishedMessage != null)
|
||||
await lastFinishedMessage.Delete().ConfigureAwait(false);
|
||||
if (playingMessage != null)
|
||||
await playingMessage.Delete().ConfigureAwait(false);
|
||||
lastFinishedMessage = await textCh.SendMessageAsync($"🎵`Finished`{song.PrettyName}").ConfigureAwait(false);
|
||||
if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube")
|
||||
{
|
||||
await QueueSong(queuer.Server.CurrentUser, textCh, voiceCh, (await SearchHelper.GetRelatedVideoIds(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
mp.OnStarted += async (s, song) =>
|
||||
{
|
||||
if (song.PrintStatusMessage)
|
||||
{
|
||||
var sender = s as MusicPlayer;
|
||||
if (sender == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
var msgTxt = $"🎵`Playing`{song.PrettyName} `Vol: {(int)(sender.Volume * 100)}%`";
|
||||
playingMessage = await textCh.SendMessageAsync(msgTxt).ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
};
|
||||
return mp;
|
||||
});
|
||||
Song resolvedSong;
|
||||
try
|
||||
{
|
||||
musicPlayer.ThrowIfQueueFull();
|
||||
resolvedSong = await Song.ResolveSong(query, musicType).ConfigureAwait(false);
|
||||
|
||||
musicPlayer.AddSong(resolvedSong, queuer.Name);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
await textCh.SendMessageAsync($"🎵 `Queue is full at {musicPlayer.MaxQueueSize}/{musicPlayer.MaxQueueSize}.` ");
|
||||
throw;
|
||||
}
|
||||
if (!silent)
|
||||
{
|
||||
var queuedMessage = await textCh.SendMessageAsync($"🎵`Queued`{resolvedSong.PrettyName} **at** `#{musicPlayer.Playlist.Count + 1}`").ConfigureAwait(false);
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await queuedMessage.Delete().ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
}).ConfigureAwait(false);
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -62,8 +62,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var chanStr = e.GetArg("channel");
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var chanStr = channel;
|
||||
|
||||
if (chanStr?.ToLowerInvariant().Trim() != "all")
|
||||
{
|
||||
@ -101,7 +101,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
await PermissionsHandler.SetServerFilterInvitesPermission(e.Server, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for this server.")
|
||||
.ConfigureAwait(false);
|
||||
|
@ -60,8 +60,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var chanStr = e.GetArg("channel")?.ToLowerInvariant().Trim();
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var chanStr = channel?.ToLowerInvariant().Trim();
|
||||
|
||||
if (chanStr != "all")
|
||||
{
|
||||
@ -95,7 +95,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var word = e.GetArg("word");
|
||||
var word = word;
|
||||
if (string.IsNullOrWhiteSpace(word))
|
||||
return;
|
||||
await PermissionsHandler.AddFilteredWord(e.Server, word.ToLowerInvariant().Trim()).ConfigureAwait(false);
|
||||
@ -117,7 +117,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var word = e.GetArg("word");
|
||||
var word = word;
|
||||
if (string.IsNullOrWhiteSpace(word))
|
||||
return;
|
||||
await PermissionsHandler.RemoveFilteredWord(e.Server, word.ToLowerInvariant().Trim()).ConfigureAwait(false);
|
||||
@ -158,7 +158,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
await PermissionsHandler.SetServerWordPermission(e.Server, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Word filtering has been **{(state ? "enabled" : "disabled")}** on this server.")
|
||||
.ConfigureAwait(false);
|
||||
|
@ -37,13 +37,13 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.GetArg("role")))
|
||||
if (string.IsNullOrWhiteSpace(role))
|
||||
{
|
||||
await channel.SendMessageAsync($"Current permissions role is `{PermissionsHandler.GetServerPermissionsRoleName(e.Server)}`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var arg = e.GetArg("role");
|
||||
var arg = role;
|
||||
Discord.Role role = null;
|
||||
try
|
||||
{
|
||||
@ -65,7 +65,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("from_to")?.Trim();
|
||||
var arg = from_to?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('~'))
|
||||
return;
|
||||
var args = arg.Split('~').Select(a => a.Trim()).ToArray();
|
||||
@ -93,7 +93,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("from_to")?.Trim();
|
||||
var arg = from_to?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('~'))
|
||||
return;
|
||||
var args = arg.Split('~').Select(a => a.Trim()).ToArray();
|
||||
@ -121,7 +121,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("from_to")?.Trim();
|
||||
var arg = from_to?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('~'))
|
||||
return;
|
||||
var args = arg.Split('~').Select(a => a.Trim()).ToArray();
|
||||
@ -150,7 +150,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("arg", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("arg");
|
||||
var arg = arg;
|
||||
var val = PermissionHelper.ValidateBool(arg);
|
||||
await PermissionsHandler.SetVerbosity(e.Server, val).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Verbosity set to {val}.").ConfigureAwait(false);
|
||||
@ -173,7 +173,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("role");
|
||||
var arg = role;
|
||||
var role = e.Server.EveryoneRole;
|
||||
if (!string.IsNullOrWhiteSpace(arg))
|
||||
try
|
||||
@ -199,7 +199,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = e.GetArg("channel");
|
||||
var arg = channel;
|
||||
var channel = e.Channel;
|
||||
if (!string.IsNullOrWhiteSpace(arg))
|
||||
try
|
||||
@ -225,10 +225,10 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Do(async e =>
|
||||
{
|
||||
var user = imsg.Author;
|
||||
if (!string.IsNullOrWhiteSpace(e.GetArg("user")))
|
||||
if (!string.IsNullOrWhiteSpace(user))
|
||||
try
|
||||
{
|
||||
user = PermissionHelper.ValidateUser(e.Server, e.GetArg("user"));
|
||||
user = PermissionHelper.ValidateUser(e.Server, user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -251,8 +251,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
await PermissionsHandler.SetServerModulePermission(e.Server, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** on this server.").ConfigureAwait(false);
|
||||
@ -275,8 +275,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(e.GetArg("command"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
await PermissionsHandler.SetServerCommandPermission(e.Server, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** on this server.").ConfigureAwait(false);
|
||||
@ -300,10 +300,10 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
if (e.GetArg("role")?.ToLower() == "all")
|
||||
if (role?.ToLower() == "all")
|
||||
{
|
||||
foreach (var role in e.Server.Roles)
|
||||
{
|
||||
@ -313,7 +313,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
}
|
||||
else
|
||||
{
|
||||
var role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role"));
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
|
||||
await PermissionsHandler.SetRoleModulePermission(role, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for **{role.Name}** role.").ConfigureAwait(false);
|
||||
@ -338,10 +338,10 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(e.GetArg("command"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
if (e.GetArg("role")?.ToLower() == "all")
|
||||
if (role?.ToLower() == "all")
|
||||
{
|
||||
foreach (var role in e.Server.Roles)
|
||||
{
|
||||
@ -351,7 +351,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
}
|
||||
else
|
||||
{
|
||||
var role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role"));
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
|
||||
await PermissionsHandler.SetRoleCommandPermission(role, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for **{role.Name}** role.").ConfigureAwait(false);
|
||||
@ -376,9 +376,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var channelArg = e.GetArg("channel");
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var channelArg = channel;
|
||||
if (channelArg?.ToLower() == "all")
|
||||
{
|
||||
foreach (var channel in e.Server.TextChannels)
|
||||
@ -419,10 +419,10 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(e.GetArg("command"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
if (e.GetArg("channel")?.ToLower() == "all")
|
||||
if (channel?.ToLower() == "all")
|
||||
{
|
||||
foreach (var channel in e.Server.TextChannels)
|
||||
{
|
||||
@ -432,7 +432,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, e.GetArg("channel"));
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, channel);
|
||||
|
||||
await PermissionsHandler.SetChannelCommandPermission(channel, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for **{channel.Name}** channel.").ConfigureAwait(false);
|
||||
@ -457,9 +457,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var user = PermissionHelper.ValidateUser(e.Server, e.GetArg("user"));
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var user = PermissionHelper.ValidateUser(e.Server, user);
|
||||
|
||||
await PermissionsHandler.SetUserModulePermission(user, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for user **{user.Name}**.").ConfigureAwait(false);
|
||||
@ -483,9 +483,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(e.GetArg("command"));
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var user = PermissionHelper.ValidateUser(e.Server, e.GetArg("user"));
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var user = PermissionHelper.ValidateUser(e.Server, user);
|
||||
|
||||
await PermissionsHandler.SetUserCommandPermission(user, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for user **{user.Name}**.").ConfigureAwait(false);
|
||||
@ -507,7 +507,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
foreach (var module in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
@ -533,8 +533,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
@ -560,8 +560,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var chArg = e.GetArg("channel");
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var chArg = channel;
|
||||
var channel = string.IsNullOrWhiteSpace(chArg) ? e.Channel : PermissionHelper.ValidateChannel(e.Server, chArg);
|
||||
foreach (var module in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
@ -589,9 +589,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, e.GetArg("channel"));
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, channel);
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
await PermissionsHandler.SetChannelCommandPermission(channel, command.Text, state).ConfigureAwait(false);
|
||||
@ -616,8 +616,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role"));
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
foreach (var module in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
await PermissionsHandler.SetRoleModulePermission(role, module.Name, state).ConfigureAwait(false);
|
||||
@ -644,9 +644,9 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(e.GetArg("bool"));
|
||||
var module = PermissionHelper.ValidateModule(e.GetArg("module"));
|
||||
if (e.GetArg("role")?.ToLower() == "all")
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
if (role?.ToLower() == "all")
|
||||
{
|
||||
foreach (var role in e.Server.Roles)
|
||||
{
|
||||
@ -659,7 +659,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
}
|
||||
else
|
||||
{
|
||||
var role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role"));
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
@ -755,7 +755,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
var arg = e.GetArg("server")?.Trim();
|
||||
var arg = server?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
var server = NadekoBot.Client.Servers.FirstOrDefault(s => s.Id.ToString() == arg) ??
|
||||
@ -788,8 +788,8 @@ namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(e.GetArg("command"));
|
||||
var secsStr = e.GetArg("secs").Trim();
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var secsStr = secs.Trim();
|
||||
int secs;
|
||||
if (!int.TryParse(secsStr, out secs) || secs < 0 || secs > 3600)
|
||||
throw new ArgumentOutOfRangeException("secs", "Invalid second parameter. (Must be a number between 0 and 3600)");
|
||||
|
@ -5,9 +5,11 @@
|
||||
"copyright": "Kwoth",
|
||||
"buildOptions": {
|
||||
"emitEntryPoint": true,
|
||||
"allowUnsafe": true,
|
||||
"compile": {
|
||||
"exclude": [ "_Models", "Classes", "_Modules" ]
|
||||
}
|
||||
},
|
||||
"define": []
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
@ -21,15 +23,20 @@
|
||||
"Discord.Net.Commands": "1.0.0-dev-*",
|
||||
"System.Resources.ResourceWriter": "4.0.0-beta-22816",
|
||||
"Google.Apis.YouTube.v3": "1.15.0.582",
|
||||
"Google.Apis.Urlshortener.v1": "1.15.0.138",
|
||||
"System.Diagnostics.Contracts": "4.0.1",
|
||||
"NLog": "4.4.0-betaV15",
|
||||
"Discord.Net": "1.0.0-dev-*",
|
||||
"CoreCLR-NCalc": "2.1.0"
|
||||
"CoreCLR-NCalc": "2.1.0",
|
||||
"VideoLibrary": "1.3.4"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"imports": "dnxcore50"
|
||||
"imports": [
|
||||
"dnxcore50",
|
||||
"portable-net45+win8+wpa81"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,19 @@
|
||||
"lib/netstandard1.3/Google.Apis.Core.dll": {}
|
||||
}
|
||||
},
|
||||
"Google.Apis.Urlshortener.v1/1.15.0.138": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Google.Apis": "1.15.0",
|
||||
"Google.Apis.Auth": "1.15.0"
|
||||
},
|
||||
"compile": {
|
||||
"lib/netstandard1.3/Google.Apis.Urlshortener.v1.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard1.3/Google.Apis.Urlshortener.v1.dll": {}
|
||||
}
|
||||
},
|
||||
"Google.Apis.YouTube.v3/1.15.0.582": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@ -687,6 +700,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Collections.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Collections.Concurrent/4.0.12": {
|
||||
@ -891,6 +907,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Diagnostics.Debug.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.DiagnosticSource/4.0.0": {
|
||||
@ -1001,6 +1020,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.0/System.Diagnostics.Tools.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.TraceSource/4.0.0": {
|
||||
@ -1039,6 +1061,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.5/System.Diagnostics.Tracing.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Dynamic.Runtime/4.0.11": {
|
||||
@ -1076,6 +1101,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Globalization.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Globalization.Calendars/4.0.1": {
|
||||
@ -1125,6 +1153,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.5/System.IO.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.IO.Compression/4.1.0": {
|
||||
@ -1148,6 +1179,9 @@
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.IO.Compression.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wpa81/_._": {}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/unix/lib/netstandard1.3/System.IO.Compression.dll": {
|
||||
"assetType": "runtime",
|
||||
@ -1407,6 +1441,9 @@
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Net.Http.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wpa81/_._": {}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/unix/lib/netstandard1.6/System.Net.Http.dll": {
|
||||
"assetType": "runtime",
|
||||
@ -1460,6 +1497,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Net.Primitives.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Net.Requests/4.0.11": {
|
||||
@ -1482,6 +1522,9 @@
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Net.Requests.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/unix/lib/netstandard1.3/System.Net.Requests.dll": {
|
||||
"assetType": "runtime",
|
||||
@ -1692,6 +1735,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.5/System.Reflection.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Reflection.DispatchProxy/4.0.1": {
|
||||
@ -1770,6 +1816,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.0/System.Reflection.Extensions.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Reflection.Metadata/1.3.0": {
|
||||
@ -1807,6 +1856,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.0/System.Reflection.Primitives.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Reflection.TypeExtensions/4.1.0": {
|
||||
@ -1849,6 +1901,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.0/System.Resources.ResourceManager.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Resources.ResourceWriter/4.0.0-beta-22816": {
|
||||
@ -1872,6 +1927,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.5/System.Runtime.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp80+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Runtime.Extensions/4.1.0": {
|
||||
@ -1883,6 +1941,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.5/System.Runtime.Extensions.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Runtime.Handles/4.0.1": {
|
||||
@ -1908,6 +1969,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.5/System.Runtime.InteropServices.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Runtime.InteropServices.RuntimeInformation/4.0.0": {
|
||||
@ -2277,6 +2341,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Text.Encoding.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding.CodePages/4.0.1": {
|
||||
@ -2315,6 +2382,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Text.Encoding.Extensions.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Text.RegularExpressions/4.1.0": {
|
||||
@ -2378,6 +2448,9 @@
|
||||
},
|
||||
"compile": {
|
||||
"ref/netstandard1.3/System.Threading.Tasks.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win8+wp8+wpa81/_._": {}
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow/4.6.0": {
|
||||
@ -2609,6 +2682,15 @@
|
||||
"lib/netstandard1.3/_._": {}
|
||||
}
|
||||
},
|
||||
"VideoLibrary/1.3.4": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10/libvideo.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10/libvideo.dll": {}
|
||||
}
|
||||
},
|
||||
"Discord.Net/1.0.0-dev": {
|
||||
"type": "project",
|
||||
"framework": ".NETStandard,Version=v1.3",
|
||||
@ -2765,6 +2847,24 @@
|
||||
"lib/portable-net45+sl50+netcore45+wpa81+wp8/Google.Apis.Core.xml"
|
||||
]
|
||||
},
|
||||
"Google.Apis.Urlshortener.v1/1.15.0.138": {
|
||||
"sha512": "67USnpqrk8tWO3LAgaK9qDQT6h8A7i7eUIOKm+OISThZoQuHiLCn6dbg46FVb597LUh57AxClSSbhnweYcYC3Q==",
|
||||
"type": "package",
|
||||
"path": "Google.Apis.Urlshortener.v1/1.15.0.138",
|
||||
"files": [
|
||||
"Google.Apis.Urlshortener.v1.1.15.0.138.nupkg.sha512",
|
||||
"Google.Apis.Urlshortener.v1.nuspec",
|
||||
"lib/netstandard1.3/Google.Apis.Urlshortener.v1.dll",
|
||||
"lib/netstandard1.3/Google.Apis.Urlshortener.v1.pdb",
|
||||
"lib/netstandard1.3/Google.Apis.Urlshortener.v1.xml",
|
||||
"lib/portable-net40+sl50+netcore45+wpa81+wp8/Google.Apis.Urlshortener.v1.dll",
|
||||
"lib/portable-net40+sl50+netcore45+wpa81+wp8/Google.Apis.Urlshortener.v1.pdb",
|
||||
"lib/portable-net40+sl50+netcore45+wpa81+wp8/Google.Apis.Urlshortener.v1.xml",
|
||||
"lib/portable-net45+netcore45+wpa81+wp8/Google.Apis.Urlshortener.v1.dll",
|
||||
"lib/portable-net45+netcore45+wpa81+wp8/Google.Apis.Urlshortener.v1.pdb",
|
||||
"lib/portable-net45+netcore45+wpa81+wp8/Google.Apis.Urlshortener.v1.xml"
|
||||
]
|
||||
},
|
||||
"Google.Apis.YouTube.v3/1.15.0.582": {
|
||||
"sha512": "isR8FdI417PKLgLlNdOVDhduO+8yqPJ+vfID1Zx0MjAa/y3q655Plk2E/KNmsrjvXkqSSWwDCQHPz/Q1fat4tA==",
|
||||
"type": "package",
|
||||
@ -8104,6 +8204,16 @@
|
||||
"ref/xamarinwatchos10/_._"
|
||||
]
|
||||
},
|
||||
"VideoLibrary/1.3.4": {
|
||||
"sha512": "HZ2RAE9xx/sjJGnwm8etawoJXYluaYGas4bAFpE14S62NFodNKzUf7Cm9TQ+JFJxAdY+1g1FEKk1b6FPSv9aMg==",
|
||||
"type": "package",
|
||||
"path": "VideoLibrary/1.3.4",
|
||||
"files": [
|
||||
"VideoLibrary.1.3.4.nupkg.sha512",
|
||||
"VideoLibrary.nuspec",
|
||||
"lib/portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10/libvideo.dll"
|
||||
]
|
||||
},
|
||||
"Discord.Net/1.0.0-dev": {
|
||||
"type": "project",
|
||||
"path": "../../discord.net/src/Discord.Net/project.json",
|
||||
@ -8120,6 +8230,7 @@
|
||||
"CoreCLR-NCalc >= 2.1.0",
|
||||
"Discord.Net >= 1.0.0-dev-*",
|
||||
"Discord.Net.Commands >= 1.0.0-dev-*",
|
||||
"Google.Apis.Urlshortener.v1 >= 1.15.0.138",
|
||||
"Google.Apis.YouTube.v3 >= 1.15.0.582",
|
||||
"Microsoft.Extensions.DependencyInjection >= 1.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions >= 1.0.0",
|
||||
@ -8128,7 +8239,8 @@
|
||||
"NLog >= 4.4.0-betaV15",
|
||||
"Newtonsoft.Json >= 9.0.1",
|
||||
"System.Diagnostics.Contracts >= 4.0.1",
|
||||
"System.Resources.ResourceWriter >= 4.0.0-beta-22816"
|
||||
"System.Resources.ResourceWriter >= 4.0.0-beta-22816",
|
||||
"VideoLibrary >= 1.3.4"
|
||||
],
|
||||
".NETCoreApp,Version=v1.0": []
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user