$nroll, refactor, maybe broke some stuff :3

This commit is contained in:
Master Kwoth 2016-01-30 09:01:48 +01:00
parent 940f47fb4f
commit 171d3cd4ab
8 changed files with 357 additions and 483 deletions

View File

@ -0,0 +1,102 @@
using Discord;
using Discord.Commands;
using Parse;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using NadekoBot.Extensions;
using System.Threading.Tasks;
namespace NadekoBot
{
public class NadekoStats
{
public string BotVersion = "0.8-beta3";
private static readonly NadekoStats _instance = new NadekoStats();
public static NadekoStats Instance => _instance;
private CommandService _service;
private DiscordClient _client;
private int _commandsRan = 0;
private string _statsCache = "";
private Stopwatch _statsSW = new Stopwatch();
List<string> messages = new List<string>();
static NadekoStats() { }
private NadekoStats() {
_service = NadekoBot.client.Commands();
_client = NadekoBot.client;
_statsSW = new Stopwatch();
_statsSW.Start();
_service.CommandExecuted += StatsCollector_RanCommand;
StartCollecting();
Console.WriteLine("Logging enabled.");
}
public string GetUptimeString() {
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
}
public void LoadStats() {
_statsCache =
"Author: Kwoth" +
$"\nDiscord.Net version: {DiscordConfig.LibVersion}" +
$"\nRuntime: {_client.GetRuntime()}" +
$"\nBot Version: {BotVersion}" +
$"\nLogged in as: {_client.CurrentUser.Name}" +
$"\nBot id: {_client.CurrentUser.Id}" +
$"\nUptime: {GetUptimeString()}" +
$"\nServers: {_client.Servers.Count()}" +
$"\nChannels: {_client.Servers.Sum(s => s.AllChannels.Count())}" +
$"\nUsers: {_client.Servers.SelectMany(x => x.Users.Select(y => y.Id)).Count()} (non-unique)" +
$"\nHeap: {Math.Round(GC.GetTotalMemory(true) / (1024.0 * 1024.0), 2).ToString()}MB" +
$"\nCommands Ran this session: {_commandsRan}";
}
public string GetStats() {
if (_statsSW.ElapsedTicks > 5) {
LoadStats();
_statsSW.Restart();
}
return _statsCache;
}
private async Task StartCollecting() {
while (true) {
var obj = new ParseObject("Stats");
obj["OnlineUsers"] = NadekoBot.client.Servers.Sum(x => x.Users.Count());
obj["ConnectedServers"] = NadekoBot.client.Servers.Count();
obj.SaveAsync();
await Task.Delay(new TimeSpan(1, 0, 0));
}
}
//todo - batch save this
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();
}
}
}

View File

