refactor (gambling module): some codecleanup and reorganization

This commit is contained in:
Gergő Törcsvári 2016-03-25 12:48:22 +01:00
parent aa589dbc05
commit 05c72ff08a
9 changed files with 351 additions and 227 deletions

View File

@ -1,57 +0,0 @@
using Discord.Commands;
using Discord.Modules;
using NadekoBot.Extensions;
using System.Linq;
using Discord;
using NadekoBot.Commands;
namespace NadekoBot.Modules
{
internal class Gambling : DiscordModule
{
public Gambling() {
commands.Add(new DrawCommand(this));
commands.Add(new FlipCoinCommand(this));
commands.Add(new DiceRollCommand(this));
}
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Gambling;
public override void Install(ModuleManager manager)
{
manager.CreateCommands("", cgb =>
{
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
commands.ForEach(com => com.Init(cgb));
cgb.CreateCommand(Prefix +"raffle")
.Description("Prints a name and ID of a random user from the online list from the (optional) role.")
.Parameter("role", ParameterType.Optional)
.Do(async e => {
var arg = string.IsNullOrWhiteSpace(e.GetArg("role")) ? "@everyone" : e.GetArg("role");
var role = e.Server.FindRoles(arg).FirstOrDefault();
if (role == null) {
await e.Channel.SendMessage("💢 Role not found.");
return;
}
var members = role.Members.Where(u => u.Status == Discord.UserStatus.Online); // only online
var membersArray = members as User[] ?? members.ToArray();
var usr = membersArray[new System.Random().Next(0, membersArray.Length)];
await e.Channel.SendMessage($"**Raffled user:** {usr.Name} (id: {usr.Id})");
});
cgb.CreateCommand(Prefix + "$$")
.Description("Check how many NadekoFlowers you have.")
.Do(async e => {
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 += "🌸";
}
await e.Channel.SendMessage(str);
});
});
}
}
}

View File

@ -1,53 +1,81 @@
using Discord.Commands;
using NadekoBot.Commands;
using NadekoBot.Extensions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules;
namespace NadekoBot.Commands { namespace NadekoBot.Modules.Gambling
internal class DiceRollCommand : DiscordCommand { {
internal class DiceRollCommand : DiscordCommand
{
public DiceRollCommand(DiscordModule module) : base(module) { } public DiceRollCommand(DiscordModule module) : base(module) { }
public Func<CommandEventArgs, Task> DoFunc() {
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "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]")
.Parameter("num", ParameterType.Optional)
.Do(Roll0to10Func());
cgb.CreateCommand(Module.Prefix + "nroll")
.Description("Rolls in a given range.\n**Usage**: `$nroll 5` (rolls 0-5) or `$nroll 5-15`")
.Parameter("range", ParameterType.Required)
.Do(Roll0to5Func());
}
private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image;
private Func<CommandEventArgs, Task> Roll0to10Func()
{
var r = new Random(); var r = new Random();
return async e => { return async e =>
if (e.Args[0] == "") { {
if (e.Args[0] == "")
{
var num1 = r.Next(0, 10); var num1 = r.Next(0, 10);
var num2 = r.Next(0, 10); var num2 = r.Next(0, 10);
Image[] images; Image[] images;
if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1) { if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1)
{
images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) }; images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) };
} else { }
else {
images = new Image[2] { GetDice(num1), GetDice(num2) }; images = new Image[2] { GetDice(num1), GetDice(num2) };
} }
var 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));
} else { }
try { else {
try
{
var 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;
} }
var dices = new List<Image>(num); var dices = new List<Image>(num);
var values = new List<int>(num); var values = new List<int>(num);
for (var i = 0; i < num; i++) { for (var i = 0; i < num; i++)
{
var randomNumber = r.Next(1, 7); var randomNumber = r.Next(1, 7);
var 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 (var 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;
} }
@ -59,31 +87,24 @@ namespace NadekoBot.Commands {
var bitmap = dices.Merge(); var bitmap = dices.Merge();
await e.Channel.SendMessage(values.Count + " Dice rolled. Total: **" + values.Sum() + "** Average: **" + (values.Sum() / (1.0f * values.Count)).ToString("N2") + "**"); await e.Channel.SendMessage(values.Count + " Dice rolled. Total: **" + values.Sum() + "** Average: **" + (values.Sum() / (1.0f * values.Count)).ToString("N2") + "**");
await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png)); await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png));
} catch { }
catch
{
await e.Channel.SendMessage("Please enter a number of dice to roll."); await e.Channel.SendMessage("Please enter a number of dice to roll.");
} }
} }
}; };
} }
private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image;
internal override void Init(CommandGroupBuilder cgb) { private Func<CommandEventArgs, Task> Roll0to5Func() =>
cgb.CreateCommand(Module.Prefix + "roll") async e =>
.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) try
.Do(DoFunc()); {
cgb.CreateCommand(Module.Prefix + "nroll")
.Description("Rolls in a given range.\n**Usage**: `$nroll 5` (rolls 0-5) or `$nroll 5-15`")
.Parameter("range", ParameterType.Required)
.Do(NDoFunc());
}
private Func<CommandEventArgs, Task> NDoFunc() =>
async e => {
try {
int rolled; int rolled;
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(int.Parse) .Select(int.Parse)
@ -91,12 +112,15 @@ namespace NadekoBot.Commands {
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.");
rolled = new Random().Next(arr[0], arr[1] + 1); rolled = new Random().Next(arr[0], arr[1] + 1);
} else { }
else {
rolled = new Random().Next(0, int.Parse(e.GetArg("range")) + 1); rolled = new Random().Next(0, int.Parse(e.GetArg("range")) + 1);
} }
await e.Channel.SendMessage($"{e.User.Mention} rolled **{rolled}**."); await e.Channel.SendMessage($"{e.User.Mention} rolled **{rolled}**.");
} catch (Exception ex) { }
catch (Exception ex)
{
await e.Channel.SendMessage($":anger: {ex.Message}"); await e.Channel.SendMessage($":anger: {ex.Message}");
} }
}; };

