Replacements. Converted music, not tested.

This commit is contained in:
Kwoth
2016-08-22 00:37:39 +02:00
parent 4317e97113
commit c218d1da96
39 changed files with 1027 additions and 1191 deletions

View File

@@ -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,7 +492,7 @@ 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(img))
// return;
@@ -511,7 +511,7 @@ 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 ?? "";
@@ -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,7 +569,7 @@ namespace NadekoBot.Modules.Administration
//[RequireContext(ContextType.Guild)]
//public async Task Donadd(IMessage imsg, IUser donator, int amount)
//{
// var channel = imsg.Channel as ITextChannel;
// var channel = (ITextChannel)imsg.Channel;
// var donator = channel.Guild.FindUsers(donator).FirstOrDefault();
// var amount = int.Parse(amount);
// if (donator == null) return;
@@ -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);

View File

@@ -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);

View File

@@ -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))

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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();

View File

@@ -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))

View File

@@ -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;

View File

@@ -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))

View File

@@ -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.

View File

@@ -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

View File

@@ -0,0 +1,281 @@
using Discord;
using Discord.Audio;
using NadekoBot.Extensions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Music.Classes
{
public enum MusicType
{
Radio,
Normal,
Local,
Soundcloud
}
public enum StreamState
{
Resolving,
Queued,
Playing,
Completed
}
public class MusicPlayer
{
private IAudioClient audioClient { get; set; }
private readonly List<Song> playlist = new List<Song>();
public IReadOnlyCollection<Song> Playlist => playlist;
public Song CurrentSong { get; private set; }
public CancellationTokenSource SongCancelSource { get; private set; }
private CancellationToken cancelToken { get; set; }
public bool Paused { get; set; }
public float Volume { get; private set; }
public event EventHandler<Song> OnCompleted = delegate { };
public event EventHandler<Song> OnStarted = delegate { };
public IVoiceChannel PlaybackVoiceChannel { get; private set; }
private bool Destroyed { get; set; } = false;
public bool RepeatSong { get; private set; } = false;
public bool RepeatPlaylist { get; private set; } = false;
public bool Autoplay { get; set; } = false;
public uint MaxQueueSize { get; set; } = 0;
private ConcurrentQueue<Action> actionQueue { get; set; } = new ConcurrentQueue<Action>();
public MusicPlayer(IVoiceChannel startingVoiceChannel, float? defaultVolume)
{
if (startingVoiceChannel == null)
throw new ArgumentNullException(nameof(startingVoiceChannel));
Volume = defaultVolume ?? 1.0f;
PlaybackVoiceChannel = startingVoiceChannel;
SongCancelSource = new CancellationTokenSource();
cancelToken = SongCancelSource.Token;
Task.Run(async () =>
{
try
{
while (!Destroyed)
{
try
{
Action action;
if (actionQueue.TryDequeue(out action))
{
action();
}
}
finally
{
await Task.Delay(100).ConfigureAwait(false);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Action queue crashed");
Console.WriteLine(ex);
}
}).ConfigureAwait(false);
var t = new Thread(new ThreadStart(async () =>
{
try
{
while (!Destroyed)
{
try
{
if (audioClient?.ConnectionState != ConnectionState.Connected)
{
audioClient = await PlaybackVoiceChannel.ConnectAsync().ConfigureAwait(false);
continue;
}
CurrentSong = GetNextSong();
RemoveSongAt(0);
if (CurrentSong == null)
continue;
OnStarted(this, CurrentSong);
await CurrentSong.Play(audioClient, cancelToken);
OnCompleted(this, CurrentSong);
if (RepeatPlaylist)
AddSong(CurrentSong, CurrentSong.QueuerName);
if (RepeatSong)
AddSong(CurrentSong, 0);
}
finally
{
if (!cancelToken.IsCancellationRequested)
{
SongCancelSource.Cancel();
}
SongCancelSource = new CancellationTokenSource();
cancelToken = SongCancelSource.Token;
CurrentSong = null;
await Task.Delay(300).ConfigureAwait(false);
}
}
}
catch (Exception ex) {
Console.WriteLine("Music thread crashed.");
Console.WriteLine(ex);
}
}));
t.Start();
}
public void Next()
{
actionQueue.Enqueue(() =>
{
Paused = false;
SongCancelSource.Cancel();
});
}
public void Stop()
{
actionQueue.Enqueue(() =>
{
RepeatPlaylist = false;
RepeatSong = false;
playlist.Clear();
if (!SongCancelSource.IsCancellationRequested)
SongCancelSource.Cancel();
});
}
public void TogglePause() => Paused = !Paused;
public int SetVolume(int volume)
{
if (volume < 0)
volume = 0;
if (volume > 100)
volume = 100;
Volume = volume / 100.0f;
return volume;
}
private Song GetNextSong() =>
playlist.FirstOrDefault();
public void Shuffle()
{
actionQueue.Enqueue(() =>
{
playlist.Shuffle();
});
}
public void AddSong(Song s, string username)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
ThrowIfQueueFull();
actionQueue.Enqueue(() =>
{
s.MusicPlayer = this;
s.QueuerName = username.TrimTo(10);
playlist.Add(s);
});
}
public void AddSong(Song s, int index)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
actionQueue.Enqueue(() =>
{
playlist.Insert(index, s);
});
}
public void RemoveSong(Song s)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
actionQueue.Enqueue(() =>
{
playlist.Remove(s);
});
}
public void RemoveSongAt(int index)
{
actionQueue.Enqueue(() =>
{
if (index < 0 || index >= playlist.Count)
return;
playlist.RemoveAt(index);
});
}
internal void ClearQueue()
{
actionQueue.Enqueue(() =>
{
playlist.Clear();
});
}
public void Destroy()
{
actionQueue.Enqueue(async () =>
{
RepeatPlaylist = false;
RepeatSong = false;
Destroyed = true;
playlist.Clear();
if (!SongCancelSource.IsCancellationRequested)
SongCancelSource.Cancel();
await audioClient.DisconnectAsync();
});
}
internal Task MoveToVoiceChannel(IVoiceChannel voiceChannel)
{
if (audioClient?.ConnectionState != ConnectionState.Connected)
throw new InvalidOperationException("Can't move while bot is not connected to voice channel.");
PlaybackVoiceChannel = voiceChannel;
return PlaybackVoiceChannel.ConnectAsync();
}
internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong;
internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist;
internal bool ToggleAutoplay() => this.Autoplay = !this.Autoplay;
internal void ThrowIfQueueFull()
{
if (MaxQueueSize == 0)
return;
if (playlist.Count >= MaxQueueSize)
throw new PlaylistFullException();
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace NadekoBot.Modules.Music.Classes
{
class PlaylistFullException : Exception
{
public PlaylistFullException(string message) : base(message)
{
}
public PlaylistFullException() : base("Queue is full.") { }
}
}

View File

@@ -0,0 +1,422 @@
using Discord.Audio;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using VideoLibrary;
namespace NadekoBot.Modules.Music.Classes
{
public class SongInfo
{
public string Provider { get; internal set; }
public MusicType ProviderType { get; internal set; }
/// <summary>
/// Will be set only if the providertype is normal
/// </summary>
public string Query { get; internal set; }
public string Title { get; internal set; }
public string Uri { get; internal set; }
}
public class Song
{
public StreamState State { get; internal set; }
public string PrettyName =>
$"**【 {SongInfo.Title.TrimTo(55)} 】**`{(SongInfo.Provider ?? "-")}` `by {QueuerName}`";
public SongInfo SongInfo { get; }
public string QueuerName { get; set; }
public MusicPlayer MusicPlayer { get; set; }
public string PrettyCurrentTime()
{
var time = TimeSpan.FromSeconds(bytesSent / 3840 / 50);
return $"【{(int)time.TotalMinutes}m {time.Seconds}s】";
}
private ulong bytesSent { get; set; } = 0;
public bool PrintStatusMessage { get; set; } = true;
private int skipTo = 0;
public int SkipTo {
get { return SkipTo; }
set {
skipTo = value;
bytesSent = (ulong)skipTo * 3840 * 50;
}
}
public Song(SongInfo songInfo)
{
this.SongInfo = songInfo;
}
public Song Clone()
{
var s = new Song(SongInfo);
s.MusicPlayer = MusicPlayer;
s.State = StreamState.Queued;
return s;
}
public Song SetMusicPlayer(MusicPlayer mp)
{
this.MusicPlayer = mp;
return this;
}
internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
{
var filename = Path.Combine(MusicModule.MusicDataPath, DateTime.Now.UnixTimestamp().ToString());
SongBuffer sb = new SongBuffer(filename, SongInfo, skipTo);
var bufferTask = sb.BufferSong(cancelToken).ConfigureAwait(false);
var inStream = new FileStream(sb.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); ;
bytesSent = 0;
try
{
var attempt = 0;
var prebufferingTask = CheckPrebufferingAsync(inStream, sb, cancelToken);
var sw = new Stopwatch();
sw.Start();
var t = await Task.WhenAny(prebufferingTask, Task.Delay(5000, cancelToken));
if (t != prebufferingTask)
{
Console.WriteLine("Prebuffering timed out or canceled. Cannot get any data from the stream.");
return;
}
else if(prebufferingTask.IsCanceled)
{
Console.WriteLine("Prebuffering timed out. Cannot get any data from the stream.");
return;
}
sw.Stop();
Console.WriteLine("Prebuffering successfully completed in "+ sw.Elapsed);
var outStream = voiceClient.CreatePCMStream(3840);
const int blockSize = 3840;
byte[] buffer = new byte[blockSize];
while (!cancelToken.IsCancellationRequested)
{
//Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
var read = inStream.Read(buffer, 0, buffer.Length);
//await inStream.CopyToAsync(voiceClient.OutputStream);
unchecked
{
bytesSent += (ulong)read;
}
if (read < blockSize)
{
if (sb.IsNextFileReady())
{
inStream.Dispose();
inStream = new FileStream(sb.GetNextFile(), FileMode.Open, FileAccess.Read, FileShare.Write);
read += inStream.Read(buffer, read, buffer.Length - read);
attempt = 0;
}
if (read == 0)
{
if (sb.BufferingCompleted)
break;
if (attempt++ == 20)
{
MusicPlayer.SongCancelSource.Cancel();
break;
}
else
await Task.Delay(100, cancelToken).ConfigureAwait(false);
}
else
attempt = 0;
}
else
attempt = 0;
while (this.MusicPlayer.Paused)
await Task.Delay(200, cancelToken).ConfigureAwait(false);
buffer = AdjustVolume(buffer, MusicPlayer.Volume);
await outStream.WriteAsync(buffer, 0, read);
}
}
finally
{
await bufferTask;
if(inStream != null)
inStream.Dispose();
Console.WriteLine("l");
sb.CleanFiles();
}
}
private async Task CheckPrebufferingAsync(Stream inStream, SongBuffer sb, CancellationToken cancelToken)
{
while (!sb.BufferingCompleted && inStream.Length < 2.MiB())
{
await Task.Delay(100, cancelToken);
}
Console.WriteLine("Buffering successfull");
}
/*
//stackoverflow ftw
private static byte[] AdjustVolume(byte[] audioSamples, float volume)
{
if (Math.Abs(volume - 1.0f) < 0.01f)
return audioSamples;
var array = new byte[audioSamples.Length];
for (var i = 0; i < array.Length; i += 2)
{
// convert byte pair to int
short buf1 = audioSamples[i + 1];
short buf2 = audioSamples[i];
buf1 = (short)((buf1 & 0xff) << 8);
buf2 = (short)(buf2 & 0xff);
var res = (short)(buf1 | buf2);
res = (short)(res * volume);
// convert back
array[i] = (byte)res;
array[i + 1] = (byte)(res >> 8);
}
return array;
}
*/
//aidiakapi ftw
public unsafe static byte[] AdjustVolume(byte[] audioSamples, float volume)
{
Contract.Requires(audioSamples != null);
Contract.Requires(audioSamples.Length % 2 == 0);
Contract.Requires(volume >= 0f && volume <= 1f);
Contract.Assert(BitConverter.IsLittleEndian);
if (Math.Abs(volume - 1f) < 0.0001f) return audioSamples;
// 16-bit precision for the multiplication
int volumeFixed = (int)Math.Round(volume * 65536d);
int count = audioSamples.Length / 2;
fixed (byte* srcBytes = audioSamples)
{
short* src = (short*)srcBytes;
for (int i = count; i != 0; i--, src++)
*src = (short)(((*src) * volumeFixed) >> 16);
}
return audioSamples;
}
public static async Task<Song> ResolveSong(string query, MusicType musicType = MusicType.Normal)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
if (musicType != MusicType.Local && IsRadioLink(query))
{
musicType = MusicType.Radio;
query = await HandleStreamContainers(query).ConfigureAwait(false) ?? query;
}
try
{
switch (musicType)
{
case MusicType.Local:
return new Song(new SongInfo
{
Uri = "\"" + Path.GetFullPath(query) + "\"",
Title = Path.GetFileNameWithoutExtension(query),
Provider = "Local File",
ProviderType = musicType,
Query = query,
});
case MusicType.Radio:
return new Song(new SongInfo
{
Uri = query,
Title = $"{query}",
Provider = "Radio Stream",
ProviderType = musicType,
Query = query
});
}
if (SoundCloud.Default.IsSoundCloudLink(query))
{
var svideo = await SoundCloud.Default.ResolveVideoAsync(query).ConfigureAwait(false);
return new Song(new SongInfo
{
Title = svideo.FullName,
Provider = "SoundCloud",
Uri = svideo.StreamLink,
ProviderType = musicType,
Query = svideo.TrackLink,
});
}
if (musicType == MusicType.Soundcloud)
{
var svideo = await SoundCloud.Default.GetVideoByQueryAsync(query).ConfigureAwait(false);
return new Song(new SongInfo
{
Title = svideo.FullName,
Provider = "SoundCloud",
Uri = svideo.StreamLink,
ProviderType = MusicType.Normal,
Query = svideo.TrackLink,
});
}
var link = (await NadekoBot.Google.GetVideosByKeywordsAsync(query).ConfigureAwait(false)).FirstOrDefault();
if (string.IsNullOrWhiteSpace(link))
throw new OperationCanceledException("Not a valid youtube query.");
var allVideos = await Task.Run(async () => await YouTube.Default.GetAllVideosAsync(link).ConfigureAwait(false)).ConfigureAwait(false);
var videos = allVideos.Where(v => v.AdaptiveKind == AdaptiveKind.Audio);
var video = videos
.Where(v => v.AudioBitrate < 192)
.OrderByDescending(v => v.AudioBitrate)
.FirstOrDefault();
if (video == null) // do something with this error
throw new Exception("Could not load any video elements based on the query.");
var m = Regex.Match(query, @"\?t=(?<t>\d*)");
int gotoTime = 0;
if (m.Captures.Count > 0)
int.TryParse(m.Groups["t"].ToString(), out gotoTime);
var song = new Song(new SongInfo
{
Title = video.Title.Substring(0, video.Title.Length - 10), // removing trailing "- You Tube"
Provider = "YouTube",
Uri = video.Uri,
Query = link,
ProviderType = musicType,
});
song.SkipTo = gotoTime;
return song;
}
catch (Exception ex)
{
Console.WriteLine($"Failed resolving the link.{ex.Message}");
return null;
}
}
private static async Task<string> HandleStreamContainers(string query)
{
string file = null;
try
{
using (var http = new HttpClient())
{
file = await http.GetStringAsync(query).ConfigureAwait(false);
}
}
catch
{
return query;
}
if (query.Contains(".pls"))
{
//File1=http://armitunes.com:8000/
//Regex.Match(query)
try
{
var m = Regex.Match(file, "File1=(?<url>.*?)\\n");
var res = m.Groups["url"]?.ToString();
return res?.Trim();
}
catch
{
Console.WriteLine($"Failed reading .pls:\n{file}");
return null;
}
}
if (query.Contains(".m3u"))
{
/*
# This is a comment
C:\xxx4xx\xxxxxx3x\xx2xxxx\xx.mp3
C:\xxx5xx\x6xxxxxx\x7xxxxx\xx.mp3
*/
try
{
var m = Regex.Match(file, "(?<url>^[^#].*)", RegexOptions.Multiline);
var res = m.Groups["url"]?.ToString();
return res?.Trim();
}
catch
{
Console.WriteLine($"Failed reading .m3u:\n{file}");
return null;
}
}
if (query.Contains(".asx"))
{
//<ref href="http://armitunes.com:8000"/>
try
{
var m = Regex.Match(file, "<ref href=\"(?<url>.*?)\"");
var res = m.Groups["url"]?.ToString();
return res?.Trim();
}
catch
{
Console.WriteLine($"Failed reading .asx:\n{file}");
return null;
}
}
if (query.Contains(".xspf"))
{
/*
<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
<track><location>file:///mp3s/song_1.mp3</location></track>
*/
try
{
var m = Regex.Match(file, "<location>(?<url>.*?)</location>");
var res = m.Groups["url"]?.ToString();
return res?.Trim();
}
catch
{
Console.WriteLine($"Failed reading .xspf:\n{file}");
return null;
}
}
return query;
}
private static bool IsRadioLink(string query) =>
(query.StartsWith("http") ||
query.StartsWith("ww"))
&&
(query.Contains(".pls") ||
query.Contains(".m3u") ||
query.Contains(".asx") ||
query.Contains(".xspf"));
}
}

View File

@@ -0,0 +1,159 @@
using NadekoBot.Extensions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Music.Classes
{
/// <summary>
/// Create a buffer for a song file. It will create multiples files to ensure, that radio don't fill up disk space.
/// It also help for large music by deleting files that are already seen.
/// </summary>
class SongBuffer
{
public SongBuffer(string basename, SongInfo songInfo, int skipTo)
{
Basename = basename;
SongInfo = songInfo;
SkipTo = skipTo;
}
private string Basename;
private SongInfo SongInfo;
private int SkipTo;
private static int MAX_FILE_SIZE = 20.MiB();
private long FileNumber = -1;
private long NextFileToRead = 0;
public bool BufferingCompleted { get; private set;} = false;
private ulong CurrentBufferSize = 0;
public Task BufferSong(CancellationToken cancelToken) =>
Task.Factory.StartNew(async () =>
{
Process p = null;
FileStream outStream = null;
try
{
p = Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-ss {SkipTo} -i {SongInfo.Uri} -f s16le -ar 48000 -ac 2 pipe:1 -loglevel quiet",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = false,
CreateNoWindow = true,
});
byte[] buffer = new byte[81920];
int currentFileSize = 0;
ulong prebufferSize = 100ul.MiB();
outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read);
while (!p.HasExited) //Also fix low bandwidth
{
int bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false);
if (currentFileSize >= MAX_FILE_SIZE)
{
try
{
outStream.Dispose();
}catch { }
outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read);
currentFileSize = bytesRead;
}
else
{
currentFileSize += bytesRead;
}
CurrentBufferSize += Convert.ToUInt64(bytesRead);
await outStream.WriteAsync(buffer, 0, bytesRead, cancelToken).ConfigureAwait(false);
while (CurrentBufferSize > prebufferSize)
await Task.Delay(100, cancelToken);
}
BufferingCompleted = true;
}
catch (System.ComponentModel.Win32Exception)
{
var oldclr = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(@"You have not properly installed or configured FFMPEG.
Please install and configure FFMPEG to play music.
Check the guides for your platform on how to setup ffmpeg correctly:
Windows Guide: https://goo.gl/SCv72y
Linux Guide: https://goo.gl/rRhjCp");
Console.ForegroundColor = oldclr;
}
catch (Exception ex)
{
Console.WriteLine($"Buffering stopped: {ex.Message}");
}
finally
{
if(outStream != null)
outStream.Dispose();
Console.WriteLine($"Buffering done.");
if (p != null)
{
try
{
p.Kill();
}
catch { }
p.Dispose();
}
}
}, TaskCreationOptions.LongRunning);
/// <summary>
/// Return the next file to read, and delete the old one
/// </summary>
/// <returns>Name of the file to read</returns>
public string GetNextFile()
{
string filename = Basename + "-" + NextFileToRead;
if (NextFileToRead != 0)
{
try
{
CurrentBufferSize -= Convert.ToUInt64(new FileInfo(Basename + "-" + (NextFileToRead - 1)).Length);
File.Delete(Basename + "-" + (NextFileToRead - 1));
}
catch { }
}
NextFileToRead++;
return filename;
}
public bool IsNextFileReady()
{
return NextFileToRead <= FileNumber;
}
public void CleanFiles()
{
for (long i = NextFileToRead - 1 ; i <= FileNumber; i++)
{
try
{
File.Delete(Basename + "-" + i);
}
catch { }
}
}
}
}