@ -7,59 +7,46 @@ using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot namespace NadekoBot {
{ class DiceRollCommand : DiscordCommand {
class DiceRollCommand : DiscordCommand
{
public DiceRollCommand() : base() { } public DiceRollCommand() : base() { }
public override Func<CommandEventArgs, Task> DoFunc() public override Func<CommandEventArgs, Task> DoFunc() {
{
Random r = new Random(); Random r = new Random();
return async e => { return async e => {
if (e.Args[0] == "") if (e.Args[0] == "") {
{
int num1 = r.Next(0, 10); int num1 = r.Next(0, 10);
int num2 = r.Next(0, 10); int num2 = r.Next(0, 10);
Image[] images; Image[] images;
if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1) if (num1 == 0 && num2 == 0 && r.Next(0, 2) == 1) {
{
images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) }; images = new Image[3] { GetDice(1), GetDice(0), GetDice(0) };
} } else {
else
{
images = new Image[2] { GetDice(num1), GetDice(num2) }; images = new Image[2] { GetDice(num1), GetDice(num2) };
} }
Bitmap bitmap = images.Merge(); Bitmap bitmap = images.Merge();
await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png)); await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png));
return; return;
} } else {
else try {
{
try
{
int num = int.Parse(e.Args[0]); int num = int.Parse(e.Args[0]);
if (num < 1) num = 1; if (num < 1) num = 1;
if (num > 30) if (num > 30) {
{ await e.Send("You can roll up to 30 dies at a time.");
await e.Send( "You can roll up to 30 dies at a time.");
num = 30; num = 30;
} }
List<Image> dices = new List<Image>(num); List<Image> dices = new List<Image>(num);
List<int> values = new List<int>(num); List<int> values = new List<int>(num);
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++) {
{
int randomNumber = r.Next(1, 7); int randomNumber = r.Next(1, 7);
int toInsert = dices.Count; int toInsert = dices.Count;
if (randomNumber == 6 || dices.Count==0) if (randomNumber == 6 || dices.Count == 0)
toInsert = 0; toInsert = 0;
else if (randomNumber!=1) else if (randomNumber != 1)
for (int j = 0; j < dices.Count; j++) { for (int j = 0; j < dices.Count; j++) {
if (values[j] < randomNumber) if (values[j] < randomNumber) {
{
toInsert = j; toInsert = j;
break; break;
} }
@ -69,12 +56,10 @@ namespace NadekoBot
} }
Bitmap bitmap = dices.Merge(); Bitmap bitmap = dices.Merge();
await e.Send( values.Count + " Dies rolled. Total: **"+values.Sum()+"** Average: **"+(values.Sum()/(1.0f*values.Count)).ToString("N2")+"**"); await e.Send(values.Count + " Dies rolled. Total: **" + values.Sum() + "** Average: **" + (values.Sum() / (1.0f * values.Count)).ToString("N2") + "**");
await e.Channel.SendFile("dices.png", bitmap.ToStream(ImageFormat.Png)); await e.Channel.SendFile("dices.png", bitmap.ToStream(ImageFormat.Png));
} } catch (Exception) {
catch (Exception) await e.Send("Please enter a number of dices to roll.");
{
await e.Send( "Please enter a number of dices to roll.");
return; return;
} }
} }
@ -83,12 +68,38 @@ namespace NadekoBot
private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image; private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image;
public override void Init(CommandGroupBuilder cgb) public override void Init(CommandGroupBuilder cgb) {
{
cgb.CreateCommand("$roll") cgb.CreateCommand("$roll")
.Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]") .Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]")
.Parameter("num", ParameterType.Optional) .Parameter("num", ParameterType.Optional)
.Do(DoFunc()); .Do(DoFunc());
cgb.CreateCommand("$nroll")
.Description("Rolls in a given range.\n**Usage**: `$nroll 5` (rolls 0-5) or `$nroll 5-15`")
.Parameter("range", ParameterType.Required)
.Do(NDoFunc());
} }
private Func<CommandEventArgs, Task> NDoFunc() =>
async e => {
try {
int rolled;
if (e.GetArg("range").Contains("-")) {
var arr = e.GetArg("range").Split('-')
.Take(2)
.Select(x => int.Parse(x))
.ToArray();
if (arr[0] > arr[1])
throw new ArgumentException("First argument should be bigger than the second one.");
rolled = new Random().Next(arr[0],arr[1]+1);
} else {
rolled = new Random().Next(0, int.Parse(e.GetArg("range"))+1);
}
await e.Send($"{e.User.Mention} rolled **{rolled}**.");
} catch (Exception ex) {
await e.Send($":anger: {ex.Message}");
}
};
} }
} }

View File

@ -0,0 +1,144 @@
using System;
using System.Threading.Tasks;
using Discord.Commands;
using Parse;
using NadekoBot.Extensions;
namespace NadekoBot.Commands {
class RequestsCommand : DiscordCommand {
public 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();
}
// todo what if it's too long?
public 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 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;
}
public class ResolveRequestObject {
public ulong Id;
public ulong ServerId;
public string Text;
}
/// <summary>
/// Resolves a request with a number and returns that users id.
/// </summary>
/// <returns>RequestObject of the request. Null if none</returns>
public 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<ulong>("UserId");
var sid = reqObj.Get<ulong>("ServerId");
reqObj.DeleteAsync();
return new ResolveRequestObject { Id = id, Text = txt, ServerId = sid };
}
i++;
}
return null;
}
public override Func<CommandEventArgs, Task> DoFunc() {
throw new NotImplementedException();
}
public override void Init(CommandGroupBuilder cgb) {
cgb.CreateCommand("req")
.Alias("request")
.Description("Requests a feature for nadeko.\n**Usage**: @NadekoBot req new_feature")
.Parameter("all", ParameterType.Unparsed)
.Do(async e => {
string str = e.Args[0];
try {
SaveRequest(e, str);
} catch (Exception) {
await e.Send("Something went wrong.");
return;
}
await e.Send("Thank you for your request.");
});
cgb.CreateCommand("lr")
.Description("PMs the user all current nadeko requests.")
.Do(async e => {
string str = GetRequests();
if (str.Trim().Length > 110)
await e.User.Send(str);
else
await e.User.Send("No requests atm.");
});
cgb.CreateCommand("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 (DeleteRequest(int.Parse(e.Args[0]))) {
await e.Send(e.User.Mention + " Request deleted.");
} else {
await e.Send("No request on that number.");
}
} catch {
await e.Send("Error deleting request, probably NaN error.");
}
} else await e.Send("You don't have permission to do that.");
});
cgb.CreateCommand("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 = ResolveRequest(int.Parse(e.Args[0]));
if (sc != null) {
await e.Send(e.User.Mention + " Request resolved, notice sent.");
await client.GetServer(sc.ServerId).GetUser(sc.Id).Send("**This request of yours has been resolved:**\n" + sc.Text);
} else {
await e.Send("No request on that number.");
}
} catch {
await e.Send("Error resolving request, probably NaN error.");
}
} else await e.Send("You don't have permission to do that.");
});
}
}
}

