Merge remote-tracking branch 'Kwoth/dev' into dev
This commit is contained in:
commit
8ab9b57c7d
12
README.md
12
README.md
@ -1,14 +1,12 @@
|
|||||||
![img](https://ci.appveyor.com/api/projects/status/gmu6b3ltc80hr3k9?svg=true)
|
![img](https://ci.appveyor.com/api/projects/status/gmu6b3ltc80hr3k9?svg=true)
|
||||||
[![Discord](https://discordapp.com/api/guilds/117523346618318850/widget.png)](https://discord.gg/nadekobot)
|
[![Discord](https://discordapp.com/api/guilds/117523346618318850/widget.png)](https://discord.gg/nadekobot)
|
||||||
[![Documentation Status](https://readthedocs.org/projects/nadekobot/badge/?version=latest)](http://nadekobot.readthedocs.io/en/latest/?badge=latest)
|
[![Documentation Status](https://readthedocs.org/projects/nadekobot/badge/?version=latest)](http://nadekobot.readthedocs.io/en/latest/?badge=latest)
|
||||||
![nadeko0](https://cdn.discordapp.com/attachments/266240393639755778/281920716809699328/part1.png)
|
[![nadeko0](https://cdn.discordapp.com/attachments/266240393639755778/281920716809699328/part1.png)](http://nadekobot.xyz)
|
||||||
[![nadeko1](https://cdn.discordapp.com/attachments/266240393639755778/281920134967328768/part2.png)](https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303)
|
[![nadeko1](https://cdn.discordapp.com/attachments/266240393639755778/281920134967328768/part2.png)](https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303)
|
||||||
[![nadeko2](https://cdn.discordapp.com/attachments/266240393639755778/281920161311883264/part3.png)](http://nadekobot.readthedocs.io/en/latest/Commands%20List/)
|
[![nadeko2](https://cdn.discordapp.com/attachments/266240393639755778/281920161311883264/part3.png)](http://nadekobot.readthedocs.io/en/latest/Commands%20List/)
|
||||||
|
|
||||||
##For Update, Help and Guidlines
|
##For Update, Help and Guidelines
|
||||||
|
|
||||||
`Follow me on twitter for updates. | Join my Discord server if you need help. | Read the Docs for hosting guides.`
|
|
||||||
|
|
||||||
[![twitter](https://cdn.discordapp.com/attachments/155726317222887425/252192520094613504/twiter_banner.JPG)](https://twitter.com/TheNadekoBot) [![discord](https://cdn.discordapp.com/attachments/266240393639755778/281920766490968064/discord.png)](https://discord.gg/nadekobot) [![Wiki](https://cdn.discordapp.com/attachments/266240393639755778/281920793330581506/datcord.png)](http://nadekobot.readthedocs.io/en/latest/)
|
|
||||||
|
|
||||||
|
|
||||||
|
| [![twitter](https://cdn.discordapp.com/attachments/155726317222887425/252192520094613504/twiter_banner.JPG)](https://twitter.com/TheNadekoBot) | [![discord](https://cdn.discordapp.com/attachments/266240393639755778/281920766490968064/discord.png)](https://discord.gg/nadekobot) | [![Wiki](https://cdn.discordapp.com/attachments/266240393639755778/281920793330581506/datcord.png)](http://nadekobot.readthedocs.io/en/latest/)
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Follow me on Twitter for updates. | Join my Discord server if you need help. | Read the Docs for hosting guides. |
|
@ -72,23 +72,42 @@ namespace NadekoBot.Modules.Administration
|
|||||||
{
|
{
|
||||||
if (_forwardDMs && ownerChannels.Any())
|
if (_forwardDMs && ownerChannels.Any())
|
||||||
{
|
{
|
||||||
var title =
|
var title = GetTextStatic("dm_from",
|
||||||
GetTextStatic("dm_from", NadekoBot.Localization.DefaultCultureInfo,
|
NadekoBot.Localization.DefaultCultureInfo,
|
||||||
typeof(Administration).Name.ToLowerInvariant()) + $" [{msg.Author}]({msg.Author.Id})";
|
typeof(Administration).Name.ToLowerInvariant()) +
|
||||||
|
$" [{msg.Author}]({msg.Author.Id})";
|
||||||
|
|
||||||
|
var attachamentsTxt = GetTextStatic("attachments",
|
||||||
|
NadekoBot.Localization.DefaultCultureInfo,
|
||||||
|
typeof(Administration).Name.ToLowerInvariant());
|
||||||
|
|
||||||
|
var toSend = msg.Content;
|
||||||
|
|
||||||
|
if (msg.Attachments.Count > 0)
|
||||||
|
{
|
||||||
|
toSend += $"\n\n{Format.Code(attachamentsTxt)}:\n" +
|
||||||
|
string.Join("\n", msg.Attachments.Select(a => a.ProxyUrl));
|
||||||
|
}
|
||||||
|
|
||||||
if (_forwardDMsToAllOwners)
|
if (_forwardDMsToAllOwners)
|
||||||
{
|
{
|
||||||
await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id)
|
await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id)
|
||||||
.Select(ch => ch.SendConfirmAsync(title, msg.Content))).ConfigureAwait(false);
|
.Select(ch => ch.SendConfirmAsync(title, toSend))).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var firstOwnerChannel = ownerChannels.First();
|
var firstOwnerChannel = ownerChannels.First();
|
||||||
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
|
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
|
||||||
try { await firstOwnerChannel.SendConfirmAsync(title, msg.Content).ConfigureAwait(false); }
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await firstOwnerChannel.SendConfirmAsync(title, toSend).ConfigureAwait(false);
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case CurrencyEvent.FlowerReaction:
|
case CurrencyEvent.FlowerReaction:
|
||||||
await FlowerReactionEvent(Context).ConfigureAwait(false);
|
await FlowerReactionEvent(Context, arg).ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
case CurrencyEvent.SneakyGameStatus:
|
case CurrencyEvent.SneakyGameStatus:
|
||||||
await SneakyGameStatusEvent(Context, arg).ConfigureAwait(false);
|
await SneakyGameStatusEvent(Context, arg).ConfigureAwait(false);
|
||||||
@ -115,23 +115,26 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
return Task.Delay(0);
|
return Task.Delay(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task FlowerReactionEvent(CommandContext context)
|
public async Task FlowerReactionEvent(CommandContext context, int amount)
|
||||||
{
|
{
|
||||||
|
if (amount <= 0)
|
||||||
|
amount = 100;
|
||||||
|
|
||||||
var title = GetText("flowerreaction_title");
|
var title = GetText("flowerreaction_title");
|
||||||
var desc = GetText("flowerreaction_desc", "🌸", Format.Bold(100.ToString()) + CurrencySign);
|
var desc = GetText("flowerreaction_desc", "🌸", Format.Bold(amount.ToString()) + CurrencySign);
|
||||||
var footer = GetText("flowerreaction_footer", 24);
|
var footer = GetText("flowerreaction_footer", 24);
|
||||||
var msg = await context.Channel.SendConfirmAsync(title,
|
var msg = await context.Channel.SendConfirmAsync(title,
|
||||||
desc, footer: footer)
|
desc, footer: footer)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
await new FlowerReactionEvent().Start(msg, context);
|
await new FlowerReactionEvent().Start(msg, context, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class CurrencyEvent
|
public abstract class CurrencyEvent
|
||||||
{
|
{
|
||||||
public abstract Task Start(IUserMessage msg, CommandContext channel);
|
public abstract Task Start(IUserMessage msg, CommandContext channel, int amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FlowerReactionEvent : CurrencyEvent
|
public class FlowerReactionEvent : CurrencyEvent
|
||||||
@ -172,7 +175,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Start(IUserMessage umsg, CommandContext context)
|
public override async Task Start(IUserMessage umsg, CommandContext context, int amount)
|
||||||
{
|
{
|
||||||
msg = umsg;
|
msg = umsg;
|
||||||
NadekoBot.Client.MessageDeleted += MessageDeletedEventHandler;
|
NadekoBot.Client.MessageDeleted += MessageDeletedEventHandler;
|
||||||
@ -193,7 +196,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
{
|
{
|
||||||
if (r.Emoji.Name == "🌸" && r.User.IsSpecified && ((DateTime.UtcNow - r.User.Value.CreatedAt).TotalDays > 5) && _flowerReactionAwardedUsers.Add(r.User.Value.Id))
|
if (r.Emoji.Name == "🌸" && r.User.IsSpecified && ((DateTime.UtcNow - r.User.Value.CreatedAt).TotalDays > 5) && _flowerReactionAwardedUsers.Add(r.User.Value.Id))
|
||||||
{
|
{
|
||||||
await CurrencyHandler.AddCurrencyAsync(r.User.Value, "Flower Reaction Event", 100, false)
|
await CurrencyHandler.AddCurrencyAsync(r.User.Value, "Flower Reaction Event", amount, false)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,10 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
[Priority(0)]
|
[Priority(0)]
|
||||||
public async Task Cash([Remainder] IUser user = null)
|
public async Task Cash([Remainder] IUser user = null)
|
||||||
{
|
{
|
||||||
user = user ?? Context.User;
|
if(user == null)
|
||||||
await ReplyConfirmLocalized("has", Format.Bold(user.ToString()), $"{GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false);
|
await ConfirmLocalized("has", Format.Bold(Context.User.ToString()), $"{GetCurrency(Context.User.Id)} {CurrencySign}").ConfigureAwait(false);
|
||||||
|
else
|
||||||
|
await ReplyConfirmLocalized("has", Format.Bold(user.ToString()), $"{GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
@ -77,10 +77,10 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
public IVoiceChannel PlaybackVoiceChannel { get; private set; }
|
public IVoiceChannel PlaybackVoiceChannel { get; private set; }
|
||||||
public ITextChannel OutputTextChannel { get; set; }
|
public ITextChannel OutputTextChannel { get; set; }
|
||||||
|
|
||||||
private bool destroyed { get; set; } = false;
|
private bool destroyed { get; set; }
|
||||||
public bool RepeatSong { get; private set; } = false;
|
public bool RepeatSong { get; private set; }
|
||||||
public bool RepeatPlaylist { get; private set; } = false;
|
public bool RepeatPlaylist { get; private set; }
|
||||||
public bool Autoplay { get; set; } = false;
|
public bool Autoplay { get; set; }
|
||||||
public uint MaxQueueSize { get; set; } = 0;
|
public uint MaxQueueSize { get; set; } = 0;
|
||||||
|
|
||||||
private ConcurrentQueue<Action> actionQueue { get; } = new ConcurrentQueue<Action>();
|
private ConcurrentQueue<Action> actionQueue { get; } = new ConcurrentQueue<Action>();
|
||||||
|
@ -5,12 +5,9 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VideoLibrary;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Music.Classes
|
namespace NadekoBot.Modules.Music.Classes
|
||||||
@ -32,13 +29,13 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
public string QueuerName { get; set; }
|
public string QueuerName { get; set; }
|
||||||
|
|
||||||
public TimeSpan TotalTime { get; set; } = TimeSpan.Zero;
|
public TimeSpan TotalTime { get; set; } = TimeSpan.Zero;
|
||||||
public TimeSpan CurrentTime => TimeSpan.FromSeconds(bytesSent / frameBytes / (1000 / milliseconds));
|
public TimeSpan CurrentTime => TimeSpan.FromSeconds(bytesSent / (float)_frameBytes / (1000 / (float)_milliseconds));
|
||||||
|
|
||||||
const int milliseconds = 20;
|
private const int _milliseconds = 20;
|
||||||
const int samplesPerFrame = (48000 / 1000) * milliseconds;
|
private const int _samplesPerFrame = (48000 / 1000) * _milliseconds;
|
||||||
const int frameBytes = 3840; //16-bit, 2 channels
|
private const int _frameBytes = 3840; //16-bit, 2 channels
|
||||||
|
|
||||||
private ulong bytesSent { get; set; } = 0;
|
private ulong bytesSent { get; set; }
|
||||||
|
|
||||||
//pwetty
|
//pwetty
|
||||||
|
|
||||||
@ -47,7 +44,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
|
|
||||||
public string PrettyFullTime => PrettyCurrentTime + " / " + PrettyTotalTime;
|
public string PrettyFullTime => PrettyCurrentTime + " / " + PrettyTotalTime;
|
||||||
|
|
||||||
public string PrettyName => $"**[{SongInfo.Title.TrimTo(65)}]({songUrl})**";
|
public string PrettyName => $"**[{SongInfo.Title.TrimTo(65)}]({SongUrl})**";
|
||||||
|
|
||||||
public string PrettyInfo => $"{MusicPlayer.PrettyVolume} | {PrettyTotalTime} | {PrettyProvider} | {QueuerName}";
|
public string PrettyInfo => $"{MusicPlayer.PrettyVolume} | {PrettyTotalTime} | {PrettyProvider} | {QueuerName}";
|
||||||
|
|
||||||
@ -65,22 +62,19 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PrettyTotalTime {
|
public string PrettyTotalTime {
|
||||||
get {
|
get
|
||||||
|
{
|
||||||
if (TotalTime == TimeSpan.Zero)
|
if (TotalTime == TimeSpan.Zero)
|
||||||
return "(?)";
|
return "(?)";
|
||||||
else if (TotalTime == TimeSpan.MaxValue)
|
if (TotalTime == TimeSpan.MaxValue)
|
||||||
return "∞";
|
return "∞";
|
||||||
else
|
var time = TotalTime.ToString(@"mm\:ss");
|
||||||
{
|
var hrs = (int)TotalTime.TotalHours;
|
||||||
var time = TotalTime.ToString(@"mm\:ss");
|
|
||||||
var hrs = (int)TotalTime.TotalHours;
|
|
||||||
|
|
||||||
if (hrs > 0)
|
if (hrs > 0)
|
||||||
return hrs + ":" + time;
|
return hrs + ":" + time;
|
||||||
else
|
return time;
|
||||||
return time;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,13 +83,13 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
switch (SongInfo.ProviderType)
|
switch (SongInfo.ProviderType)
|
||||||
{
|
{
|
||||||
case MusicType.Radio:
|
case MusicType.Radio:
|
||||||
return $"https://cdn.discordapp.com/attachments/155726317222887425/261850925063340032/1482522097_radio.png"; //test links
|
return "https://cdn.discordapp.com/attachments/155726317222887425/261850925063340032/1482522097_radio.png"; //test links
|
||||||
case MusicType.Normal:
|
case MusicType.Normal:
|
||||||
//todo have videoid in songinfo from the start
|
//todo have videoid in songinfo from the start
|
||||||
var videoId = Regex.Match(SongInfo.Query, "<=v=[a-zA-Z0-9-]+(?=&)|(?<=[0-9])[^&\n]+|(?<=v=)[^&\n]+");
|
var videoId = Regex.Match(SongInfo.Query, "<=v=[a-zA-Z0-9-]+(?=&)|(?<=[0-9])[^&\n]+|(?<=v=)[^&\n]+");
|
||||||
return $"https://img.youtube.com/vi/{ videoId }/0.jpg";
|
return $"https://img.youtube.com/vi/{ videoId }/0.jpg";
|
||||||
case MusicType.Local:
|
case MusicType.Local:
|
||||||
return $"https://cdn.discordapp.com/attachments/155726317222887425/261850914783100928/1482522077_music.png"; //test links
|
return "https://cdn.discordapp.com/attachments/155726317222887425/261850914783100928/1482522077_music.png"; //test links
|
||||||
case MusicType.Soundcloud:
|
case MusicType.Soundcloud:
|
||||||
return SongInfo.AlbumArt;
|
return SongInfo.AlbumArt;
|
||||||
default:
|
default:
|
||||||
@ -104,7 +98,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string songUrl {
|
public string SongUrl {
|
||||||
get {
|
get {
|
||||||
switch (SongInfo.ProviderType)
|
switch (SongInfo.ProviderType)
|
||||||
{
|
{
|
||||||
@ -122,36 +116,32 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int skipTo = 0;
|
public int SkipTo { get; set; }
|
||||||
public int SkipTo {
|
|
||||||
get { return skipTo; }
|
|
||||||
set {
|
|
||||||
skipTo = value;
|
|
||||||
bytesSent = (ulong)skipTo * 3840 * 50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
public Song(SongInfo songInfo)
|
public Song(SongInfo songInfo)
|
||||||
{
|
{
|
||||||
this.SongInfo = songInfo;
|
SongInfo = songInfo;
|
||||||
this._log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Song Clone()
|
public Song Clone()
|
||||||
{
|
{
|
||||||
var s = new Song(SongInfo);
|
var s = new Song(SongInfo)
|
||||||
s.MusicPlayer = MusicPlayer;
|
{
|
||||||
s.QueuerName = QueuerName;
|
MusicPlayer = MusicPlayer,
|
||||||
|
QueuerName = QueuerName
|
||||||
|
};
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
|
public async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
|
||||||
{
|
{
|
||||||
|
bytesSent = (ulong) SkipTo * 3840 * 50;
|
||||||
var filename = Path.Combine(Music.MusicDataPath, DateTime.Now.UnixTimestamp().ToString());
|
var filename = Path.Combine(Music.MusicDataPath, DateTime.Now.UnixTimestamp().ToString());
|
||||||
|
|
||||||
SongBuffer inStream = new SongBuffer(MusicPlayer, filename, SongInfo, skipTo, frameBytes * 100);
|
var inStream = new SongBuffer(MusicPlayer, filename, SongInfo, SkipTo, _frameBytes * 100);
|
||||||
var bufferTask = inStream.BufferSong(cancelToken).ConfigureAwait(false);
|
var bufferTask = inStream.BufferSong(cancelToken).ConfigureAwait(false);
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -200,22 +190,22 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
|
|
||||||
var outStream = voiceClient.CreatePCMStream(960);
|
var outStream = voiceClient.CreatePCMStream(960);
|
||||||
|
|
||||||
int nextTime = Environment.TickCount + milliseconds;
|
int nextTime = Environment.TickCount + _milliseconds;
|
||||||
|
|
||||||
byte[] buffer = new byte[frameBytes];
|
byte[] buffer = new byte[_frameBytes];
|
||||||
while (!cancelToken.IsCancellationRequested && //song canceled for whatever reason
|
while (!cancelToken.IsCancellationRequested && //song canceled for whatever reason
|
||||||
!(MusicPlayer.MaxPlaytimeSeconds != 0 && CurrentTime.TotalSeconds >= MusicPlayer.MaxPlaytimeSeconds)) // or exceedded max playtime
|
!(MusicPlayer.MaxPlaytimeSeconds != 0 && CurrentTime.TotalSeconds >= MusicPlayer.MaxPlaytimeSeconds)) // or exceedded max playtime
|
||||||
{
|
{
|
||||||
//Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
|
//Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
|
||||||
var read = await inStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
|
var read = await inStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
|
||||||
//await inStream.CopyToAsync(voiceClient.OutputStream);
|
//await inStream.CopyToAsync(voiceClient.OutputStream);
|
||||||
if (read < frameBytes)
|
if (read < _frameBytes)
|
||||||
_log.Debug("read {0}", read);
|
_log.Debug("read {0}", read);
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
bytesSent += (ulong)read;
|
bytesSent += (ulong)read;
|
||||||
}
|
}
|
||||||
if (read < frameBytes)
|
if (read < _frameBytes)
|
||||||
{
|
{
|
||||||
if (read == 0)
|
if (read == 0)
|
||||||
{
|
{
|
||||||
@ -231,12 +221,12 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
_log.Warn("Slow connection has disrupted music, waiting a bit for buffer");
|
_log.Warn("Slow connection has disrupted music, waiting a bit for buffer");
|
||||||
|
|
||||||
await Task.Delay(1000, cancelToken).ConfigureAwait(false);
|
await Task.Delay(1000, cancelToken).ConfigureAwait(false);
|
||||||
nextTime = Environment.TickCount + milliseconds;
|
nextTime = Environment.TickCount + _milliseconds;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Task.Delay(100, cancelToken).ConfigureAwait(false);
|
await Task.Delay(100, cancelToken).ConfigureAwait(false);
|
||||||
nextTime = Environment.TickCount + milliseconds;
|
nextTime = Environment.TickCount + _milliseconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -245,16 +235,16 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
else
|
else
|
||||||
attempt = 0;
|
attempt = 0;
|
||||||
|
|
||||||
while (this.MusicPlayer.Paused)
|
while (MusicPlayer.Paused)
|
||||||
{
|
{
|
||||||
await Task.Delay(200, cancelToken).ConfigureAwait(false);
|
await Task.Delay(200, cancelToken).ConfigureAwait(false);
|
||||||
nextTime = Environment.TickCount + milliseconds;
|
nextTime = Environment.TickCount + _milliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
buffer = AdjustVolume(buffer, MusicPlayer.Volume);
|
buffer = AdjustVolume(buffer, MusicPlayer.Volume);
|
||||||
if (read != frameBytes) continue;
|
if (read != _frameBytes) continue;
|
||||||
nextTime = unchecked(nextTime + milliseconds);
|
nextTime = unchecked(nextTime + _milliseconds);
|
||||||
int delayMillis = unchecked(nextTime - Environment.TickCount);
|
int delayMillis = unchecked(nextTime - Environment.TickCount);
|
||||||
if (delayMillis > 0)
|
if (delayMillis > 0)
|
||||||
await Task.Delay(delayMillis, cancelToken).ConfigureAwait(false);
|
await Task.Delay(delayMillis, cancelToken).ConfigureAwait(false);
|
||||||
@ -264,8 +254,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
await bufferTask;
|
await bufferTask;
|
||||||
if (inStream != null)
|
inStream.Dispose();
|
||||||
inStream.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +268,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
//aidiakapi ftw
|
//aidiakapi ftw
|
||||||
public unsafe static byte[] AdjustVolume(byte[] audioSamples, float volume)
|
public static unsafe byte[] AdjustVolume(byte[] audioSamples, float volume)
|
||||||
{
|
{
|
||||||
Contract.Requires(audioSamples != null);
|
Contract.Requires(audioSamples != null);
|
||||||
Contract.Requires(audioSamples.Length % 2 == 0);
|
Contract.Requires(audioSamples.Length % 2 == 0);
|
||||||
@ -289,15 +278,15 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
if (Math.Abs(volume - 1f) < 0.0001f) return audioSamples;
|
if (Math.Abs(volume - 1f) < 0.0001f) return audioSamples;
|
||||||
|
|
||||||
// 16-bit precision for the multiplication
|
// 16-bit precision for the multiplication
|
||||||
int volumeFixed = (int)Math.Round(volume * 65536d);
|
var volumeFixed = (int)Math.Round(volume * 65536d);
|
||||||
|
|
||||||
int count = audioSamples.Length / 2;
|
var count = audioSamples.Length / 2;
|
||||||
|
|
||||||
fixed (byte* srcBytes = audioSamples)
|
fixed (byte* srcBytes = audioSamples)
|
||||||
{
|
{
|
||||||
short* src = (short*)srcBytes;
|
var src = (short*)srcBytes;
|
||||||
|
|
||||||
for (int i = count; i != 0; i--, src++)
|
for (var i = count; i != 0; i--, src++)
|
||||||
*src = (short)(((*src) * volumeFixed) >> 16);
|
*src = (short)(((*src) * volumeFixed) >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,14 @@ using System.Net.Http;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
using VideoLibrary;
|
using VideoLibrary;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Music.Classes
|
namespace NadekoBot.Modules.Music.Classes
|
||||||
{
|
{
|
||||||
public static class SongHandler
|
public static class SongHandler
|
||||||
{
|
{
|
||||||
|
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
|
||||||
public static async Task<Song> ResolveSong(string query, MusicType musicType = MusicType.Normal)
|
public static async Task<Song> ResolveSong(string query, MusicType musicType = MusicType.Normal)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(query))
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
@ -106,7 +108,8 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Failed resolving the link.{ex.Message}");
|
_log.Warn($"Failed resolving the link.{ex.Message}");
|
||||||
|
_log.Warn(ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +140,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Failed reading .pls:\n{file}");
|
_log.Warn($"Failed reading .pls:\n{file}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +159,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Failed reading .m3u:\n{file}");
|
_log.Warn($"Failed reading .m3u:\n{file}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +175,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Failed reading .asx:\n{file}");
|
_log.Warn($"Failed reading .asx:\n{file}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +195,7 @@ namespace NadekoBot.Modules.Music.Classes
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Failed reading .xspf:\n{file}");
|
_log.Warn($"Failed reading .xspf:\n{file}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ using System.Net.Http;
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Music
|
namespace NadekoBot.Modules.Music
|
||||||
@ -78,7 +77,10 @@ namespace NadekoBot.Modules.Music
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +218,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
.Take(itemsPerPage)
|
.Take(itemsPerPage)
|
||||||
.Select(v => $"`{++number}.` {v.PrettyFullName}"));
|
.Select(v => $"`{++number}.` {v.PrettyFullName}"));
|
||||||
|
|
||||||
if (currentSong != null)
|
desc = $"`🔊` {currentSong.PrettyFullName}\n\n" + desc;
|
||||||
desc = $"`🔊` {currentSong.PrettyFullName}\n\n" + desc;
|
|
||||||
|
|
||||||
if (musicPlayer.RepeatSong)
|
if (musicPlayer.RepeatSong)
|
||||||
desc = "🔂 Repeating Current Song\n\n" + desc;
|
desc = "🔂 Repeating Current Song\n\n" + desc;
|
||||||
@ -512,12 +513,13 @@ namespace NadekoBot.Modules.Music
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task MoveSong([Remainder] string fromto)
|
public async Task MoveSong([Remainder] string fromto)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(fromto))
|
||||||
|
return;
|
||||||
|
|
||||||
MusicPlayer musicPlayer;
|
MusicPlayer musicPlayer;
|
||||||
if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
|
if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
fromto = fromto?.Trim();
|
fromto = fromto?.Trim();
|
||||||
var fromtoArr = fromto.Split('>');
|
var fromtoArr = fromto.Split('>');
|
||||||
|
|
||||||
@ -541,7 +543,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = new EmbedBuilder()
|
||||||
.WithTitle($"{s.SongInfo.Title.TrimTo(70)}")
|
.WithTitle($"{s.SongInfo.Title.TrimTo(70)}")
|
||||||
.WithUrl($"{s.SongInfo.Query}")
|
.WithUrl(s.SongUrl)
|
||||||
.WithAuthor(eab => eab.WithName("Song Moved").WithIconUrl("https://cdn.discordapp.com/attachments/155726317222887425/258605269972549642/music1.png"))
|
.WithAuthor(eab => eab.WithName("Song Moved").WithIconUrl("https://cdn.discordapp.com/attachments/155726317222887425/258605269972549642/music1.png"))
|
||||||
.AddField(fb => fb.WithName("**From Position**").WithValue($"#{n1}").WithIsInline(true))
|
.AddField(fb => fb.WithName("**From Position**").WithValue($"#{n1}").WithIsInline(true))
|
||||||
.AddField(fb => fb.WithName("**To Position**").WithValue($"#{n2}").WithIsInline(true))
|
.AddField(fb => fb.WithName("**To Position**").WithValue($"#{n2}").WithIsInline(true))
|
||||||
@ -861,8 +863,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
textCh,
|
textCh,
|
||||||
voiceCh,
|
voiceCh,
|
||||||
relatedVideos[new NadekoRandom().Next(0, relatedVideos.Count)],
|
relatedVideos[new NadekoRandom().Next(0, relatedVideos.Count)],
|
||||||
true,
|
true).ConfigureAwait(false);
|
||||||
musicType).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@ -870,7 +871,11 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
mp.OnStarted += async (player, song) =>
|
mp.OnStarted += async (player, song) =>
|
||||||
{
|
{
|
||||||
try { await mp.UpdateSongDurationsAsync().ConfigureAwait(false); } catch { }
|
try { await mp.UpdateSongDurationsAsync().ConfigureAwait(false); }
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
var sender = player as MusicPlayer;
|
var sender = player as MusicPlayer;
|
||||||
if (sender == null)
|
if (sender == null)
|
||||||
return;
|
return;
|
||||||
@ -914,7 +919,10 @@ namespace NadekoBot.Modules.Music
|
|||||||
await mp.OutputTextChannel.EmbedAsync(embed).ConfigureAwait(false);
|
await mp.OutputTextChannel.EmbedAsync(embed).ConfigureAwait(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return mp;
|
return mp;
|
||||||
});
|
});
|
||||||
@ -945,10 +953,12 @@ namespace NadekoBot.Modules.Music
|
|||||||
.WithThumbnailUrl(resolvedSong.Thumbnail)
|
.WithThumbnailUrl(resolvedSong.Thumbnail)
|
||||||
.WithFooter(ef => ef.WithText(resolvedSong.PrettyProvider)))
|
.WithFooter(ef => ef.WithText(resolvedSong.PrettyProvider)))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
if (queuedMessage != null)
|
queuedMessage?.DeleteAfter(10);
|
||||||
queuedMessage.DeleteAfter(10);
|
|
||||||
}
|
}
|
||||||
catch { } // if queued message sending fails, don't attempt to delete it
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
} // if queued message sending fails, don't attempt to delete it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
using (var http = new HttpClient())
|
using (var http = new HttpClient())
|
||||||
{
|
{
|
||||||
var res = JObject.Parse(await http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false));
|
var res = JObject.Parse(await http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false));
|
||||||
await Context.Channel.SendMessageAsync(res["file"].ToString()).ConfigureAwait(false);
|
await Context.Channel.SendMessageAsync(Uri.EscapeUriString(res["file"].ToString())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
|
|
||||||
var results = elems.Select<IElement, GoogleSearchResult?>(elem =>
|
var results = elems.Select<IElement, GoogleSearchResult?>(elem =>
|
||||||
{
|
{
|
||||||
var aTag = (elem.Children.FirstOrDefault().Children.FirstOrDefault() as IHtmlAnchorElement); // <h3> -> <a>
|
var aTag = (elem.Children.FirstOrDefault()?.Children.FirstOrDefault() as IHtmlAnchorElement); // <h3> -> <a>
|
||||||
var href = aTag?.Href;
|
var href = aTag?.Href;
|
||||||
var name = aTag?.TextContent;
|
var name = aTag?.TextContent;
|
||||||
if (href == null || name == null)
|
if (href == null || name == null)
|
||||||
@ -292,7 +292,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
.WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50))
|
.WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50))
|
||||||
.WithUrl(fullQueryLink)
|
.WithUrl(fullQueryLink)
|
||||||
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
|
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
|
||||||
.WithTitle(Context.User.Mention)
|
.WithTitle(Context.User.ToString())
|
||||||
.WithFooter(efb => efb.WithText(totalResults));
|
.WithFooter(efb => efb.WithText(totalResults));
|
||||||
|
|
||||||
var desc = await Task.WhenAll(results.Select(async res =>
|
var desc = await Task.WhenAll(results.Select(async res =>
|
||||||
|
@ -8,13 +8,14 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NadekoBot.DataStructures;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Utility
|
namespace NadekoBot.Modules.Utility
|
||||||
{
|
{
|
||||||
public partial class Utility
|
public partial class Utility
|
||||||
{
|
{
|
||||||
[Group]
|
[Group]
|
||||||
public class QuoteCommands : ModuleBase
|
public class QuoteCommands : NadekoSubmodule
|
||||||
{
|
{
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
@ -56,6 +57,17 @@ namespace NadekoBot.Modules.Utility
|
|||||||
if (quote == null)
|
if (quote == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CREmbed crembed;
|
||||||
|
if (CREmbed.TryParse(quote.Text, out crembed))
|
||||||
|
{
|
||||||
|
try { await Context.Channel.EmbedAsync(crembed.ToEmbed(), crembed.PlainText ?? "").ConfigureAwait(false); }
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.Warn("Sending CREmbed failed");
|
||||||
|
_log.Warn(ex);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
await Context.Channel.SendMessageAsync("📣 " + quote.Text.SanitizeMentions());
|
await Context.Channel.SendMessageAsync("📣 " + quote.Text.SanitizeMentions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace NadekoBot.Services
|
|||||||
private readonly CommandService _commandService;
|
private readonly CommandService _commandService;
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
private List<IDMChannel> ownerChannels { get; set; }
|
private List<IDMChannel> ownerChannels { get; set; } = new List<IDMChannel>();
|
||||||
|
|
||||||
public event Func<SocketUserMessage, CommandInfo, Task> CommandExecuted = delegate { return Task.CompletedTask; };
|
public event Func<SocketUserMessage, CommandInfo, Task> CommandExecuted = delegate { return Task.CompletedTask; };
|
||||||
|
|
||||||
@ -61,21 +61,57 @@ namespace NadekoBot.Services
|
|||||||
UsersOnShortCooldown.Clear();
|
UsersOnShortCooldown.Clear();
|
||||||
}, null, GlobalCommandsCooldown, GlobalCommandsCooldown);
|
}, null, GlobalCommandsCooldown, GlobalCommandsCooldown);
|
||||||
}
|
}
|
||||||
public async Task StartHandling()
|
public Task StartHandling()
|
||||||
{
|
{
|
||||||
ownerChannels = (await Task.WhenAll(_client.GetGuilds().SelectMany(g => g.Users)
|
var _ = Task.Run(async () =>
|
||||||
.Where(u => NadekoBot.Credentials.OwnerIds.Contains(u.Id))
|
{
|
||||||
.Distinct(new IGuildUserComparer())
|
await Task.Delay(5000).ConfigureAwait(false);
|
||||||
.Select(async u => { try { return await u.CreateDMChannelAsync(); } catch { return null; } })))
|
ownerChannels = (await Task.WhenAll(_client.GetGuilds().SelectMany(g => g.Users)
|
||||||
.Where(ch => ch != null)
|
.Where(u => NadekoBot.Credentials.OwnerIds.Contains(u.Id))
|
||||||
.ToList();
|
.Distinct(new IGuildUserComparer())
|
||||||
|
.Select(async u =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await u.CreateDMChannelAsync();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})))
|
||||||
|
.Where(ch => ch != null)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
if (!ownerChannels.Any())
|
if (!ownerChannels.Any())
|
||||||
_log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file.");
|
_log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file.");
|
||||||
else
|
else
|
||||||
_log.Info($"Created {ownerChannels.Count} out of {NadekoBot.Credentials.OwnerIds.Count} owner message channels.");
|
_log.Info($"Created {ownerChannels.Count} out of {NadekoBot.Credentials.OwnerIds.Count} owner message channels.");
|
||||||
|
});
|
||||||
|
|
||||||
_client.MessageReceived += MessageReceivedHandler;
|
_client.MessageReceived += MessageReceivedHandler;
|
||||||
|
_client.MessageUpdated += (oldmsg, newMsg) =>
|
||||||
|
{
|
||||||
|
var ignore = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var usrMsg = newMsg as SocketUserMessage;
|
||||||
|
var guild = (usrMsg?.Channel as ITextChannel)?.Guild;
|
||||||
|
|
||||||
|
if (guild != null && !await InviteFiltered(guild, usrMsg).ConfigureAwait(false))
|
||||||
|
await WordFiltered(guild, usrMsg).ConfigureAwait(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.Warn(ex);
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> TryRunCleverbot(SocketUserMessage usrMsg, IGuild guild)
|
private async Task<bool> TryRunCleverbot(SocketUserMessage usrMsg, IGuild guild)
|
||||||
|
Loading…
Reference in New Issue
Block a user