View File

@@ -0,0 +1,141 @@
using NadekoBot.Classes;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Music.Classes
{
public class SoundCloud
{
private static readonly SoundCloud _instance = new SoundCloud();
public static SoundCloud Default => _instance;
static SoundCloud() { }
public SoundCloud() { }
public async Task<SoundCloudVideo> ResolveVideoAsync(string url)
{
if (string.IsNullOrWhiteSpace(url))
throw new ArgumentNullException(nameof(url));
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.SoundCloudClientId))
throw new ArgumentNullException(nameof(NadekoBot.Credentials.SoundCloudClientId));
string response = "";
using (var http = new HttpClient())
{
response = await http.GetStringAsync($"http://api.soundcloud.com/resolve?url={url}&client_id={NadekoBot.Credentials.SoundCloudClientId}").ConfigureAwait(false);
}
var responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject<SoundCloudVideo>(response);
if (responseObj?.Kind != "track")
throw new InvalidOperationException("Url is either not a track, or it doesn't exist.");
return responseObj;
}
public bool IsSoundCloudLink(string url) =>
System.Text.RegularExpressions.Regex.IsMatch(url, "(.*)(soundcloud.com|snd.sc)(.*)");
internal async Task<SoundCloudVideo> GetVideoByQueryAsync(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.SoundCloudClientId))
throw new ArgumentNullException(nameof(NadekoBot.Credentials.SoundCloudClientId));
var response = "";
using (var http = new HttpClient())
{
await http.GetStringAsync($"http://api.soundcloud.com/tracks?q={Uri.EscapeDataString(query)}&client_id={NadekoBot.Credentials.SoundCloudClientId}").ConfigureAwait(false);
}
var responseObj = JsonConvert.DeserializeObject<SoundCloudVideo[]>(response).Where(s => s.Streamable).FirstOrDefault();
if (responseObj?.Kind != "track")
throw new InvalidOperationException("Query yielded no results.");
return responseObj;
}
}
public class SoundCloudVideo
{
public string Kind { get; set; } = "";
public long Id { get; set; } = 0;
public SoundCloudUser User { get; set; } = new SoundCloudUser();
public string Title { get; set; } = "";
[JsonIgnore]
public string FullName => User.Name + " - " + Title;
public bool Streamable { get; set; } = false;
[JsonProperty("permalink_url")]
public string TrackLink { get; set; } = "";
[JsonIgnore]
public string StreamLink => $"https://api.soundcloud.com/tracks/{Id}/stream?client_id={NadekoBot.Credentials.SoundCloudClientId}";
}
public class SoundCloudUser
{
[Newtonsoft.Json.JsonProperty("username")]
public string Name { get; set; }
}
/*
{"kind":"track",
"id":238888167,
"created_at":"2015/12/24 01:04:52 +0000",
"user_id":43141975,
"duration":120852,
"commentable":true,
"state":"finished",
"original_content_size":4834829,
"last_modified":"2015/12/24 01:17:59 +0000",
"sharing":"public",
"tag_list":"Funky",
"permalink":"18-fd",
"streamable":true,
"embeddable_by":"all",
"downloadable":false,
"purchase_url":null,
"label_id":null,
"purchase_title":null,
"genre":"Disco",
"title":"18 Ж",
"description":"",
"label_name":null,
"release":null,
"track_type":null,
"key_signature":null,
"isrc":null,
"video_url":null,
"bpm":null,
"release_year":null,
"release_month":null,
"release_day":null,
"original_format":"mp3",
"license":"all-rights-reserved",
"uri":"https://api.soundcloud.com/tracks/238888167",
"user":{
"id":43141975,
"kind":"user",
"permalink":"mrb00gi",
"username":"Mrb00gi",
"last_modified":"2015/12/01 16:06:57 +0000",
"uri":"https://api.soundcloud.com/users/43141975",
"permalink_url":"http://soundcloud.com/mrb00gi",
"avatar_url":"https://a1.sndcdn.com/images/default_avatar_large.png"
},
"permalink_url":"http://soundcloud.com/mrb00gi/18-fd",
"artwork_url":null,
"waveform_url":"https://w1.sndcdn.com/gsdLfvEW1cUK_m.png",
"stream_url":"https://api.soundcloud.com/tracks/238888167/stream",
"playback_count":7,
"download_count":0,
"favoritings_count":1,
"comment_count":0,
"attachments_uri":"https://api.soundcloud.com/tracks/238888167/attachments"}
*/
}