View File

@ -1,24 +1,60 @@
using System; using Discord.Commands;
using NadekoBot.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules.Gambling.Helpers;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using NadekoBot.Modules;
namespace NadekoBot.Commands { namespace NadekoBot.Modules.Gambling
internal class DrawCommand : DiscordCommand { {
internal class DrawCommand : DiscordCommand
{
public DrawCommand(DiscordModule module) : base(module) { }
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "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]")
.Parameter("count", ParameterType.Optional)
.Do(DrawCardFunc());
cgb.CreateCommand(Module.Prefix + "shuffle")
.Alias(Module.Prefix + "sh")
.Description("Reshuffles all cards back into the deck.")
.Do(ReshuffleTask());
}
private static readonly ConcurrentDictionary<Discord.Server, Cards> AllDecks = new ConcurrentDictionary<Discord.Server, Cards>(); private static readonly ConcurrentDictionary<Discord.Server, Cards> AllDecks = new ConcurrentDictionary<Discord.Server, Cards>();
public Func<CommandEventArgs, Task> DoFunc() => async (e) => { private static Func<CommandEventArgs, Task> ReshuffleTask()
{
return async e =>
{
AllDecks.AddOrUpdate(e.Server,
(s) => new Cards(),
(s, c) =>
{
c.Restart();
return c;
});
await e.Channel.SendMessage("Deck reshuffled.");
};
}
private Func<CommandEventArgs, Task> DrawCardFunc() => async (e) =>
{
var cards = AllDecks.GetOrAdd(e.Server, (s) => new Cards()); var cards = AllDecks.GetOrAdd(e.Server, (s) => new Cards());
try { try
{
var num = 1; var num = 1;
var isParsed = int.TryParse(e.GetArg("count"), out num); var isParsed = int.TryParse(e.GetArg("count"), out num);
if (!isParsed || num < 2) { if (!isParsed || num < 2)
{
var c = cards.DrawACard(); var c = cards.DrawACard();
await e.Channel.SendFile(c.Name + ".jpg", (Properties.Resources.ResourceManager.GetObject(c.Name) as Image).ToStream()); await e.Channel.SendFile(c.Name + ".jpg", (Properties.Resources.ResourceManager.GetObject(c.Name) as Image).ToStream());
return; return;
@ -28,8 +64,10 @@ namespace NadekoBot.Commands {
var images = new List<Image>(); var images = new List<Image>();
var cardObjects = new List<Cards.Card>(); var cardObjects = new List<Cards.Card>();
for (var i = 0; i < num; i++) { for (var i = 0; i < num; i++)
if (cards.CardPool.Count == 0 && i != 0) { {
if (cards.CardPool.Count == 0 && i != 0)
{
await e.Channel.SendMessage("No more cards in a deck."); await e.Channel.SendMessage("No more cards in a deck.");
break; break;
} }
@ -39,35 +77,15 @@ namespace NadekoBot.Commands {
} }
var bitmap = images.Merge(); var bitmap = images.Merge();
await e.Channel.SendFile(images.Count + " cards.jpg", bitmap.ToStream()); await e.Channel.SendFile(images.Count + " cards.jpg", bitmap.ToStream());
if (cardObjects.Count == 5) { if (cardObjects.Count == 5)
{
await e.Channel.SendMessage(Cards.GetHandValue(cardObjects)); await e.Channel.SendMessage(Cards.GetHandValue(cardObjects));
} }
} catch (Exception ex) { }
catch (Exception ex)
{
Console.WriteLine("Error drawing (a) card(s) " + ex.ToString()); Console.WriteLine("Error drawing (a) card(s) " + ex.ToString());
} }
}; };
internal override void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(Module.Prefix + "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]")
.Parameter("count", ParameterType.Optional)
.Do(DoFunc());
cgb.CreateCommand(Module.Prefix + "shuffle")
.Alias(Module.Prefix + "sh")
.Description("Reshuffles all cards back into the deck.")
.Do(async e => {
AllDecks.AddOrUpdate(e.Server,
(s) => new Cards(),
(s, c) => {
c.Restart();
return c;
});
await e.Channel.SendMessage("Deck reshuffled.");
});
}
public DrawCommand(DiscordModule module) : base(module) {}
} }
} }

View File

@ -1,29 +1,48 @@
using Discord.Commands;
using NadekoBot.Commands;
using NadekoBot.Extensions;
using System; using System;
using System.Drawing; using System.Drawing;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules;
namespace NadekoBot.Commands { namespace NadekoBot.Modules.Gambling
internal class FlipCoinCommand : DiscordCommand { {
internal class FlipCoinCommand : DiscordCommand
{
public FlipCoinCommand(DiscordModule module) : base(module) { }
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "flip")
.Description("Flips coin(s) - heads or tails, and shows an image.\n**Usage**: `$flip` or `$flip 3`")
.Parameter("count", ParameterType.Optional)
.Do(FlipCoinFunc());
}
private readonly Random rng = new Random(); private readonly Random rng = new Random();
public Func<CommandEventArgs, Task> DoFunc() => async e => { public Func<CommandEventArgs, Task> FlipCoinFunc() => async e =>
{
if (e.GetArg("count") == "") { if (e.GetArg("count") == "")
{
if (rng.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));
} else { }
else {
int result; int result;
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;
var imgs = new Image[result]; var imgs = new Image[result];
for (var i = 0; i < result; i++) { for (var i = 0; i < result; i++)
{
imgs[i] = rng.Next(0, 2) == 0 ? imgs[i] = rng.Next(0, 2) == 0 ?
Properties.Resources.tails : Properties.Resources.tails :
Properties.Resources.heads; Properties.Resources.heads;
@ -34,14 +53,5 @@ namespace NadekoBot.Commands {
await e.Channel.SendMessage("Invalid number"); await e.Channel.SendMessage("Invalid number");
} }
}; };
internal override void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand(Module.Prefix + "flip")
.Description("Flips coin(s) - heads or tails, and shows an image.\n**Usage**: `$flip` or `$flip 3`")
.Parameter("count", ParameterType.Optional)
.Do(DoFunc());
}
public FlipCoinCommand(DiscordModule module) : base(module) {}
} }
} }

