Initial commit

Enjoy
This commit is contained in:
Master Kwoth
2015-12-05 11:27:00 +01:00
parent 81642424aa
commit a909d69e4a
30 changed files with 2773 additions and 0 deletions

155
NadekoBot/Classes/Cards.cs Normal file
View 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;
}

View 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;
}
}
}
}

View 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
View 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;
}
}
}

View 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;
}
}
}