View 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 MusicModule : DiscordModule
{
public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers = new ConcurrentDictionary<ulong, MusicPlayer>();
public const string MusicDataPath = "data/musicdata";
private IGoogleApiService _google;
public MusicModule(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
}
}
}
}

View File

@@ -26,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() ?? "";
@@ -45,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);
@@ -59,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);
@@ -73,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);
@@ -87,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);
@@ -101,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);
}
@@ -110,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;
@@ -130,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
{

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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(' ', '-'));

View File

@@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches
[RequireContext(ContextType.Guild)]
public async Task Osu(IMessage imsg, string usr, string mode)
{
var channel = imsg.Channel as ITextChannel;
var channel = (ITextChannel)imsg.Channel;
if (string.IsNullOrWhiteSpace(usr))
return;
@@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Searches
[RequireContext(ContextType.Guild)]
public async Task Osub(IMessage imsg, [Remainder] string map)
{
var channel = imsg.Channel as ITextChannel;
var channel = (ITextChannel)imsg.Channel;
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
{
@@ -100,7 +100,7 @@ namespace NadekoBot.Modules.Searches
[RequireContext(ContextType.Guild)]
public async Task Osu5(IMessage imsg, string user, [Remainder] string mode)
{
var channel = imsg.Channel as ITextChannel;
var channel = (ITextChannel)imsg.Channel;
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
{
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);

View File

@@ -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))

View File

@@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches
[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 +51,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 _google.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 +66,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 +90,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 +103,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 +114,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 +144,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,7 +176,7 @@ $@"🌍 **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))
@@ -190,7 +190,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,7 +204,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
//[RequireContext(ContextType.Guild)]
//public async Task Hearthstone(IMessage imsg, [Remainder] string name = null)
//{
// var channel = imsg.Channel as ITextChannel;
// var channel = (ITextChannel)imsg.Channel;
// var arg = name;
// if (string.IsNullOrWhiteSpace(arg))
// {
@@ -249,7 +249,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))
@@ -283,7 +283,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))
@@ -318,7 +318,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 +328,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 +342,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 +359,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 +371,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 +385,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 +406,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 +431,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 +454,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)

View File

@@ -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);
}

View File

@@ -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"))
@@ -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());
}