View File

@ -0,0 +1,71 @@
using Discord;
using Discord.Commands;
using Discord.Modules;
using NadekoBot.Extensions;
using System.Linq;
namespace NadekoBot.Modules.Gambling
{
internal class GamblingModule : DiscordModule
{
public GamblingModule()
{
commands.Add(new DrawCommand(this));
commands.Add(new FlipCoinCommand(this));
commands.Add(new DiceRollCommand(this));
}
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Gambling;
public override void Install(ModuleManager manager)
{
manager.CreateCommands("", cgb =>
{
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
commands.ForEach(com => com.Init(cgb));
cgb.CreateCommand(Prefix + "raffle")
.Description("Prints a name and ID of a random user from the online list from the (optional) role.")
.Parameter("role", ParameterType.Optional)
.Do(RaffleTask());
cgb.CreateCommand(Prefix + "$$")
.Description("Check how many NadekoFlowers you have.")
.Do(NadekoFlowerCheckTask());
});
}
private static System.Func<CommandEventArgs, System.Threading.Tasks.Task> NadekoFlowerCheckTask()
{
return async e =>
{
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 += "🌸";
}
await e.Channel.SendMessage(str);
};
}
private static System.Func<CommandEventArgs, System.Threading.Tasks.Task> RaffleTask()
{
return async e =>
{
var arg = string.IsNullOrWhiteSpace(e.GetArg("role")) ? "@everyone" : e.GetArg("role");
var role = e.Server.FindRoles(arg).FirstOrDefault();
if (role == null)
{
await e.Channel.SendMessage("💢 Role not found.");
return;
}
var members = role.Members.Where(u => u.Status == Discord.UserStatus.Online); // only online
var membersArray = members as User[] ?? members.ToArray();
var usr = membersArray[new System.Random().Next(0, membersArray.Length)];
await e.Channel.SendMessage($"**Raffled user:** {usr.Name} (id: {usr.Id})");
};
}
}
}

