few more thingies, ready for prerelease

This commit is contained in:
Master Kwoth 2016-03-03 18:24:58 +01:00
parent 827b5bae0c
commit a6ebff0a17
31 changed files with 190 additions and 185 deletions

View File

@ -45,9 +45,9 @@ namespace NadekoBot.Classes {
} }
} }
internal List<T> GetAllRows<T>() where T : IDataModel, new() { internal HashSet<T> GetAllRows<T>() where T : IDataModel, new() {
using (var conn = new SQLiteConnection(FilePath)) { using (var conn = new SQLiteConnection(FilePath)) {
return conn.Table<T>().ToList(); return new HashSet<T>(conn.Table<T>());
} }
} }

View File

@ -24,10 +24,10 @@ namespace NadekoBot.Classes.Music {
public class MusicPlayer { public class MusicPlayer {
public static int MaximumPlaylistSize => 50; public static int MaximumPlaylistSize => 50;
private IAudioClient _client { get; set; } private IAudioClient audioClient { get; set; }
private List<Song> _playlist = new List<Song>(); private readonly List<Song> playlist = new List<Song>();
public IReadOnlyCollection<Song> Playlist => _playlist; public IReadOnlyCollection<Song> Playlist => playlist;
private readonly object playlistLock = new object(); private readonly object playlistLock = new object();
public Song CurrentSong { get; set; } = default(Song); public Song CurrentSong { get; set; } = default(Song);
@ -57,7 +57,7 @@ namespace NadekoBot.Classes.Music {
Task.Run(async () => { Task.Run(async () => {
while (true) { while (true) {
try { try {
_client = await PlaybackVoiceChannel.JoinAudio(); audioClient = await PlaybackVoiceChannel.JoinAudio();
} }
catch { catch {
await Task.Delay(1000); await Task.Delay(1000);
@ -67,7 +67,7 @@ namespace NadekoBot.Classes.Music {
if (CurrentSong != null) { if (CurrentSong != null) {
try { try {
OnStarted(CurrentSong); OnStarted(CurrentSong);
await CurrentSong.Play(_client, cancelToken); await CurrentSong.Play(audioClient, cancelToken);
} }
catch (OperationCanceledException) { catch (OperationCanceledException) {
Console.WriteLine("Song canceled"); Console.WriteLine("Song canceled");
@ -98,7 +98,7 @@ namespace NadekoBot.Classes.Music {
public void Stop() { public void Stop() {
lock (playlistLock) { lock (playlistLock) {
_playlist.Clear(); playlist.Clear();
try { try {
if (!SongCancelSource.IsCancellationRequested) if (!SongCancelSource.IsCancellationRequested)
SongCancelSource.Cancel(); SongCancelSource.Cancel();
@ -113,7 +113,7 @@ namespace NadekoBot.Classes.Music {
public void Shuffle() { public void Shuffle() {
lock (playlistLock) { lock (playlistLock) {
_playlist.Shuffle(); playlist.Shuffle();
} }
} }
@ -129,10 +129,10 @@ namespace NadekoBot.Classes.Music {
private Song GetNextSong() { private Song GetNextSong() {
lock (playlistLock) { lock (playlistLock) {
if (_playlist.Count == 0) if (playlist.Count == 0)
return null; return null;
var toReturn = _playlist[0]; var toReturn = playlist[0];
_playlist.RemoveAt(0); playlist.RemoveAt(0);
return toReturn; return toReturn;
} }
} }
@ -141,7 +141,7 @@ namespace NadekoBot.Classes.Music {
if (s == null) if (s == null)
throw new ArgumentNullException(nameof(s)); throw new ArgumentNullException(nameof(s));
lock (playlistLock) { lock (playlistLock) {
_playlist.Add(s); playlist.Add(s);
} }
} }
@ -149,20 +149,20 @@ namespace NadekoBot.Classes.Music {
if (s == null) if (s == null)
throw new ArgumentNullException(nameof(s)); throw new ArgumentNullException(nameof(s));
lock (playlistLock) { lock (playlistLock) {
_playlist.Remove(s); playlist.Remove(s);
} }
} }
public void RemoveSongAt(int index) { public void RemoveSongAt(int index) {
lock (playlistLock) { lock (playlistLock) {
if (index < 0 || index >= _playlist.Count) if (index < 0 || index >= playlist.Count)
throw new ArgumentException("Invalid index"); throw new ArgumentException("Invalid index");
_playlist.RemoveAt(index); playlist.RemoveAt(index);
} }
} }
internal Task MoveToVoiceChannel(Channel voiceChannel) { internal Task MoveToVoiceChannel(Channel voiceChannel) {
if (_client?.State != ConnectionState.Connected) if (audioClient?.State != ConnectionState.Connected)
throw new InvalidOperationException("Can't move while bot is not connected to voice channel."); throw new InvalidOperationException("Can't move while bot is not connected to voice channel.");
PlaybackVoiceChannel = voiceChannel; PlaybackVoiceChannel = voiceChannel;
return PlaybackVoiceChannel.JoinAudio(); return PlaybackVoiceChannel.JoinAudio();
@ -170,7 +170,7 @@ namespace NadekoBot.Classes.Music {
internal void ClearQueue() { internal void ClearQueue() {
lock (playlistLock) { lock (playlistLock) {
_playlist.Clear(); playlist.Clear();
} }
} }
} }

View File

@ -124,7 +124,7 @@ namespace NadekoBot.Classes.Music {
$"**【 {SongInfo.Title.TrimTo(55)} 】**`{(SongInfo.Provider ?? "-")}`"; $"**【 {SongInfo.Title.TrimTo(55)} 】**`{(SongInfo.Provider ?? "-")}`";
public SongInfo SongInfo { get; } public SongInfo SongInfo { get; }
private PoopyBuffer songBuffer { get; } = new PoopyBuffer(10.MB()); private PoopyBuffer songBuffer { get; } = new PoopyBuffer(4.MiB());
private bool prebufferingComplete { get; set; } = false; private bool prebufferingComplete { get; set; } = false;
public MusicPlayer MusicPlayer { get; set; } public MusicPlayer MusicPlayer { get; set; }
@ -145,7 +145,7 @@ namespace NadekoBot.Classes.Music {
RedirectStandardError = false, RedirectStandardError = false,
CreateNoWindow = true, CreateNoWindow = true,
}); });
var blockSize = 3840; const int blockSize = 3840;
var buffer = new byte[blockSize]; var buffer = new byte[blockSize];
var attempt = 0; var attempt = 0;
while (!cancelToken.IsCancellationRequested) { while (!cancelToken.IsCancellationRequested) {
@ -164,6 +164,7 @@ namespace NadekoBot.Classes.Music {
} catch { } catch {
Console.WriteLine("Buffering errored"); Console.WriteLine("Buffering errored");
} finally { } finally {
Console.WriteLine($"Buffering done." + $" [{songBuffer.ContentLength}]");
if (p != null) { if (p != null) {
p.CancelOutputRead(); p.CancelOutputRead();
p.StandardOutput.Dispose(); p.StandardOutput.Dispose();
@ -172,11 +173,10 @@ namespace NadekoBot.Classes.Music {
p.Dispose(); p.Dispose();
} }
} }
Console.WriteLine($"Buffering done." + $" [{songBuffer.ContentLength}]");
}); });
internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) { internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) {
var t = BufferSong(cancelToken).ConfigureAwait(false); var bufferTask = BufferSong(cancelToken).ConfigureAwait(false);
var bufferAttempts = 0; var bufferAttempts = 0;
const int waitPerAttempt = 500; const int waitPerAttempt = 500;
var toAttemptTimes = SongInfo.ProviderType != MusicType.Normal ? 5 : 9; var toAttemptTimes = SongInfo.ProviderType != MusicType.Normal ? 5 : 9;
@ -185,7 +185,7 @@ namespace NadekoBot.Classes.Music {
} }
cancelToken.ThrowIfCancellationRequested(); cancelToken.ThrowIfCancellationRequested();
Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}"); Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}");
var blockSize = 3840; const int blockSize = 3840;
var buffer = new byte[blockSize]; var buffer = new byte[blockSize];
var attempt = 0; var attempt = 0;
while (!cancelToken.IsCancellationRequested) { while (!cancelToken.IsCancellationRequested) {
@ -206,6 +206,7 @@ namespace NadekoBot.Classes.Music {
buffer = AdjustVolume(buffer, MusicPlayer.Volume); buffer = AdjustVolume(buffer, MusicPlayer.Volume);
voiceClient.Send(buffer, 0, read); voiceClient.Send(buffer, 0, read);
} }
await bufferTask;
cancelToken.ThrowIfCancellationRequested(); cancelToken.ThrowIfCancellationRequested();
//try { //try {
// voiceClient.Clear(); // voiceClient.Clear();
@ -366,14 +367,13 @@ namespace NadekoBot.Classes.Music {
return query; return query;
} }
private static bool IsRadioLink(string query) { private static bool IsRadioLink(string query) =>
return (query.StartsWith("http") || (query.StartsWith("http") ||
query.StartsWith("ww")) query.StartsWith("ww"))
&& &&
(query.Contains(".pls") || (query.Contains(".pls") ||
query.Contains(".m3u") || query.Contains(".m3u") ||
query.Contains(".asx") || query.Contains(".asx") ||
query.Contains(".xspf")); query.Contains(".xspf"));
}
} }
} }

View File

@ -6,6 +6,7 @@ using System.Linq;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Reflection; using System.Reflection;
using NadekoBot.Modules;
namespace NadekoBot { namespace NadekoBot {
public class NadekoStats { public class NadekoStats {
@ -84,22 +85,27 @@ namespace NadekoBot {
public Task LoadStats() => public Task LoadStats() =>
Task.Run(() => { Task.Run(() => {
var songs = Music.MusicPlayers.Count;
var sb = new System.Text.StringBuilder(); var sb = new System.Text.StringBuilder();
sb.AppendLine("`Author: Kwoth` `Library: Discord.Net`"); sb.AppendLine("`Author: Kwoth` `Library: Discord.Net`");
sb.AppendLine($"`Bot Version: {BotVersion}`"); sb.AppendLine($"`Bot Version: {BotVersion}`");
sb.AppendLine($"`Bot id: {NadekoBot.Client.CurrentUser.Id}`"); sb.AppendLine($"`Bot id: {NadekoBot.Client.CurrentUser.Id}`");
sb.AppendLine($"`Owner id: {(NadekoBot.Creds.OwnerIds.FirstOrDefault())}`"); sb.Append("`Owners' Ids:` ");
sb.AppendLine("`" + String.Join(", ", NadekoBot.Creds.OwnerIds) + "`");
sb.AppendLine($"`Uptime: {GetUptimeString()}`"); sb.AppendLine($"`Uptime: {GetUptimeString()}`");
sb.Append($"`Servers: {ServerCount}"); sb.Append($"`Servers: {ServerCount}");
sb.Append($" | TextChannels: {TextChannelsCount}"); sb.Append($" | TextChannels: {TextChannelsCount}");
sb.AppendLine($" | VoiceChannels: {VoiceChannelsCount}`"); sb.AppendLine($" | VoiceChannels: {VoiceChannelsCount}`");
sb.AppendLine($"`Commands Ran this session: {commandsRan}`"); sb.AppendLine($"`Commands Ran this session: {commandsRan}`");
sb.AppendLine($"`Message queue size:{NadekoBot.Client.MessageQueue.Count}`"); sb.AppendLine($"`Message queue size: {NadekoBot.Client.MessageQueue.Count}`");
sb.AppendLine($"`Greeted {Commands.ServerGreetCommand.Greeted} times.`"); sb.Append($"`Greeted {Commands.ServerGreetCommand.Greeted} times.`");
sb.AppendLine($" `| Playing {songs} songs, ".SnPl(songs) +
$"{Music.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count)} queued.`");
sb.AppendLine($"`Heap: {Heap(false)}`");
statsCache = sb.ToString(); statsCache = sb.ToString();
}); });
public string Heap() => Math.Round((double)GC.GetTotalMemory(true) / 1.MiB(), 2).ToString(); public string Heap(bool pass = true) => Math.Round((double)GC.GetTotalMemory(pass) / 1.MiB(), 2).ToString();
public async Task<string> GetStats() { public async Task<string> GetStats() {
if (statsStopwatch.Elapsed.Seconds <= 5) return statsCache; if (statsStopwatch.Elapsed.Seconds <= 5) return statsCache;

View File

@ -4,12 +4,14 @@ using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
namespace NadekoBot.Classes.Permissions { namespace NadekoBot.Classes.Permissions {
internal class PermissionChecker : IPermissionChecker { internal class PermissionChecker : IPermissionChecker {
public static PermissionChecker Instance { get; } = new PermissionChecker(); public static PermissionChecker Instance { get; } = new PermissionChecker();
private ConcurrentDictionary<User, DateTime> timeBlackList { get; } = new ConcurrentDictionary<User, DateTime>(); private ConcurrentDictionary<User, DateTime> timeBlackList { get; } = new ConcurrentDictionary<User, DateTime>();
private HashSet<ulong> serverBlacklist { get; } = new HashSet<ulong>();
static PermissionChecker() { } static PermissionChecker() { }
public PermissionChecker() { public PermissionChecker() {

View File

@ -21,7 +21,7 @@ namespace NadekoBot.Classes.Trivia {
private CancellationTokenSource triviaCancelSource { get; set; } private CancellationTokenSource triviaCancelSource { get; set; }
public TriviaQuestion CurrentQuestion { get; private set; } public TriviaQuestion CurrentQuestion { get; private set; }
public List<TriviaQuestion> oldQuestions { get; } = new List<TriviaQuestion>(); public HashSet<TriviaQuestion> oldQuestions { get; } = new HashSet<TriviaQuestion>();
public ConcurrentDictionary<User, int> Users { get; } = new ConcurrentDictionary<User, int>(); public ConcurrentDictionary<User, int> Users { get; } = new ConcurrentDictionary<User, int>();

View File

@ -7,7 +7,7 @@ using System.Text.RegularExpressions;
namespace NadekoBot.Classes.Trivia { namespace NadekoBot.Classes.Trivia {
public class TriviaQuestion { public class TriviaQuestion {
//represents the min size to judge levDistance with //represents the min size to judge levDistance with
public static List<Tuple<int, int>> strictness = new List<Tuple<int, int>>() { private static readonly HashSet<Tuple<int, int>> strictness = new HashSet<Tuple<int, int>> {
new Tuple<int, int>(6, 0), new Tuple<int, int>(6, 0),
new Tuple<int, int>(7, 1), new Tuple<int, int>(7, 1),
new Tuple<int, int>(12, 2), new Tuple<int, int>(12, 2),

View File

@ -6,12 +6,11 @@ using System.Linq;
namespace NadekoBot.Classes.Trivia { namespace NadekoBot.Classes.Trivia {
public class TriviaQuestionPool { public class TriviaQuestionPool {
private static readonly TriviaQuestionPool _instance = new TriviaQuestionPool(); public static TriviaQuestionPool Instance { get; } = new TriviaQuestionPool();
public static TriviaQuestionPool Instance => _instance;
public List<TriviaQuestion> pool = new List<TriviaQuestion>(); public HashSet<TriviaQuestion> pool = new HashSet<TriviaQuestion>();
private Random _r { get; } = new Random(); private Random rng { get; } = new Random();
static TriviaQuestionPool() { } static TriviaQuestionPool() { }
@ -19,22 +18,21 @@ namespace NadekoBot.Classes.Trivia {
Reload(); Reload();
} }
public TriviaQuestion GetRandomQuestion(List<TriviaQuestion> exclude) { public TriviaQuestion GetRandomQuestion(IEnumerable<TriviaQuestion> exclude) {
var list = pool.Except(exclude).ToList(); var list = pool.Except(exclude).ToList();
var rand = _r.Next(0, list.Count); var rand = rng.Next(0, list.Count);
return list[rand]; return list[rand];
} }
internal void Reload() { internal void Reload() {
JArray arr = JArray.Parse(File.ReadAllText("data/questions.txt")); var arr = JArray.Parse(File.ReadAllText("data/questions.txt"));
foreach (var item in arr) { foreach (var item in arr) {
TriviaQuestion tq; var tq = new TriviaQuestion(item["Question"].ToString(), item["Answer"].ToString(), item["Category"]?.ToString());
tq = new TriviaQuestion(item["Question"].ToString(), item["Answer"].ToString(), item["Category"]?.ToString());
pool.Add(tq); pool.Add(tq);
} }
var r = new Random(); var r = new Random();
pool = pool.OrderBy(x => r.Next()).ToList(); pool = new HashSet<TriviaQuestion>(pool.OrderBy(x => r.Next()));
} }
} }
} }

View File

@ -8,7 +8,7 @@ using System.Linq;
using System.Threading; using System.Threading;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class ClashOfClans : DiscordCommand { internal class ClashOfClans : IDiscordCommand {
private const string prefix = ","; private const string prefix = ",";
public static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; } = new ConcurrentDictionary<ulong, List<ClashWar>>(); public static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; } = new ConcurrentDictionary<ulong, List<ClashWar>>();
@ -19,7 +19,7 @@ namespace NadekoBot.Commands {
} }
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
if (!e.User.ServerPermissions.ManageChannels) if (!e.User.ServerPermissions.ManageChannels)
return; return;
List<ClashWar> wars; List<ClashWar> wars;
@ -50,7 +50,7 @@ namespace NadekoBot.Commands {
//war with the index X started. //war with the index X started.
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(prefix + "createwar") cgb.CreateCommand(prefix + "createwar")
.Alias(prefix + "cw") .Alias(prefix + "cw")
.Description($"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name.\n**Usage**:{prefix}cw 15 The Enemy Clan") .Description($"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name.\n**Usage**:{prefix}cw 15 The Enemy Clan")

View File

@ -5,14 +5,13 @@ using Discord.Commands;
namespace NadekoBot.Commands namespace NadekoBot.Commands
{ {
internal class CopyCommand : DiscordCommand internal class CopyCommand : IDiscordCommand
{ {
private List<ulong> CopiedUsers; private readonly HashSet<ulong> CopiedUsers = new HashSet<ulong>();
public CopyCommand() public CopyCommand()
{ {
CopiedUsers = new List<ulong>(); NadekoBot.Client.MessageReceived += Client_MessageReceived;
client.MessageReceived += Client_MessageReceived;
} }
private async void Client_MessageReceived(object sender, Discord.MessageEventArgs e) private async void Client_MessageReceived(object sender, Discord.MessageEventArgs e)
@ -27,16 +26,15 @@ namespace NadekoBot.Commands
catch { } catch { }
} }
public override Func<CommandEventArgs, Task> DoFunc() => async e => public Func<CommandEventArgs, Task> DoFunc() => async e =>
{ {
if (CopiedUsers.Contains(e.User.Id)) return; if (CopiedUsers.Contains(e.User.Id)) return;
CopiedUsers.Add(e.User.Id); CopiedUsers.Add(e.User.Id);
await e.Channel.SendMessage(" I'll start copying you now."); await e.Channel.SendMessage(" I'll start copying you now.");
return;
}; };
public override void Init(CommandGroupBuilder cgb) public void Init(CommandGroupBuilder cgb)
{ {
cgb.CreateCommand("copyme") cgb.CreateCommand("copyme")
.Alias("cm") .Alias("cm")
@ -55,7 +53,6 @@ namespace NadekoBot.Commands
CopiedUsers.Remove(e.User.Id); CopiedUsers.Remove(e.User.Id);
await e.Channel.SendMessage(" I wont copy anymore."); await e.Channel.SendMessage(" I wont copy anymore.");
return;
}; };
} }
} }

View File

@ -8,15 +8,14 @@ using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class DiceRollCommand : DiscordCommand { internal class DiceRollCommand : IDiscordCommand {
public DiceRollCommand() { }
public override Func<CommandEventArgs, Task> DoFunc() { public Func<CommandEventArgs, Task> DoFunc() {
Random r = new Random(); var r = new Random();
return async e => { return async e => {
if (e.Args[0] == "") { if (e.Args[0] == "") {
int num1 = r.Next(0, 10); var num1 = r.Next(0, 10);
int num2 = r.Next(0, 10); var num2 = r.Next(0, 10);
Image[] images; Image[] images;
@ -26,26 +25,25 @@ namespace NadekoBot.Commands {
images = new Image[2] { GetDice(num1), GetDice(num2) }; images = new Image[2] { GetDice(num1), GetDice(num2) };
} }
Bitmap bitmap = images.Merge(); var bitmap = images.Merge();
await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png)); await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png));
return;
} else { } else {
try { try {
int num = int.Parse(e.Args[0]); var num = int.Parse(e.Args[0]);
if (num < 1) num = 1; if (num < 1) num = 1;
if (num > 30) { if (num > 30) {
await e.Channel.SendMessage("You can roll up to 30 dies at a time."); await e.Channel.SendMessage("You can roll up to 30 dies at a time.");
num = 30; num = 30;
} }
List<Image> dices = new List<Image>(num); var dices = new List<Image>(num);
List<int> values = new List<int>(num); var values = new List<int>(num);
for (int i = 0; i < num; i++) { for (var i = 0; i < num; i++) {
int randomNumber = r.Next(1, 7); var randomNumber = r.Next(1, 7);
int toInsert = dices.Count; var toInsert = dices.Count;
if (randomNumber == 6 || dices.Count == 0) if (randomNumber == 6 || dices.Count == 0)
toInsert = 0; toInsert = 0;
else if (randomNumber != 1) else if (randomNumber != 1)
for (int j = 0; j < dices.Count; j++) { for (var j = 0; j < dices.Count; j++) {
if (values[j] < randomNumber) { if (values[j] < randomNumber) {
toInsert = j; toInsert = j;
break; break;
@ -55,12 +53,11 @@ namespace NadekoBot.Commands {
values.Insert(toInsert, randomNumber); values.Insert(toInsert, randomNumber);
} }
Bitmap bitmap = dices.Merge(); var bitmap = dices.Merge();
await e.Channel.SendMessage(values.Count + " Dies rolled. Total: **" + values.Sum() + "** Average: **" + (values.Sum() / (1.0f * values.Count)).ToString("N2") + "**"); await e.Channel.SendMessage(values.Count + " Dies rolled. Total: **" + values.Sum() + "** Average: **" + (values.Sum() / (1.0f * values.Count)).ToString("N2") + "**");
await e.Channel.SendFile("dices.png", bitmap.ToStream(ImageFormat.Png)); await e.Channel.SendFile("dices.png", bitmap.ToStream(ImageFormat.Png));
} catch { } catch {
await e.Channel.SendMessage("Please enter a number of dices to roll."); await e.Channel.SendMessage("Please enter a number of dices to roll.");
return;
} }
} }
}; };
@ -68,7 +65,7 @@ namespace NadekoBot.Commands {
private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image; private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image;
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("$roll") cgb.CreateCommand("$roll")
.Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]") .Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]")
.Parameter("num", ParameterType.Optional) .Parameter("num", ParameterType.Optional)
@ -86,7 +83,7 @@ namespace NadekoBot.Commands {
if (e.GetArg("range").Contains("-")) { if (e.GetArg("range").Contains("-")) {
var arr = e.GetArg("range").Split('-') var arr = e.GetArg("range").Split('-')
.Take(2) .Take(2)
.Select(x => int.Parse(x)) .Select(int.Parse)
.ToArray(); .ToArray();
if (arr[0] > arr[1]) if (arr[0] > arr[1])
throw new ArgumentException("First argument should be bigger than the second one."); throw new ArgumentException("First argument should be bigger than the second one.");

View File

@ -7,14 +7,14 @@ using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class DrawCommand : DiscordCommand { internal class DrawCommand : IDiscordCommand {
private static ConcurrentDictionary<Discord.Server, Cards> AllDecks = new ConcurrentDictionary<Discord.Server, Cards>(); private static ConcurrentDictionary<Discord.Server, Cards> AllDecks = new ConcurrentDictionary<Discord.Server, Cards>();
public DrawCommand() { public DrawCommand() {
} }
public override Func<CommandEventArgs, Task> DoFunc() => async (e) => { public Func<CommandEventArgs, Task> DoFunc() => async (e) => {
if (!AllDecks.ContainsKey(e.Server)) { if (!AllDecks.ContainsKey(e.Server)) {
await e.Channel.SendMessage("Shuffling cards..."); await e.Channel.SendMessage("Shuffling cards...");
AllDecks.TryAdd(e.Server, new Cards()); AllDecks.TryAdd(e.Server, new Cards());
@ -53,7 +53,7 @@ namespace NadekoBot.Commands {
} }
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("$draw") cgb.CreateCommand("$draw")
.Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck.\n**Usage**: $draw [x]") .Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck.\n**Usage**: $draw [x]")
.Parameter("count", ParameterType.Optional) .Parameter("count", ParameterType.Optional)

View File

@ -5,17 +5,14 @@ using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class FlipCoinCommand : DiscordCommand { internal class FlipCoinCommand : IDiscordCommand {
private Random _r; private readonly Random rng = new Random();
public FlipCoinCommand() {
_r = new Random();
}
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
if (e.GetArg("count") == "") { if (e.GetArg("count") == "") {
if (_r.Next(0, 2) == 1) if (rng.Next(0, 2) == 1)
await e.Channel.SendFile("heads.png", Properties.Resources.heads.ToStream(System.Drawing.Imaging.ImageFormat.Png)); await e.Channel.SendFile("heads.png", Properties.Resources.heads.ToStream(System.Drawing.Imaging.ImageFormat.Png));
else else
await e.Channel.SendFile("tails.png", Properties.Resources.tails.ToStream(System.Drawing.Imaging.ImageFormat.Png)); await e.Channel.SendFile("tails.png", Properties.Resources.tails.ToStream(System.Drawing.Imaging.ImageFormat.Png));
@ -24,22 +21,20 @@ namespace NadekoBot.Commands {
if (int.TryParse(e.GetArg("count"), out result)) { if (int.TryParse(e.GetArg("count"), out result)) {
if (result > 10) if (result > 10)
result = 10; result = 10;
Image[] imgs = new Image[result]; var imgs = new Image[result];
for (int i = 0; i < result; i++) { for (var i = 0; i < result; i++) {
imgs[i] = _r.Next(0, 2) == 0 ? imgs[i] = rng.Next(0, 2) == 0 ?
Properties.Resources.tails : Properties.Resources.tails :
Properties.Resources.heads; Properties.Resources.heads;
} }
await e.Channel.SendFile($"{result} coins.png", imgs.Merge().ToStream(System.Drawing.Imaging.ImageFormat.Png)); await e.Channel.SendFile($"{result} coins.png", imgs.Merge().ToStream(System.Drawing.Imaging.ImageFormat.Png));
return; return;
} }
await e.Channel.SendMessage("Invalid number"); await e.Channel.SendMessage("Invalid number");
} }
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("$flip") cgb.CreateCommand("$flip")
.Description("Flips coin(s) - heads or tails, and shows an image.\n**Usage**: `$flip` or `$flip 3`") .Description("Flips coin(s) - heads or tails, and shows an image.\n**Usage**: `$flip` or `$flip 3`")
.Parameter("count", ParameterType.Optional) .Parameter("count", ParameterType.Optional)

View File

@ -6,8 +6,8 @@ using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class HelpCommand : DiscordCommand { internal class HelpCommand : IDiscordCommand {
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
#region OldHelp #region OldHelp
/* /*
string helpstr = "**COMMANDS DO NOT WORK IN PERSONAL MESSAGES**\nOfficial repo: **github.com/Kwoth/NadekoBot/**"; string helpstr = "**COMMANDS DO NOT WORK IN PERSONAL MESSAGES**\nOfficial repo: **github.com/Kwoth/NadekoBot/**";
@ -60,7 +60,7 @@ Version: `{NadekoStats.Instance.BotVersion}`";
string lastCategory = ""; string lastCategory = "";
foreach (var com in client.GetService<CommandService>().AllCommands) { foreach (var com in NadekoBot.Client.GetService<CommandService>().AllCommands) {
if (com.Category != lastCategory) { if (com.Category != lastCategory) {
helpstr += "\n### " + com.Category + " \n"; helpstr += "\n### " + com.Category + " \n";
helpstr += "Command and aliases | Description | Usage\n"; helpstr += "Command and aliases | Description | Usage\n";
@ -76,10 +76,9 @@ Version: `{NadekoStats.Instance.BotVersion}`";
#else #else
File.WriteAllText("commandlist.md", helpstr); File.WriteAllText("commandlist.md", helpstr);
#endif #endif
return;
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("-h") cgb.CreateCommand("-h")
.Alias(new string[] { "-help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h" }) .Alias(new string[] { "-help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h" })
.Description("Either shows a help for a single command, or PMs you help link if no arguments are specified.\n**Usage**: '-h !m q' or just '-h' ") .Description("Either shows a help for a single command, or PMs you help link if no arguments are specified.\n**Usage**: '-h !m q' or just '-h' ")

View File

@ -0,0 +1,19 @@
using System;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
namespace NadekoBot.Commands
{
/// <summary>
/// Base DiscordCommand Class.
/// Inherit this class to create your own command.
/// </summary>
public interface IDiscordCommand
{
/// <summary>
/// Initializes the CommandBuilder with values using CommandGroupBuilder
/// </summary>
void Init(CommandGroupBuilder cgb);
}
}

View File

@ -10,7 +10,7 @@ using NadekoBot.Extensions;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class LoLCommands : DiscordCommand { internal class LoLCommands : IDiscordCommand {
private class CachedChampion { private class CachedChampion {
public System.IO.Stream ImageStream { get; set; } public System.IO.Stream ImageStream { get; set; }
@ -43,7 +43,7 @@ namespace NadekoBot.Commands {
"If you consider playing teemo, do it. If you consider teemo, you deserve him.", "If you consider playing teemo, do it. If you consider teemo, you deserve him.",
"Doesn't matter what you ban really. Enemy will ban your main and you will lose." }; "Doesn't matter what you ban really. Enemy will ban your main and you will lose." };
public override Func<CommandEventArgs, Task> DoFunc() { public Func<CommandEventArgs, Task> DoFunc() {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -55,7 +55,7 @@ namespace NadekoBot.Commands {
public float StatScore { get; set; } public float StatScore { get; set; }
} }
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("~lolchamp") cgb.CreateCommand("~lolchamp")
.Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role.\n**Usage**:~lolchamp Riven or ~lolchamp Annie sup") .Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role.\n**Usage**:~lolchamp Riven or ~lolchamp Annie sup")
.Parameter("champ", ParameterType.Required) .Parameter("champ", ParameterType.Required)

View File

@ -5,7 +5,7 @@ using Discord.Commands;
using Discord; using Discord;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class LogCommand : DiscordCommand { internal class LogCommand : IDiscordCommand {
public LogCommand() { public LogCommand() {
NadekoBot.Client.MessageReceived += MsgRecivd; NadekoBot.Client.MessageReceived += MsgRecivd;
@ -14,12 +14,12 @@ namespace NadekoBot.Commands {
NadekoBot.Client.UserUpdated += UsrUpdtd; NadekoBot.Client.UserUpdated += UsrUpdtd;
} }
private ConcurrentDictionary<Server, Channel> logs = new ConcurrentDictionary<Server, Channel>(); private readonly ConcurrentDictionary<Server, Channel> logs = new ConcurrentDictionary<Server, Channel>();
private ConcurrentDictionary<Server, Channel> loggingPresences = new ConcurrentDictionary<Server, Channel>(); private readonly ConcurrentDictionary<Server, Channel> loggingPresences = new ConcurrentDictionary<Server, Channel>();
// //
private ConcurrentDictionary<Channel, Channel> voiceChannelLog = new ConcurrentDictionary<Channel, Channel>(); private readonly ConcurrentDictionary<Channel, Channel> voiceChannelLog = new ConcurrentDictionary<Channel, Channel>();
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
if (!NadekoBot.IsOwner(e.User.Id) || if (!NadekoBot.IsOwner(e.User.Id) ||
!e.User.ServerPermissions.ManageServer) !e.User.ServerPermissions.ManageServer)
return; return;
@ -107,7 +107,7 @@ namespace NadekoBot.Commands {
} }
catch { } catch { }
} }
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(".logserver") cgb.CreateCommand(".logserver")
.Description("Toggles logging in this channel. Logs every message sent/deleted/edited on the server. BOT OWNER ONLY. SERVER OWNER ONLY.") .Description("Toggles logging in this channel. Logs every message sent/deleted/edited on the server. BOT OWNER ONLY. SERVER OWNER ONLY.")
.Do(DoFunc()); .Do(DoFunc());

View File

@ -8,9 +8,9 @@ using System.Timers;
using NadekoBot.Modules; using NadekoBot.Modules;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class PlayingRotate : DiscordCommand { internal class PlayingRotate : IDiscordCommand {
private static List<string> rotatingStatuses = new List<string>(); private static readonly List<string> rotatingStatuses = new List<string>();
private static readonly Timer timer = new Timer(12000); private static readonly Timer timer = new Timer(12000);
public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } = public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } =
@ -60,7 +60,7 @@ namespace NadekoBot.Commands {
}; };
} }
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
if (timer.Enabled) if (timer.Enabled)
timer.Stop(); timer.Stop();
else else
@ -68,7 +68,7 @@ namespace NadekoBot.Commands {
await e.Channel.SendMessage($"❗`Rotating playing status has been {(timer.Enabled ? "enabled" : "disabled")}.`"); await e.Channel.SendMessage($"❗`Rotating playing status has been {(timer.Enabled ? "enabled" : "disabled")}.`");
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(".rotateplaying") cgb.CreateCommand(".rotateplaying")
.Alias(".ropl") .Alias(".ropl")
.Description("Toggles rotation of playing status of the dynamic strings you specified earlier.") .Description("Toggles rotation of playing status of the dynamic strings you specified earlier.")

View File

@ -8,15 +8,15 @@ using Discord;
using Discord.Commands; using Discord.Commands;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class PollCommand : DiscordCommand { internal class PollCommand : IDiscordCommand {
public static ConcurrentDictionary<Server, Poll> ActivePolls = new ConcurrentDictionary<Server, Poll>(); public static ConcurrentDictionary<Server, Poll> ActivePolls = new ConcurrentDictionary<Server, Poll>();
public override Func<CommandEventArgs, Task> DoFunc() { public Func<CommandEventArgs, Task> DoFunc() {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(">poll") cgb.CreateCommand(">poll")
.Description("Creates a poll, only person who has manage server permission can do it.\n**Usage**: >poll Question?;Answer1;Answ 2;A_3") .Description("Creates a poll, only person who has manage server permission can do it.\n**Usage**: >poll Question?;Answer1;Answ 2;A_3")
.Parameter("allargs", ParameterType.Unparsed) .Parameter("allargs", ParameterType.Unparsed)

View File

@ -4,7 +4,7 @@ using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class RequestsCommand : DiscordCommand { internal class RequestsCommand : IDiscordCommand {
public void SaveRequest(CommandEventArgs e, string text) { public void SaveRequest(CommandEventArgs e, string text) {
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Request { Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Request {
RequestText = text, RequestText = text,
@ -37,11 +37,7 @@ namespace NadekoBot.Commands {
public Classes._DataModels.Request ResolveRequest(int requestNumber) => public Classes._DataModels.Request ResolveRequest(int requestNumber) =>
Classes.DbHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber); Classes.DbHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber);
public override Func<CommandEventArgs, Task> DoFunc() { public void Init(CommandGroupBuilder cgb) {
throw new NotImplementedException();
}
public override void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("req") cgb.CreateCommand("req")
.Alias("request") .Alias("request")
@ -95,7 +91,7 @@ namespace NadekoBot.Commands {
var sc = ResolveRequest(int.Parse(e.Args[0])); var sc = ResolveRequest(int.Parse(e.Args[0]));
if (sc != null) { if (sc != null) {
await e.Channel.SendMessage(e.User.Mention + " Request resolved, notice sent."); await e.Channel.SendMessage(e.User.Mention + " Request resolved, notice sent.");
await client.GetServer((ulong)sc.ServerId).GetUser((ulong)sc.UserId).Send("**This request of yours has been resolved:**\n" + sc.RequestText); await NadekoBot.Client.GetServer((ulong)sc.ServerId).GetUser((ulong)sc.UserId).Send("**This request of yours has been resolved:**\n" + sc.RequestText);
} else { } else {
await e.Channel.SendMessage("No request on that number."); await e.Channel.SendMessage("No request on that number.");
} }

View File

@ -21,7 +21,7 @@ public class AsyncLazy<T> : Lazy<Task<T>>
*/ */
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class ServerGreetCommand : DiscordCommand { internal class ServerGreetCommand : IDiscordCommand {
public static ConcurrentDictionary<ulong, AnnounceControls> AnnouncementsDictionary; public static ConcurrentDictionary<ulong, AnnounceControls> AnnouncementsDictionary;
@ -33,11 +33,11 @@ namespace NadekoBot.Commands {
NadekoBot.Client.UserJoined += UserJoined; NadekoBot.Client.UserJoined += UserJoined;
NadekoBot.Client.UserLeft += UserLeft; NadekoBot.Client.UserLeft += UserLeft;
List<Classes._DataModels.Announcement> data = Classes.DbHandler.Instance.GetAllRows<Classes._DataModels.Announcement>(); var data = Classes.DbHandler.Instance.GetAllRows<Classes._DataModels.Announcement>();
if (data.Any()) if (!data.Any()) return;
foreach (var obj in data) foreach (var obj in data)
AnnouncementsDictionary.TryAdd((ulong)obj.ServerId, new AnnounceControls(obj)); AnnouncementsDictionary.TryAdd((ulong)obj.ServerId, new AnnounceControls(obj));
} }
private async void UserLeft(object sender, UserEventArgs e) { private async void UserLeft(object sender, UserEventArgs e) {
@ -172,11 +172,11 @@ namespace NadekoBot.Commands {
} }
} }
public override Func<CommandEventArgs, Task> DoFunc() { public Func<CommandEventArgs, Task> DoFunc() {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(".greet") cgb.CreateCommand(".greet")
.Description("Enables or Disables anouncements on the current channel when someone joins the server.") .Description("Enables or Disables anouncements on the current channel when someone joins the server.")

View File

@ -21,12 +21,12 @@ namespace NadekoBot.Commands {
} }
public class TypingGame { public class TypingGame {
public static float WORD_VALUE { get; } = 4.5f; public const float WORD_VALUE = 4.5f;
private Channel channel; private readonly Channel channel;
public string currentSentence; public string CurrentSentence;
public bool IsActive; public bool IsActive;
private Stopwatch sw; private readonly Stopwatch sw;
private List<ulong> finishedUserIds; private readonly List<ulong> finishedUserIds;
public TypingGame(Channel channel) { public TypingGame(Channel channel) {
this.channel = channel; this.channel = channel;
@ -49,32 +49,33 @@ namespace NadekoBot.Commands {
} }
internal async Task Start() { internal async Task Start() {
if (IsActive) return; // can't start running game while (true) {
IsActive = true; if (IsActive) return; // can't start running game
currentSentence = SentencesProvider.GetRandomSentence(); IsActive = true;
int i = (int)(currentSentence.Length / WORD_VALUE * 1.7f); CurrentSentence = SentencesProvider.GetRandomSentence();
await channel.SendMessage($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can."); var i = (int) (CurrentSentence.Length/WORD_VALUE*1.7f);
await channel.SendMessage($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.");
var msg = await channel.SendMessage("Starting new typing contest in **3**..."); var msg = await channel.SendMessage("Starting new typing contest in **3**...");
await Task.Delay(1000);
await msg.Edit("Starting new typing contest in **2**...");
await Task.Delay(1000);
await msg.Edit("Starting new typing contest in **1**...");
await Task.Delay(1000);
await msg.Edit($":book:**{currentSentence.Replace(" ", " \x200B")}**:book:");
sw.Start();
HandleAnswers();
while (i > 0) {
await Task.Delay(1000); await Task.Delay(1000);
i--; await msg.Edit("Starting new typing contest in **2**...");
if (!IsActive) await Task.Delay(1000);
return; await msg.Edit("Starting new typing contest in **1**...");
} await Task.Delay(1000);
await msg.Edit($":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:");
sw.Start();
HandleAnswers();
await Stop(); while (i > 0) {
await Start(); await Task.Delay(1000);
i--;
if (!IsActive)
return;
}
await Stop();
}
} }
private void HandleAnswers() { private void HandleAnswers() {
@ -87,13 +88,13 @@ namespace NadekoBot.Commands {
var guess = e.Message.RawText; var guess = e.Message.RawText;
var distance = currentSentence.LevenshteinDistance(guess); var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length); var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(e.User.Id)) { if (decision && !finishedUserIds.Contains(e.User.Id)) {
finishedUserIds.Add(e.User.Id); finishedUserIds.Add(e.User.Id);
await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ currentSentence.Length / TypingGame.WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!"); await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / TypingGame.WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!");
if (finishedUserIds.Count % 2 == 0) { if (finishedUserIds.Count % 2 == 0) {
await e.Channel.SendMessage($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{currentSentence}**:book:"); await e.Channel.SendMessage($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:");
} }
} }
@ -105,7 +106,7 @@ namespace NadekoBot.Commands {
} }
internal class SpeedTyping : DiscordCommand { internal class SpeedTyping : IDiscordCommand {
private static Dictionary<ulong, TypingGame> runningContests; private static Dictionary<ulong, TypingGame> runningContests;
@ -113,7 +114,7 @@ namespace NadekoBot.Commands {
runningContests = new Dictionary<ulong, TypingGame>(); runningContests = new Dictionary<ulong, TypingGame>();
} }
public override Func<CommandEventArgs, Task> DoFunc() => public Func<CommandEventArgs, Task> DoFunc() =>
async e => { async e => {
if (runningContests.ContainsKey(e.User.Server.Id) && runningContests[e.User.Server.Id].IsActive) { if (runningContests.ContainsKey(e.User.Server.Id) && runningContests[e.User.Server.Id].IsActive) {
await e.Channel.SendMessage($"Contest already running in { runningContests[e.User.Server.Id].Channell.Mention } channel."); await e.Channel.SendMessage($"Contest already running in { runningContests[e.User.Server.Id].Channell.Mention } channel.");
@ -138,7 +139,7 @@ namespace NadekoBot.Commands {
await e.Channel.SendMessage("No contest to stop on this channel."); await e.Channel.SendMessage("No contest to stop on this channel.");
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("typestart") cgb.CreateCommand("typestart")
.Description("Starts a typing contest.") .Description("Starts a typing contest.")
.Do(DoFunc()); .Do(DoFunc());

View File

@ -6,10 +6,10 @@ using Discord;
using TriviaGame = NadekoBot.Classes.Trivia.TriviaGame; using TriviaGame = NadekoBot.Classes.Trivia.TriviaGame;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class Trivia : DiscordCommand { internal class Trivia : IDiscordCommand {
public static ConcurrentDictionary<Server, TriviaGame> runningTrivias = new ConcurrentDictionary<Server, TriviaGame>(); public static ConcurrentDictionary<Server, TriviaGame> runningTrivias = new ConcurrentDictionary<Server, TriviaGame>();
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
TriviaGame trivia; TriviaGame trivia;
if (!runningTrivias.TryGetValue(e.Server, out trivia)) { if (!runningTrivias.TryGetValue(e.Server, out trivia)) {
var triviaGame = new TriviaGame(e); var triviaGame = new TriviaGame(e);
@ -21,7 +21,7 @@ namespace NadekoBot.Commands {
await e.Channel.SendMessage("Trivia game is already running on this server.\n" + trivia.CurrentQuestion); await e.Channel.SendMessage("Trivia game is already running on this server.\n" + trivia.CurrentQuestion);
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("t") cgb.CreateCommand("t")
.Description("Starts a game of trivia.") .Description("Starts a game of trivia.")
.Alias("-t") .Alias("-t")

View File

@ -6,17 +6,12 @@ using System.Collections.Concurrent;
using Discord; using Discord;
namespace NadekoBot.Commands { namespace NadekoBot.Commands {
internal class VoiceNotificationCommand : DiscordCommand { internal class VoiceNotificationCommand : IDiscordCommand {
public VoiceNotificationCommand() {
//NadekoBot.client.
}
//voicechannel/text channel //voicechannel/text channel
private ConcurrentDictionary<Channel, Channel> subscribers = new ConcurrentDictionary<Channel, Channel>(); private readonly ConcurrentDictionary<Channel, Channel> subscribers = new ConcurrentDictionary<Channel, Channel>();
public override Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> DoFunc() => async e => {
var arg = e.GetArg("voice_name"); var arg = e.GetArg("voice_name");
if (string.IsNullOrWhiteSpace("voice_name")) if (string.IsNullOrWhiteSpace("voice_name"))
return; return;
@ -32,7 +27,7 @@ namespace NadekoBot.Commands {
} }
}; };
public override void Init(CommandGroupBuilder cgb) { public void Init(CommandGroupBuilder cgb) {
/* /*
cgb.CreateCommand(".voicenotif") cgb.CreateCommand(".voicenotif")
.Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club") .Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club")

View File

@ -4,10 +4,7 @@ using NadekoBot.Commands;
namespace NadekoBot.Modules { namespace NadekoBot.Modules {
internal abstract class DiscordModule : IModule { internal abstract class DiscordModule : IModule {
protected List<DiscordCommand> commands = new List<DiscordCommand>(); protected readonly HashSet<IDiscordCommand> commands = new HashSet<IDiscordCommand>();
protected DiscordModule() {
}
public abstract void Install(ModuleManager manager); public abstract void Install(ModuleManager manager);
} }

View File

@ -4,6 +4,8 @@ using Discord.Modules;
using NadekoBot.Commands; using NadekoBot.Commands;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.IO; using System.IO;
using NadekoBot.Extensions;
//🃏 //🃏
//🏁 //🏁
namespace NadekoBot.Modules { namespace NadekoBot.Modules {

View File

@ -2,6 +2,7 @@
using Discord.Modules; using Discord.Modules;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Commands; using NadekoBot.Commands;
using NadekoBot.Extensions;
namespace NadekoBot.Modules { namespace NadekoBot.Modules {
internal class Help : DiscordModule { internal class Help : DiscordModule {

View File

@ -4,6 +4,7 @@ using Discord.Commands;
using NadekoBot.Classes; using NadekoBot.Classes;
using PermsHandler = NadekoBot.Classes.Permissions.PermissionsHandler; using PermsHandler = NadekoBot.Classes.Permissions.PermissionsHandler;
using System.Linq; using System.Linq;
using NadekoBot.Extensions;
namespace NadekoBot.Modules { namespace NadekoBot.Modules {
internal class PermissionModule : DiscordModule { internal class PermissionModule : DiscordModule {
@ -14,7 +15,6 @@ namespace NadekoBot.Modules {
} }
//todo word filtering/invite bans (?:discord(?:\.gg|app\.com\/invite)\/(?<id>([\w]{16}|(?:[\w]+-?){3}))) //todo word filtering/invite bans (?:discord(?:\.gg|app\.com\/invite)\/(?<id>([\w]{16}|(?:[\w]+-?){3})))
public override void Install(ModuleManager manager) { public override void Install(ModuleManager manager) {
var client = NadekoBot.Client;
manager.CreateCommands("", cgb => { manager.CreateCommands("", cgb => {
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance); cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
@ -75,7 +75,7 @@ namespace NadekoBot.Modules {
var role = e.Server.EveryoneRole; var role = e.Server.EveryoneRole;
if (!string.IsNullOrWhiteSpace(arg)) if (!string.IsNullOrWhiteSpace(arg))
try { try {
role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role")); role = PermissionHelper.ValidateRole(e.Server, arg);
} }
catch (Exception ex) { catch (Exception ex) {
await e.Channel.SendMessage("💢 Error: " + ex.Message); await e.Channel.SendMessage("💢 Error: " + ex.Message);
@ -98,7 +98,7 @@ namespace NadekoBot.Modules {
var channel = e.Channel; var channel = e.Channel;
if (!string.IsNullOrWhiteSpace(arg)) if (!string.IsNullOrWhiteSpace(arg))
try { try {
channel = PermissionHelper.ValidateChannel(e.Server, e.GetArg("channel")); channel = PermissionHelper.ValidateChannel(e.Server, arg);
} }
catch (Exception ex) { catch (Exception ex) {
await e.Channel.SendMessage("💢 Error: " + ex.Message); await e.Channel.SendMessage("💢 Error: " + ex.Message);
@ -116,7 +116,6 @@ namespace NadekoBot.Modules {
.Description("Shows banned permissions for a certain user. No argument means for yourself.\n**Usage**: ;up Kwoth") .Description("Shows banned permissions for a certain user. No argument means for yourself.\n**Usage**: ;up Kwoth")
.Parameter("user", ParameterType.Unparsed) .Parameter("user", ParameterType.Unparsed)
.Do(async e => { .Do(async e => {
var arg = e.GetArg("user");
var user = e.User; var user = e.User;
if (!string.IsNullOrWhiteSpace(e.GetArg("user"))) if (!string.IsNullOrWhiteSpace(e.GetArg("user")))
try { try {

View File

@ -127,8 +127,8 @@ namespace NadekoBot.Modules {
var headers = new Dictionary<string, string> { { "X-Mashape-Key", NadekoBot.Creds.MashapeKey } }; var headers = new Dictionary<string, string> { { "X-Mashape-Key", NadekoBot.Creds.MashapeKey } };
var res = await SearchHelper.GetResponseStringAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}", headers); var res = await SearchHelper.GetResponseStringAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}", headers);
try { try {
var items = JArray.Parse(res) as JArray; var items = JArray.Parse(res);
var images = new List<System.Drawing.Image>(); var images = new List<Image>();
if (items == null) if (items == null)
throw new KeyNotFoundException("Cannot find a card by that name"); throw new KeyNotFoundException("Cannot find a card by that name");
var cnt = 0; var cnt = 0;

View File

@ -9,6 +9,7 @@ using Discord.Audio;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands.Permissions.Userlist;
using NadekoBot.Classes.JSONModels; using NadekoBot.Classes.JSONModels;
using NadekoBot.Commands; using NadekoBot.Commands;

View File

@ -155,7 +155,7 @@
<Compile Include="Classes\Extensions.cs" /> <Compile Include="Classes\Extensions.cs" />
<Compile Include="Commands\CopyCommand.cs" /> <Compile Include="Commands\CopyCommand.cs" />
<Compile Include="Commands\DiceRollCommand.cs" /> <Compile Include="Commands\DiceRollCommand.cs" />
<Compile Include="Commands\DiscordCommand.cs" /> <Compile Include="Commands\IDiscordCommand.cs" />
<Compile Include="Commands\DrawCommand.cs" /> <Compile Include="Commands\DrawCommand.cs" />
<Compile Include="Commands\FlipCoinCommand.cs" /> <Compile Include="Commands\FlipCoinCommand.cs" />
<Compile Include="Commands\HelpCommand.cs" /> <Compile Include="Commands\HelpCommand.cs" />