more cleanup, should build from now on - with frequent breaking changes tho.
This commit is contained in:
parent
af5d11d533
commit
d5442a4e42
@ -4,7 +4,7 @@ using System;
|
||||
|
||||
public class Cards
|
||||
{
|
||||
private static Dictionary<int, string> cardNames = new Dictionary<int, string>() {
|
||||
private static readonly Dictionary<int, string> cardNames = new Dictionary<int, string>() {
|
||||
{ 1, "Ace" },
|
||||
{ 2, "Two" },
|
||||
{ 3, "Three" },
|
||||
@ -17,13 +17,13 @@ public class Cards
|
||||
{ 10, "Ten" },
|
||||
{ 11, "Jack" },
|
||||
{ 12, "Queen" },
|
||||
{ 13, "King" },
|
||||
{ 13, "King" }
|
||||
};
|
||||
|
||||
private static Dictionary<string, Func<List<Card>, bool>> handValues;
|
||||
|
||||
|
||||
public enum CARD_SUIT
|
||||
public enum CardSuit
|
||||
{
|
||||
Spades = 1,
|
||||
Hearts = 2,
|
||||
@ -33,41 +33,41 @@ public class Cards
|
||||
|
||||
public class Card : IComparable
|
||||
{
|
||||
public CARD_SUIT suit;
|
||||
public int number;
|
||||
public CardSuit Suit { get; }
|
||||
public int Number { get; }
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
string str = "";
|
||||
var str = "";
|
||||
|
||||
if (number <= 10 && number > 1)
|
||||
if (Number <= 10 && Number > 1)
|
||||
{
|
||||
str += "_"+number;
|
||||
str += "_"+Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
str += GetName().ToLower();
|
||||
}
|
||||
return str + "_of_" + suit.ToString().ToLower();
|
||||
return str + "_of_" + Suit.ToString().ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
public Card(CARD_SUIT s, int card_num) {
|
||||
this.suit = s;
|
||||
this.number = card_num;
|
||||
public Card(CardSuit s, int cardNum) {
|
||||
this.Suit = s;
|
||||
this.Number = cardNum;
|
||||
}
|
||||
|
||||
public string GetName() => cardNames[number];
|
||||
public string GetName() => cardNames[Number];
|
||||
|
||||
public override string ToString() => cardNames[number] + " Of " + suit;
|
||||
public override string ToString() => cardNames[Number] + " Of " + Suit;
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (!(obj is Card)) return 0;
|
||||
var c = (Card)obj;
|
||||
return this.number - c.number;
|
||||
return this.Number - c.Number;
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,15 +101,15 @@ public class Cards
|
||||
{
|
||||
cardPool.Clear();
|
||||
//foreach suit
|
||||
for (int j = 1; j < 14; j++)
|
||||
for (var j = 1; j < 14; j++)
|
||||
{
|
||||
// and number
|
||||
for (int i = 1; i < 5; i++)
|
||||
for (var i = 1; i < 5; i++)
|
||||
{
|
||||
//generate a card of that suit and number and add it to the pool
|
||||
|
||||
// the pool will go from ace of spades,hears,diamonds,clubs all the way to the king of spades. hearts, ...
|
||||
cardPool.Add(new Card((CARD_SUIT)i, j));
|
||||
cardPool.Add(new Card((CardSuit)i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,8 +124,8 @@ public class Cards
|
||||
Restart();
|
||||
//you can either do this if your deck is not shuffled
|
||||
|
||||
int num = r.Next(0, cardPool.Count);
|
||||
Card c = cardPool[num];
|
||||
var num = r.Next(0, cardPool.Count);
|
||||
var c = cardPool[num];
|
||||
cardPool.RemoveAt(num);
|
||||
return c;
|
||||
|
||||
@ -140,44 +140,43 @@ public class Cards
|
||||
/// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method.
|
||||
/// </summary>
|
||||
private void Shuffle() {
|
||||
if (cardPool.Count > 1)
|
||||
{
|
||||
cardPool.OrderBy(x => r.Next());
|
||||
}
|
||||
if (cardPool.Count <= 1) return;
|
||||
var orderedPool = cardPool.OrderBy(x => r.Next());
|
||||
cardPool = cardPool as List<Card> ?? orderedPool.ToList();
|
||||
}
|
||||
public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine;
|
||||
|
||||
public void InitHandValues() {
|
||||
Func<List<Card>, bool> hasPair =
|
||||
cards => cards.GroupBy(card => card.number)
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count(group => group.Count() == 2) == 1;
|
||||
Func<List<Card>, bool> isPair =
|
||||
cards => cards.GroupBy(card => card.number)
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count(group => group.Count() == 3) == 0
|
||||
&& hasPair(cards);
|
||||
|
||||
Func<List<Card>, bool> isTwoPair =
|
||||
cards => cards.GroupBy(card => card.number)
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count(group => group.Count() == 2) == 2;
|
||||
|
||||
Func<List<Card>, bool> isStraight =
|
||||
cards => cards.GroupBy(card => card.number)
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count() == cards.Count()
|
||||
&& cards.Max(card => (int)card.number)
|
||||
- cards.Min(card => (int)card.number) == 4;
|
||||
&& cards.Max(card => (int)card.Number)
|
||||
- cards.Min(card => (int)card.Number) == 4;
|
||||
|
||||
Func<List<Card>, bool> hasThreeOfKind =
|
||||
cards => cards.GroupBy(card => card.number)
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Any(group => group.Count() == 3);
|
||||
|
||||
Func<List<Card>, bool> isThreeOfKind =
|
||||
cards => hasThreeOfKind(cards) && !hasPair(cards);
|
||||
|
||||
Func<List<Card>, bool> isFlush =
|
||||
cards => cards.GroupBy(card => card.suit).Count() == 1;
|
||||
cards => cards.GroupBy(card => card.Suit).Count() == 1;
|
||||
|
||||
Func<List<Card>, bool> isFourOfKind =
|
||||
cards => cards.GroupBy(card => card.number)
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Any(group => group.Count() == 4);
|
||||
|
||||
Func<List<Card>, bool> isFullHouse =
|
||||
@ -187,7 +186,7 @@ public class Cards
|
||||
cards => isFlush(cards) && isStraight(cards);
|
||||
|
||||
Func<List<Card>, bool> isRoyalFlush =
|
||||
cards => cards.Min(card => (int)card.number) == 10
|
||||
cards => cards.Min(card => card.Number) == 10
|
||||
&& hasStraightFlush(cards);
|
||||
|
||||
Func<List<Card>, bool> isStraightFlush =
|
||||
@ -207,13 +206,9 @@ public class Cards
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetHandValue(List<Card> cards)
|
||||
{
|
||||
foreach (var KVP in handValues)
|
||||
{
|
||||
if (KVP.Value(cards)) {
|
||||
return KVP.Key;
|
||||
}
|
||||
public static string GetHandValue(List<Card> cards) {
|
||||
foreach (var kvp in handValues.Where(x => x.Value(cards))) {
|
||||
return kvp.Key;
|
||||
}
|
||||
return "High card "+cards.Max().GetName();
|
||||
}
|
||||
|
@ -6,63 +6,62 @@ using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace NadekoBot.Classes {
|
||||
internal class DBHandler {
|
||||
private static readonly DBHandler _instance = new DBHandler();
|
||||
public static DBHandler Instance => _instance;
|
||||
internal class DbHandler {
|
||||
public static DbHandler Instance { get; } = new DbHandler();
|
||||
|
||||
private string _filePath { get; } = "data/nadekobot.sqlite";
|
||||
private string FilePath { get; } = "data/nadekobot.sqlite";
|
||||
|
||||
static DBHandler() { }
|
||||
public DBHandler() {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
_conn.CreateTable<Stats>();
|
||||
_conn.CreateTable<Command>();
|
||||
_conn.CreateTable<Announcement>();
|
||||
_conn.CreateTable<Request>();
|
||||
_conn.CreateTable<TypingArticle>();
|
||||
_conn.CreateTable<CurrencyState>();
|
||||
_conn.CreateTable<CurrencyTransaction>();
|
||||
_conn.CreateTable<Donator>();
|
||||
_conn.CreateTable<UserQuote>();
|
||||
_conn.Execute(Queries.TransactionTriggerQuery);
|
||||
static DbHandler() { }
|
||||
public DbHandler() {
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
conn.CreateTable<Stats>();
|
||||
conn.CreateTable<Command>();
|
||||
conn.CreateTable<Announcement>();
|
||||
conn.CreateTable<Request>();
|
||||
conn.CreateTable<TypingArticle>();
|
||||
conn.CreateTable<CurrencyState>();
|
||||
conn.CreateTable<CurrencyTransaction>();
|
||||
conn.CreateTable<Donator>();
|
||||
conn.CreateTable<UserQuote>();
|
||||
conn.Execute(Queries.TransactionTriggerQuery);
|
||||
}
|
||||
}
|
||||
|
||||
internal void InsertData<T>(T o) where T : IDataModel {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
_conn.Insert(o, typeof(T));
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
conn.Insert(o, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
internal void InsertMany<T>(T objects) where T : IEnumerable<IDataModel> {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
_conn.InsertAll(objects);
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
conn.InsertAll(objects);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateData<T>(T o) where T : IDataModel {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
_conn.Update(o, typeof(T));
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
conn.Update(o, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
internal List<T> GetAllRows<T>() where T : IDataModel, new() {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
return _conn.Table<T>().ToList();
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
return conn.Table<T>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
internal CurrencyState GetStateByUserId(long Id) {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
return _conn.Table<CurrencyState>().Where(x => x.UserId == Id).FirstOrDefault();
|
||||
internal CurrencyState GetStateByUserId(long id) {
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
return conn.Table<CurrencyState>().Where(x => x.UserId == id).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
internal T Delete<T>(int Id) where T : IDataModel, new() {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
var found = _conn.Find<T>(Id);
|
||||
internal T Delete<T>(int id) where T : IDataModel, new() {
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
var found = conn.Find<T>(id);
|
||||
if (found != null)
|
||||
_conn.Delete<T>(found.Id);
|
||||
conn.Delete<T>(found.Id);
|
||||
return found;
|
||||
}
|
||||
}
|
||||
@ -71,19 +70,19 @@ namespace NadekoBot.Classes {
|
||||
/// Updates an existing object or creates a new one
|
||||
/// </summary>
|
||||
internal void Save<T>(T o) where T : IDataModel, new() {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
var found = _conn.Find<T>(o.Id);
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
var found = conn.Find<T>(o.Id);
|
||||
if (found == null)
|
||||
_conn.Insert(o, typeof(T));
|
||||
conn.Insert(o, typeof(T));
|
||||
else
|
||||
_conn.Update(o, typeof(T));
|
||||
conn.Update(o, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
internal T GetRandom<T>(Expression<Func<T, bool>> p) where T : IDataModel, new() {
|
||||
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||
using (var conn = new SQLiteConnection(FilePath)) {
|
||||
var r = new Random();
|
||||
return _conn.Table<T>().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault();
|
||||
return conn.Table<T>().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ namespace NadekoBot.Extensions {
|
||||
public static string Scramble(this string word) {
|
||||
|
||||
var letters = word.ToArray();
|
||||
int count = 0;
|
||||
for (int i = 0; i < letters.Length; i++) {
|
||||
var count = 0;
|
||||
for (var i = 0; i < letters.Length; i++) {
|
||||
if (letters[i] == ' ')
|
||||
continue;
|
||||
|
||||
@ -34,11 +34,11 @@ namespace NadekoBot.Extensions {
|
||||
}
|
||||
public static string TrimTo(this string str, int num) {
|
||||
if (num < 0)
|
||||
throw new ArgumentException("TrimTo argument cannot be less than 0");
|
||||
throw new ArgumentOutOfRangeException(nameof(num), "TrimTo argument cannot be less than 0");
|
||||
if (num == 0)
|
||||
return String.Empty;
|
||||
return string.Empty;
|
||||
if (num <= 3)
|
||||
return String.Join("", str.Select(c => '.'));
|
||||
return string.Join("", str.Select(c => '.'));
|
||||
if (str.Length < num)
|
||||
return str;
|
||||
return string.Join("", str.Take(num - 3)) + "...";
|
||||
@ -131,16 +131,16 @@ namespace NadekoBot.Extensions {
|
||||
/// <param name="list"></param>
|
||||
public static void Shuffle<T>(this IList<T> list)
|
||||
{
|
||||
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
|
||||
int n = list.Count;
|
||||
var provider = new RNGCryptoServiceProvider();
|
||||
var n = list.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
byte[] box = new byte[1];
|
||||
var box = new byte[1];
|
||||
do provider.GetBytes(box);
|
||||
while (!(box[0] < n * (Byte.MaxValue / n)));
|
||||
int k = (box[0] % n);
|
||||
while (!(box[0] < n * (byte.MaxValue / n)));
|
||||
var k = (box[0] % n);
|
||||
n--;
|
||||
T value = list[k];
|
||||
var value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
@ -163,16 +163,16 @@ namespace NadekoBot.Extensions {
|
||||
public static string GetRuntime(this DiscordClient c) => ".Net Framework 4.5.2";
|
||||
|
||||
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
|
||||
foreach (T element in source) {
|
||||
foreach (var element in source) {
|
||||
action(element);
|
||||
}
|
||||
}
|
||||
|
||||
//http://www.dotnetperls.com/levenshtein
|
||||
public static int LevenshteinDistance(this string s, string t) {
|
||||
int n = s.Length;
|
||||
int m = t.Length;
|
||||
int[,] d = new int[n + 1, m + 1];
|
||||
var n = s.Length;
|
||||
var m = t.Length;
|
||||
var d = new int[n + 1, m + 1];
|
||||
|
||||
// Step 1
|
||||
if (n == 0) {
|
||||
@ -184,18 +184,18 @@ namespace NadekoBot.Extensions {
|
||||
}
|
||||
|
||||
// Step 2
|
||||
for (int i = 0; i <= n; d[i, 0] = i++) {
|
||||
for (var i = 0; i <= n; d[i, 0] = i++) {
|
||||
}
|
||||
|
||||
for (int j = 0; j <= m; d[0, j] = j++) {
|
||||
for (var j = 0; j <= m; d[0, j] = j++) {
|
||||
}
|
||||
|
||||
// Step 3
|
||||
for (int i = 1; i <= n; i++) {
|
||||
for (var i = 1; i <= n; i++) {
|
||||
//Step 4
|
||||
for (int j = 1; j <= m; j++) {
|
||||
for (var j = 1; j <= m; j++) {
|
||||
// Step 5
|
||||
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
|
||||
var cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
|
||||
|
||||
// Step 6
|
||||
d[i, j] = Math.Min(
|
||||
@ -219,7 +219,7 @@ namespace NadekoBot.Extensions {
|
||||
public static Stream ToStream(this Image img, System.Drawing.Imaging.ImageFormat format = null) {
|
||||
if (format == null)
|
||||
format = System.Drawing.Imaging.ImageFormat.Jpeg;
|
||||
MemoryStream stream = new MemoryStream();
|
||||
var stream = new MemoryStream();
|
||||
img.Save(stream, format);
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
@ -231,16 +231,17 @@ namespace NadekoBot.Extensions {
|
||||
/// <param name="images">The Images you want to merge.</param>
|
||||
/// <returns>Merged bitmap</returns>
|
||||
public static Bitmap Merge(this IEnumerable<Image> images,int reverseScaleFactor = 1) {
|
||||
if (images.Count() == 0) return null;
|
||||
int width = images.Sum(i => i.Width);
|
||||
int height = images.First().Height ;
|
||||
Bitmap bitmap = new Bitmap(width / reverseScaleFactor, height / reverseScaleFactor);
|
||||
var imageArray = images as Image[] ?? images.ToArray();
|
||||
if (!imageArray.Any()) return null;
|
||||
var width = imageArray.Sum(i => i.Width);
|
||||
var height = imageArray.First().Height ;
|
||||
var bitmap = new Bitmap(width / reverseScaleFactor, height / reverseScaleFactor);
|
||||
var r = new Random();
|
||||
int offsetx = 0;
|
||||
foreach (var img in images) {
|
||||
Bitmap bm = new Bitmap(img);
|
||||
for (int w = 0; w < img.Width; w++) {
|
||||
for (int h = 0; h < bitmap.Height; h++) {
|
||||
var offsetx = 0;
|
||||
foreach (var img in imageArray) {
|
||||
var bm = new Bitmap(img);
|
||||
for (var w = 0; w < img.Width; w++) {
|
||||
for (var h = 0; h < bitmap.Height; h++) {
|
||||
bitmap.SetPixel(w / reverseScaleFactor + offsetx, h , bm.GetPixel(w, h *reverseScaleFactor));
|
||||
}
|
||||
}
|
||||
@ -248,10 +249,12 @@ namespace NadekoBot.Extensions {
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges Images into 1 Image and returns a bitmap asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="images">The Images you want to merge.</param>
|
||||
/// <param name="reverseScaleFactor"></param>
|
||||
/// <returns>Merged bitmap</returns>
|
||||
public static async Task<Bitmap> MergeAsync(this IEnumerable<Image> images, int reverseScaleFactor = 1) =>
|
||||
await Task.Run(() => images.Merge(reverseScaleFactor));
|
||||
|
@ -6,14 +6,14 @@ namespace NadekoBot.Classes {
|
||||
if (amount <= 0)
|
||||
return;
|
||||
await Task.Run(() => {
|
||||
DBHandler.Instance.InsertData(new _DataModels.CurrencyTransaction {
|
||||
DbHandler.Instance.InsertData(new _DataModels.CurrencyTransaction {
|
||||
Reason = reason,
|
||||
UserId = (long)u.Id,
|
||||
Value = amount,
|
||||
});
|
||||
});
|
||||
string flows = "";
|
||||
for (int i = 0; i < amount; i++) {
|
||||
var flows = "";
|
||||
for (var i = 0; i < amount; i++) {
|
||||
flows += "🌸";
|
||||
}
|
||||
await u.SendMessage("👑Congratulations!👑\nYou got: "+flows);
|
||||
|
@ -11,8 +11,6 @@ namespace NadekoBot {
|
||||
public class NadekoStats {
|
||||
public static NadekoStats Instance { get; } = new NadekoStats();
|
||||
|
||||
private readonly CommandService commandService;
|
||||
|
||||
public string BotVersion => $"{Assembly.GetExecutingAssembly().GetName().Name} v{Assembly.GetExecutingAssembly().GetName().Version}";
|
||||
|
||||
private int _commandsRan = 0;
|
||||
@ -26,7 +24,7 @@ namespace NadekoBot {
|
||||
static NadekoStats() { }
|
||||
|
||||
private NadekoStats() {
|
||||
commandService = NadekoBot.Client.GetService<CommandService>();
|
||||
var commandService = NadekoBot.Client.GetService<CommandService>();
|
||||
|
||||
statsStopwatch = new Stopwatch();
|
||||
statsStopwatch.Start();
|
||||
@ -37,8 +35,9 @@ namespace NadekoBot {
|
||||
|
||||
ServerCount = NadekoBot.Client.Servers.Count();
|
||||
var channels = NadekoBot.Client.Servers.SelectMany(s => s.AllChannels);
|
||||
TextChannelsCount = channels.Count(c => c.Type == ChannelType.Text);
|
||||
VoiceChannelsCount = channels.Count() - TextChannelsCount;
|
||||
var channelsArray = channels as Channel[] ?? channels.ToArray();
|
||||
TextChannelsCount = channelsArray.Count(c => c.Type == ChannelType.Text);
|
||||
VoiceChannelsCount = channelsArray.Count() - TextChannelsCount;
|
||||
|
||||
NadekoBot.Client.JoinedServer += (s, e) => {
|
||||
try {
|
||||
@ -123,7 +122,7 @@ namespace NadekoBot {
|
||||
.Sum(x => x.Users.Count(u => u.Status == UserStatus.Online)));
|
||||
var connectedServers = NadekoBot.Client.Servers.Count();
|
||||
|
||||
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.Stats {
|
||||
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Stats {
|
||||
OnlineUsers = onlineUsers,
|
||||
RealOnlineUsers = realOnlineUsers,
|
||||
Uptime = GetUptime(),
|
||||
@ -141,7 +140,7 @@ namespace NadekoBot {
|
||||
private void StatsCollector_RanCommand(object sender, CommandEventArgs e) {
|
||||
try {
|
||||
_commandsRan++;
|
||||
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.Command {
|
||||
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.Command {
|
||||
ServerId = (long)e.Server.Id,
|
||||
ServerName = e.Server.Name,
|
||||
ChannelId = (long)e.Channel.Id,
|
||||
|
@ -7,8 +7,7 @@ using System.Collections.Concurrent;
|
||||
|
||||
namespace NadekoBot.Classes.Permissions {
|
||||
internal class PermissionChecker : IPermissionChecker {
|
||||
public static readonly PermissionChecker _instance = new PermissionChecker();
|
||||
public static PermissionChecker Instance => _instance;
|
||||
public static PermissionChecker Instance { get; } = new PermissionChecker();
|
||||
|
||||
private ConcurrentDictionary<User, DateTime> timeBlackList { get; } = new ConcurrentDictionary<User, DateTime>();
|
||||
|
||||
|
@ -146,10 +146,12 @@ namespace NadekoBot.Classes {
|
||||
return obj.items[0].id.playlistId.ToString();
|
||||
}
|
||||
|
||||
public static async Task<IEnumerable<string>> GetVideoIDs(string playlist) {
|
||||
public static async Task<IEnumerable<string>> GetVideoIDs(string playlist, int number = 30) {
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey)) {
|
||||
throw new ArgumentNullException(nameof(playlist));
|
||||
}
|
||||
if (number < 1 || number > 100)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
var link =
|
||||
$"https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails" +
|
||||
$"&maxResults={30}" +
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -12,8 +13,8 @@ namespace NadekoBot.Classes.Trivia {
|
||||
internal class TriviaGame {
|
||||
private readonly object _guessLock = new object();
|
||||
|
||||
private Server _server { get; }
|
||||
private Channel _channel { get; }
|
||||
private Server server { get; }
|
||||
private Channel channel { get; }
|
||||
|
||||
private int QuestionDurationMiliseconds { get; } = 30000;
|
||||
private int HintTimeoutMiliseconds { get; } = 6000;
|
||||
@ -22,7 +23,7 @@ namespace NadekoBot.Classes.Trivia {
|
||||
public TriviaQuestion CurrentQuestion { get; private set; }
|
||||
public List<TriviaQuestion> oldQuestions { get; } = new List<TriviaQuestion>();
|
||||
|
||||
public ConcurrentDictionary<User, int> users { get; } = new ConcurrentDictionary<User, int>();
|
||||
public ConcurrentDictionary<User, int> Users { get; } = new ConcurrentDictionary<User, int>();
|
||||
|
||||
public bool GameActive { get; private set; } = false;
|
||||
public bool ShouldStopGame { get; private set; }
|
||||
@ -30,9 +31,9 @@ namespace NadekoBot.Classes.Trivia {
|
||||
public int WinRequirement { get; } = 10;
|
||||
|
||||
public TriviaGame(CommandEventArgs e) {
|
||||
_server = e.Server;
|
||||
_channel = e.Channel;
|
||||
Task.Run(() => StartGame());
|
||||
server = e.Server;
|
||||
channel = e.Channel;
|
||||
Task.Run(StartGame);
|
||||
}
|
||||
|
||||
private async Task StartGame() {
|
||||
@ -43,13 +44,13 @@ namespace NadekoBot.Classes.Trivia {
|
||||
// load question
|
||||
CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(oldQuestions);
|
||||
if (CurrentQuestion == null) {
|
||||
await _channel.SendMessage($":exclamation: Failed loading a trivia question");
|
||||
End().Wait();
|
||||
await channel.SendMessage($":exclamation: Failed loading a trivia question");
|
||||
await End();
|
||||
return;
|
||||
}
|
||||
oldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again
|
||||
//sendquestion
|
||||
await _channel.SendMessage($":question: **{CurrentQuestion.Question}**");
|
||||
await channel.SendMessage($":question: **{CurrentQuestion.Question}**");
|
||||
|
||||
//receive messages
|
||||
NadekoBot.Client.MessageReceived += PotentialGuess;
|
||||
@ -60,7 +61,7 @@ namespace NadekoBot.Classes.Trivia {
|
||||
try {
|
||||
//hint
|
||||
await Task.Delay(HintTimeoutMiliseconds, token);
|
||||
await _channel.SendMessage($":exclamation:**Hint:** {CurrentQuestion.GetHint()}");
|
||||
await channel.SendMessage($":exclamation:**Hint:** {CurrentQuestion.GetHint()}");
|
||||
|
||||
//timeout
|
||||
await Task.Delay(QuestionDurationMiliseconds - HintTimeoutMiliseconds, token);
|
||||
@ -70,7 +71,7 @@ namespace NadekoBot.Classes.Trivia {
|
||||
}
|
||||
GameActive = false;
|
||||
if (!triviaCancelSource.IsCancellationRequested)
|
||||
await _channel.Send($":clock2: :question: **Time's up!** The correct answer was **{CurrentQuestion.Answer}**");
|
||||
await channel.Send($":clock2: :question: **Time's up!** The correct answer was **{CurrentQuestion.Answer}**");
|
||||
NadekoBot.Client.MessageReceived -= PotentialGuess;
|
||||
// load next question if game is still running
|
||||
await Task.Delay(2000);
|
||||
@ -80,58 +81,53 @@ namespace NadekoBot.Classes.Trivia {
|
||||
|
||||
private async Task End() {
|
||||
ShouldStopGame = true;
|
||||
await _channel.SendMessage("**Trivia game ended**\n"+GetLeaderboard());
|
||||
await channel.SendMessage("**Trivia game ended**\n" + GetLeaderboard());
|
||||
TriviaGame throwAwayValue;
|
||||
Commands.Trivia.runningTrivias.TryRemove(_server, out throwAwayValue);
|
||||
Commands.Trivia.runningTrivias.TryRemove(server, out throwAwayValue);
|
||||
}
|
||||
|
||||
public async Task StopGame() {
|
||||
if (!ShouldStopGame)
|
||||
await _channel.SendMessage(":exclamation: Trivia will stop after this question.");
|
||||
await channel.SendMessage(":exclamation: Trivia will stop after this question.");
|
||||
ShouldStopGame = true;
|
||||
}
|
||||
|
||||
private async void PotentialGuess(object sender, MessageEventArgs e) {
|
||||
try {
|
||||
if (e.Channel.IsPrivate) return;
|
||||
if (e.Server != _server) return;
|
||||
if (e.Server != server) return;
|
||||
|
||||
bool guess = false;
|
||||
var guess = false;
|
||||
lock (_guessLock) {
|
||||
if (GameActive && CurrentQuestion.IsAnswerCorrect(e.Message.Text) && !triviaCancelSource.IsCancellationRequested) {
|
||||
users.TryAdd(e.User, 0); //add if not exists
|
||||
users[e.User]++; //add 1 point to the winner
|
||||
Users.TryAdd(e.User, 0); //add if not exists
|
||||
Users[e.User]++; //add 1 point to the winner
|
||||
guess = true;
|
||||
}
|
||||
}
|
||||
if (guess) {
|
||||
triviaCancelSource.Cancel();
|
||||
await _channel.SendMessage($"☑️ {e.User.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**");
|
||||
if (users[e.User] == WinRequirement) {
|
||||
ShouldStopGame = true;
|
||||
await _channel.Send($":exclamation: We have a winner! Its {e.User.Mention}.");
|
||||
// add points to the winner
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Won Trivia", 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
if (!guess) return;
|
||||
triviaCancelSource.Cancel();
|
||||
await channel.SendMessage($"☑️ {e.User.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**");
|
||||
if (Users[e.User] != WinRequirement) return;
|
||||
ShouldStopGame = true;
|
||||
await channel.Send($":exclamation: We have a winner! Its {e.User.Mention}.");
|
||||
// add points to the winner
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Won Trivia", 2);
|
||||
} catch { }
|
||||
}
|
||||
|
||||
public string GetLeaderboard() {
|
||||
if (users.Count == 0)
|
||||
if (Users.Count == 0)
|
||||
return "";
|
||||
|
||||
string str = "**Leaderboard:**\n-----------\n";
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("**Leaderboard:**\n-----------\n");
|
||||
|
||||
if (users.Count > 1)
|
||||
users.OrderBy(kvp => kvp.Value);
|
||||
|
||||
foreach (var kvp in users) {
|
||||
str += $"**{kvp.Key.Name}** has {kvp.Value} points".ToString().SnPl(kvp.Value) + Environment.NewLine;
|
||||
foreach (var kvp in Users.OrderBy(kvp => kvp.Value)) {
|
||||
sb.AppendLine($"**{kvp.Key.Name}** has {kvp.Value} points".ToString().SnPl(kvp.Value));
|
||||
}
|
||||
|
||||
return str;
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,18 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace NadekoBot.Commands {
|
||||
internal class ClashOfClans : DiscordCommand {
|
||||
|
||||
private static string prefix = ",";
|
||||
private const string prefix = ",";
|
||||
|
||||
public static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; } = new ConcurrentDictionary<ulong, List<ClashWar>>();
|
||||
|
||||
private object writeLock { get; } = new object();
|
||||
private readonly object writeLock = new object();
|
||||
|
||||
public ClashOfClans() {
|
||||
public ClashOfClans() {
|
||||
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ namespace NadekoBot.Commands {
|
||||
if (!ClashWars.TryAdd(e.Server.Id, wars))
|
||||
return;
|
||||
}
|
||||
string enemyClan = e.GetArg("enemy_clan");
|
||||
var enemyClan = e.GetArg("enemy_clan");
|
||||
if (string.IsNullOrWhiteSpace(enemyClan)) {
|
||||
return;
|
||||
}
|
||||
@ -70,10 +70,10 @@ namespace NadekoBot.Commands {
|
||||
}
|
||||
var war = warsInfo.Item1[warsInfo.Item2];
|
||||
try {
|
||||
war.Start();
|
||||
var startTask = war.Start();
|
||||
await e.Channel.SendMessage($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**");
|
||||
}
|
||||
catch {
|
||||
await startTask;
|
||||
} catch {
|
||||
await e.Channel.SendMessage($"🔰**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**");
|
||||
}
|
||||
});
|
||||
@ -96,7 +96,7 @@ namespace NadekoBot.Commands {
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("🔰 **LIST OF ACTIVE WARS**");
|
||||
sb.AppendLine("**-------------------------**");
|
||||
for (int i = 0; i < wars.Count; i++) {
|
||||
for (var i = 0; i < wars.Count; i++) {
|
||||
sb.AppendLine($"**#{i + 1}.** `Enemy:` **{wars[i].EnemyClan}**");
|
||||
sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**");
|
||||
sb.AppendLine("**-------------------------**");
|
||||
@ -131,16 +131,15 @@ namespace NadekoBot.Commands {
|
||||
await e.Channel.SendMessage("💢🔰 **Invalid base number.**");
|
||||
return;
|
||||
}
|
||||
string usr =
|
||||
var usr =
|
||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||
e.User.Name :
|
||||
e.GetArg("other_name");
|
||||
try {
|
||||
var war = warsInfo.Item1[warsInfo.Item2];
|
||||
await war.Call(usr, baseNum - 1);
|
||||
war.Call(usr, baseNum - 1);
|
||||
await e.Channel.SendMessage($"🔰**{usr}** claimed a base #{baseNum} for a war against {war.ShortPrint()}");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
||||
}
|
||||
});
|
||||
@ -156,7 +155,7 @@ namespace NadekoBot.Commands {
|
||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||
return;
|
||||
}
|
||||
string usr =
|
||||
var usr =
|
||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||
e.User.Name :
|
||||
e.GetArg("other_name");
|
||||
@ -165,8 +164,7 @@ namespace NadekoBot.Commands {
|
||||
try {
|
||||
var baseNum = war.FinishClaim(usr);
|
||||
await e.Channel.SendMessage($"❗🔰{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
||||
}
|
||||
});
|
||||
@ -183,16 +181,15 @@ namespace NadekoBot.Commands {
|
||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**");
|
||||
return;
|
||||
}
|
||||
string usr =
|
||||
var usr =
|
||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||
e.User.Name :
|
||||
e.GetArg("other_name");
|
||||
try {
|
||||
var war = warsInfo.Item1[warsInfo.Item2];
|
||||
int baseNumber = war.Uncall(usr);
|
||||
var baseNumber = war.Uncall(usr);
|
||||
await e.Channel.SendMessage($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}");
|
||||
}
|
||||
});
|
||||
@ -236,12 +233,12 @@ namespace NadekoBot.Commands {
|
||||
}
|
||||
warsInfo.Item1[warsInfo.Item2].End();
|
||||
|
||||
int size = warsInfo.Item1[warsInfo.Item2].Size;
|
||||
var size = warsInfo.Item1[warsInfo.Item2].Size;
|
||||
warsInfo.Item1.RemoveAt(warsInfo.Item2);
|
||||
});
|
||||
}
|
||||
|
||||
private Tuple<List<ClashWar>, int> GetInfo(CommandEventArgs e) {
|
||||
private static Tuple<List<ClashWar>, int> GetInfo(CommandEventArgs e) {
|
||||
//check if there are any wars
|
||||
List<ClashWar> wars = null;
|
||||
ClashWars.TryGetValue(e.Server.Id, out wars);
|
||||
@ -262,67 +259,65 @@ namespace NadekoBot.Commands {
|
||||
}
|
||||
|
||||
internal class Caller {
|
||||
private string _user;
|
||||
public string CallUser { get; }
|
||||
|
||||
public string CallUser
|
||||
{
|
||||
get { return _user; }
|
||||
set { _user = value; }
|
||||
}
|
||||
|
||||
private DateTime timeAdded;
|
||||
|
||||
public DateTime TimeAdded
|
||||
{
|
||||
get { return timeAdded; }
|
||||
set { timeAdded = value; }
|
||||
}
|
||||
public DateTime TimeAdded { get; private set; }
|
||||
|
||||
public bool BaseDestroyed { get; internal set; }
|
||||
|
||||
public Caller(string callUser, DateTime timeAdded, bool baseDestroyed) {
|
||||
CallUser = callUser;
|
||||
TimeAdded = timeAdded;
|
||||
BaseDestroyed = baseDestroyed;
|
||||
}
|
||||
|
||||
public void ResetTime() {
|
||||
TimeAdded = DateTime.Now;
|
||||
}
|
||||
|
||||
public void Destroy() {
|
||||
BaseDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ClashWar {
|
||||
|
||||
public static TimeSpan callExpire => new TimeSpan(2, 0, 0);
|
||||
private static TimeSpan callExpire => new TimeSpan(2, 0, 0);
|
||||
|
||||
private CommandEventArgs e;
|
||||
private string enemyClan;
|
||||
public string EnemyClan => enemyClan;
|
||||
private int size;
|
||||
public int Size => size;
|
||||
private Caller[] bases;
|
||||
public string EnemyClan { get; }
|
||||
public int Size { get; }
|
||||
|
||||
private Caller[] bases { get; }
|
||||
private CancellationTokenSource[] baseCancelTokens;
|
||||
private CancellationTokenSource endTokenSource = new CancellationTokenSource();
|
||||
public Action<string> OnUserTimeExpired { get; set; } = null;
|
||||
public Action OnWarEnded { get; set; } = null;
|
||||
private CancellationTokenSource endTokenSource { get; } = new CancellationTokenSource();
|
||||
public event Action<string> OnUserTimeExpired = delegate { };
|
||||
public event Action OnWarEnded = delegate { };
|
||||
public bool Started { get; set; } = false;
|
||||
|
||||
public ClashWar(string enemyClan, int size, CommandEventArgs e) {
|
||||
this.enemyClan = enemyClan;
|
||||
this.size = size;
|
||||
this.EnemyClan = enemyClan;
|
||||
this.Size = size;
|
||||
this.bases = new Caller[size];
|
||||
this.baseCancelTokens = new CancellationTokenSource[size];
|
||||
}
|
||||
|
||||
internal void End() {
|
||||
if (!endTokenSource.Token.IsCancellationRequested) {
|
||||
endTokenSource.Cancel();
|
||||
if (OnWarEnded != null)
|
||||
OnWarEnded();
|
||||
}
|
||||
if (endTokenSource.Token.IsCancellationRequested) return;
|
||||
endTokenSource.Cancel();
|
||||
OnWarEnded();
|
||||
}
|
||||
|
||||
internal async Task Call(string u, int baseNumber) {
|
||||
internal void Call(string u, int baseNumber) {
|
||||
if (baseNumber < 0 || baseNumber >= bases.Length)
|
||||
throw new ArgumentException("Invalid base number");
|
||||
if (bases[baseNumber] != null)
|
||||
throw new ArgumentException("That base is already claimed.");
|
||||
for (int i = 0; i < bases.Length; i++) {
|
||||
for (var i = 0; i < bases.Length; i++) {
|
||||
if (bases[i]?.BaseDestroyed == false && bases[i]?.CallUser == u)
|
||||
throw new ArgumentException($"@{u} You already claimed a base #{i + 1}. You can't claim a new one.");
|
||||
}
|
||||
|
||||
bases[baseNumber] = new Caller { CallUser = u.Trim(), TimeAdded = DateTime.Now, BaseDestroyed = false };
|
||||
bases[baseNumber] = new Caller(u.Trim(), DateTime.Now, false);
|
||||
}
|
||||
|
||||
internal async Task Start() {
|
||||
@ -330,25 +325,21 @@ namespace NadekoBot.Commands {
|
||||
throw new InvalidOperationException();
|
||||
try {
|
||||
Started = true;
|
||||
for (int i = 0; i < bases.Length; i++) {
|
||||
if (bases[i] != null)
|
||||
bases[i].TimeAdded = DateTime.Now;
|
||||
foreach (var b in bases.Where(b => b != null)) {
|
||||
b.ResetTime();
|
||||
}
|
||||
Task.Run(async () => await ClearArray());
|
||||
Task.Run(async () => await ClearArray()).ConfigureAwait(false);
|
||||
await Task.Delay(new TimeSpan(24, 0, 0), endTokenSource.Token);
|
||||
}
|
||||
catch (Exception) { }
|
||||
finally {
|
||||
} catch { } finally {
|
||||
End();
|
||||
}
|
||||
}
|
||||
internal int Uncall(string user) {
|
||||
user = user.Trim();
|
||||
for (int i = 0; i < bases.Length; i++) {
|
||||
if (bases[i]?.CallUser == user) {
|
||||
bases[i] = null;
|
||||
return i;
|
||||
}
|
||||
for (var i = 0; i < bases.Length; i++) {
|
||||
if (bases[i]?.CallUser != user) continue;
|
||||
bases[i] = null;
|
||||
return i;
|
||||
}
|
||||
throw new InvalidOperationException("You are not participating in that war.");
|
||||
}
|
||||
@ -356,12 +347,11 @@ namespace NadekoBot.Commands {
|
||||
private async Task ClearArray() {
|
||||
while (!endTokenSource.IsCancellationRequested) {
|
||||
await Task.Delay(5000);
|
||||
for (int i = 0; i < bases.Length; i++) {
|
||||
for (var i = 0; i < bases.Length; i++) {
|
||||
if (bases[i] == null) continue;
|
||||
if (!bases[i].BaseDestroyed && DateTime.Now - bases[i].TimeAdded >= callExpire) {
|
||||
Console.WriteLine($"Removing user {bases[i].CallUser}");
|
||||
if (OnUserTimeExpired != null)
|
||||
OnUserTimeExpired(bases[i].CallUser);
|
||||
OnUserTimeExpired(bases[i].CallUser);
|
||||
bases[i] = null;
|
||||
}
|
||||
}
|
||||
@ -370,23 +360,21 @@ namespace NadekoBot.Commands {
|
||||
}
|
||||
|
||||
public string ShortPrint() =>
|
||||
$"`{enemyClan}` ({size} v {size})";
|
||||
$"`{EnemyClan}` ({Size} v {Size})";
|
||||
|
||||
public override string ToString() {
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine($"🔰**WAR AGAINST `{enemyClan}` ({size} v {size}) INFO:**");
|
||||
sb.AppendLine($"🔰**WAR AGAINST `{EnemyClan}` ({Size} v {Size}) INFO:**");
|
||||
if (!Started)
|
||||
sb.AppendLine("`not started`");
|
||||
for (int i = 0; i < bases.Length; i++) {
|
||||
for (var i = 0; i < bases.Length; i++) {
|
||||
if (bases[i] == null) {
|
||||
sb.AppendLine($"`{i + 1}.` ❌*unclaimed*");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (bases[i].BaseDestroyed) {
|
||||
sb.AppendLine($"`{i + 1}.` ✅ `{bases[i].CallUser}` ⭐ ⭐ ⭐");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
var left = Started ? callExpire - (DateTime.Now - bases[i].TimeAdded) : callExpire;
|
||||
sb.AppendLine($"`{i + 1}.` ✅ `{bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left");
|
||||
}
|
||||
@ -398,11 +386,10 @@ namespace NadekoBot.Commands {
|
||||
|
||||
internal int FinishClaim(string user) {
|
||||
user = user.Trim();
|
||||
for (int i = 0; i < bases.Length; i++) {
|
||||
if (bases[i]?.BaseDestroyed == false && bases[i]?.CallUser == user) {
|
||||
bases[i].BaseDestroyed = true;
|
||||
return i;
|
||||
}
|
||||
for (var i = 0; i < bases.Length; i++) {
|
||||
if (bases[i]?.BaseDestroyed != false || bases[i]?.CallUser != user) continue;
|
||||
bases[i].BaseDestroyed = true;
|
||||
return i;
|
||||
}
|
||||
throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base.");
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace NadekoBot
|
||||
namespace NadekoBot.Commands
|
||||
{
|
||||
internal class CopyCommand : DiscordCommand
|
||||
{
|
||||
|
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using NadekoBot.Extensions;
|
||||
|
||||
namespace NadekoBot {
|
||||
namespace NadekoBot.Commands {
|
||||
internal class DiceRollCommand : DiscordCommand {
|
||||
public DiceRollCommand() { }
|
||||
|
||||
|
@ -3,7 +3,7 @@ using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace NadekoBot
|
||||
namespace NadekoBot.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Base DiscordCommand Class.
|
||||
|
@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using System.Drawing;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using NadekoBot.Extensions;
|
||||
|
||||
namespace NadekoBot {
|
||||
namespace NadekoBot.Commands {
|
||||
internal class DrawCommand : DiscordCommand {
|
||||
private static ConcurrentDictionary<Discord.Server, Cards> AllDecks = new ConcurrentDictionary<Discord.Server, Cards>();
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Drawing;
|
||||
|
||||
namespace NadekoBot {
|
||||
namespace NadekoBot.Commands {
|
||||
internal class FlipCoinCommand : DiscordCommand {
|
||||
|
||||
private Random _r;
|
||||
|
@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot {
|
||||
namespace NadekoBot.Commands {
|
||||
internal class HelpCommand : DiscordCommand {
|
||||
public override Func<CommandEventArgs, Task> DoFunc() => async e => {
|
||||
#region OldHelp
|
||||
|
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using Discord;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace NadekoBot.Modules {
|
||||
namespace NadekoBot.Commands {
|
||||
internal class PollCommand : DiscordCommand {
|
||||
|
||||
public static ConcurrentDictionary<Server, Poll> ActivePolls = new ConcurrentDictionary<Server, Poll>();
|
||||
|
@ -6,7 +6,7 @@ using NadekoBot.Extensions;
|
||||
namespace NadekoBot.Commands {
|
||||
internal class RequestsCommand : DiscordCommand {
|
||||
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,
|
||||
UserName = e.User.Name,
|
||||
UserId = (long)e.User.Id,
|
||||
@ -17,7 +17,7 @@ namespace NadekoBot.Commands {
|
||||
}
|
||||
// todo what if it's too long?
|
||||
public string GetRequests() {
|
||||
var task = Classes.DBHandler.Instance.GetAllRows<Classes._DataModels.Request>();
|
||||
var task = Classes.DbHandler.Instance.GetAllRows<Classes._DataModels.Request>();
|
||||
|
||||
string str = "Here are all current requests for NadekoBot:\n\n";
|
||||
foreach (var reqObj in task) {
|
||||
@ -28,14 +28,14 @@ namespace NadekoBot.Commands {
|
||||
}
|
||||
|
||||
public bool DeleteRequest(int requestNumber) =>
|
||||
Classes.DBHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber) != null;
|
||||
Classes.DbHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber) != null;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a request with a number and returns that request object.
|
||||
/// </summary>
|
||||
/// <returns>RequestObject of the request. Null if none</returns>
|
||||
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() {
|
||||
throw new NotImplementedException();
|
||||
|
@ -33,7 +33,7 @@ namespace NadekoBot.Commands {
|
||||
NadekoBot.Client.UserJoined += UserJoined;
|
||||
NadekoBot.Client.UserLeft += UserLeft;
|
||||
|
||||
List<Classes._DataModels.Announcement> data = Classes.DBHandler.Instance.GetAllRows<Classes._DataModels.Announcement>();
|
||||
List<Classes._DataModels.Announcement> data = Classes.DbHandler.Instance.GetAllRows<Classes._DataModels.Announcement>();
|
||||
|
||||
if (data.Any())
|
||||
foreach (var obj in data)
|
||||
@ -168,7 +168,7 @@ namespace NadekoBot.Commands {
|
||||
internal bool ToggleByePM() => ByePM = !ByePM;
|
||||
|
||||
private void Save() {
|
||||
Classes.DBHandler.Instance.Save(_model);
|
||||
Classes.DbHandler.Instance.Save(_model);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace NadekoBot.Commands {
|
||||
|
||||
public static class SentencesProvider {
|
||||
internal static string GetRandomSentence() {
|
||||
var data = Classes.DBHandler.Instance.GetAllRows<Classes._DataModels.TypingArticle>();
|
||||
var data = Classes.DbHandler.Instance.GetAllRows<Classes._DataModels.TypingArticle>();
|
||||
try {
|
||||
return data.ToList()[new Random().Next(0, data.Count())].Text;
|
||||
} catch {
|
||||
@ -153,7 +153,7 @@ namespace NadekoBot.Commands {
|
||||
.Do(async e => {
|
||||
if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
|
||||
|
||||
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.TypingArticle {
|
||||
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.TypingArticle {
|
||||
Text = e.GetArg("text"),
|
||||
DateAdded = DateTime.Now
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ using System.IO;
|
||||
using System.Collections.Concurrent;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Classes.Permissions;
|
||||
using NadekoBot.Classes._DataModels;
|
||||
using Timer = System.Timers.Timer;
|
||||
@ -199,8 +200,10 @@ namespace NadekoBot.Modules {
|
||||
.Do(async e => {
|
||||
try {
|
||||
if (e.User.ServerPermissions.KickMembers && e.Message.MentionedUsers.Any()) {
|
||||
var usr = e.Message.MentionedUsers.First();
|
||||
await e.Message.MentionedUsers.First().Kick();
|
||||
var usr = e.Message.MentionedUsers.FirstOrDefault();
|
||||
if (usr == null)
|
||||
return;
|
||||
await usr.Kick();
|
||||
await e.Channel.SendMessage("Kicked user " + usr.Name + " Id: " + usr.Id);
|
||||
}
|
||||
} catch {
|
||||
@ -215,7 +218,7 @@ namespace NadekoBot.Modules {
|
||||
await e.Channel.SendMessage("You do not have permission to do that.");
|
||||
return;
|
||||
}
|
||||
if (e.Message.MentionedUsers.Count() == 0)
|
||||
if (!e.Message.MentionedUsers.Any())
|
||||
return;
|
||||
try {
|
||||
foreach (var u in e.Message.MentionedUsers) {
|
||||
@ -235,7 +238,7 @@ namespace NadekoBot.Modules {
|
||||
await e.Channel.SendMessage("You do not have permission to do that.");
|
||||
return;
|
||||
}
|
||||
if (e.Message.MentionedUsers.Count() == 0)
|
||||
if (!e.Message.MentionedUsers.Any())
|
||||
return;
|
||||
try {
|
||||
foreach (var u in e.Message.MentionedUsers) {
|
||||
@ -256,7 +259,7 @@ namespace NadekoBot.Modules {
|
||||
await e.Channel.SendMessage("You do not have permission to do that.");
|
||||
return;
|
||||
}
|
||||
if (e.Message.MentionedUsers.Count() == 0)
|
||||
if (!e.Message.MentionedUsers.Any())
|
||||
return;
|
||||
try {
|
||||
foreach (var u in e.Message.MentionedUsers) {
|
||||
@ -277,7 +280,7 @@ namespace NadekoBot.Modules {
|
||||
await e.Channel.SendMessage("You do not have permission to do that.");
|
||||
return;
|
||||
}
|
||||
if (e.Message.MentionedUsers.Count() == 0)
|
||||
if (!e.Message.MentionedUsers.Any())
|
||||
return;
|
||||
try {
|
||||
foreach (var u in e.Message.MentionedUsers) {
|
||||
@ -323,7 +326,9 @@ namespace NadekoBot.Modules {
|
||||
.Do(async e => {
|
||||
try {
|
||||
if (e.User.ServerPermissions.ManageChannels) {
|
||||
await e.Server.FindChannels(e.GetArg("channel_name"), ChannelType.Text).FirstOrDefault()?.Delete();
|
||||
var channel = e.Server.FindChannels(e.GetArg("channel_name"), ChannelType.Text).FirstOrDefault();
|
||||
if (channel == null) return;
|
||||
await channel.Delete();
|
||||
await e.Channel.SendMessage($"Removed text channel **{e.GetArg("channel_name")}**.");
|
||||
}
|
||||
} catch {
|
||||
@ -413,15 +418,12 @@ namespace NadekoBot.Modules {
|
||||
.Description("Works only for the owner. Shuts the bot down and notifies users about the restart.")
|
||||
.Do(async e => {
|
||||
if (NadekoBot.IsOwner(e.User.Id)) {
|
||||
Timer t = new Timer();
|
||||
t.Interval = 2000;
|
||||
t.Elapsed += (s, ev) => { Environment.Exit(0); };
|
||||
t.Start();
|
||||
await e.Channel.SendMessage("`Shutting down.`");
|
||||
await Task.Delay(2000);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
ConcurrentDictionary<Server, bool> clearDictionary = new ConcurrentDictionary<Server, bool>();
|
||||
cgb.CreateCommand(".clr")
|
||||
.Description("Clears some of Nadeko's (or some other user's if supplied) messages from the current channel.\n**Usage**: .clr @X")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
@ -462,18 +464,13 @@ namespace NadekoBot.Modules {
|
||||
if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("img")))
|
||||
return;
|
||||
// Gather user provided URL.
|
||||
string avatarAddress = e.GetArg("img");
|
||||
// Creates an HTTPWebRequest object, which references the URL given by the user.
|
||||
System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(Uri.EscapeUriString(avatarAddress));
|
||||
// Discard the response if image isnt downloaded in 5 s as to not lock Nadeko. Prevents loading from faulty links.
|
||||
webRequest.Timeout = 5000;
|
||||
// Gathers the webRequest response as a Stream object.
|
||||
System.Net.WebResponse webResponse = await webRequest.GetResponseAsync();
|
||||
// Create image object from the response we got from the webRequest stream. This is because there is no "GetResponseStream".
|
||||
System.Drawing.Image image = System.Drawing.Image.FromStream(webResponse.GetResponseStream());
|
||||
var avatarAddress = e.GetArg("img");
|
||||
var imageStream = await SearchHelper.GetResponseStreamAsync(avatarAddress);
|
||||
var image = System.Drawing.Image.FromStream(imageStream);
|
||||
// Save the image to disk.
|
||||
image.Save("data/avatar.png", System.Drawing.Imaging.ImageFormat.Png);
|
||||
await client.CurrentUser.Edit(NadekoBot.Creds.Password, avatar: image.ToStream());
|
||||
imageStream.Position = 0;
|
||||
await client.CurrentUser.Edit(NadekoBot.Creds.Password, avatar: imageStream);
|
||||
// Send confirm.
|
||||
await e.Channel.SendMessage("New avatar set.");
|
||||
});
|
||||
@ -490,8 +487,8 @@ namespace NadekoBot.Modules {
|
||||
cgb.CreateCommand(".checkmyperms")
|
||||
.Description("Checks your userspecific permissions on this channel.")
|
||||
.Do(async e => {
|
||||
string output = "```\n";
|
||||
foreach (var p in e.User.ServerPermissions.GetType().GetProperties().Where(p => p.GetGetMethod().GetParameters().Count() == 0)) {
|
||||
var output = "```\n";
|
||||
foreach (var p in e.User.ServerPermissions.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) {
|
||||
output += p.Name + ": " + p.GetValue(e.User.ServerPermissions, null).ToString() + "\n";
|
||||
}
|
||||
output += "```";
|
||||
@ -558,23 +555,27 @@ namespace NadekoBot.Modules {
|
||||
.Description("Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have mention everyone permission.")
|
||||
.Parameter("roles", ParameterType.Unparsed)
|
||||
.Do(async e => {
|
||||
if (!e.User.ServerPermissions.MentionEveryone) return;
|
||||
var arg = e.GetArg("roles").Split(',').Select(r => r.Trim());
|
||||
string send = $"--{e.User.Mention} has invoked a mention on the following roles--";
|
||||
foreach (var roleStr in arg) {
|
||||
if (string.IsNullOrWhiteSpace(roleStr)) continue;
|
||||
var role = e.Server.FindRoles(roleStr).FirstOrDefault();
|
||||
if (role == null) continue;
|
||||
send += $"\n`{role.Name}`\n";
|
||||
send += string.Join(", ", role.Members.Select(r => r.Mention));
|
||||
}
|
||||
await Task.Run(async () => {
|
||||
if (!e.User.ServerPermissions.MentionEveryone) return;
|
||||
var arg = e.GetArg("roles").Split(',').Select(r => r.Trim());
|
||||
string send = $"--{e.User.Mention} has invoked a mention on the following roles--";
|
||||
foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str))) {
|
||||
var role = e.Server.FindRoles(roleStr).FirstOrDefault();
|
||||
if (role == null) continue;
|
||||
send += $"\n`{role.Name}`\n";
|
||||
send += string.Join(", ", role.Members.Select(r => r.Mention));
|
||||
}
|
||||
|
||||
while (send.Length > 2000) {
|
||||
var curstr = send.Substring(0, 2000);
|
||||
await e.Channel.Send(curstr.Substring(0, curstr.LastIndexOf(", ") + 1));
|
||||
send = curstr.Substring(curstr.LastIndexOf(", ") + 1) + send.Substring(2000);
|
||||
}
|
||||
await e.Channel.Send(send);
|
||||
while (send.Length > 2000) {
|
||||
var curstr = send.Substring(0, 2000);
|
||||
await
|
||||
e.Channel.Send(curstr.Substring(0,
|
||||
curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1));
|
||||
send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) +
|
||||
send.Substring(2000);
|
||||
}
|
||||
await e.Channel.Send(send);
|
||||
});
|
||||
});
|
||||
|
||||
cgb.CreateCommand(".parsetosql")
|
||||
@ -593,7 +594,7 @@ namespace NadekoBot.Modules {
|
||||
|
||||
cgb.CreateCommand(".unstuck")
|
||||
.Description("Clears the message queue. **OWNER ONLY**")
|
||||
.AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly())
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(e => {
|
||||
NadekoBot.Client.MessageQueue.Clear();
|
||||
});
|
||||
@ -602,7 +603,7 @@ namespace NadekoBot.Modules {
|
||||
.Description("List of lovely people who donated to keep this project alive.")
|
||||
.Do(async e => {
|
||||
await Task.Run(async () => {
|
||||
var rows = Classes.DBHandler.Instance.GetAllRows<Donator>();
|
||||
var rows = Classes.DbHandler.Instance.GetAllRows<Donator>();
|
||||
var donatorsOrdered = rows.OrderByDescending(d => d.Amount);
|
||||
string str = $"**Thanks to the people listed below for making this project happen!**\n";
|
||||
|
||||
@ -616,22 +617,22 @@ namespace NadekoBot.Modules {
|
||||
.Description("Add a donator to the database.")
|
||||
.Parameter("donator")
|
||||
.Parameter("amount")
|
||||
.Do(e => {
|
||||
try {
|
||||
.Do(async e => {
|
||||
await Task.Run(() => {
|
||||
if (!NadekoBot.IsOwner(e.User.Id))
|
||||
return;
|
||||
var donator = e.Server.FindUsers(e.GetArg("donator")).FirstOrDefault();
|
||||
var amount = int.Parse(e.GetArg("amount"));
|
||||
Classes.DBHandler.Instance.InsertData(new Donator {
|
||||
Amount = amount,
|
||||
UserName = donator.Name,
|
||||
UserId = (long)e.User.Id
|
||||
});
|
||||
e.Channel.SendMessage("Successfuly added a new donator. 👑");
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine(ex);
|
||||
Console.WriteLine("---------------\nInner error:\n" + ex.InnerException);
|
||||
}
|
||||
if (donator == null) return;
|
||||
try {
|
||||
Classes.DbHandler.Instance.InsertData(new Donator {
|
||||
Amount = amount,
|
||||
UserName = donator.Name,
|
||||
UserId = (long)e.User.Id
|
||||
});
|
||||
e.Channel.SendMessage("Successfuly added a new donator. 👑");
|
||||
} catch { }
|
||||
});
|
||||
});
|
||||
|
||||
cgb.CreateCommand(".videocall")
|
||||
@ -639,13 +640,11 @@ namespace NadekoBot.Modules {
|
||||
.Parameter("arg", ParameterType.Unparsed)
|
||||
.Do(async e => {
|
||||
try {
|
||||
string str = "http://appear.in/";
|
||||
var allUsrs = e.Message.MentionedUsers.Union(new User[] { e.User });
|
||||
foreach (var usr in allUsrs) {
|
||||
str += Uri.EscapeUriString(usr.Name[0].ToString());
|
||||
}
|
||||
str += new Random().Next(100000, 1000000);
|
||||
foreach (var usr in allUsrs) {
|
||||
var allUsrsArray = allUsrs as User[] ?? allUsrs.ToArray();
|
||||
var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Name[0].ToString()));
|
||||
str += new Random().Next();
|
||||
foreach (var usr in allUsrsArray) {
|
||||
await usr.SendMessage(str);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
@ -659,11 +658,10 @@ namespace NadekoBot.Modules {
|
||||
try {
|
||||
var data = File.ReadAllText(where);
|
||||
var arr = JObject.Parse(data)["results"] as JArray;
|
||||
var objects = new List<T>();
|
||||
foreach (JObject obj in arr) {
|
||||
objects.Add(obj.ToObject<T>());
|
||||
}
|
||||
Classes.DBHandler.Instance.InsertMany(objects);
|
||||
if (arr == null)
|
||||
return;
|
||||
var objects = arr.Select(x => x.ToObject<T>());
|
||||
Classes.DbHandler.Instance.InsertMany(objects);
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace NadekoBot.Modules {
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return;
|
||||
await Task.Run(() =>
|
||||
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.UserQuote() {
|
||||
Classes.DbHandler.Instance.InsertData(new Classes._DataModels.UserQuote() {
|
||||
DateAdded = DateTime.Now,
|
||||
Keyword = e.GetArg("keyword").ToLowerInvariant(),
|
||||
Text = text,
|
||||
@ -64,7 +64,7 @@ namespace NadekoBot.Modules {
|
||||
return;
|
||||
|
||||
var quote =
|
||||
Classes.DBHandler.Instance.GetRandom<Classes._DataModels.UserQuote>(
|
||||
Classes.DbHandler.Instance.GetRandom<Classes._DataModels.UserQuote>(
|
||||
uqm => uqm.Keyword == keyword);
|
||||
|
||||
if (quote != null)
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Discord.Modules;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Commands;
|
||||
|
||||
namespace NadekoBot.Modules {
|
||||
internal abstract class DiscordModule : IModule {
|
||||
|
@ -3,6 +3,7 @@ using Discord.Modules;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Linq;
|
||||
using Discord;
|
||||
using NadekoBot.Commands;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
@ -41,7 +42,7 @@ namespace NadekoBot.Modules
|
||||
cgb.CreateCommand("$$$")
|
||||
.Description("Check how many NadekoFlowers you have.")
|
||||
.Do(async e => {
|
||||
var pts = Classes.DBHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
|
||||
var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
|
||||
var str = $"`You have {pts} NadekoFlowers".SnPl((int)pts)+"`\n";
|
||||
for (var i = 0; i < pts; i++) {
|
||||
str += "🌸";
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using Discord.Modules;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Commands;
|
||||
|
||||
namespace NadekoBot.Modules {
|
||||
internal class Help : DiscordModule {
|
||||
|
@ -11,6 +11,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Classes.JSONModels;
|
||||
using NadekoBot.Commands;
|
||||
|
||||
namespace NadekoBot {
|
||||
public class NadekoBot {
|
||||
|
@ -226,9 +226,6 @@
|
||||
<ItemGroup>
|
||||
<None Include="resources\images\hidden.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resources\images\nadeko.jpg" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resources\images\rip.png" />
|
||||
</ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user