Initial commit
Enjoy
This commit is contained in:
parent
81642424aa
commit
a909d69e4a
231
.gitignore
vendored
Normal file
231
.gitignore
vendored
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
build/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# Visual Studio 2015 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUNIT
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# DNX
|
||||||
|
project.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_i.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# JustCode is a .NET coding add-in
|
||||||
|
.JustCode
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/packages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/packages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/packages/repositories.config
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
node_modules/
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
25
NadekoBot.sln
Normal file
25
NadekoBot.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.24720.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot", "NadekoBot\NadekoBot.csproj", "{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
FullDebug|Any CPU = FullDebug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
14
NadekoBot/App.config
Normal file
14
NadekoBot/App.config
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
|
</startup>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
</configuration>
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
NadekoBot/Commands/CopyCommand.cs
Normal file
64
NadekoBot/Commands/CopyCommand.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Commands;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
class CopyCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
private List<long> CopiedUsers;
|
||||||
|
|
||||||
|
public CopyCommand() : base()
|
||||||
|
{
|
||||||
|
CopiedUsers = new List<long>();
|
||||||
|
client.MessageReceived += Client_MessageReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Client_MessageReceived(object sender, Discord.MessageEventArgs e)
|
||||||
|
{
|
||||||
|
if (CopiedUsers.Contains(e.User.Id)) {
|
||||||
|
await client.SendMessage(e.Channel, e.Message.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Func<CommandEventArgs, Task> DoFunc()
|
||||||
|
{
|
||||||
|
return async e =>
|
||||||
|
{
|
||||||
|
if (CopiedUsers.Contains(e.User.Id)) return;
|
||||||
|
|
||||||
|
CopiedUsers.Add(e.User.Id);
|
||||||
|
await client.SendMessage(e.Channel, " I'll start copying you now.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand("copyme")
|
||||||
|
.Alias("cm")
|
||||||
|
.Description("Nadeko starts copying everything you say. Disable with cs")
|
||||||
|
.Do(DoFunc());
|
||||||
|
|
||||||
|
cgb.CreateCommand("cs")
|
||||||
|
.Alias("copystop")
|
||||||
|
.Description("Nadeko stops copying you")
|
||||||
|
.Do(StopCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Func<CommandEventArgs, Task> StopCopy()
|
||||||
|
{
|
||||||
|
return async e =>
|
||||||
|
{
|
||||||
|
if (!CopiedUsers.Contains(e.User.Id)) return;
|
||||||
|
|
||||||
|
CopiedUsers.Remove(e.User.Id);
|
||||||
|
await client.SendMessage(e.Channel, " I wont copy anymore.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
NadekoBot/Commands/DiceRollCommand.cs
Normal file
101
NadekoBot/Commands/DiceRollCommand.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.Modules;
|
||||||
|
using Discord;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
class DiceRollCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
public DiceRollCommand() : base() { }
|
||||||
|
|
||||||
|
public override Func<CommandEventArgs, Task> DoFunc()
|
||||||
|
{
|
||||||
|
Random r = new Random();
|
||||||
|
return async e => {
|
||||||
|
if (e.Args[0] == "")
|
||||||
|
{
|
||||||
|
int num1 = r.Next(0, 10);
|
||||||
|
int num2 = r.Next(0, 10);
|
||||||
|
|
||||||
|
Console.WriteLine(num1+"|"+num2);
|
||||||
|
|
||||||
|
Image[] images;
|
||||||
|
|
||||||
|
if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1)
|
||||||
|
{
|
||||||
|
images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
images = new Image[2] { GetDice(num1), GetDice(num2) };
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bitmap = ImageHandler.MergeImages(images);
|
||||||
|
bitmap.Save("dices.png");
|
||||||
|
await client.SendFile(e.Channel, "dices.png");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int num = int.Parse(e.Args[0]);
|
||||||
|
if (num < 1) num = 1;
|
||||||
|
if (num > 30)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "You can roll up to 30 dies at a time.");
|
||||||
|
num = 30;
|
||||||
|
}
|
||||||
|
List<Image> dices = new List<Image>(num);
|
||||||
|
List<int> values = new List<int>(num);
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
int randomNumber = r.Next(1, 7);
|
||||||
|
int toInsert = dices.Count;
|
||||||
|
if (randomNumber == 6 || dices.Count==0)
|
||||||
|
toInsert = 0;
|
||||||
|
else if (randomNumber!=1)
|
||||||
|
for (int j = 0; j < dices.Count; j++) {
|
||||||
|
if (values[j] < randomNumber)
|
||||||
|
{
|
||||||
|
toInsert = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dices.Insert(toInsert, GetDice(randomNumber));
|
||||||
|
values.Insert(toInsert, randomNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bitmap = ImageHandler.MergeImages(dices.ToArray());
|
||||||
|
bitmap.Save("dices.png");
|
||||||
|
await client.SendMessage(e.Channel, values.Count + " Dies rolled. Total: **"+values.Sum()+"** Average: **"+(values.Sum()/(1.0f*values.Count)).ToString("N2")+"**");
|
||||||
|
await client.SendFile(e.Channel, "dices.png");
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Please enter a number of dices to roll.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image GetDice(int num) {
|
||||||
|
return Image.FromFile("images/dice/"+num+".png");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand("$roll")
|
||||||
|
.Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\nUsage: $roll [x]")
|
||||||
|
.Parameter("num", ParameterType.Optional)
|
||||||
|
.Do(DoFunc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
NadekoBot/Commands/DiscordCommand.cs
Normal file
42
NadekoBot/Commands/DiscordCommand.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base DiscordCommand Class.
|
||||||
|
/// Inherit this class to create your own command.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DiscordCommand
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client at the moment of creating this object
|
||||||
|
/// </summary>
|
||||||
|
public DiscordClient client { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor of the base class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cb">CommandBuilder which will be modified</param>
|
||||||
|
protected DiscordCommand()
|
||||||
|
{
|
||||||
|
client = NadekoBot.client;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Function containing the behaviour of the command.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">Client who will handle the message sending, etc, if any.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public abstract Func<CommandEventArgs,Task> DoFunc();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the CommandBuilder with values
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Init(CommandGroupBuilder cgb);
|
||||||
|
}
|
||||||
|
}
|
66
NadekoBot/Commands/DrawCommand.cs
Normal file
66
NadekoBot/Commands/DrawCommand.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
class DrawCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
private Cards cards = null;
|
||||||
|
|
||||||
|
public DrawCommand() : base() { }
|
||||||
|
|
||||||
|
public override Func<CommandEventArgs,Task> DoFunc() {
|
||||||
|
return async (e) =>
|
||||||
|
{
|
||||||
|
if (cards == null)
|
||||||
|
{
|
||||||
|
cards = new Cards();
|
||||||
|
await client.SendMessage(e.Channel, "Shuffling cards...");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int num = int.Parse(e.Args[0]);
|
||||||
|
if (num > 5)
|
||||||
|
{
|
||||||
|
num = 5;
|
||||||
|
}
|
||||||
|
else if (num < 1)
|
||||||
|
{
|
||||||
|
num = 1;
|
||||||
|
}
|
||||||
|
Image[] images = new Image[num];
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
if (cards.CardPool.Count == 0)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "No more cards in a deck...\nGetting a new deck...\nShuffling cards...");
|
||||||
|
}
|
||||||
|
images[i] = Image.FromFile(cards.DrawACard().Path);
|
||||||
|
}
|
||||||
|
Bitmap bitmap = ImageHandler.MergeImages(images);
|
||||||
|
bitmap.Save("cards.png");
|
||||||
|
await client.SendFile(e.Channel, "cards.png");
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
Console.WriteLine("Error drawing (a) card(s)");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand("$draw")
|
||||||
|
.Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck.\nUsage: $draw [x]")
|
||||||
|
.Parameter("count", ParameterType.Multiple)
|
||||||
|
.Do(DoFunc());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
38
NadekoBot/Commands/FlipCoinCommand.cs
Normal file
38
NadekoBot/Commands/FlipCoinCommand.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Commands;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
class FlipCoinCommand : DiscordCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
private Random _r;
|
||||||
|
public FlipCoinCommand() : base()
|
||||||
|
{
|
||||||
|
_r = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Func<CommandEventArgs, Task> DoFunc()
|
||||||
|
{
|
||||||
|
return async e => {
|
||||||
|
int num = _r.Next(0, 2);
|
||||||
|
if (num == 1)
|
||||||
|
{
|
||||||
|
await client.SendFile(e.Channel, @"images/coins/heads.png");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendFile(e.Channel, @"images/coins/tails.png");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init(CommandGroupBuilder cgb)
|
||||||
|
{
|
||||||
|
cgb.CreateCommand("$flip")
|
||||||
|
.Description("Flips a coin, heads or tails, and shows an image of it.")
|
||||||
|
.Do(DoFunc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
585
NadekoBot/Modules/Conversations.cs
Normal file
585
NadekoBot/Modules/Conversations.cs
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.Modules;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules
|
||||||
|
{
|
||||||
|
class Conversations : DiscordModule
|
||||||
|
{
|
||||||
|
private string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥";
|
||||||
|
public Conversations() : base()
|
||||||
|
{
|
||||||
|
commands.Add(new CopyCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
private CommandBuilder CreateCommand(CommandGroupBuilder cbg, string txt)
|
||||||
|
{
|
||||||
|
CommandBuilder cb = cbg.CreateCommand(txt);
|
||||||
|
return AliasCommand(cb, txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CommandBuilder AliasCommand(CommandBuilder cb, string txt)
|
||||||
|
{
|
||||||
|
return cb.Alias(new string[] { "," + txt, "-" + txt });
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Install(ModuleManager manager)
|
||||||
|
{
|
||||||
|
Random rng = new Random();
|
||||||
|
manager.CreateCommands("", cgb =>
|
||||||
|
{
|
||||||
|
var client = manager.Client;
|
||||||
|
|
||||||
|
cgb.CreateCommand("\\o\\")
|
||||||
|
.Description("Nadeko replies with /o/")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + "/o/");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("/o/")
|
||||||
|
.Description("Nadeko replies with \\o\\")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + "\\o\\");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
manager.CreateCommands(NadekoBot.botMention, cgb =>
|
||||||
|
{
|
||||||
|
var client = manager.Client;
|
||||||
|
|
||||||
|
commands.ForEach(cmd => cmd.Init(cgb));
|
||||||
|
|
||||||
|
CreateCommand(cgb, "do you love me")
|
||||||
|
.Description("Replies with positive answer only to the bot owner.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + ", Of course I do, my Master.");
|
||||||
|
else
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + ", Don't be silly.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "die")
|
||||||
|
.Description("Works only for the owner. Shuts the bot down.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
Timer t = new Timer();
|
||||||
|
t.Interval = 2000;
|
||||||
|
t.Elapsed += (s, ev) => { Environment.Exit(0); };
|
||||||
|
t.Start();
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + ", Yes, my love.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + ", No.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "how are you")
|
||||||
|
.Description("Replies positive only if bot owner is online.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " I am great as long as you are here.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var kw = client.GetUser(e.Server, NadekoBot.OwnerID);
|
||||||
|
if (kw != null && kw.Status == UserStatus.Online)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " I am great as long as " + Mention.User(kw) + " is with me.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " I am sad. My Master is not with me.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "insult")
|
||||||
|
.Parameter("mention", ParameterType.Required)
|
||||||
|
.Description("Only works for owner. Insults @X person.\nUsage: @NadekoBot insult @X.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
List<string> insults = new List<string> { " you are a poop.", " you jerk.", " i will eat you when i get my powers back." };
|
||||||
|
Random r = new Random();
|
||||||
|
var u = e.Message.MentionedUsers.Last();
|
||||||
|
if (u.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "I would never insult my master <3");
|
||||||
|
}
|
||||||
|
else if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(u) + insults[r.Next(0, insults.Count)]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " Eww, why would i do that for you ?!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "praise")
|
||||||
|
.Description("Only works for owner. Praises @X person.\nUsage: @NadekoBot insult @X.")
|
||||||
|
.Parameter("mention", ParameterType.Required)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
List<string> praises = new List<string> { " You are cool.", " You are nice... But don't get any wrong ideas.", " You did a good job." };
|
||||||
|
Random r = new Random();
|
||||||
|
var u = e.Message.MentionedUsers.First();
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
if (u.Id != NadekoBot.OwnerID)
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(u) + praises[r.Next(0, praises.Count)]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(u) + " No need, you know I love you <3");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (u.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " I don't need your permission to praise my beloved Master <3");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " Yeah... No.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "are you real")
|
||||||
|
.Description("Useless.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " I will be soon.");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("are you there")
|
||||||
|
.Description("Checks if nadeko is operational.")
|
||||||
|
.Alias(new string[] { "!", "?", "??", "???", "!!", "!!!" })
|
||||||
|
.Do(SayYes());
|
||||||
|
|
||||||
|
CreateCommand(cgb, "draw")
|
||||||
|
.Description("Nadeko instructs you to type $draw. Gambling functions start with $")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Sorry i dont gamble, type $draw for that function.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "uptime")
|
||||||
|
.Description("Shows how long is Nadeko running for.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||||
|
string str = "I am online for " + time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
||||||
|
await client.SendMessage(e.Channel, str);
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "fire")
|
||||||
|
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire.\nUsage: @NadekoBot fire [x]")
|
||||||
|
.Parameter("times", ParameterType.Optional)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
if (e.Args?.Length > 0)
|
||||||
|
int.TryParse(e.Args[0], out count);
|
||||||
|
|
||||||
|
if (count < 1)
|
||||||
|
count = 1;
|
||||||
|
else if (count > 12)
|
||||||
|
count = 12;
|
||||||
|
string str = "";
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
str += firestr;
|
||||||
|
}
|
||||||
|
await client.SendMessage(e.Channel, str);
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "rip")
|
||||||
|
.Description("Shows a grave image.Optional parameter [@X] instructs her to put X's name on the grave.\nUsage: @NadekoBot rip [@X]")
|
||||||
|
.Parameter("all", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
|
||||||
|
if (e.Message.MentionedUsers.Count() == 1)
|
||||||
|
{
|
||||||
|
await client.SendFile(e.Channel, @"images\rip.png");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (User u in e.Message.MentionedUsers)
|
||||||
|
{
|
||||||
|
if (u.Name == "NadekoBot") continue;
|
||||||
|
RipName(u.Name);
|
||||||
|
await client.SendFile(e.Channel, @"images\ripnew.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("j")
|
||||||
|
.Description("Joins a server using a code. Obsolete, since nadeko will autojoin any valid code in chat.")
|
||||||
|
.Parameter("id", ParameterType.Required)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await client.AcceptInvite(client.GetInvite(e.Args[0]).Result);
|
||||||
|
await client.SendMessage(e.Channel, "I got in!");
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Invalid code.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("i")
|
||||||
|
.Description("Pulls a first image using a search parameter.\nUsage: @NadekoBot img Multiword_search_parameter")
|
||||||
|
.Alias("img")
|
||||||
|
.Parameter("all", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var httpClient = new System.Net.Http.HttpClient();
|
||||||
|
string str = e.Args[0];
|
||||||
|
|
||||||
|
var r = httpClient.GetAsync("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" + Uri.EscapeDataString(str) + "&start=0").Result;
|
||||||
|
|
||||||
|
dynamic obj = JObject.Parse(r.Content.ReadAsStringAsync().Result);
|
||||||
|
if (obj.responseData.results.Count == 0)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "No results found for that keyword :\\");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string s = Searches.ShortenUrl(obj.responseData.results[0].url.ToString());
|
||||||
|
await client.SendMessage(e.Channel, s);
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("ir")
|
||||||
|
.Description("Pulls a random image using a search parameter.\nUsage: @NadekoBot img Multiword_search_parameter")
|
||||||
|
.Alias("imgrandom")
|
||||||
|
.Parameter("all", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
|
||||||
|
var httpClient = new System.Net.Http.HttpClient();
|
||||||
|
string str = e.Args[0];
|
||||||
|
var r = httpClient.GetAsync("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" + Uri.EscapeDataString(str) + "&start=" + rng.Next(0, 30)).Result;
|
||||||
|
dynamic obj = JObject.Parse(r.Content.ReadAsStringAsync().Result);
|
||||||
|
if (obj.responseData.results.Count == 0)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "No results found for that keyword :\\");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int rnd = rng.Next(0, obj.responseData.results.Count);
|
||||||
|
string s = Searches.ShortenUrl(obj.responseData.results[rnd].url.ToString());
|
||||||
|
await client.SendMessage(e.Channel, s);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
AliasCommand(CreateCommand(cgb, "save"), "s")
|
||||||
|
.Description("Saves something for the owner in a file.")
|
||||||
|
.Parameter("all", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
string m = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileStream f = File.OpenWrite("saves.txt");
|
||||||
|
m = e.Args[0];
|
||||||
|
byte[] b = Encoding.ASCII.GetBytes(m + "\n");
|
||||||
|
f.Seek(f.Length, SeekOrigin.Begin);
|
||||||
|
f.Write(b, 0, b.Length);
|
||||||
|
f.Close();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Error saving. Sorry :(");
|
||||||
|
}
|
||||||
|
if (m.Length > 0)
|
||||||
|
await client.SendMessage(e.Channel, "I saved this for you: " + Environment.NewLine + "```" + m + "```");
|
||||||
|
else
|
||||||
|
await client.SendMessage(e.Channel, "No point in saving empty message...");
|
||||||
|
}
|
||||||
|
else await client.SendMessage(e.Channel, "Not for you, only my Master <3");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "ls")
|
||||||
|
.Description("Shows all saved items.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
FileStream f = File.OpenRead("saves.txt");
|
||||||
|
if (f.Length == 0)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Saves are empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte[] b = new byte[f.Length / sizeof(byte)];
|
||||||
|
f.Read(b, 0, b.Length);
|
||||||
|
f.Close();
|
||||||
|
string str = Encoding.ASCII.GetString(b);
|
||||||
|
await client.SendPrivateMessage(e.User, "```" + (str.Length < 1950 ? str : str.Substring(0, 1950)) + "```");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "cs")
|
||||||
|
.Description("Deletes all saves")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
File.Delete("saves.txt");
|
||||||
|
await client.SendMessage(e.Channel, "Cleared all saves.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "bb")
|
||||||
|
.Description("Says bye to someone.\nUsage: @NadekoBot bb @X")
|
||||||
|
.Parameter("ppl", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
string str = "Bye";
|
||||||
|
foreach (var u in e.Message.MentionedUsers)
|
||||||
|
{
|
||||||
|
str += " " + Mention.User(u);
|
||||||
|
}
|
||||||
|
await client.SendMessage(e.Channel, str);
|
||||||
|
});
|
||||||
|
|
||||||
|
AliasCommand(CreateCommand(cgb, "req"), "request")
|
||||||
|
.Description("Requests a feature for nadeko.\nUsage: @NadekoBot req Mutliword_feature_request")
|
||||||
|
.Parameter("all", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
string str = e.Args[0];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StatsCollector.SaveRequest(e, str);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Something went wrong.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await client.SendMessage(e.Channel, "Thank you for your request.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "lr")
|
||||||
|
.Description("PMs the user all current nadeko requests.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
string str = StatsCollector.GetRequests();
|
||||||
|
if (str.Trim().Length > 110)
|
||||||
|
await client.SendPrivateMessage(e.User, str);
|
||||||
|
else
|
||||||
|
await client.SendPrivateMessage(e.User, "No requests atm.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "dr")
|
||||||
|
.Description("Deletes a request. Only owner is able to do this.")
|
||||||
|
.Parameter("reqNumber", ParameterType.Required)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (StatsCollector.DeleteRequest(int.Parse(e.Args[0])))
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " Request deleted.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "No request on that number.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Error deleting request, probably NaN error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else await client.SendMessage(e.Channel, "You don't have permission to do that.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "rr")
|
||||||
|
.Description("Resolves a request. Only owner is able to do this.")
|
||||||
|
.Parameter("reqNumber", ParameterType.Required)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.User.Id == NadekoBot.OwnerID)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sc = StatsCollector.ResolveRequest(int.Parse(e.Args[0]));
|
||||||
|
if (sc != null)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, Mention.User(e.User) + " Request resolved, notice sent.");
|
||||||
|
await client.SendPrivateMessage(client.GetUser(client.GetServer(sc.ServerId), sc.Id), "**This request of yours has been resolved:**\n" + sc.Text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "No request on that number.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Error resolving request, probably NaN error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else await client.SendMessage(e.Channel, "You don't have permission to do that.");
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "clr")
|
||||||
|
.Description("Clears some of nadeko's messages from the current channel.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (e.Channel.Messages.Count() < 50)
|
||||||
|
{
|
||||||
|
await client.DownloadMessages(e.Channel, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.DeleteMessages(e.Channel.Messages.Where(msg => msg.User.Id == client.CurrentUser.Id));
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "I cant do it :(");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "call")
|
||||||
|
.Description("Useless. Writes calling @X to chat.\nUsage: @NadekoBot call @X ")
|
||||||
|
.Parameter("who", ParameterType.Required)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Calling " + e.Args[0] + "...");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("cid")
|
||||||
|
.Description("Shows current channel id")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "This channel's id is " + e.Channel.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("sid")
|
||||||
|
.Description("Shows current server id")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "This server's id is " + e.Server.Id);
|
||||||
|
});
|
||||||
|
CreateCommand(cgb, "hide")
|
||||||
|
.Description("Hides nadeko in plain sight!11!!")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
using (Image img = Image.FromFile("images/hidden.png"))
|
||||||
|
{
|
||||||
|
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
||||||
|
|
||||||
|
await client.EditProfile("", null, null, null, ms, ImageType.Png);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
StatsCollector.DEBUG_LOG(ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateCommand(cgb, "unhide")
|
||||||
|
.Description("Hides nadeko in plain sight!11!!")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
using (Image img = Image.FromFile("images/nadeko.jpg"))
|
||||||
|
{
|
||||||
|
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||||
|
|
||||||
|
await client.EditProfile("", null, null, null,ms, ImageType.Jpeg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
StatsCollector.DEBUG_LOG(ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CreateCommand(cgb, "stats")
|
||||||
|
.Description("Shows some basic stats for nadeko")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
int serverCount = client.AllServers.Count();
|
||||||
|
int uniqueUserCount = client.AllUsers.Count();
|
||||||
|
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||||
|
string uptime = " " + time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
||||||
|
|
||||||
|
await client.SendMessage(e.Channel, String.Format("```Servers: {0}\nUnique Users: {1}\nUptime: {2}\nMy id is: {3}```", serverCount, uniqueUserCount, uptime, client.CurrentUserId));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//TODO add eval
|
||||||
|
/*
|
||||||
|
cgb.CreateCommand(">")
|
||||||
|
.Parameter("code", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.Message.User.Id == NadekoBot.OwnerId)
|
||||||
|
{
|
||||||
|
var result = await CSharpScript.EvaluateAsync(e.Args[0]);
|
||||||
|
await client.SendMessage(e.Channel, result?.ToString() ?? "null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RipName(string name)
|
||||||
|
{
|
||||||
|
Bitmap bm = new Bitmap(Image.FromFile(@"images\rip.png"));
|
||||||
|
|
||||||
|
int offset = name.Length * 5;
|
||||||
|
|
||||||
|
int fontSize = 20;
|
||||||
|
|
||||||
|
if (name.Length > 10)
|
||||||
|
{
|
||||||
|
fontSize -= (name.Length - 10) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO use measure string
|
||||||
|
Graphics g = Graphics.FromImage(bm);
|
||||||
|
g.DrawString(name, new Font("Comic Sans MS", fontSize, FontStyle.Bold), Brushes.Black, 100 - offset, 200);
|
||||||
|
g.DrawString("? - " + DateTime.Now.Year, new Font("Consolas", 12, FontStyle.Bold), Brushes.Black, 80, 235);
|
||||||
|
g.Flush();
|
||||||
|
g.Dispose();
|
||||||
|
|
||||||
|
bm.Save(@"images\ripnew.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Func<CommandEventArgs, Task> SayYes()
|
||||||
|
{
|
||||||
|
return async e =>
|
||||||
|
{
|
||||||
|
await NadekoBot.client.SendMessage(e.Channel, "Yes. :)");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
NadekoBot/Modules/DiscordModule.cs
Normal file
20
NadekoBot/Modules/DiscordModule.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Discord.Modules;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules
|
||||||
|
{
|
||||||
|
abstract class DiscordModule : IModule
|
||||||
|
{
|
||||||
|
public List<DiscordCommand> commands;
|
||||||
|
|
||||||
|
protected DiscordModule() {
|
||||||
|
commands = new List<DiscordCommand>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Install(ModuleManager manager);
|
||||||
|
}
|
||||||
|
}
|
23
NadekoBot/Modules/Gambling.cs
Normal file
23
NadekoBot/Modules/Gambling.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Discord.Commands;
|
||||||
|
using Discord.Modules;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules
|
||||||
|
{
|
||||||
|
class Gambling : DiscordModule
|
||||||
|
{
|
||||||
|
|
||||||
|
public Gambling() {
|
||||||
|
commands.Add(new DrawCommand());
|
||||||
|
commands.Add(new FlipCoinCommand());
|
||||||
|
commands.Add(new DiceRollCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Install(ModuleManager manager)
|
||||||
|
{
|
||||||
|
manager.CreateCommands("", cgb =>
|
||||||
|
{
|
||||||
|
commands.ForEach(com => com.Init(cgb));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
NadekoBot/Modules/Games.cs
Normal file
24
NadekoBot/Modules/Games.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Modules;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules
|
||||||
|
{
|
||||||
|
class Games : DiscordModule
|
||||||
|
{
|
||||||
|
public Games() : base() {
|
||||||
|
commands.Add(new Trivia());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Install(ModuleManager manager)
|
||||||
|
{
|
||||||
|
manager.CreateCommands("", cgb =>
|
||||||
|
{
|
||||||
|
commands.ForEach(cmd => cmd.Init(cgb));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
230
NadekoBot/Modules/Music.cs
Normal file
230
NadekoBot/Modules/Music.cs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Modules;
|
||||||
|
using Discord.Commands;
|
||||||
|
using System.IO;
|
||||||
|
using Discord;
|
||||||
|
using Discord.Audio;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using VideoLibrary;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules
|
||||||
|
{
|
||||||
|
class Music : DiscordModule
|
||||||
|
{
|
||||||
|
private static bool exit = true;
|
||||||
|
|
||||||
|
public static bool NextSong = false;
|
||||||
|
public static IDiscordVoiceClient Voice;
|
||||||
|
public static Channel VoiceChannel;
|
||||||
|
public static bool Pause = false;
|
||||||
|
public static List<YouTubeVideo> SongQueue = new List<YouTubeVideo>();
|
||||||
|
|
||||||
|
public static YouTubeVideo CurrentSong;
|
||||||
|
|
||||||
|
public static bool Exit
|
||||||
|
{
|
||||||
|
get { return exit; }
|
||||||
|
set { exit = value;} // if i set this to true, break the song and exit the main loop
|
||||||
|
}
|
||||||
|
|
||||||
|
public Music() : base() {
|
||||||
|
//commands.Add(new PlayMusic());
|
||||||
|
}
|
||||||
|
|
||||||
|
//m r,radio - init
|
||||||
|
//m n,next - next in que
|
||||||
|
//m p,pause - pauses, call again to unpause
|
||||||
|
//m yq [key_words] - queue from yt by keywords
|
||||||
|
//m s,stop - stop
|
||||||
|
//m sh - shuffle songs
|
||||||
|
//m pl - current playlist
|
||||||
|
|
||||||
|
|
||||||
|
public override void Install(ModuleManager manager)
|
||||||
|
{
|
||||||
|
var client = NadekoBot.client;
|
||||||
|
manager.CreateCommands("!m", cgb =>
|
||||||
|
{
|
||||||
|
//queue all more complex commands
|
||||||
|
commands.ForEach(cmd => cmd.Init(cgb));
|
||||||
|
|
||||||
|
cgb.CreateCommand("n")
|
||||||
|
.Alias("next")
|
||||||
|
.Description("Goes to the next song in the queue.")
|
||||||
|
.Do(e =>
|
||||||
|
{
|
||||||
|
if (Voice != null && Exit == false)
|
||||||
|
{
|
||||||
|
NextSong = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("s")
|
||||||
|
.Alias("stop")
|
||||||
|
.Description("Completely stops the music and unbinds the bot from the channel.")
|
||||||
|
.Do(e =>
|
||||||
|
{
|
||||||
|
if (Voice != null && Exit == false)
|
||||||
|
{
|
||||||
|
Exit = true;
|
||||||
|
SongQueue = new List<YouTubeVideo>();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("p")
|
||||||
|
.Alias("pause")
|
||||||
|
.Description("Pauses the song")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (Voice != null && Exit == false && CurrentSong != null)
|
||||||
|
{
|
||||||
|
Pause = !Pause;
|
||||||
|
if (Pause)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Pausing. Run the command again to resume.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Resuming...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("q")
|
||||||
|
.Alias("yq")
|
||||||
|
.Description("Queue a song using a multi/single word name.\nUsage: `!m q Dream Of Venice`")
|
||||||
|
.Parameter("Query", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
var youtube = YouTube.Default;
|
||||||
|
var video = youtube.GetAllVideos(Searches.FindYoutubeUrlByKeywords(e.Args[0]))
|
||||||
|
.Where(v => v.AdaptiveKind == AdaptiveKind.Audio)
|
||||||
|
.OrderByDescending(v => v.AudioBitrate).FirstOrDefault();
|
||||||
|
|
||||||
|
if (video?.Uri != "" && video.Uri != null)
|
||||||
|
{
|
||||||
|
SongQueue.Add(video);
|
||||||
|
await client.SendMessage(e.Channel, "**Queued** " + video.FullName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("lq")
|
||||||
|
.Alias("ls").Alias("lp")
|
||||||
|
.Description("Lists up to 10 currently queued songs.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, SongQueue.Count + " videos currently queued.");
|
||||||
|
await client.SendMessage(e.Channel, string.Join("\n", SongQueue.Select(v => v.FullName).Take(10)));
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("sh")
|
||||||
|
.Description("Shuffles the current playlist.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (SongQueue.Count < 2)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Not enough songs in order to perform the shuffle.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SongQueue.Shuffle();
|
||||||
|
await client.SendMessage(e.Channel, "Songs shuffled!");
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("radio")
|
||||||
|
.Alias("music")
|
||||||
|
.Description("Binds to a voice and text channel in order to play music.")
|
||||||
|
.Parameter("ChannelName", ParameterType.Unparsed)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (Voice != null) return;
|
||||||
|
VoiceChannel = client.FindChannels(e.Server, e.GetArg("ChannelName").Trim(), ChannelType.Voice).FirstOrDefault();
|
||||||
|
Voice = await client.JoinVoiceServer(VoiceChannel);
|
||||||
|
Exit = false;
|
||||||
|
NextSong = false;
|
||||||
|
Pause = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (Exit) break;
|
||||||
|
if (SongQueue.Count == 0 || Pause) { Thread.Sleep(100); continue; }
|
||||||
|
if (!LoadNextSong()) break;
|
||||||
|
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
if (Exit)
|
||||||
|
{
|
||||||
|
Voice = null;
|
||||||
|
Exit = false;
|
||||||
|
await client.SendMessage(e.Channel, "Exiting...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int blockSize = 1920;
|
||||||
|
byte[] buffer = new byte[1920];
|
||||||
|
//float multiplier = 1.0f / 48000 / 2;
|
||||||
|
|
||||||
|
var msg = await client.SendMessage(e.Channel, "Playing " + Music.CurrentSong.FullName + " [00:00]");
|
||||||
|
int counter = 0;
|
||||||
|
int byteCount;
|
||||||
|
using (var stream = GetAudioFileStream(Music.CurrentSong.Uri))
|
||||||
|
{
|
||||||
|
while ((byteCount = stream.Read(buffer, 0, blockSize)) > 0)
|
||||||
|
{
|
||||||
|
Voice.SendVoicePCM(buffer, byteCount);
|
||||||
|
counter += blockSize;
|
||||||
|
if (NextSong)
|
||||||
|
{
|
||||||
|
NextSong = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Exit)
|
||||||
|
{
|
||||||
|
Exit = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (Pause) Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await Voice.WaitVoice();
|
||||||
|
}
|
||||||
|
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
|
||||||
|
await client.LeaveVoiceServer(VoiceChannel.Server);
|
||||||
|
Voice = null;
|
||||||
|
VoiceChannel = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream GetAudioFileStream(string file)
|
||||||
|
{
|
||||||
|
Process p = Process.Start(new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
FileName = "ffmpeg",
|
||||||
|
Arguments = "-i \"" + Uri.EscapeUriString(file) + "\" -f s16le -ar 48000 -af volume=1 -ac 1 pipe:1 ",
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true
|
||||||
|
});
|
||||||
|
return p.StandardOutput.BaseStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool LoadNextSong()
|
||||||
|
{
|
||||||
|
if (SongQueue.Count == 0) {
|
||||||
|
CurrentSong = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CurrentSong = SongQueue[0];
|
||||||
|
SongQueue.RemoveAt(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
197
NadekoBot/Modules/Searches.cs
Normal file
197
NadekoBot/Modules/Searches.cs
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Modules;
|
||||||
|
using System.Net;
|
||||||
|
using System.IO;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules
|
||||||
|
{
|
||||||
|
class Searches : DiscordModule
|
||||||
|
{
|
||||||
|
public Searches() : base()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Install(ModuleManager manager)
|
||||||
|
{
|
||||||
|
var client = NadekoBot.client;
|
||||||
|
|
||||||
|
manager.CreateCommands("",cgb =>
|
||||||
|
{
|
||||||
|
cgb.CreateCommand("~av")
|
||||||
|
.Parameter("mention", Discord.Commands.ParameterType.Required)
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (e.Message.MentionedUsers.Count() == 0) {
|
||||||
|
await client.SendMessage(e.Channel, "You need to mention a person");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string av = e.Message.MentionedUsers.First().AvatarUrl;
|
||||||
|
await client.SendMessage(e.Channel, ShortenUrl("http://www.discordapp.com/api/" + av));
|
||||||
|
|
||||||
|
});
|
||||||
|
cgb.CreateCommand("~yt")
|
||||||
|
.Parameter("query",Discord.Commands.ParameterType.Unparsed)
|
||||||
|
.Description("Queries youtubes and embeds the first result")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
|
||||||
|
|
||||||
|
var str = ShortenUrl(FindYoutubeUrlByKeywords(e.GetArg("query")));
|
||||||
|
if (str == null || str.Trim().Length < 5)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Query failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await client.SendMessage(e.Channel, str);
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("~ani")
|
||||||
|
.Alias("~anime").Alias("~aq")
|
||||||
|
.Parameter("query", Discord.Commands.ParameterType.Unparsed)
|
||||||
|
.Description("Queries anilist for an anime and shows the first result.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
|
||||||
|
|
||||||
|
var result = GetAnimeQueryResultLink(e.GetArg("query"));
|
||||||
|
if (result == null) {
|
||||||
|
await client.SendMessage(e.Channel, "Failed to find that anime.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.SendMessage(e.Channel,result.ToString());
|
||||||
|
});
|
||||||
|
|
||||||
|
cgb.CreateCommand("~mang")
|
||||||
|
.Alias("~manga").Alias("~mq")
|
||||||
|
.Parameter("query", Discord.Commands.ParameterType.Unparsed)
|
||||||
|
.Description("Queries anilist for a manga and shows the first result.")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
|
||||||
|
|
||||||
|
var result = GetMangaQueryResultLink(e.GetArg("query"));
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
await client.SendMessage(e.Channel, "Failed to find that anime.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await client.SendMessage(e.Channel, result.ToString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private string token = "";
|
||||||
|
private AnimeResult GetAnimeQueryResultLink(string query)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cl = new RestSharp.RestClient("https://anilist.co/api");
|
||||||
|
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
|
||||||
|
|
||||||
|
RefreshToken();
|
||||||
|
|
||||||
|
rq = new RestSharp.RestRequest("/anime/search/" + Uri.EscapeUriString(query));
|
||||||
|
rq.AddParameter("access_token", token);
|
||||||
|
|
||||||
|
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
|
||||||
|
|
||||||
|
rq = new RestSharp.RestRequest("anime/" + smallObj["id"]);
|
||||||
|
rq.AddParameter("access_token", token);
|
||||||
|
return JsonConvert.DeserializeObject<AnimeResult>(cl.Execute(rq).Content);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MangaResult GetMangaQueryResultLink(string query)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RefreshToken();
|
||||||
|
|
||||||
|
var cl = new RestSharp.RestClient("https://anilist.co/api");
|
||||||
|
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
|
||||||
|
rq = new RestSharp.RestRequest("/manga/search/"+Uri.EscapeUriString(query));
|
||||||
|
rq.AddParameter("access_token", token);
|
||||||
|
|
||||||
|
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
|
||||||
|
|
||||||
|
rq = new RestSharp.RestRequest("manga/" + smallObj["id"]);
|
||||||
|
rq.AddParameter("access_token", token);
|
||||||
|
return JsonConvert.DeserializeObject<MangaResult> (cl.Execute(rq).Content);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshToken()
|
||||||
|
{
|
||||||
|
var cl = new RestSharp.RestClient("https://anilist.co/api");
|
||||||
|
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
|
||||||
|
rq.AddParameter("grant_type", "client_credentials");
|
||||||
|
rq.AddParameter("client_id", "kwoth-w0ki9");
|
||||||
|
rq.AddParameter("client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z");
|
||||||
|
token = JObject.Parse(cl.Execute(rq).Content)["access_token"].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<bool> ValidateQuery(Discord.Channel ch,string query) {
|
||||||
|
if (query == null || query.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
await NadekoBot.client.SendMessage(ch, "Please specify search parameters.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FindYoutubeUrlByKeywords(string v)
|
||||||
|
{
|
||||||
|
WebRequest wr = WebRequest.Create("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=" + Uri.EscapeDataString(v) + "&key=" + NadekoBot.GoogleAPIKey);
|
||||||
|
|
||||||
|
var sr = new StreamReader(wr.GetResponse().GetResponseStream());
|
||||||
|
|
||||||
|
dynamic obj = JObject.Parse(sr.ReadToEnd());
|
||||||
|
return "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ShortenUrl(string url)
|
||||||
|
{
|
||||||
|
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey);
|
||||||
|
httpWebRequest.ContentType = "application/json";
|
||||||
|
httpWebRequest.Method = "POST";
|
||||||
|
|
||||||
|
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
||||||
|
{
|
||||||
|
string json = "{\"longUrl\":\"" + url + "\"}";
|
||||||
|
streamWriter.Write(json);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
|
||||||
|
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
|
||||||
|
{
|
||||||
|
var responseText = streamReader.ReadToEnd();
|
||||||
|
string MATCH_PATTERN = @"""id"": ?""(?<id>.+)""";
|
||||||
|
return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
151
NadekoBot/NadekoBot.cs
Normal file
151
NadekoBot/NadekoBot.cs
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
using Discord;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.Modules;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Parse;
|
||||||
|
using NadekoBot.Modules;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
class NadekoBot
|
||||||
|
{
|
||||||
|
public static DiscordClient client;
|
||||||
|
public static StatsCollector sc;
|
||||||
|
public static string botMention;
|
||||||
|
public static string GoogleAPIKey;
|
||||||
|
public static long OwnerID;
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
//load credentials from credentials.json
|
||||||
|
Credentials c;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
c = JsonConvert.DeserializeObject<Credentials>(File.ReadAllText("credentials.json"));
|
||||||
|
botMention = c.BotMention;
|
||||||
|
GoogleAPIKey = c.GoogleAPIKey;
|
||||||
|
OwnerID = c.OwnerID;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Failed to load stuff from credentials.json, RTFM");
|
||||||
|
Console.ReadKey();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//init parse
|
||||||
|
if (c.ParseKey != null && c.ParseID != null)
|
||||||
|
ParseClient.Initialize(c.ParseID,c.ParseKey);
|
||||||
|
|
||||||
|
//create new discord client
|
||||||
|
client = new DiscordClient(new DiscordClientConfig() {
|
||||||
|
VoiceMode = DiscordVoiceMode.Outgoing,
|
||||||
|
});
|
||||||
|
|
||||||
|
//create a command service
|
||||||
|
var commandService = new CommandService(new CommandServiceConfig
|
||||||
|
{
|
||||||
|
CommandChar = null,
|
||||||
|
HelpMode = HelpMode.Disable
|
||||||
|
});
|
||||||
|
|
||||||
|
//monitor commands for logging
|
||||||
|
sc = new StatsCollector(commandService);
|
||||||
|
|
||||||
|
//add command service
|
||||||
|
var commands = client.AddService(commandService);
|
||||||
|
|
||||||
|
//help command
|
||||||
|
commands.CreateCommand("-h")
|
||||||
|
.Alias(new string[]{"-help",NadekoBot.botMention+" help", NadekoBot.botMention+" h"})
|
||||||
|
.Description("Help command")
|
||||||
|
.Do(async e =>
|
||||||
|
{
|
||||||
|
string helpstr = "";
|
||||||
|
foreach (var com in client.Commands().AllCommands) {
|
||||||
|
helpstr += "&###**#" + com.Category + "#**\n";
|
||||||
|
helpstr += PrintCommandHelp(com);
|
||||||
|
}
|
||||||
|
while (helpstr.Length > 2000) {
|
||||||
|
var curstr = helpstr.Substring(0, 2000);
|
||||||
|
await client.SendPrivateMessage(e.User, curstr.Substring(0,curstr.LastIndexOf("&")));
|
||||||
|
helpstr = curstr.Substring(curstr.LastIndexOf("&")) + helpstr.Substring(2000);
|
||||||
|
}
|
||||||
|
await client.SendPrivateMessage(e.User, helpstr);
|
||||||
|
});
|
||||||
|
|
||||||
|
//create module service
|
||||||
|
var modules = client.AddService(new ModuleService());
|
||||||
|
|
||||||
|
//install modules
|
||||||
|
modules.Install(new Conversations(), "Conversation", FilterType.Unrestricted);
|
||||||
|
modules.Install(new Gambling(), "Gambling", FilterType.Unrestricted);
|
||||||
|
modules.Install(new Games(), "Games", FilterType.Unrestricted);
|
||||||
|
modules.Install(new Music(), "Music", FilterType.Unrestricted);
|
||||||
|
modules.Install(new Searches(), "Searches", FilterType.Unrestricted);
|
||||||
|
|
||||||
|
commands.CommandError += Commands_CommandError;
|
||||||
|
|
||||||
|
//run the bot
|
||||||
|
client.Run(async () =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to connect...");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await client.Connect(c.Username, c.Password);
|
||||||
|
Console.WriteLine("Connected!");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Console.WriteLine("Exiting...");
|
||||||
|
Console.ReadKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Commands_CommandError(object sender, CommandErrorEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Command != null)
|
||||||
|
client.SendMessage(e.Channel, Mention.User(e.User) + " Command failed. See help (-h).");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string PrintCommandHelp(Command com)
|
||||||
|
{
|
||||||
|
var str = "`" + com.Text + "`\n";
|
||||||
|
foreach (var a in com.Aliases)
|
||||||
|
str += "`" + a + "`\n";
|
||||||
|
str += "Description: " + com.Description + "\n";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
/* removed
|
||||||
|
private static void Crawl()
|
||||||
|
{
|
||||||
|
Timer t = new Timer();
|
||||||
|
t.Interval = 5000; // start crawling after 5 seconds
|
||||||
|
t.Elapsed += (s, e) => {
|
||||||
|
var wc = new WebCrawler.WebCrawler();
|
||||||
|
WebCrawler.WebCrawler.OnFoundInvite += inv => { TryJoin(inv); };
|
||||||
|
t.Stop();
|
||||||
|
};
|
||||||
|
t.Start();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static async void TryJoin(string code)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await NadekoBot.client.AcceptInvite(await NadekoBot.client.GetInvite(code));
|
||||||
|
File.AppendAllText("invites.txt", code + "\n");
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
StatsCollector.DEBUG_LOG("Failed to join " + code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
NadekoBot/NadekoBot.csproj
Normal file
117
NadekoBot/NadekoBot.csproj
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>NadekoBot</RootNamespace>
|
||||||
|
<AssemblyName>NadekoBot</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Discord.Net">
|
||||||
|
<HintPath>E:\Ostalo\Discord.Net\src\Discord.Net.Modules.Net45\bin\Debug\Discord.Net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Discord.Net.Commands">
|
||||||
|
<HintPath>E:\Ostalo\Discord.Net\src\Discord.Net.Modules.Net45\bin\Debug\Discord.Net.Commands.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Discord.Net.Modules">
|
||||||
|
<HintPath>E:\Ostalo\Discord.Net\src\Discord.Net.Modules.Net45\bin\Debug\Discord.Net.Modules.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="libvideo, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\VideoLibrary.1.3.1\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\libvideo.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.8.0.1-beta3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Parse, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Parse.1.6.2\lib\net45\Parse.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Parse.NetFx45, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Parse.1.6.2\lib\net45\Parse.NetFx45.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="policy.2.0.taglib-sharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=db62eba44689b5b0, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\taglib.2.1.0.0\lib\policy.2.0.taglib-sharp.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="taglib-sharp, Version=2.1.0.0, Culture=neutral, PublicKeyToken=db62eba44689b5b0, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\taglib.2.1.0.0\lib\taglib-sharp.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Classes\_JSONModels.cs" />
|
||||||
|
<Compile Include="Classes\Cards.cs" />
|
||||||
|
<Compile Include="Classes\Extensions.cs" />
|
||||||
|
<Compile Include="Classes\ImageHandler.cs" />
|
||||||
|
<Compile Include="Classes\Trivia.cs" />
|
||||||
|
<Compile Include="Commands\CopyCommand.cs" />
|
||||||
|
<Compile Include="Commands\DiceRollCommand.cs" />
|
||||||
|
<Compile Include="Commands\DiscordCommand.cs" />
|
||||||
|
<Compile Include="Commands\DrawCommand.cs" />
|
||||||
|
<Compile Include="Commands\FlipCoinCommand.cs" />
|
||||||
|
<Compile Include="Modules\Conversations.cs" />
|
||||||
|
<Compile Include="Modules\DiscordModule.cs" />
|
||||||
|
<Compile Include="Modules\Gambling.cs" />
|
||||||
|
<Compile Include="Modules\Games.cs" />
|
||||||
|
<Compile Include="Modules\Music.cs" />
|
||||||
|
<Compile Include="Modules\Searches.cs" />
|
||||||
|
<Compile Include="NadekoBot.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="StatsCollector.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- 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.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
36
NadekoBot/Properties/AssemblyInfo.cs
Normal file
36
NadekoBot/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("NadekoBot")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("NadekoBot")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("27a886f5-cdda-4f4a-81ee-6dafcce9de46")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
207
NadekoBot/StatsCollector.cs
Normal file
207
NadekoBot/StatsCollector.cs
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.Modules;
|
||||||
|
using Parse;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace NadekoBot
|
||||||
|
{
|
||||||
|
public class StatsCollector
|
||||||
|
{
|
||||||
|
|
||||||
|
private CommandService _service;
|
||||||
|
|
||||||
|
string lastMention = "";
|
||||||
|
string lastMessage = "No messages.";
|
||||||
|
int commandsRan = 0;
|
||||||
|
string dataLastSent = "Data last sent at: NEVER";
|
||||||
|
|
||||||
|
List<string> messages = new List<string>();
|
||||||
|
|
||||||
|
public StatsCollector(CommandService service)
|
||||||
|
{
|
||||||
|
this._service = service;
|
||||||
|
|
||||||
|
_service.RanCommand += StatsCollector_RanCommand;
|
||||||
|
NadekoBot.client.MessageReceived += Client_MessageReceived;
|
||||||
|
/*
|
||||||
|
Timer t = new Timer();
|
||||||
|
|
||||||
|
t.Interval = 5000;
|
||||||
|
|
||||||
|
t.Elapsed += (s,e) =>
|
||||||
|
{
|
||||||
|
FillConsole();
|
||||||
|
};
|
||||||
|
|
||||||
|
t.Start();
|
||||||
|
*/
|
||||||
|
|
||||||
|
StartCollecting();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FillConsole() {
|
||||||
|
Console.Clear();
|
||||||
|
|
||||||
|
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||||
|
string str = "Online for " + time.Days + "d, " + time.Hours + "h, " + time.Minutes + "m, "+time.Seconds+"s.";
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, 0);
|
||||||
|
Console.Write(str);
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, 1);
|
||||||
|
Console.Write(dataLastSent);
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, 2);
|
||||||
|
Console.Write("Commands ran since start: " +commandsRan);
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, 3);
|
||||||
|
Console.Write(lastMention);
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, 4);
|
||||||
|
Console.WriteLine(lastMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Client_MessageReceived(object sender, MessageEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
lastMessage = "[" + e.User.Name + "] on [" + e.Server.Name + "] server, channel: [" + e.Channel.Name + "] \n" + "Body: " + e.Message.Text + " ";
|
||||||
|
|
||||||
|
if (e.Message.MentionedUsers.Where(u => u.Id == NadekoBot.OwnerID).Count() > 0)
|
||||||
|
{
|
||||||
|
lastMention = "You were last mentioned in '" + e.Server.Name + "' server, channel '" + e.Channel.Name + "', by " + e.User.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void TryJoin(MessageEventArgs e, string code) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await NadekoBot.client.AcceptInvite(await NadekoBot.client.GetInvite(code));
|
||||||
|
await NadekoBot.client.SendMessage(e.Channel, Mention.User(e.User) + " I joined it, thanks :)");
|
||||||
|
DEBUG_LOG("Sucessfuly joined server with code " + code);
|
||||||
|
DEBUG_LOG("Here is a link for you: discord.gg/" + code);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
DEBUG_LOG("Failed to join " + code);
|
||||||
|
DEBUG_LOG("Reason: " + ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DEBUG_LOG(string text) {
|
||||||
|
NadekoBot.client.SendMessage(NadekoBot.client.GetChannel(119365591852122112), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartCollecting() {
|
||||||
|
Timer t = new Timer();
|
||||||
|
t.Interval = 3600000;
|
||||||
|
t.Enabled = true;
|
||||||
|
t.Elapsed += (s, e) =>
|
||||||
|
{
|
||||||
|
var obj = new ParseObject("Stats");
|
||||||
|
dataLastSent = "Data last sent at: "+DateTime.Now.Hour+":"+DateTime.Now.Minute;
|
||||||
|
obj["OnlineUsers"] = NadekoBot.client.AllUsers.Count();
|
||||||
|
obj["ConnectedServers"] = NadekoBot.client.AllServers.Count();
|
||||||
|
|
||||||
|
obj.SaveAsync();
|
||||||
|
};
|
||||||
|
Console.WriteLine("Server stats sent.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveRequest(CommandEventArgs e, string text) {
|
||||||
|
|
||||||
|
var obj = new ParseObject("Requests");
|
||||||
|
|
||||||
|
obj["ServerId"] = e.Server.Id;
|
||||||
|
obj["ServerName"] = e.Server.Name;
|
||||||
|
obj["UserId"] = e.User.Id;
|
||||||
|
obj["UserName"] = e.User.Name;
|
||||||
|
obj["Request"] = text;
|
||||||
|
|
||||||
|
obj.SaveAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetRequests() {
|
||||||
|
var task = ParseObject.GetQuery("Requests")
|
||||||
|
.FindAsync().Result;
|
||||||
|
|
||||||
|
string str = "Here are all current requests for NadekoBot:\n\n";
|
||||||
|
int i = 1;
|
||||||
|
foreach (var reqObj in task)
|
||||||
|
{
|
||||||
|
|
||||||
|
str += (i++) + ". by **" + reqObj["UserName"] +"** from **" + reqObj["ServerName"] + "** at "+ reqObj.CreatedAt.Value.ToLocalTime() + "\n";
|
||||||
|
str+= "**"+reqObj["Request"]+"**\n----------\n";
|
||||||
|
}
|
||||||
|
return str+"\n__Type [@NadekoBot clr] to clear all of my messages.__";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool DeleteRequest(int requestNumber) {
|
||||||
|
var task = ParseObject.GetQuery("Requests")
|
||||||
|
.FindAsync().Result;
|
||||||
|
int i = 1;
|
||||||
|
foreach (var reqObj in task)
|
||||||
|
{
|
||||||
|
if (i == requestNumber)
|
||||||
|
{
|
||||||
|
reqObj.DeleteAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves a request with a number and returns that users id.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>RequestObject of the request. Null if none</returns>
|
||||||
|
public static ResolveRequestObject ResolveRequest(int requestNumber) {
|
||||||
|
var task = ParseObject.GetQuery("Requests")
|
||||||
|
.FindAsync().Result;
|
||||||
|
int i = 1;
|
||||||
|
foreach (var reqObj in task)
|
||||||
|
{
|
||||||
|
if (i == requestNumber) {
|
||||||
|
var txt = reqObj.Get<string>("Request");
|
||||||
|
var id = reqObj.Get<long>("UserId");
|
||||||
|
var sid = reqObj.Get<long>("ServerId");
|
||||||
|
reqObj.DeleteAsync();
|
||||||
|
return new ResolveRequestObject { Id = id, Text = txt, ServerId=sid };
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResolveRequestObject {
|
||||||
|
public long Id;
|
||||||
|
public long ServerId;
|
||||||
|
public string Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StatsCollector_RanCommand(object sender, CommandEventArgs e)
|
||||||
|
{
|
||||||
|
commandsRan++;
|
||||||
|
var obj = new ParseObject("CommandsRan");
|
||||||
|
|
||||||
|
obj["ServerId"] = e.Server.Id;
|
||||||
|
obj["ServerName"] = e.Server.Name;
|
||||||
|
|
||||||
|
obj["ChannelId"] = e.Channel.Id;
|
||||||
|
obj["ChannelName"] = e.Channel.Name;
|
||||||
|
|
||||||
|
obj["UserId"] = e.User.Id;
|
||||||
|
obj["UserName"] = e.User.Name;
|
||||||
|
|
||||||
|
obj["CommandName"] = e.Command.Text;
|
||||||
|
obj.SaveAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
NadekoBot/packages.config
Normal file
8
NadekoBot/packages.config
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Newtonsoft.Json" version="8.0.1-beta3" targetFramework="net452" />
|
||||||
|
<package id="Parse" version="1.6.2" targetFramework="net452" />
|
||||||
|
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
||||||
|
<package id="taglib" version="2.1.0.0" targetFramework="net452" />
|
||||||
|
<package id="VideoLibrary" version="1.3.1" targetFramework="net452" />
|
||||||
|
</packages>
|
BIN
dlls/Discord.Net.Commands.dll
Normal file
BIN
dlls/Discord.Net.Commands.dll
Normal file
Binary file not shown.
BIN
dlls/Discord.Net.Modules.dll
Normal file
BIN
dlls/Discord.Net.Modules.dll
Normal file
Binary file not shown.
BIN
dlls/Discord.Net.dll
Normal file
BIN
dlls/Discord.Net.dll
Normal file
Binary file not shown.
BIN
dlls/lib/libsodium.dll
Normal file
BIN
dlls/lib/libsodium.dll
Normal file
Binary file not shown.
BIN
dlls/lib/opus.dll
Normal file
BIN
dlls/lib/opus.dll
Normal file
Binary file not shown.
BIN
dlls/websocket-sharp.dll
Normal file
BIN
dlls/websocket-sharp.dll
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user