Initial commit
Enjoy
This commit is contained in:
155
NadekoBot/Classes/Cards.cs
Normal file
155
NadekoBot/Classes/Cards.cs
Normal file
@ -0,0 +1,155 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
public class Cards
|
||||
{
|
||||
private static Dictionary<int, string> cardNames = new Dictionary<int, string>() {
|
||||
{ 1, "Ace" },
|
||||
{ 2, "Two" },
|
||||
{ 3, "Three" },
|
||||
{ 4, "Four" },
|
||||
{ 5, "Five" },
|
||||
{ 6, "Six" },
|
||||
{ 7, "Seven" },
|
||||
{ 8, "Eight" },
|
||||
{ 9, "Nine" },
|
||||
{ 10, "Ten" },
|
||||
{ 11, "Jack" },
|
||||
{ 12, "Queen" },
|
||||
{ 13, "King" },
|
||||
};
|
||||
|
||||
public enum CARD_SUIT
|
||||
{
|
||||
Spades = 1,
|
||||
Hearts = 2,
|
||||
Diamonds = 3,
|
||||
Clubs = 4
|
||||
}
|
||||
|
||||
public class Card
|
||||
{
|
||||
public CARD_SUIT suit;
|
||||
public int number;
|
||||
|
||||
public string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
string str = "";
|
||||
|
||||
if (number <= 10 && number > 1)
|
||||
{
|
||||
str += number;
|
||||
}
|
||||
else
|
||||
{
|
||||
str += GetName().ToLower();
|
||||
}
|
||||
return @"images/cards/" + str + "_of_" + suit.ToString().ToLower() + ".jpg";
|
||||
}
|
||||
}
|
||||
|
||||
public Card(CARD_SUIT s, int card_num) {
|
||||
this.suit = s;
|
||||
this.number = card_num;
|
||||
}
|
||||
public string GetName() {
|
||||
return cardNames[number];
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return cardNames[number] + " Of " + suit;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Card> cardPool;
|
||||
public List<Card> CardPool
|
||||
{
|
||||
get { return cardPool; }
|
||||
set { cardPool = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time.
|
||||
/// </summary>
|
||||
public Cards()
|
||||
{
|
||||
cardPool = new List<Card>(52);
|
||||
RefillPool();
|
||||
}
|
||||
/// <summary>
|
||||
/// Restart the game of blackjack. It will only refill the pool for now. Probably wont be used, unless you want to have only 1 bjg running at one time,
|
||||
/// then you will restart the same game every time.
|
||||
/// </summary>
|
||||
public void Restart()
|
||||
{
|
||||
// you dont have to uncover what is actually happening anda da hood
|
||||
RefillPool();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
private void RefillPool()
|
||||
{
|
||||
cardPool.Clear();
|
||||
//foreach suit
|
||||
for (int j = 1; j < 14; j++)
|
||||
{
|
||||
// and number
|
||||
for (int 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 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>
|
||||
/// <returns>A card from the pool</returns>
|
||||
public Card DrawACard()
|
||||
{
|
||||
if (CardPool.Count > 0)
|
||||
{
|
||||
//you can either do this if your deck is not shuffled
|
||||
Random r = new Random((int)DateTime.Now.Ticks);
|
||||
int num = r.Next(0, cardPool.Count);
|
||||
Card c = cardPool[num];
|
||||
cardPool.RemoveAt(num);
|
||||
return c;
|
||||
|
||||
// if you want to shuffle when you fill, then take the first one
|
||||
/*
|
||||
Card c = cardPool[0];
|
||||
cardPool.RemoveAt(0);
|
||||
return c;
|
||||
*/
|
||||
}
|
||||
else {
|
||||
|
||||
//for now return null
|
||||
Restart();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 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)
|
||||
{
|
||||
Random r = new Random();
|
||||
cardPool.OrderBy(x => r.Next());
|
||||
}
|
||||
}
|
||||
//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;
|
||||
}
|
||||
|
29
NadekoBot/Classes/Extensions.cs
Normal file
29
NadekoBot/Classes/Extensions.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace NadekoBot
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static void Shuffle<T>(this IList<T> list)
|
||||
{
|
||||
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
|
||||
int n = list.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
byte[] box = new byte[1];
|
||||
do provider.GetBytes(box);
|
||||
while (!(box[0] < n * (Byte.MaxValue / n)));
|
||||
int k = (box[0] % n);
|
||||
n--;
|
||||
T value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
NadekoBot/Classes/ImageHandler.cs
Normal file
39
NadekoBot/Classes/ImageHandler.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot
|
||||
{
|
||||
class ImageHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Merges Images into 1 Image and returns a bitmap.
|
||||
/// </summary>
|
||||
/// <param name="images">The Images you want to merge.</param>
|
||||
/// <returns>Merged bitmap</returns>
|
||||
public static Bitmap MergeImages(Image[] images)
|
||||
{
|
||||
int width = images.Sum(i => i.Width);
|
||||
int height = images[0].Height;
|
||||
Bitmap bitmap = new Bitmap(width, height);
|
||||
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 < img.Height; h++)
|
||||
{
|
||||
bitmap.SetPixel(w + offsetx, h, bm.GetPixel(w, h));
|
||||
}
|
||||
}
|
||||
offsetx += img.Width;
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
315
NadekoBot/Classes/Trivia.cs
Normal file
315
NadekoBot/Classes/Trivia.cs
Normal file
@ -0,0 +1,315 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
|
||||
namespace NadekoBot
|
||||
{
|
||||
public class Trivia : DiscordCommand
|
||||
{
|
||||
public static Dictionary<long, TriviaGame> runningTrivias;
|
||||
|
||||
public Trivia() : base() {
|
||||
runningTrivias = new Dictionary<long, TriviaGame>();
|
||||
}
|
||||
|
||||
public static TriviaGame StartNewGame(CommandEventArgs e) {
|
||||
if (runningTrivias.ContainsKey(e.User.Server.Id))
|
||||
return null;
|
||||
|
||||
var tg = new TriviaGame(e, NadekoBot.client);
|
||||
runningTrivias.Add(e.Server.Id, tg);
|
||||
|
||||
return tg;
|
||||
}
|
||||
|
||||
public TriviaQuestion GetCurrentQuestion(long serverId) {
|
||||
return runningTrivias[serverId].currentQuestion;
|
||||
}
|
||||
|
||||
public override Func<CommandEventArgs, Task> DoFunc()
|
||||
{
|
||||
return async e =>
|
||||
{
|
||||
TriviaGame tg;
|
||||
if ((tg = StartNewGame(e))!=null)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "**Trivia game started!** It is bound to this channel. But only 1 game can run per server. \n First player to get to 10 points wins! You have 30 seconds per question.\nUse command [tq] if game was started by accident.");
|
||||
}
|
||||
else
|
||||
await client.SendMessage(e.Channel, "Trivia game is already running on this server. The question is:\n**"+GetCurrentQuestion(e.Server.Id).Question+"**\n[tq quits trivia]\n[@NadekoBot clr clears my messages]"); // TODO type x to be reminded of the question
|
||||
};
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> LbFunc()
|
||||
{
|
||||
return async e =>
|
||||
{
|
||||
if (runningTrivias.ContainsKey(e.Server.Id))
|
||||
{
|
||||
var lb = runningTrivias[e.User.Server.Id].GetLeaderboard();
|
||||
await client.SendMessage(e.Channel, lb);
|
||||
}
|
||||
else
|
||||
await client.SendMessage(e.Channel, "Trivia game is not running on this server."); // TODO type x to be reminded of the question
|
||||
};
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> RepeatFunc()
|
||||
{
|
||||
return async e =>
|
||||
{
|
||||
if (runningTrivias.ContainsKey(e.Server.Id))
|
||||
{
|
||||
var lb = runningTrivias[e.User.Server.Id].GetLeaderboard();
|
||||
await client.SendMessage(e.Channel, lb);
|
||||
}
|
||||
else
|
||||
await client.SendMessage(e.Channel, "Trivia game is not running on this server."); // TODO type x to be reminded of the question
|
||||
};
|
||||
}
|
||||
|
||||
public override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand("t")
|
||||
.Description("Starts a game of trivia. Questions suck and repeat a lot atm.")
|
||||
.Alias("-t")
|
||||
.Do(DoFunc());
|
||||
|
||||
cgb.CreateCommand("tl")
|
||||
.Description("Shows a current trivia leaderboard.")
|
||||
.Alias("-tl")
|
||||
.Alias("tlb")
|
||||
.Alias("-tlb")
|
||||
.Do(LbFunc());
|
||||
|
||||
cgb.CreateCommand("tq")
|
||||
.Description("Quits current trivia after current question.")
|
||||
.Alias("-tq")
|
||||
.Do(QuitFunc());
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> QuitFunc()
|
||||
{
|
||||
return async e =>
|
||||
{
|
||||
if (runningTrivias.ContainsKey(e.Server.Id) && runningTrivias[e.Server.Id].ChannelId ==e.Channel.Id)
|
||||
{
|
||||
await client.SendMessage(e.Channel, "Trivia will stop after this question. Run [**@NadekoBot clr**] to remove this bot's messages from the channel.");
|
||||
runningTrivias[e.Server.Id].StopGame();
|
||||
}
|
||||
else await client.SendMessage(e.Channel, "No trivias are running on this channel.");
|
||||
};
|
||||
}
|
||||
|
||||
internal static void FinishGame(TriviaGame triviaGame)
|
||||
{
|
||||
runningTrivias.Remove(runningTrivias.Where(kvp => kvp.Value == triviaGame).First().Key);
|
||||
}
|
||||
}
|
||||
|
||||
public class TriviaGame {
|
||||
|
||||
private DiscordClient client;
|
||||
private long _serverId;
|
||||
private long _channellId;
|
||||
|
||||
public long ChannelId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _channellId;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<long, int> users;
|
||||
|
||||
public List<string> oldQuestions;
|
||||
|
||||
public TriviaQuestion currentQuestion = null;
|
||||
|
||||
private bool active = false;
|
||||
|
||||
private Timer timeout;
|
||||
private bool isQuit = false;
|
||||
|
||||
public TriviaGame(CommandEventArgs starter, DiscordClient client) {
|
||||
this.users = new Dictionary<long, int>();
|
||||
this.client = client;
|
||||
this._serverId = starter.Server.Id;
|
||||
this._channellId= starter.Channel.Id;
|
||||
|
||||
oldQuestions = new List<string>();
|
||||
client.MessageReceived += PotentialGuess;
|
||||
|
||||
timeout = new Timer();
|
||||
timeout.Interval = 30000;
|
||||
timeout.Elapsed += (s, e) => { TimeUp(); };
|
||||
|
||||
LoadNextRound();
|
||||
}
|
||||
|
||||
private async void PotentialGuess(object sender, MessageEventArgs e)
|
||||
{
|
||||
if (e.Server.Id != _serverId || !active)
|
||||
return;
|
||||
|
||||
if (e.Message.Text.ToLower() == currentQuestion.Answer.ToLower())
|
||||
{
|
||||
active = false; //start pause between rounds
|
||||
timeout.Enabled = false;
|
||||
|
||||
if (!users.ContainsKey(e.User.Id))
|
||||
users.Add(e.User.Id, 1);
|
||||
else
|
||||
{
|
||||
users[e.User.Id]++;
|
||||
}
|
||||
await client.SendMessage(e.Channel, Mention.User(e.User) + " Guessed it!\n The answer was: **" + currentQuestion.Answer + "**");
|
||||
|
||||
if (users[e.User.Id] >= 10) {
|
||||
await client.SendMessage(e.Channel, " We have a winner! It's " + Mention.User(e.User)+"\n"+GetLeaderboard()+"\n To start a new game type '@NadekoBot t'");
|
||||
FinishGame();
|
||||
return;
|
||||
}
|
||||
|
||||
//if it still didnt return, we can safely start another round :D
|
||||
LoadNextRound();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopGame() {
|
||||
isQuit = true;
|
||||
}
|
||||
|
||||
private void LoadNextRound()
|
||||
{
|
||||
Channel ch = client.GetChannel(_channellId);
|
||||
|
||||
|
||||
if(currentQuestion!=null)
|
||||
oldQuestions.Add(currentQuestion.Question);
|
||||
|
||||
currentQuestion = TriviaQuestionsPool.Instance.GetRandomQuestion(oldQuestions);
|
||||
|
||||
if (currentQuestion == null || isQuit)
|
||||
{
|
||||
client.SendMessage(ch, "Trivia bot stopping. :\\\n" + GetLeaderboard());
|
||||
FinishGame();
|
||||
return;
|
||||
}
|
||||
Timer t = new Timer();
|
||||
t.Interval = 2500;
|
||||
t.Enabled = true;
|
||||
t.Elapsed += async (s, ev) => {
|
||||
active = true;
|
||||
await client.SendMessage(ch, "QUESTION\n**" + currentQuestion.Question + " **");
|
||||
t.Enabled = false;
|
||||
timeout.Enabled = true;//starting countdown of the next question
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
private async void TimeUp() {
|
||||
await client.SendMessage(client.GetChannel(_channellId), "**Time's up.**\nCorrect answer was: **" + currentQuestion.Answer+"**\n**[tq quits trivia][tl shows leaderboard][@NadekoBot clr clears my messages]**");
|
||||
LoadNextRound();
|
||||
}
|
||||
|
||||
public void FinishGame() {
|
||||
isQuit = true;
|
||||
active = false;
|
||||
client.MessageReceived -= PotentialGuess;
|
||||
timeout.Enabled = false;
|
||||
timeout.Dispose();
|
||||
Trivia.FinishGame(this);
|
||||
}
|
||||
|
||||
public string GetLeaderboard() {
|
||||
if (users.Count == 0)
|
||||
return "";
|
||||
|
||||
|
||||
string str = "**Leaderboard:**\n-----------\n";
|
||||
|
||||
if(users.Count>1)
|
||||
users.OrderBy(kvp => kvp.Value);
|
||||
|
||||
foreach (var KeyValuePair in users)
|
||||
{
|
||||
str += "**" + client.GetUser(client.GetServer(_serverId), KeyValuePair.Key).Name + "** has " +KeyValuePair.Value + (KeyValuePair.Value == 1 ? "point." : "points.") + Environment.NewLine;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
public class TriviaQuestion {
|
||||
public string Question;
|
||||
public string Answer;
|
||||
public TriviaQuestion(string q, string a) {
|
||||
this.Question = q;
|
||||
this.Answer = a;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Question;
|
||||
}
|
||||
}
|
||||
|
||||
public class TriviaQuestionsPool {
|
||||
private static TriviaQuestionsPool instance = null;
|
||||
|
||||
public static TriviaQuestionsPool Instance
|
||||
{
|
||||
get {
|
||||
if (instance == null)
|
||||
instance = new TriviaQuestionsPool();
|
||||
return instance;
|
||||
}
|
||||
private set { instance = value; }
|
||||
}
|
||||
|
||||
public List<TriviaQuestion> pool;
|
||||
|
||||
private Random _r;
|
||||
|
||||
public TriviaQuestionsPool() {
|
||||
_r = new Random();
|
||||
pool = new List<TriviaQuestion>();
|
||||
var httpClient = new System.Net.Http.HttpClient();
|
||||
|
||||
|
||||
var r = httpClient.GetAsync("http://jservice.io/api/clues?category=19").Result;
|
||||
string str = r.Content.ReadAsStringAsync().Result;
|
||||
dynamic obj = JArray.Parse(str);
|
||||
|
||||
foreach (var item in obj)
|
||||
{
|
||||
pool.Add(new TriviaQuestion((string)item.question,(string)item.answer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public TriviaQuestion GetRandomQuestion(List<string> exclude) {
|
||||
if (pool.Count == 0)
|
||||
return null;
|
||||
|
||||
TriviaQuestion tq = pool[_r.Next(0, pool.Count)];
|
||||
if (exclude.Count > 0 && exclude.Count < pool.Count)
|
||||
{
|
||||
while (exclude.Contains(tq.Question))
|
||||
{
|
||||
tq = pool[_r.Next(0, pool.Count)];
|
||||
}
|
||||
}
|
||||
return tq;
|
||||
}
|
||||
}
|
||||
}
|
56
NadekoBot/Classes/_JSONModels.cs
Normal file
56
NadekoBot/Classes/_JSONModels.cs
Normal file
@ -0,0 +1,56 @@
|
||||
namespace NadekoBot
|
||||
{
|
||||
public class Credentials
|
||||
{
|
||||
public string Username;
|
||||
public string Password;
|
||||
public string BotMention;
|
||||
public string GoogleAPIKey;
|
||||
public long OwnerID;
|
||||
public bool Crawl;
|
||||
public string ParseID;
|
||||
public string ParseKey;
|
||||
}
|
||||
|
||||
class AnimeResult
|
||||
{
|
||||
public int id;
|
||||
public string airing_status;
|
||||
public string title_english;
|
||||
public int total_episodes;
|
||||
public string description;
|
||||
public string image_url_lge;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "`Title:` **" + title_english +
|
||||
"**\n`Status:` " + airing_status +
|
||||
"\n`Episodes:` " + total_episodes +
|
||||
"\n`Link:` http://anilist.co/anime/" + id +
|
||||
"\n`Synopsis:` " + description.Substring(0, description.Length > 500 ? 500 : description.Length) + "..." +
|
||||
"\n`img:` " + image_url_lge;
|
||||
}
|
||||
}
|
||||
|
||||
class MangaResult
|
||||
{
|
||||
public int id;
|
||||
public string publishing_status;
|
||||
public string image_url_lge;
|
||||
public string title_english;
|
||||
public int total_chapters;
|
||||
public int total_volumes;
|
||||
public string description;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "`Title:` **" + title_english +
|
||||
"**\n`Status:` " + publishing_status +
|
||||
"\n`Chapters:` " + total_chapters +
|
||||
"\n`Volumes:` " + total_volumes +
|
||||
"\n`Link:` http://anilist.co/manga/" + id +
|
||||
"\n`Synopsis:` " + description.Substring(0, description.Length > 500 ? 500 : description.Length) + "..." +
|
||||
"\n`img:` " + image_url_lge;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user