View File

@ -1,9 +1,11 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System;
namespace NadekoBot.Classes { namespace NadekoBot.Modules.Gambling.Helpers
public class Cards { {
public class Cards
{
private static readonly Dictionary<int, string> cardNames = new Dictionary<int, string>() { private static readonly Dictionary<int, string> cardNames = new Dictionary<int, string>() {
{ 1, "Ace" }, { 1, "Ace" },
{ 2, "Two" }, { 2, "Two" },
@ -22,31 +24,38 @@ namespace NadekoBot.Classes {
private static Dictionary<string, Func<List<Card>, bool>> handValues; private static Dictionary<string, Func<List<Card>, bool>> handValues;
public enum CardSuit { public enum CardSuit
{
Spades = 1, Spades = 1,
Hearts = 2, Hearts = 2,
Diamonds = 3, Diamonds = 3,
Clubs = 4 Clubs = 4
} }
public class Card : IComparable { public class Card : IComparable
{
public CardSuit Suit { get; } public CardSuit Suit { get; }
public int Number { get; } public int Number { get; }
public string Name { public string Name
get { {
get
{
var str = ""; var str = "";
if (Number <= 10 && Number > 1) { if (Number <= 10 && Number > 1)
{
str += "_" + Number; str += "_" + Number;
} else { }
else {
str += GetName().ToLower(); str += GetName().ToLower();
} }
return str + "_of_" + Suit.ToString().ToLower(); return str + "_of_" + Suit.ToString().ToLower();
} }
} }
public Card(CardSuit s, int cardNum) { public Card(CardSuit s, int cardNum)
{
this.Suit = s; this.Suit = s;
this.Number = cardNum; this.Number = cardNum;
} }
@ -55,7 +64,8 @@ namespace NadekoBot.Classes {
public override string ToString() => cardNames[Number] + " Of " + Suit; public override string ToString() => cardNames[Number] + " Of " + Suit;
public int CompareTo(object obj) { public int CompareTo(object obj)
{
if (!(obj is Card)) return 0; if (!(obj is Card)) return 0;
var c = (Card)obj; var c = (Card)obj;
return this.Number - c.Number; return this.Number - c.Number;
@ -63,7 +73,8 @@ namespace NadekoBot.Classes {
} }
private List<Card> cardPool; private List<Card> cardPool;
public List<Card> CardPool { public List<Card> CardPool
{
get { return cardPool; } get { return cardPool; }
set { cardPool = value; } set { cardPool = value; }
} }
@ -71,7 +82,8 @@ namespace NadekoBot.Classes {
/// <summary> /// <summary>
/// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time. /// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time.
/// </summary> /// </summary>
public Cards() { public Cards()
{
cardPool = new List<Card>(52); cardPool = new List<Card>(52);
RefillPool(); RefillPool();
InitHandValues(); InitHandValues();
@ -86,12 +98,15 @@ namespace NadekoBot.Classes {
/// Removes all cards from the pool and refills the pool with all of the possible cards. NOTE: I think this is too expensive. /// Removes all cards from the pool and refills the pool with all of the possible cards. NOTE: I think this is too expensive.
/// We should probably make it so it copies another premade list with all the cards, or something. /// We should probably make it so it copies another premade list with all the cards, or something.
/// </summary> /// </summary>
private void RefillPool() { private void RefillPool()
{
cardPool.Clear(); cardPool.Clear();
//foreach suit //foreach suit
for (var j = 1; j < 14; j++) { for (var j = 1; j < 14; j++)
{
// and number // and number
for (var 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 //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, ... // the pool will go from ace of spades,hears,diamonds,clubs all the way to the king of spades. hearts, ...
@ -104,7 +119,8 @@ namespace NadekoBot.Classes {
/// Take a card from the pool, you either take it from the top if the deck is shuffled, or from a random place if the deck is in the default order. /// Take a card from the pool, you either take it from the top if the deck is shuffled, or from a random place if the deck is in the default order.
/// </summary> /// </summary>
/// <returns>A card from the pool</returns> /// <returns>A card from the pool</returns>
public Card DrawACard() { public Card DrawACard()
{
if (CardPool.Count == 0) if (CardPool.Count == 0)
Restart(); Restart();
//you can either do this if your deck is not shuffled //you can either do this if your deck is not shuffled
@ -124,14 +140,16 @@ namespace NadekoBot.Classes {
/// <summary> /// <summary>
/// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method. /// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method.
/// </summary> /// </summary>
private void Shuffle() { private void Shuffle()
{
if (cardPool.Count <= 1) return; if (cardPool.Count <= 1) return;
var orderedPool = cardPool.OrderBy(x => r.Next()); var orderedPool = cardPool.OrderBy(x => r.Next());
cardPool = cardPool as List<Card> ?? orderedPool.ToList(); cardPool = cardPool as List<Card> ?? orderedPool.ToList();
} }
public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine; public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine;
private static void InitHandValues() { private static void InitHandValues()
{
Func<List<Card>, bool> hasPair = Func<List<Card>, bool> hasPair =
cards => cards.GroupBy(card => card.Number) cards => cards.GroupBy(card => card.Number)
.Count(group => group.Count() == 2) == 1; .Count(group => group.Count() == 2) == 1;
@ -145,7 +163,8 @@ namespace NadekoBot.Classes {
.Count(group => group.Count() == 2) == 2; .Count(group => group.Count() == 2) == 2;
Func<List<Card>, bool> isStraight = Func<List<Card>, bool> isStraight =
cards => { cards =>
{
if (cards.GroupBy(card => card.Number).Count() != cards.Count()) if (cards.GroupBy(card => card.Number).Count() != cards.Count())
return false; return false;
var toReturn = (cards.Max(card => (int)card.Number) var toReturn = (cards.Max(card => (int)card.Number)
@ -199,10 +218,12 @@ namespace NadekoBot.Classes {
}; };
} }
public static string GetHandValue(List<Card> cards) { public static string GetHandValue(List<Card> cards)
{
if (handValues == null) if (handValues == null)
InitHandValues(); InitHandValues();
foreach (var kvp in handValues.Where(x => x.Value(cards))) { foreach (var kvp in handValues.Where(x => x.Value(cards)))
{
return kvp.Key; return kvp.Key;
} }
return "High card " + cards.Max().GetName(); return "High card " + cards.Max().GetName();

View File

@ -1,23 +1,23 @@
using Discord; using Discord;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using Newtonsoft.Json;
using Discord.Commands;
using NadekoBot.Modules;
using Discord.Modules;
using Discord.Audio; using Discord.Audio;
using System.Linq; using Discord.Commands;
using System.Linq.Expressions; using Discord.Modules;
using System.Text;
using System.Threading.Tasks;
using Manatee.StateMachine.Exceptions;
using NadekoBot.Classes.JSONModels; using NadekoBot.Classes.JSONModels;
using NadekoBot.Commands; using NadekoBot.Commands;
using NadekoBot.Modules;
using NadekoBot.Modules.Gambling;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot { namespace NadekoBot
public class NadekoBot { {
public class NadekoBot
{
public static DiscordClient Client; public static DiscordClient Client;
public static Credentials Creds { get; set; } public static Credentials Creds { get; set; }
public static Configuration Config { get; set; } public static Configuration Config { get; set; }
@ -26,7 +26,8 @@ namespace NadekoBot {
private static Channel OwnerPrivateChannel { get; set; } private static Channel OwnerPrivateChannel { get; set; }
private static void Main() { private static void Main()
{
Console.OutputEncoding = Encoding.Unicode; Console.OutputEncoding = Encoding.Unicode;
//var lines = File.ReadAllLines("data/input.txt"); //var lines = File.ReadAllLines("data/input.txt");
@ -44,36 +45,46 @@ namespace NadekoBot {
//Console.ReadKey(); //Console.ReadKey();
// generate credentials example so people can know about the changes i make // generate credentials example so people can know about the changes i make
try { try
{
File.WriteAllText("data/config_example.json", JsonConvert.SerializeObject(new Configuration(), Formatting.Indented)); File.WriteAllText("data/config_example.json", JsonConvert.SerializeObject(new Configuration(), Formatting.Indented));
if (!File.Exists("data/config.json")) if (!File.Exists("data/config.json"))
File.Copy("data/config_example.json", "data/config.json"); File.Copy("data/config_example.json", "data/config.json");
File.WriteAllText("credentials_example.json", JsonConvert.SerializeObject(new Credentials(), Formatting.Indented)); File.WriteAllText("credentials_example.json", JsonConvert.SerializeObject(new Credentials(), Formatting.Indented));
} catch { }
catch
{
Console.WriteLine("Failed writing credentials_example.json or data/config_example.json"); Console.WriteLine("Failed writing credentials_example.json or data/config_example.json");
} }
try { try
{
Config = JsonConvert.DeserializeObject<Configuration>(File.ReadAllText("data/config.json")); Config = JsonConvert.DeserializeObject<Configuration>(File.ReadAllText("data/config.json"));
Config.Quotes = JsonConvert.DeserializeObject<List<Quote>>(File.ReadAllText("data/quotes.json")); Config.Quotes = JsonConvert.DeserializeObject<List<Quote>>(File.ReadAllText("data/quotes.json"));
} catch { }
catch
{
Console.WriteLine("Failed loading configuration."); Console.WriteLine("Failed loading configuration.");
Console.ReadKey(); Console.ReadKey();
return; return;
} }
try { try
{
//load credentials from credentials.json //load credentials from credentials.json
Creds = JsonConvert.DeserializeObject<Credentials>(File.ReadAllText("credentials.json")); Creds = JsonConvert.DeserializeObject<Credentials>(File.ReadAllText("credentials.json"));
} catch (Exception ex) { }
catch (Exception ex)
{
Console.WriteLine($"Failed to load stuff from credentials.json, RTFM\n{ex.Message}"); Console.WriteLine($"Failed to load stuff from credentials.json, RTFM\n{ex.Message}");
Console.ReadKey(); Console.ReadKey();
return; return;
} }
//if password is not entered, prompt for password //if password is not entered, prompt for password
if (string.IsNullOrWhiteSpace(Creds.Password)) { if (string.IsNullOrWhiteSpace(Creds.Password))
{
Console.WriteLine("Password blank. Please enter your password:\n"); Console.WriteLine("Password blank. Please enter your password:\n");
Creds.Password = Console.ReadLine(); Creds.Password = Console.ReadLine();
} }
@ -94,7 +105,8 @@ namespace NadekoBot {
BotMention = $"<@{Creds.BotId}>"; BotMention = $"<@{Creds.BotId}>";
//create new discord client and log //create new discord client and log
Client = new DiscordClient(new DiscordConfigBuilder() { Client = new DiscordClient(new DiscordConfigBuilder()
{
MessageCacheSize = 10, MessageCacheSize = 10,
ConnectionTimeout = 60000, ConnectionTimeout = 60000,
LogLevel = LogSeverity.Warning, LogLevel = LogSeverity.Warning,
@ -105,18 +117,22 @@ namespace NadekoBot {
}); });
//create a command service //create a command service
var commandService = new CommandService(new CommandServiceConfigBuilder { var commandService = new CommandService(new CommandServiceConfigBuilder
{
AllowMentionPrefix = false, AllowMentionPrefix = false,
CustomPrefixHandler = m => 0, CustomPrefixHandler = m => 0,
HelpMode = HelpMode.Disabled, HelpMode = HelpMode.Disabled,
ErrorHandler = async (s, e) => { ErrorHandler = async (s, e) =>
{
if (e.ErrorType != CommandErrorType.BadPermissions) if (e.ErrorType != CommandErrorType.BadPermissions)
return; return;
if (string.IsNullOrWhiteSpace(e.Exception?.Message)) if (string.IsNullOrWhiteSpace(e.Exception?.Message))
return; return;
try { try
{
await e.Channel.SendMessage(e.Exception.Message); await e.Channel.SendMessage(e.Exception.Message);
} catch { } }
catch { }
} }
}); });
@ -130,7 +146,8 @@ namespace NadekoBot {
var modules = Client.AddService<ModuleService>(new ModuleService()); var modules = Client.AddService<ModuleService>(new ModuleService());
//add audio service //add audio service
Client.AddService<AudioService>(new AudioService(new AudioServiceConfigBuilder() { Client.AddService<AudioService>(new AudioService(new AudioServiceConfigBuilder()
{
Channels = 2, Channels = 2,
EnableEncryption = false, EnableEncryption = false,
EnableMultiserver = true, EnableMultiserver = true,
@ -142,7 +159,7 @@ namespace NadekoBot {
modules.Add(new Help(), "Help", ModuleFilter.None); modules.Add(new Help(), "Help", ModuleFilter.None);
modules.Add(new PermissionModule(), "Permissions", ModuleFilter.None); modules.Add(new PermissionModule(), "Permissions", ModuleFilter.None);
modules.Add(new Conversations(), "Conversations", ModuleFilter.None); modules.Add(new Conversations(), "Conversations", ModuleFilter.None);
modules.Add(new Gambling(), "Gambling", ModuleFilter.None); modules.Add(new GamblingModule(), "Gambling", ModuleFilter.None);
modules.Add(new Games(), "Games", ModuleFilter.None); modules.Add(new Games(), "Games", ModuleFilter.None);
modules.Add(new Music(), "Music", ModuleFilter.None); modules.Add(new Music(), "Music", ModuleFilter.None);
modules.Add(new Searches(), "Searches", ModuleFilter.None); modules.Add(new Searches(), "Searches", ModuleFilter.None);
@ -152,10 +169,14 @@ namespace NadekoBot {
modules.Add(new Trello(), "Trello", ModuleFilter.None); modules.Add(new Trello(), "Trello", ModuleFilter.None);
//run the bot //run the bot
Client.ExecuteAndWait(async () => { Client.ExecuteAndWait(async () =>
try { {
try
{
await Client.Connect(Creds.Username, Creds.Password); await Client.Connect(Creds.Username, Creds.Password);
} catch (Exception ex) { }
catch (Exception ex)
{
Console.WriteLine($"Probably wrong EMAIL or PASSWORD.\n{ex.Message}"); Console.WriteLine($"Probably wrong EMAIL or PASSWORD.\n{ex.Message}");
Console.ReadKey(); Console.ReadKey();
Console.WriteLine(ex); Console.WriteLine(ex);
@ -166,15 +187,19 @@ namespace NadekoBot {
Console.WriteLine(await NadekoStats.Instance.GetStats()); Console.WriteLine(await NadekoStats.Instance.GetStats());
Console.WriteLine("-----------------"); Console.WriteLine("-----------------");
try { try
{
OwnerPrivateChannel = await Client.CreatePrivateChannel(Creds.OwnerIds[0]); OwnerPrivateChannel = await Client.CreatePrivateChannel(Creds.OwnerIds[0]);
} catch { }
catch
{
Console.WriteLine("Failed creating private channel with the first owner listed in credentials.json"); Console.WriteLine("Failed creating private channel with the first owner listed in credentials.json");
} }
Classes.Permissions.PermissionsHandler.Initialize(); Classes.Permissions.PermissionsHandler.Initialize();
Client.ClientAPI.SendingRequest += (s, e) => { Client.ClientAPI.SendingRequest += (s, e) =>
{
var request = e.Request as Discord.API.Client.Rest.SendMessageRequest; var request = e.Request as Discord.API.Client.Rest.SendMessageRequest;
if (request == null) return; if (request == null) return;
request.Content = request.Content?.Replace("@everyone", "@everyοne") ?? "_error_"; request.Content = request.Content?.Replace("@everyone", "@everyοne") ?? "_error_";
@ -188,26 +213,34 @@ namespace NadekoBot {
public static bool IsOwner(ulong id) => Creds.OwnerIds.Contains(id); public static bool IsOwner(ulong id) => Creds.OwnerIds.Contains(id);
public async Task SendMessageToOwner(string message) { public async Task SendMessageToOwner(string message)
{
if (Config.ForwardMessages && OwnerPrivateChannel != null) if (Config.ForwardMessages && OwnerPrivateChannel != null)
await OwnerPrivateChannel.SendMessage(message); await OwnerPrivateChannel.SendMessage(message);
} }
private static bool repliedRecently = false; private static bool repliedRecently = false;
private static async void Client_MessageReceived(object sender, MessageEventArgs e) { private static async void Client_MessageReceived(object sender, MessageEventArgs e)
try { {
try
{
if (e.Server != null || e.User.Id == Client.CurrentUser.Id) return; if (e.Server != null || e.User.Id == Client.CurrentUser.Id) return;
if (PollCommand.ActivePolls.SelectMany(kvp => kvp.Key.Users.Select(u => u.Id)).Contains(e.User.Id)) return; if (PollCommand.ActivePolls.SelectMany(kvp => kvp.Key.Users.Select(u => u.Id)).Contains(e.User.Id)) return;
if (ConfigHandler.IsBlackListed(e)) if (ConfigHandler.IsBlackListed(e))
return; return;
if (!NadekoBot.Config.DontJoinServers) { if (!NadekoBot.Config.DontJoinServers)
try { {
try
{
await (await Client.GetInvite(e.Message.Text)).Accept(); await (await Client.GetInvite(e.Message.Text)).Accept();
await e.Channel.SendMessage("I got in!"); await e.Channel.SendMessage("I got in!");
return; return;
} catch { }
if (e.User.Id == 109338686889476096) { //carbonitex invite catch
{
if (e.User.Id == 109338686889476096)
{ //carbonitex invite
await e.Channel.SendMessage("Failed to join the server."); await e.Channel.SendMessage("Failed to join the server.");
return; return;
} }
@ -223,7 +256,8 @@ namespace NadekoBot {
await e.Channel.SendMessage(HelpCommand.HelpString); await e.Channel.SendMessage(HelpCommand.HelpString);
await Task.Delay(2000); await Task.Delay(2000);
repliedRecently = false; repliedRecently = false;
} catch { } }
catch { }
} }
} }
} }

View File

@ -163,20 +163,20 @@
<Compile Include="Commands\RequestsCommand.cs" /> <Compile Include="Commands\RequestsCommand.cs" />
<Compile Include="Commands\ServerGreetCommand.cs" /> <Compile Include="Commands\ServerGreetCommand.cs" />
<Compile Include="Commands\SpeedTyping.cs" /> <Compile Include="Commands\SpeedTyping.cs" />
<Compile Include="Classes\Cards.cs" /> <Compile Include="Modules\Gambling\Helpers\Cards.cs" />
<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="Modules\Gambling\DiceRollCommand.cs" />
<Compile Include="Commands\IDiscordCommand.cs" /> <Compile Include="Commands\IDiscordCommand.cs" />
<Compile Include="Commands\DrawCommand.cs" /> <Compile Include="Modules\Gambling\DrawCommand.cs" />
<Compile Include="Commands\FlipCoinCommand.cs" /> <Compile Include="Modules\Gambling\FlipCoinCommand.cs" />
<Compile Include="Commands\HelpCommand.cs" /> <Compile Include="Commands\HelpCommand.cs" />
<Compile Include="Commands\VoiceNotificationCommand.cs" /> <Compile Include="Commands\VoiceNotificationCommand.cs" />
<Compile Include="Commands\VoicePlusTextCommand.cs" /> <Compile Include="Commands\VoicePlusTextCommand.cs" />
<Compile Include="Modules\Administration.cs" /> <Compile Include="Modules\Administration.cs" />
<Compile Include="Modules\Conversations.cs" /> <Compile Include="Modules\Conversations.cs" />
<Compile Include="Modules\DiscordModule.cs" /> <Compile Include="Modules\DiscordModule.cs" />
<Compile Include="Modules\Gambling.cs" /> <Compile Include="Modules\Gambling\Gambling.cs" />
<Compile Include="Modules\Games.cs" /> <Compile Include="Modules\Games.cs" />
<Compile Include="Modules\Help.cs" /> <Compile Include="Modules\Help.cs" />
<Compile Include="Modules\Music.cs" /> <Compile Include="Modules\Music.cs" />
@ -442,6 +442,7 @@
<Name>Discord.Net</Name> <Name>Discord.Net</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -1,13 +1,15 @@
using System; using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting; using static NadekoBot.Modules.Gambling.Helpers.Cards;
using static NadekoBot.Classes.Cards;
namespace Tests { namespace Tests
{
[TestClass] [TestClass]
public class TestCards { public class TestCards
{
[TestMethod] [TestMethod]
public void TestHandValues() { public void TestHandValues()
{
var setting1 = new List<Card> { var setting1 = new List<Card> {
new Card(CardSuit.Clubs,10), new Card(CardSuit.Clubs,10),
new Card(CardSuit.Clubs,10), new Card(CardSuit.Clubs,10),