View File

@ -272,7 +272,7 @@ namespace NadekoBot.Modules {
.Description("Shows some basic stats for nadeko") .Description("Shows some basic stats for nadeko")
.Do(async e => { .Do(async e => {
var t = Task.Run(() => { var t = Task.Run(() => {
return "```" + NadekoBot.GetStats() + "\n" + Music.GetMusicStats() + "```"; return "```" + NadekoStats.Instance.GetStats() + "\n" + Music.GetMusicStats() + "```";
}); });
await e.Send(await t); await e.Send(await t);

View File

@ -13,42 +13,36 @@ using System.Text;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Properties; using NadekoBot.Properties;
using NadekoBot.Commands;
namespace NadekoBot.Modules namespace NadekoBot.Modules {
{ class Conversations : DiscordModule {
class Conversations : DiscordModule
{
private string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥"; private string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥";
public Conversations() : base() public Conversations() : base() {
{
commands.Add(new CopyCommand()); commands.Add(new CopyCommand());
commands.Add(new RequestsCommand());
} }
public override void Install(ModuleManager manager) public override void Install(ModuleManager manager) {
{
Random rng = new Random(); Random rng = new Random();
manager.CreateCommands("", cgb => manager.CreateCommands("", cgb => {
{
var client = manager.Client; var client = manager.Client;
cgb.CreateCommand("\\o\\") cgb.CreateCommand("\\o\\")
.Description("Nadeko replies with /o/") .Description("Nadeko replies with /o/")
.Do(async e => .Do(async e => {
{
await e.Send(e.User.Mention + "/o/"); await e.Send(e.User.Mention + "/o/");
}); });
cgb.CreateCommand("/o/") cgb.CreateCommand("/o/")
.Description("Nadeko replies with \\o\\") .Description("Nadeko replies with \\o\\")
.Do(async e => .Do(async e => {
{ await e.Send(e.User.Mention + "\\o\\");
await e.Send( e.User.Mention + "\\o\\");
}); });
}); });
manager.CreateCommands(NadekoBot.botMention, cgb => manager.CreateCommands(NadekoBot.botMention, cgb => {
{
var client = manager.Client; var client = manager.Client;
commands.ForEach(cmd => cmd.Init(cgb)); commands.ForEach(cmd => cmd.Init(cgb));
@ -63,17 +57,14 @@ namespace NadekoBot.Modules
cgb.CreateCommand("die") cgb.CreateCommand("die")
.Description("Works only for the owner. Shuts the bot down.") .Description("Works only for the owner. Shuts the bot down.")
.Do(async e => .Do(async e => {
{ if (e.User.Id == NadekoBot.OwnerID) {
if (e.User.Id == NadekoBot.OwnerID)
{
Timer t = new Timer(); Timer t = new Timer();
t.Interval = 2000; t.Interval = 2000;
t.Elapsed += (s, ev) => { Environment.Exit(0); }; t.Elapsed += (s, ev) => { Environment.Exit(0); };
t.Start(); t.Start();
await e.Send(e.User.Mention + ", Yes, my love."); await e.Send(e.User.Mention + ", Yes, my love.");
} } else
else
await e.Send(e.User.Mention + ", No."); await e.Send(e.User.Mention + ", No.");
}); });
@ -137,21 +128,14 @@ namespace NadekoBot.Modules
cgb.CreateCommand("how are you") cgb.CreateCommand("how are you")
.Description("Replies positive only if bot owner is online.") .Description("Replies positive only if bot owner is online.")
.Do(async e => .Do(async e => {
{ if (e.User.Id == NadekoBot.OwnerID) {
if (e.User.Id == NadekoBot.OwnerID)
{
await e.Send(e.User.Mention + " I am great as long as you are here."); await e.Send(e.User.Mention + " I am great as long as you are here.");
} } else {
else
{
var kw = e.Server.GetUser(NadekoBot.OwnerID); var kw = e.Server.GetUser(NadekoBot.OwnerID);
if (kw != null && kw.Status == UserStatus.Online) if (kw != null && kw.Status == UserStatus.Online) {
{
await e.Send(e.User.Mention + " I am great as long as " + kw.Mention + " is with me."); await e.Send(e.User.Mention + " I am great as long as " + kw.Mention + " is with me.");
} } else {
else
{
await e.Send(e.User.Mention + " I am sad. My Master is not with me."); await e.Send(e.User.Mention + " I am sad. My Master is not with me.");
} }
} }
@ -160,8 +144,7 @@ namespace NadekoBot.Modules
cgb.CreateCommand("insult") cgb.CreateCommand("insult")
.Parameter("mention", ParameterType.Required) .Parameter("mention", ParameterType.Required)
.Description("Only works for owner. Insults @X person.\n**Usage**: @NadekoBot insult @X.") .Description("Only works for owner. Insults @X person.\n**Usage**: @NadekoBot insult @X.")
.Do(async e => .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." }; 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(); Random r = new Random();
var u = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault(); var u = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
@ -180,8 +163,7 @@ namespace NadekoBot.Modules
cgb.CreateCommand("praise") cgb.CreateCommand("praise")
.Description("Only works for owner. Praises @X person.\n**Usage**: @NadekoBot praise @X.") .Description("Only works for owner. Praises @X person.\n**Usage**: @NadekoBot praise @X.")
.Parameter("mention", ParameterType.Required) .Parameter("mention", ParameterType.Required)
.Do(async e => .Do(async e => {
{
List<string> praises = new List<string> { " You are cool.", List<string> praises = new List<string> { " You are cool.",
" You are nice!", " You are nice!",
" You did a good job.", " You did a good job.",
@ -192,8 +174,7 @@ namespace NadekoBot.Modules
Random r = new Random(); Random r = new Random();
var u = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault(); var u = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
if (u == null) if (u == null) {
{
await e.Send("Invalid user specified."); await e.Send("Invalid user specified.");
return; return;
} }
@ -207,8 +188,7 @@ namespace NadekoBot.Modules
cgb.CreateCommand("are you real") cgb.CreateCommand("are you real")
.Description("Useless.") .Description("Useless.")
.Do(async e => .Do(async e => {
{
await e.Send(e.User.Mention + " I will be soon."); await e.Send(e.User.Mention + " I will be soon.");
}); });
@ -219,15 +199,13 @@ namespace NadekoBot.Modules
cgb.CreateCommand("draw") cgb.CreateCommand("draw")
.Description("Nadeko instructs you to type $draw. Gambling functions start with $") .Description("Nadeko instructs you to type $draw. Gambling functions start with $")
.Do(async e => .Do(async e => {
{
await e.Send("Sorry, I don't gamble, type $draw for that function."); await e.Send("Sorry, I don't gamble, type $draw for that function.");
}); });
cgb.CreateCommand("fire") cgb.CreateCommand("fire")
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire.\n**Usage**: @NadekoBot fire [x]") .Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire.\n**Usage**: @NadekoBot fire [x]")
.Parameter("times", ParameterType.Optional) .Parameter("times", ParameterType.Optional)
.Do(async e => .Do(async e => {
{
int count = 0; int count = 0;
if (e.Args?.Length > 0) if (e.Args?.Length > 0)
int.TryParse(e.Args[0], out count); int.TryParse(e.Args[0], out count);
@ -237,8 +215,7 @@ namespace NadekoBot.Modules
else if (count > 12) else if (count > 12)
count = 12; count = 12;
string str = ""; string str = "";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++) {
{
str += firestr; str += firestr;
} }
await e.Send(str); await e.Send(str);
@ -247,15 +224,12 @@ namespace NadekoBot.Modules
cgb.CreateCommand("rip") cgb.CreateCommand("rip")
.Description("Shows a grave image.Optional parameter [@X] instructs her to put X's name on the grave.\n**Usage**: @NadekoBot rip [@X]") .Description("Shows a grave image.Optional parameter [@X] instructs her to put X's name on the grave.\n**Usage**: @NadekoBot rip [@X]")
.Parameter("user", ParameterType.Unparsed) .Parameter("user", ParameterType.Unparsed)
.Do(async e => .Do(async e => {
{
var usr = e.Channel.FindUsers(e.GetArg("user")).FirstOrDefault(); var usr = e.Channel.FindUsers(e.GetArg("user")).FirstOrDefault();
string text = ""; string text = "";
if (usr == null) if (usr == null) {
{
text = e.GetArg("user"); text = e.GetArg("user");
} } else {
else {
text = usr.Name; text = usr.Name;
} }
await e.Channel.SendFile("ripzor_m8.png", RipName(text)); await e.Channel.SendFile("ripzor_m8.png", RipName(text));
@ -264,15 +238,11 @@ namespace NadekoBot.Modules
cgb.CreateCommand("j") cgb.CreateCommand("j")
.Description("Joins a server using a code.") .Description("Joins a server using a code.")
.Parameter("id", ParameterType.Required) .Parameter("id", ParameterType.Required)
.Do(async e => .Do(async e => {
{ try {
try
{
await (await client.GetInvite(e.Args[0])).Accept(); await (await client.GetInvite(e.Args[0])).Accept();
await e.Send("I got in!"); await e.Send("I got in!");
} } catch (Exception) {
catch (Exception)
{
await e.Send("Invalid code."); await e.Send("Invalid code.");
} }
}); });
@ -280,39 +250,31 @@ namespace NadekoBot.Modules
cgb.CreateCommand("save") cgb.CreateCommand("save")
.Description("Saves something for the owner in a file.") .Description("Saves something for the owner in a file.")
.Parameter("all", ParameterType.Unparsed) .Parameter("all", ParameterType.Unparsed)
.Do(async e => .Do(async e => {
{ if (e.User.Id == NadekoBot.OwnerID) {
if (e.User.Id == NadekoBot.OwnerID)
{
string m = ""; string m = "";
try try {
{
FileStream f = File.OpenWrite("saves.txt"); FileStream f = File.OpenWrite("saves.txt");
m = e.Args[0]; m = e.Args[0];
byte[] b = Encoding.ASCII.GetBytes(m + "\n"); byte[] b = Encoding.ASCII.GetBytes(m + "\n");
f.Seek(f.Length, SeekOrigin.Begin); f.Seek(f.Length, SeekOrigin.Begin);
f.Write(b, 0, b.Length); f.Write(b, 0, b.Length);
f.Close(); f.Close();
} } catch (Exception) {
catch (Exception)
{
await e.Send("Error saving. Sorry :("); await e.Send("Error saving. Sorry :(");
} }
if (m.Length > 0) if (m.Length > 0)
await e.Send("I saved this for you: " + Environment.NewLine + "```" + m + "```"); await e.Send("I saved this for you: " + Environment.NewLine + "```" + m + "```");
else else
await e.Send("No point in saving empty message..."); await e.Send("No point in saving empty message...");
} } else await e.Send("Not for you, only my Master <3");
else await e.Send("Not for you, only my Master <3");
}); });
cgb.CreateCommand("ls") cgb.CreateCommand("ls")
.Description("Shows all saved items.") .Description("Shows all saved items.")
.Do(async e => .Do(async e => {
{
FileStream f = File.OpenRead("saves.txt"); FileStream f = File.OpenRead("saves.txt");
if (f.Length == 0) if (f.Length == 0) {
{
await e.Send("Saves are empty."); await e.Send("Saves are empty.");
return; return;
} }
@ -351,8 +313,7 @@ namespace NadekoBot.Modules
}); });
cgb.CreateCommand("cs") cgb.CreateCommand("cs")
.Description("Deletes all saves") .Description("Deletes all saves")
.Do(async e => .Do(async e => {
{
File.Delete("saves.txt"); File.Delete("saves.txt");
await e.Send("Cleared all saves."); await e.Send("Cleared all saves.");
}); });
@ -360,159 +321,51 @@ namespace NadekoBot.Modules
cgb.CreateCommand("bb") cgb.CreateCommand("bb")
.Description("Says bye to someone. **Usage**: @NadekoBot bb @X") .Description("Says bye to someone. **Usage**: @NadekoBot bb @X")
.Parameter("ppl", ParameterType.Unparsed) .Parameter("ppl", ParameterType.Unparsed)
.Do(async e => .Do(async e => {
{
string str = "Bye"; string str = "Bye";
foreach (var u in e.Message.MentionedUsers) foreach (var u in e.Message.MentionedUsers) {
{
str += " " + u.Mention; str += " " + u.Mention;
} }
await e.Send(str); await e.Send(str);
}); });
cgb.CreateCommand("req")
.Alias("request")
.Description("Requests a feature for nadeko.\n**Usage**: @NadekoBot req new_feature")
.Parameter("all", ParameterType.Unparsed)
.Do(async e =>
{
string str = e.Args[0];
try
{
StatsCollector.SaveRequest(e, str);
}
catch (Exception)
{
await e.Send("Something went wrong.");
return;
}
await e.Send("Thank you for your request.");
});
cgb.CreateCommand("lr")
.Description("PMs the user all current nadeko requests.")
.Do(async e =>
{
string str = StatsCollector.GetRequests();
if (str.Trim().Length > 110)
await e.User.Send(str);
else
await e.User.Send("No requests atm.");
});
cgb.CreateCommand("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 e.Send(e.User.Mention + " Request deleted.");
}
else
{
await e.Send("No request on that number.");
}
}
catch
{
await e.Send("Error deleting request, probably NaN error.");
}
}
else await e.Send("You don't have permission to do that.");
});
cgb.CreateCommand("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 e.Send(e.User.Mention + " Request resolved, notice sent.");
await client.GetServer(sc.ServerId).GetUser(sc.Id).Send("**This request of yours has been resolved:**\n" + sc.Text);
}
else
{
await e.Send("No request on that number.");
}
}
catch
{
await e.Send("Error resolving request, probably NaN error.");
}
}
else await e.Send("You don't have permission to do that.");
});
cgb.CreateCommand("call") cgb.CreateCommand("call")
.Description("Useless. Writes calling @X to chat.\n**Usage**: @NadekoBot call @X ") .Description("Useless. Writes calling @X to chat.\n**Usage**: @NadekoBot call @X ")
.Parameter("who", ParameterType.Required) .Parameter("who", ParameterType.Required)
.Do(async e => .Do(async e => {
{
await e.Send("Calling " + e.Args[0] + "..."); await e.Send("Calling " + e.Args[0] + "...");
}); });
cgb.CreateCommand("hide") cgb.CreateCommand("hide")
.Description("Hides nadeko in plain sight!11!!") .Description("Hides nadeko in plain sight!11!!")
.Do(async e => .Do(async e => {
{ using (Stream ms = Resources.hidden.ToStream(ImageFormat.Png)) {
try await client.CurrentUser.Edit(NadekoBot.password, avatar: ms);
{
using (Stream ms = Resources.hidden.ToStream(ImageFormat.Png))
{
await client.CurrentUser.Edit(NadekoBot.password, avatar: ms);
}
await e.Send("*hides*");
}
catch (Exception ex)
{
StatsCollector.DEBUG_LOG(ex.ToString());
} }
await e.Send("*hides*");
}); });
cgb.CreateCommand("unhide") cgb.CreateCommand("unhide")
.Description("Unhides nadeko in plain sight!1!!1") .Description("Unhides nadeko in plain sight!1!!1")
.Do(async e => .Do(async e => {
{ using (Stream ms = Resources.nadeko.ToStream()) {
try await client.CurrentUser.Edit(NadekoBot.password, avatar: ms, avatarType: ImageType.Jpeg);
{
using (Stream ms = Resources.nadeko.ToStream()) {
await client.CurrentUser.Edit(NadekoBot.password, avatar: ms,avatarType:ImageType.Jpeg);
}
await e.Send("*unhides*");
}
catch (Exception ex)
{
StatsCollector.DEBUG_LOG(ex.ToString());
} }
await e.Send("*unhides*");
}); });
cgb.CreateCommand("dump") cgb.CreateCommand("dump")
.Description("Dumps all of the invites it can to dump.txt.** Owner Only.**") .Description("Dumps all of the invites it can to dump.txt.** Owner Only.**")
.Do(async e => .Do(async e => {
{
if (NadekoBot.OwnerID != e.User.Id) return; if (NadekoBot.OwnerID != e.User.Id) return;
int i = 0; int i = 0;
int j = 0; int j = 0;
string invites = ""; string invites = "";
foreach (var s in client.Servers) { foreach (var s in client.Servers) {
try try {
{
var invite = await s.CreateInvite(0); var invite = await s.CreateInvite(0);
invites+=invite.Url+"\n"; invites += invite.Url + "\n";
i++; i++;
} } catch (Exception) {
catch (Exception) {
j++; j++;
continue; continue;
} }
@ -521,13 +374,12 @@ namespace NadekoBot.Modules
await e.Send($"Got invites for {i} servers and failed to get invites for {j} servers"); await e.Send($"Got invites for {i} servers and failed to get invites for {j} servers");
}); });
cgb.CreateCommand("av").Alias("avatar") cgb.CreateCommand("av").Alias("avatar")
.Parameter("mention", ParameterType.Required) .Parameter("mention", ParameterType.Required)
.Description("Shows a mentioned person's avatar. **Usage**: ~av @X") .Description("Shows a mentioned person's avatar. **Usage**: ~av @X")
.Do(async e => .Do(async e => {
{
var usr = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault(); var usr = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
if (usr == null) { if (usr == null) {
await e.Send("Invalid user specified."); await e.Send("Invalid user specified.");
@ -553,16 +405,14 @@ namespace NadekoBot.Modules
}); });
} }
public Stream RipName(string name) public Stream RipName(string name) {
{
Bitmap bm = Resources.rip; Bitmap bm = Resources.rip;
int offset = name.Length * 5; int offset = name.Length * 5;
int fontSize = 20; int fontSize = 20;
if (name.Length > 10) if (name.Length > 10) {
{
fontSize -= (name.Length - 10) / 2; fontSize -= (name.Length - 10) / 2;
} }
@ -576,7 +426,7 @@ namespace NadekoBot.Modules
return bm.ToStream(ImageFormat.Png); return bm.ToStream(ImageFormat.Png);
} }
private Func<CommandEventArgs, Task> SayYes() private Func<CommandEventArgs, Task> SayYes()
=> async e => await e.Send("Yes. :)"); => async e => await e.Send("Yes. :)");
} }
} }

View File

@ -15,7 +15,6 @@ using System.Diagnostics;
namespace NadekoBot { namespace NadekoBot {
class NadekoBot { class NadekoBot {
public static DiscordClient client; public static DiscordClient client;
public static StatsCollector stats_collector;
public static string botMention; public static string botMention;
public static string GoogleAPIKey = null; public static string GoogleAPIKey = null;
public static ulong OwnerID; public static ulong OwnerID;
@ -23,8 +22,6 @@ namespace NadekoBot {
public static string password; public static string password;
public static string TrelloAppKey; public static string TrelloAppKey;
public static bool ForwardMessages = false; public static bool ForwardMessages = false;
public static string BotVersion = "0.8-beta2";
public static int commandsRan = 0;
static void Main() { static void Main() {
//load credentials from credentials.json //load credentials from credentials.json
@ -75,7 +72,7 @@ namespace NadekoBot {
ParseClient.Initialize(c.ParseID, c.ParseKey); ParseClient.Initialize(c.ParseID, c.ParseKey);
//monitor commands for logging //monitor commands for logging
stats_collector = new StatsCollector(commandService);
} else { } else {
Console.WriteLine("Parse key and/or ID not found. Logging disabled."); Console.WriteLine("Parse key and/or ID not found. Logging disabled.");
} }
@ -86,9 +83,6 @@ namespace NadekoBot {
//add command service //add command service
var commands = client.Services.Add<CommandService>(commandService); var commands = client.Services.Add<CommandService>(commandService);
//count commands ran
client.Commands().CommandExecuted += (s, e) => commandsRan++;
//create module service //create module service
var modules = client.Services.Add<ModuleService>(new ModuleService()); var modules = client.Services.Add<ModuleService>(new ModuleService());
@ -110,15 +104,11 @@ namespace NadekoBot {
if (loadTrello) if (loadTrello)
modules.Add(new Trello(), "Trello", ModuleFilter.None); modules.Add(new Trello(), "Trello", ModuleFilter.None);
//start the timer for stats
_statsSW.Start();
//run the bot //run the bot
client.ExecuteAndWait(async () => { client.ExecuteAndWait(async () => {
await client.Connect(c.Username, c.Password); await client.Connect(c.Username, c.Password);
LoadStats();
Console.WriteLine("-----------------"); Console.WriteLine("-----------------");
Console.WriteLine(GetStats()); Console.WriteLine(NadekoStats.Instance.GetStats());
Console.WriteLine("-----------------"); Console.WriteLine("-----------------");
foreach (var serv in client.Servers) { foreach (var serv in client.Servers) {
@ -129,36 +119,7 @@ namespace NadekoBot {
}); });
Console.WriteLine("Exiting..."); Console.WriteLine("Exiting...");
Console.ReadKey(); Console.ReadKey();
} }
private static string _statsCache = "";
private static Stopwatch _statsSW = new Stopwatch();
public static string GetStats() {
if (_statsSW.ElapsedTicks > 5) {
LoadStats();
_statsSW.Restart();
}
return _statsCache;
}
private static void LoadStats() {
_statsCache =
"Author: Kwoth" +
$"\nDiscord.Net version: {DiscordConfig.LibVersion}" +
$"\nRuntime: {client.GetRuntime()}" +
$"\nBot Version: {BotVersion}" +
$"\nLogged in as: {client.CurrentUser.Name}" +
$"\nBot id: {client.CurrentUser.Id}" +
$"\nUptime: {GetUptimeString()}" +
$"\nServers: {client.Servers.Count()}" +
$"\nChannels: {client.Servers.Sum(s => s.AllChannels.Count())}" +
$"\nUsers: {client.Servers.SelectMany(x => x.Users.Select(y => y.Id)).Count()} (non-unique)" +
$"\nHeap: {Math.Round(GC.GetTotalMemory(true) / (1024.0 * 1024.0), 2).ToString()}MB" +
$"\nCommands Ran this session: {commandsRan}";
}
public static string GetUptimeString() {
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
}
static bool repliedRecently = false; static bool repliedRecently = false;
private static async void Client_MessageReceived(object sender, MessageEventArgs e) { private static async void Client_MessageReceived(object sender, MessageEventArgs e) {

View File

@ -147,6 +147,7 @@
<Compile Include="Classes\Music\MusicControls.cs" /> <Compile Include="Classes\Music\MusicControls.cs" />
<Compile Include="Classes\Music\StreamRequest.cs" /> <Compile Include="Classes\Music\StreamRequest.cs" />
<Compile Include="Classes\SParser.cs" /> <Compile Include="Classes\SParser.cs" />
<Compile Include="Commands\RequestsCommand.cs" />
<Compile Include="Commands\ServerGreetCommand.cs" /> <Compile Include="Commands\ServerGreetCommand.cs" />
<Compile Include="Commands\SpeedTyping.cs" /> <Compile Include="Commands\SpeedTyping.cs" />
<Compile Include="Classes\_JSONModels.cs" /> <Compile Include="Classes\_JSONModels.cs" />
@ -174,7 +175,7 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="StatsCollector.cs" /> <Compile Include="Classes\NadekoStats.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />

View File

@ -1,195 +0,0 @@
using Discord;
using Discord.Commands;
using Parse;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using NadekoBot.Extensions;
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.CommandExecuted += StatsCollector_RanCommand;
//NadekoBot.client.MessageReceived += Client_MessageReceived;
StartCollecting();
Console.WriteLine("Logging enabled.");
}
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 (await NadekoBot.client.GetInvite(code)).Accept();
await e.Send(e.User.Mention + " I joined it, thanks :)");
DEBUG_LOG("Successfuly 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) {
#pragma warning disable CS4014
//NadekoBot.client.GetChannel(119365591852122112).Send(text);
Console.WriteLine(text);
#pragma warning restore CS4014
}
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.Servers.Sum(x=>x.Users.Count());
obj["ConnectedServers"] = NadekoBot.client.Servers.Count();
obj.SaveAsync();
};
}
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<ulong>("UserId");
var sid = reqObj.Get<ulong>("ServerId");
reqObj.DeleteAsync();
return new ResolveRequestObject { Id = id, Text = txt, ServerId=sid };
}
i++;
}
return null;
}
public class ResolveRequestObject {
public ulong Id;
public ulong 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();
}
}
}