Adding Initial API support, updating readme
This commit is contained in:
parent
6732506dae
commit
92015d8880
27 changed files with 78 additions and 33 deletions
196
Geekbot.net/Commands/AdminCmd.cs
Normal file
196
Geekbot.net/Commands/AdminCmd.cs
Normal file
|
@ -0,0 +1,196 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using Geekbot.net.Lib;
|
||||
using Serilog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
[Group("admin")]
|
||||
public class AdminCmd : ModuleBase
|
||||
{
|
||||
private readonly IDatabase _redis;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IErrorHandler _errorHandler;
|
||||
|
||||
public AdminCmd(IDatabase redis, DiscordSocketClient client, ILogger logger, IUserRepository userRepositry, IErrorHandler errorHandler)
|
||||
{
|
||||
_redis = redis;
|
||||
_client = client;
|
||||
_logger = logger;
|
||||
_userRepository = userRepositry;
|
||||
_errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[Command("welcome", RunMode = RunMode.Async)]
|
||||
[Summary("Set a Welcome Message (use '$user' to mention the new joined user).")]
|
||||
public async Task SetWelcomeMessage([Remainder] [Summary("message")] string welcomeMessage)
|
||||
{
|
||||
_redis.HashSet($"{Context.Guild.Id}:Settings", new HashEntry[] { new HashEntry("WelcomeMsg", welcomeMessage) });
|
||||
var formatedMessage = welcomeMessage.Replace("$user", Context.User.Mention);
|
||||
await ReplyAsync("Welcome message has been changed\r\nHere is an example of how it would look:\r\n" +
|
||||
formatedMessage);
|
||||
}
|
||||
|
||||
[Command("youtubekey", RunMode = RunMode.Async)]
|
||||
[Summary("Set the youtube api key")]
|
||||
public async Task SetYoutubeKey([Summary("API Key")] string key)
|
||||
{
|
||||
var botOwner = Context.Guild.GetUserAsync(ulong.Parse(_redis.StringGet("botOwner"))).Result;
|
||||
if (!Context.User.Id.ToString().Equals(botOwner.Id.ToString()))
|
||||
{
|
||||
await ReplyAsync($"Sorry, only the botowner can do this ({botOwner.Username}#{botOwner.Discriminator})");
|
||||
return;
|
||||
}
|
||||
|
||||
_redis.StringSet("youtubeKey", key);
|
||||
await ReplyAsync("Apikey has been set");
|
||||
}
|
||||
|
||||
[Command("game", RunMode = RunMode.Async)]
|
||||
[Summary("Set the game that the bot is playing")]
|
||||
public async Task SetGame([Remainder] [Summary("Game")] string key)
|
||||
{
|
||||
var botOwner = Context.Guild.GetUserAsync(ulong.Parse(_redis.StringGet("botOwner"))).Result;
|
||||
if (!Context.User.Id.ToString().Equals(botOwner.Id.ToString()))
|
||||
{
|
||||
await ReplyAsync($"Sorry, only the botowner can do this ({botOwner.Username}#{botOwner.Discriminator})");
|
||||
return;
|
||||
}
|
||||
|
||||
_redis.StringSet("Game", key);
|
||||
await _client.SetGameAsync(key);
|
||||
_logger.Information($"[Geekbot] Changed game to {key}");
|
||||
await ReplyAsync($"Now Playing {key}");
|
||||
}
|
||||
|
||||
[Command("popuserrepo", RunMode = RunMode.Async)]
|
||||
[Summary("Set the game that the bot is playing")]
|
||||
public async Task popUserRepoCommand()
|
||||
{
|
||||
try
|
||||
{
|
||||
var botOwner = Context.Guild.GetUserAsync(ulong.Parse(_redis.StringGet("botOwner"))).Result;
|
||||
if (!Context.User.Id.ToString().Equals(botOwner.Id.ToString()))
|
||||
{
|
||||
await ReplyAsync(
|
||||
$"Sorry, only the botowner can do this ({botOwner.Username}#{botOwner.Discriminator})");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await ReplyAsync(
|
||||
$"Sorry, only the botowner can do this");
|
||||
return;
|
||||
}
|
||||
var success = 0;
|
||||
var failed = 0;
|
||||
try
|
||||
{
|
||||
_logger.Warning("[UserRepository] Populating User Repositry");
|
||||
await ReplyAsync("Starting Population of User Repository");
|
||||
foreach (var guild in _client.Guilds)
|
||||
{
|
||||
_logger.Information($"[UserRepository] Populating users from {guild.Name}");
|
||||
foreach (var user in guild.Users)
|
||||
{
|
||||
var succeded = await _userRepository.Update(user);
|
||||
var inc = succeded ? success++ : failed++;
|
||||
}
|
||||
}
|
||||
_logger.Warning("[UserRepository] Finished Updating User Repositry");
|
||||
await ReplyAsync($"Successfully Populated User Repository with {success} Users in {_client.Guilds.Count} Guilds (Failed: {failed})");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context, "Couldn't complete User Repository, see console for more info");
|
||||
}
|
||||
}
|
||||
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[Command("modchannel", RunMode = RunMode.Async)]
|
||||
[Summary("Set the game that the bot is playing")]
|
||||
public async Task selectModChannel([Summary("ChannelId")] ulong channelId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channel = (ISocketMessageChannel)_client.GetChannel(channelId);
|
||||
if (string.IsNullOrEmpty(channel.Name))
|
||||
{
|
||||
await ReplyAsync("I couldn't find that channel...");
|
||||
return;
|
||||
}
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Successfully saved mod channel, you can now do the following");
|
||||
sb.AppendLine("- `!admin showleave true` - send message to mod channel when someone leaves");
|
||||
sb.AppendLine("- `!admin showdel true` - send message to mod channel when someone deletes a message");
|
||||
await channel.SendMessageAsync(sb.ToString());
|
||||
_redis.HashSet($"{Context.Guild.Id}:Settings", new HashEntry[] {new HashEntry("ModChannel", channel.Id.ToString())});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context, "That channel doesn't seem to be valid");
|
||||
}
|
||||
}
|
||||
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[Command("showleave", RunMode = RunMode.Async)]
|
||||
[Summary("Notify modchannel when someone leaves")]
|
||||
public async Task showLeave([Summary("true/false")] bool enabled)
|
||||
{
|
||||
var modChannelId = (ulong)_redis.HashGet($"{Context.Guild.Id}:Settings", "ModChannel");
|
||||
try
|
||||
{
|
||||
var modChannel = (ISocketMessageChannel) _client.GetChannel(modChannelId);
|
||||
if (enabled)
|
||||
{
|
||||
await modChannel.SendMessageAsync("Saved - now sending messages here when someone leaves");
|
||||
_redis.HashSet($"{Context.Guild.Id}:Settings", new HashEntry[] {new HashEntry("ShowLeave", true)});
|
||||
}
|
||||
else
|
||||
{
|
||||
await modChannel.SendMessageAsync("Saved - stopping sending messages here when someone leaves");
|
||||
_redis.HashSet($"{Context.Guild.Id}:Settings", new HashEntry[] {new HashEntry("ShowLeave", false)});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context, "Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`");
|
||||
}
|
||||
}
|
||||
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[Command("showdel", RunMode = RunMode.Async)]
|
||||
[Summary("Notify modchannel when someone leaves")]
|
||||
public async Task showDelete([Summary("true/false")] bool enabled)
|
||||
{
|
||||
var modChannelId = (ulong)_redis.HashGet($"{Context.Guild.Id}:Settings", "ModChannel");
|
||||
try
|
||||
{
|
||||
var modChannel = (ISocketMessageChannel) _client.GetChannel(modChannelId);
|
||||
if (enabled)
|
||||
{
|
||||
await modChannel.SendMessageAsync("Saved - now sending messages here when someone deletes a message");
|
||||
_redis.HashSet($"{Context.Guild.Id}:Settings", new HashEntry[] {new HashEntry("ShowDelete", true)});
|
||||
}
|
||||
else
|
||||
{
|
||||
await modChannel.SendMessageAsync("Saved - stopping sending messages here when someone deletes a message");
|
||||
_redis.HashSet($"{Context.Guild.Id}:Settings", new HashEntry[] {new HashEntry("ShowDelete", false)});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context, "Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
Geekbot.net/Commands/Cat.cs
Normal file
39
Geekbot.net/Commands/Cat.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Cat : ModuleBase
|
||||
{
|
||||
[Command("cat", RunMode = RunMode.Async)]
|
||||
[Summary("Return a random image of a cat.")]
|
||||
public async Task Say()
|
||||
{
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
client.BaseAddress = new Uri("http://random.cat");
|
||||
var response = await client.GetAsync("/meow.php");
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||
var catFile = JsonConvert.DeserializeObject<CatResponse>(stringResponse);
|
||||
await ReplyAsync(catFile.file);
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
await ReplyAsync($"Seems like the dog cought the cat (error occured)\r\n{e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CatResponse
|
||||
{
|
||||
public string file { get; set; }
|
||||
}
|
||||
}
|
75
Geekbot.net/Commands/CheckEm.cs
Normal file
75
Geekbot.net/Commands/CheckEm.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
using Geekbot.net.Lib.Media;
|
||||
using Serilog;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class CheckEm : ModuleBase
|
||||
{
|
||||
private readonly ICheckEmImageProvider checkEmImages;
|
||||
private readonly Random rnd;
|
||||
private readonly ILogger logger;
|
||||
private readonly IErrorHandler errorHandler;
|
||||
|
||||
public CheckEm(Random RandomClient, ICheckEmImageProvider checkEmImages, ILogger logger, IErrorHandler errorHandler)
|
||||
{
|
||||
this.rnd = RandomClient;
|
||||
this.checkEmImages = checkEmImages;
|
||||
this.logger = logger;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
[Command("checkem", RunMode = RunMode.Async)]
|
||||
[Summary("Check for dubs")]
|
||||
public async Task MuhDubs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var number = rnd.Next(10000000, 99999999);
|
||||
var dubtriqua = "";
|
||||
|
||||
var ns = GetIntArray(number);
|
||||
if (ns[7] == ns[6])
|
||||
{
|
||||
dubtriqua = "DUBS";
|
||||
if (ns[6] == ns[5])
|
||||
{
|
||||
dubtriqua = "TRIPS";
|
||||
if (ns[5] == ns[4])
|
||||
dubtriqua = "QUADS";
|
||||
}
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"Check em {Context.User.Mention}");
|
||||
sb.AppendLine($"**{number}**");
|
||||
if (!string.IsNullOrEmpty(dubtriqua))
|
||||
sb.AppendLine($":tada: {dubtriqua} :tada:");
|
||||
sb.AppendLine(checkEmImages.GetRandomCheckEmPic());
|
||||
|
||||
await ReplyAsync(sb.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] GetIntArray(int num)
|
||||
{
|
||||
var listOfInts = new List<int>();
|
||||
while (num > 0)
|
||||
{
|
||||
listOfInts.Add(num % 10);
|
||||
num = num / 10;
|
||||
}
|
||||
listOfInts.Reverse();
|
||||
return listOfInts.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
25
Geekbot.net/Commands/Choose.cs
Normal file
25
Geekbot.net/Commands/Choose.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Choose : ModuleBase
|
||||
{
|
||||
private readonly Random rnd;
|
||||
|
||||
public Choose(Random RandomClient)
|
||||
{
|
||||
rnd = RandomClient;
|
||||
}
|
||||
|
||||
[Command("choose", RunMode = RunMode.Async)]
|
||||
[Summary("Seperate options with a semicolon.")]
|
||||
public async Task Command([Remainder] [Summary("option1;option2")] string choices)
|
||||
{
|
||||
var choicesArray = choices.Split(';');
|
||||
var choice = rnd.Next(choicesArray.Length);
|
||||
await ReplyAsync($"I choose **{choicesArray[choice]}**");
|
||||
}
|
||||
}
|
||||
}
|
125
Geekbot.net/Commands/Counters.cs
Normal file
125
Geekbot.net/Commands/Counters.cs
Normal file
|
@ -0,0 +1,125 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
using Serilog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Counters : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
private readonly ILogger logger;
|
||||
private readonly IErrorHandler errorHandler;
|
||||
|
||||
public Counters(IDatabase redis, ILogger logger, IErrorHandler errorHandler)
|
||||
{
|
||||
this.redis = redis;
|
||||
this.logger = logger;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
[Command("good", RunMode = RunMode.Async)]
|
||||
[Summary("Increase Someones Karma")]
|
||||
public async Task Good([Summary("@someone")] IUser user)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastKarmaFromRedis = redis.HashGet($"{Context.Guild.Id}:KarmaTimeout", Context.User.Id.ToString());
|
||||
var lastKarma = ConvertToDateTimeOffset(lastKarmaFromRedis.ToString());
|
||||
if (user.Id == Context.User.Id)
|
||||
{
|
||||
await ReplyAsync($"Sorry {Context.User.Username}, but you can't lower your own karma");
|
||||
}
|
||||
else if (TimeoutFinished(lastKarma))
|
||||
{
|
||||
await ReplyAsync(
|
||||
$"Sorry {Context.User.Username}, but you have to wait {GetTimeLeft(lastKarma)} before you can give karma again...");
|
||||
}
|
||||
else
|
||||
{
|
||||
var newKarma = redis.HashIncrement($"{Context.Guild.Id}:Karma", user.Id.ToString());
|
||||
redis.HashSet($"{Context.Guild.Id}:KarmaTimeout",
|
||||
new HashEntry[] {new HashEntry(Context.User.Id.ToString(), DateTimeOffset.Now.ToString("u"))});
|
||||
|
||||
var eb = new EmbedBuilder();
|
||||
eb.WithAuthor(new EmbedAuthorBuilder()
|
||||
.WithIconUrl(user.GetAvatarUrl())
|
||||
.WithName(user.Username));
|
||||
|
||||
eb.WithColor(new Color(138, 219, 146));
|
||||
eb.Title = "Karma Increased";
|
||||
eb.AddInlineField("By", Context.User.Username);
|
||||
eb.AddInlineField("amount", "+1");
|
||||
eb.AddInlineField("Current Karma", newKarma);
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
|
||||
[Command("bad", RunMode = RunMode.Async)]
|
||||
[Summary("Decrease Someones Karma")]
|
||||
public async Task Bad([Summary("@someone")] IUser user)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastKarmaFromRedis = redis.HashGet($"{Context.Guild.Id}:KarmaTimeout", Context.User.Id.ToString());
|
||||
var lastKarma = ConvertToDateTimeOffset(lastKarmaFromRedis.ToString());
|
||||
if (user.Id == Context.User.Id)
|
||||
{
|
||||
await ReplyAsync($"Sorry {Context.User.Username}, but you can't lower your own karma");
|
||||
}
|
||||
else if (TimeoutFinished(lastKarma))
|
||||
{
|
||||
await ReplyAsync(
|
||||
$"Sorry {Context.User.Username}, but you have to wait {GetTimeLeft(lastKarma)} before you can take karma again...");
|
||||
}
|
||||
else
|
||||
{
|
||||
var newKarma = redis.HashDecrement($"{Context.Guild.Id}:Karma", user.Id.ToString());
|
||||
redis.HashSet($"{Context.Guild.Id}:KarmaTimeout",
|
||||
new HashEntry[] {new HashEntry(Context.User.Id.ToString(), DateTimeOffset.Now.ToString())});
|
||||
|
||||
var eb = new EmbedBuilder();
|
||||
eb.WithAuthor(new EmbedAuthorBuilder()
|
||||
.WithIconUrl(user.GetAvatarUrl())
|
||||
.WithName(user.Username));
|
||||
|
||||
eb.WithColor(new Color(138, 219, 146));
|
||||
eb.Title = "Karma Decreased";
|
||||
eb.AddInlineField("By", Context.User.Username);
|
||||
eb.AddInlineField("amount", "-1");
|
||||
eb.AddInlineField("Current Karma", newKarma);
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
|
||||
private DateTimeOffset ConvertToDateTimeOffset(string dateTimeOffsetString)
|
||||
{
|
||||
if(string.IsNullOrEmpty(dateTimeOffsetString)) return DateTimeOffset.Now.Subtract(new TimeSpan(7, 18, 0, 0));
|
||||
return DateTimeOffset.Parse(dateTimeOffsetString);
|
||||
}
|
||||
|
||||
private bool TimeoutFinished(DateTimeOffset lastKarma)
|
||||
{
|
||||
return lastKarma.AddMinutes(3) > DateTimeOffset.Now;
|
||||
}
|
||||
|
||||
private string GetTimeLeft(DateTimeOffset lastKarma)
|
||||
{
|
||||
var dt = lastKarma.AddMinutes(3).Subtract(DateTimeOffset.Now);
|
||||
return $"{dt.Minutes} Minutes and {dt.Seconds} Seconds";
|
||||
}
|
||||
}
|
||||
}
|
124
Geekbot.net/Commands/Dice.cs
Normal file
124
Geekbot.net/Commands/Dice.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Dice : ModuleBase
|
||||
{
|
||||
private readonly Random rnd;
|
||||
|
||||
public Dice(Random RandomClient)
|
||||
{
|
||||
rnd = RandomClient;
|
||||
}
|
||||
|
||||
[Command("dice", RunMode = RunMode.Async)]
|
||||
[Summary("Roll a dice.")]
|
||||
public async Task RollCommand([Remainder] [Summary("diceType")] string diceType = "1d20")
|
||||
{
|
||||
var splitedDices = diceType.Split("+");
|
||||
var dices = new List<DiceTypeDto>();
|
||||
var mod = 0;
|
||||
foreach (var i in splitedDices)
|
||||
{
|
||||
var dice = toDice(i);
|
||||
if (dice.sides != 0 && dice.times != 0)
|
||||
{
|
||||
dices.Add(dice);
|
||||
}
|
||||
else if (dice.mod != 0)
|
||||
{
|
||||
if (mod != 0)
|
||||
{
|
||||
await ReplyAsync("You can only have one mod");
|
||||
return;
|
||||
}
|
||||
mod = dice.mod;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dices.Any())
|
||||
{
|
||||
await ReplyAsync(
|
||||
"That is not a valid dice, examples are: 1d20, 1d6, 2d6, 1d6+2, 1d6+2d8+1d20+6, etc...");
|
||||
return;
|
||||
}
|
||||
|
||||
var rep = new StringBuilder();
|
||||
rep.AppendLine($":game_die: {Context.User.Mention}");
|
||||
rep.Append("**Result:** ");
|
||||
var resultStrings = new List<string>();
|
||||
var total = 0;
|
||||
var extraText = "";
|
||||
foreach (var dice in dices)
|
||||
{
|
||||
var results = new List<int>();
|
||||
for (var i = 0; i < dice.times; i++)
|
||||
{
|
||||
var roll = rnd.Next(1, dice.sides);
|
||||
total += roll;
|
||||
results.Add(roll);
|
||||
if (roll == dice.sides)
|
||||
{
|
||||
extraText = "**Critical Hit!**";
|
||||
}
|
||||
if (roll == 1)
|
||||
{
|
||||
extraText = "**Critical Fail!**";
|
||||
}
|
||||
}
|
||||
resultStrings.Add($"{dice.diceType} ({string.Join(",", results)})");
|
||||
}
|
||||
rep.Append(string.Join(" + ", resultStrings));
|
||||
if (mod != 0)
|
||||
{
|
||||
rep.Append($" + {mod}");
|
||||
total += mod;
|
||||
}
|
||||
rep.AppendLine();
|
||||
rep.AppendLine($"**Total:** {total}");
|
||||
if (extraText != "")
|
||||
{
|
||||
rep.AppendLine(extraText);
|
||||
}
|
||||
await ReplyAsync(rep.ToString());
|
||||
}
|
||||
|
||||
private DiceTypeDto toDice(string dice)
|
||||
{
|
||||
var diceParts = dice.Split('d');
|
||||
if (diceParts.Length == 2
|
||||
&& int.TryParse(diceParts[0], out int times)
|
||||
&& int.TryParse(diceParts[1], out int max))
|
||||
{
|
||||
return new DiceTypeDto()
|
||||
{
|
||||
diceType = dice,
|
||||
times = times,
|
||||
sides = max
|
||||
};
|
||||
}
|
||||
if (dice.Length == 1
|
||||
&& int.TryParse(diceParts[0], out int mod))
|
||||
{
|
||||
return new DiceTypeDto()
|
||||
{
|
||||
mod = mod
|
||||
};
|
||||
}
|
||||
return new DiceTypeDto();
|
||||
}
|
||||
}
|
||||
|
||||
class DiceTypeDto
|
||||
{
|
||||
public string diceType { get; set; }
|
||||
public int times { get; set; }
|
||||
public int sides { get; set; }
|
||||
public int mod { get; set; }
|
||||
}
|
||||
}
|
39
Geekbot.net/Commands/Dog.cs
Normal file
39
Geekbot.net/Commands/Dog.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Dog : ModuleBase
|
||||
{
|
||||
[Command("dog", RunMode = RunMode.Async)]
|
||||
[Summary("Return a random image of a dog.")]
|
||||
public async Task Say()
|
||||
{
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
client.BaseAddress = new Uri("http://random.dog");
|
||||
var response = await client.GetAsync("/woof.json");
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||
var dogFile = JsonConvert.DeserializeObject<DogResponse>(stringResponse);
|
||||
await ReplyAsync(dogFile.url);
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
await ReplyAsync($"Seems like the dog got lost (error occured)\r\n{e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DogResponse
|
||||
{
|
||||
public string url { get; set; }
|
||||
}
|
||||
}
|
49
Geekbot.net/Commands/EightBall.cs
Normal file
49
Geekbot.net/Commands/EightBall.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class EightBall : ModuleBase
|
||||
{
|
||||
private readonly Random rnd;
|
||||
|
||||
public EightBall(Random RandomClient)
|
||||
{
|
||||
rnd = RandomClient;
|
||||
}
|
||||
|
||||
[Command("8ball", RunMode = RunMode.Async)]
|
||||
[Summary("Ask 8Ball a Question.")]
|
||||
public async Task Ball([Remainder] [Summary("Question")] string echo)
|
||||
{
|
||||
var replies = new List<string>
|
||||
{
|
||||
"It is certain",
|
||||
"It is decidedly so",
|
||||
"Without a doubt",
|
||||
"Yes, definitely",
|
||||
"You may rely on it",
|
||||
"As I see it, yes",
|
||||
"Most likely",
|
||||
"Outlook good",
|
||||
"Yes",
|
||||
"Signs point to yes",
|
||||
"Reply hazy try again",
|
||||
"Ask again later",
|
||||
"Better not tell you now",
|
||||
"Cannot predict now",
|
||||
"Concentrate and ask again",
|
||||
"Don't count on it",
|
||||
"My reply is no",
|
||||
"My sources say no",
|
||||
"Outlook not so good",
|
||||
"Very doubtful"
|
||||
};
|
||||
|
||||
var answer = rnd.Next(replies.Count);
|
||||
await ReplyAsync(replies[answer]);
|
||||
}
|
||||
}
|
||||
}
|
23
Geekbot.net/Commands/Fortune.cs
Normal file
23
Geekbot.net/Commands/Fortune.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib.Media;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Fortune : ModuleBase
|
||||
{
|
||||
private readonly IFortunesProvider fortunes;
|
||||
|
||||
public Fortune(IFortunesProvider fortunes)
|
||||
{
|
||||
this.fortunes = fortunes;
|
||||
}
|
||||
|
||||
[Command("fortune", RunMode = RunMode.Async)]
|
||||
[Summary("Get a random fortune")]
|
||||
public async Task GetAFortune()
|
||||
{
|
||||
await ReplyAsync(fortunes.GetRandomFortune());
|
||||
}
|
||||
}
|
||||
}
|
17
Geekbot.net/Commands/Google.cs
Normal file
17
Geekbot.net/Commands/Google.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Google : ModuleBase
|
||||
{
|
||||
[Command("google", RunMode = RunMode.Async)]
|
||||
[Summary("Google Something.")]
|
||||
public async Task Eyes([Remainder, Summary("SearchText")] string searchText)
|
||||
{
|
||||
var url = $"http://lmgtfy.com/?q={searchText.Replace(' ', '+')}";
|
||||
|
||||
await ReplyAsync($"Please click here :unamused:\r\n{url}");
|
||||
}
|
||||
}
|
||||
}
|
50
Geekbot.net/Commands/GuildInfo.cs
Normal file
50
Geekbot.net/Commands/GuildInfo.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class GuildInfo : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
|
||||
public GuildInfo(IDatabase redis)
|
||||
{
|
||||
this.redis = redis;
|
||||
}
|
||||
|
||||
[Command("serverstats", RunMode = RunMode.Async)]
|
||||
[Summary("Show some info about the bot.")]
|
||||
public async Task getInfo()
|
||||
{
|
||||
var eb = new EmbedBuilder();
|
||||
eb.WithAuthor(new EmbedAuthorBuilder()
|
||||
.WithIconUrl(Context.Guild.IconUrl)
|
||||
.WithName(Context.Guild.Name));
|
||||
eb.WithColor(new Color(110, 204, 147));
|
||||
|
||||
var created = Context.Guild.CreatedAt;
|
||||
var age = Math.Floor((DateTime.Now - created).TotalDays);
|
||||
|
||||
var messages = redis.HashGet($"{Context.Guild.Id}:Messages", 0.ToString());
|
||||
var level = LevelCalc.GetLevelAtExperience((int) messages);
|
||||
|
||||
eb.AddField("Server Age", $"{created.Day}/{created.Month}/{created.Year} ({age} days)");
|
||||
eb.AddInlineField("Level", level)
|
||||
.AddInlineField("Messages", messages);
|
||||
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
|
||||
public static string FirstCharToUpper(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
throw new ArgumentException("ARGH!");
|
||||
return input.First().ToString().ToUpper() + input.Substring(1);
|
||||
}
|
||||
}
|
||||
}
|
48
Geekbot.net/Commands/Help.cs
Normal file
48
Geekbot.net/Commands/Help.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Help : ModuleBase
|
||||
{
|
||||
private readonly CommandService commands;
|
||||
|
||||
public Help(CommandService commands)
|
||||
{
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
[Command("help", RunMode = RunMode.Async)]
|
||||
[Summary("List all Commands")]
|
||||
public async Task GetHelp()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("```");
|
||||
sb.AppendLine("**Geekbot Command list**");
|
||||
sb.AppendLine("");
|
||||
sb.AppendLine(tp("Name", 15) + tp("Parameters", 19) + "Description");
|
||||
foreach (var cmd in commands.Commands)
|
||||
{
|
||||
var param = string.Join(", !", cmd.Aliases);
|
||||
if (!param.Contains("admin"))
|
||||
if (cmd.Parameters.Any())
|
||||
sb.AppendLine(tp(param, 15) +
|
||||
tp(string.Join(" ", cmd.Parameters.Select(e => e.Summary)), 19) +
|
||||
cmd.Summary);
|
||||
else
|
||||
sb.AppendLine(tp(param, 34) + cmd.Summary);
|
||||
}
|
||||
sb.AppendLine("```");
|
||||
var dm = await Context.User.GetOrCreateDMChannelAsync();
|
||||
await dm.SendMessageAsync(sb.ToString());
|
||||
}
|
||||
|
||||
// Table Padding, short function name because of many usages
|
||||
private string tp(string text, int shouldHave)
|
||||
{
|
||||
return text.PadRight(shouldHave);
|
||||
}
|
||||
}
|
||||
}
|
49
Geekbot.net/Commands/Info.cs
Normal file
49
Geekbot.net/Commands/Info.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Info : ModuleBase
|
||||
{
|
||||
private readonly IDatabase _redis;
|
||||
private readonly IErrorHandler _errorHandler;
|
||||
|
||||
public Info(IDatabase redis, IErrorHandler errorHandler)
|
||||
{
|
||||
_redis = redis;
|
||||
_errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
[Command("info", RunMode = RunMode.Async)]
|
||||
[Summary("Get Information about the bot")]
|
||||
public async Task BotInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var eb = new EmbedBuilder();
|
||||
|
||||
eb.WithTitle("Geekbot V3.3");
|
||||
|
||||
var botOwner = Context.Guild.GetUserAsync(ulong.Parse(_redis.StringGet("botOwner"))).Result;
|
||||
var uptime = (DateTime.Now.Subtract(Process.GetCurrentProcess().StartTime));
|
||||
|
||||
eb.AddInlineField("Bot Name", Context.Client.CurrentUser.Username)
|
||||
.AddInlineField("Servers", Context.Client.GetGuildsAsync().Result.Count)
|
||||
.AddInlineField("Uptime", $"{uptime.Days}D {uptime.Hours}H {uptime.Minutes}M {uptime.Seconds}S")
|
||||
.AddInlineField("Bot Owner", $"{botOwner.Username}#{botOwner.Discriminator}")
|
||||
.AddInlineField("Website", "https://geekbot.pizzaandcoffee.rocks/");
|
||||
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
Geekbot.net/Commands/Panda.cs
Normal file
23
Geekbot.net/Commands/Panda.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib.Media;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Panda : ModuleBase
|
||||
{
|
||||
private readonly IPandaProvider pandaImages;
|
||||
|
||||
public Panda(IPandaProvider pandaImages)
|
||||
{
|
||||
this.pandaImages = pandaImages;
|
||||
}
|
||||
|
||||
[Command("panda", RunMode = RunMode.Async)]
|
||||
[Summary("Get a random panda")]
|
||||
public async Task PandaCommand()
|
||||
{
|
||||
await ReplyAsync(pandaImages.GetRandomPanda());
|
||||
}
|
||||
}
|
||||
}
|
15
Geekbot.net/Commands/Ping.cs
Normal file
15
Geekbot.net/Commands/Ping.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Ping : ModuleBase
|
||||
{
|
||||
[Command("👀", RunMode = RunMode.Async)]
|
||||
[Summary("Look at the bot.")]
|
||||
public async Task Eyes()
|
||||
{
|
||||
await ReplyAsync("S... Stop looking at me... baka!");
|
||||
}
|
||||
}
|
||||
}
|
171
Geekbot.net/Commands/Quote.cs
Normal file
171
Geekbot.net/Commands/Quote.cs
Normal file
|
@ -0,0 +1,171 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
[Group("quote")]
|
||||
public class Quote : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
private readonly ILogger logger;
|
||||
private readonly IErrorHandler errorHandler;
|
||||
|
||||
public Quote(IDatabase redis, ILogger logger, IErrorHandler errorHandler)
|
||||
{
|
||||
this.redis = redis;
|
||||
this.logger = logger;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
[Command()]
|
||||
[Summary("Return a random quoute from the database")]
|
||||
public async Task getRandomQuote()
|
||||
{
|
||||
var randomQuote = redis.SetRandomMember($"{Context.Guild.Id}:Quotes");
|
||||
try
|
||||
{
|
||||
var quote = JsonConvert.DeserializeObject<QuoteObject>(randomQuote);
|
||||
var embed = quoteBuilder(quote);
|
||||
await ReplyAsync("", false, embed.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context, "Whoops, seems like the quote was to edgy to return");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("save")]
|
||||
[Summary("Save a quote from the last sent message by @user")]
|
||||
public async Task saveQuote([Summary("@user")] IUser user)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastMessage = await getLastMessageByUser(user);
|
||||
var quote = createQuoteObject(lastMessage);
|
||||
var quoteStore = JsonConvert.SerializeObject(quote);
|
||||
redis.SetAdd($"{Context.Guild.Id}:Quotes", quoteStore);
|
||||
var embed = quoteBuilder(quote);
|
||||
await ReplyAsync("**Quote Added**", false, embed.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context, "I counldn't find a quote from that user :disappointed:");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("save")]
|
||||
[Summary("Save a quote from a message id")]
|
||||
public async Task saveQuote([Summary("messageId")] ulong messageId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var message = await Context.Channel.GetMessageAsync(messageId);
|
||||
var quote = createQuoteObject(message);
|
||||
var quoteStore = JsonConvert.SerializeObject(quote);
|
||||
redis.SetAdd($"{Context.Guild.Id}:Quotes", quoteStore);
|
||||
var embed = quoteBuilder(quote);
|
||||
await ReplyAsync("**Quote Added**", false, embed.Build());
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context, "I couldn't find a message with that id :disappointed:");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("make")]
|
||||
[Summary("Create a quote from the last sent message by @user")]
|
||||
public async Task returnSpecifiedQuote([Summary("@user")] IUser user)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastMessage = await getLastMessageByUser(user);
|
||||
var quote = createQuoteObject(lastMessage);
|
||||
var embed = quoteBuilder(quote);
|
||||
await ReplyAsync("", false, embed.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context, "I counldn't find a quote from that user :disappointed:");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("make")]
|
||||
[Summary("Create a quote from a message id")]
|
||||
public async Task returnSpecifiedQuote([Summary("messageId")] ulong messageId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var message = await Context.Channel.GetMessageAsync(messageId);
|
||||
var quote = createQuoteObject(message);
|
||||
var embed = quoteBuilder(quote);
|
||||
await ReplyAsync("", false, embed.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context, "I couldn't find a message with that id :disappointed:");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IMessage> getLastMessageByUser(IUser user)
|
||||
{
|
||||
Task<IEnumerable<IMessage>> list = Context.Channel.GetMessagesAsync().Flatten();
|
||||
await list;
|
||||
return list.Result
|
||||
.First(msg => msg.Author.Id == user.Id
|
||||
&& msg.Embeds.Count == 0
|
||||
&& msg.Id != Context.Message.Id
|
||||
&& !msg.Content.ToLower().StartsWith("!"));
|
||||
}
|
||||
|
||||
private EmbedBuilder quoteBuilder(QuoteObject quote)
|
||||
{
|
||||
var user = Context.Client.GetUserAsync(quote.userId).Result;
|
||||
var eb = new EmbedBuilder();
|
||||
eb.WithColor(new Color(143, 167, 232));
|
||||
eb.Title = $"{user.Username} @ {quote.time.Day}.{quote.time.Month}.{quote.time.Year}";
|
||||
eb.Description = quote.quote;
|
||||
eb.ThumbnailUrl = user.GetAvatarUrl();
|
||||
if (quote.image != null)
|
||||
{
|
||||
eb.ImageUrl = quote.image;
|
||||
}
|
||||
return eb;
|
||||
}
|
||||
|
||||
private QuoteObject createQuoteObject(IMessage message)
|
||||
{
|
||||
string image;
|
||||
try
|
||||
{
|
||||
image = message.Attachments.First().Url;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
image = null;
|
||||
}
|
||||
return new QuoteObject()
|
||||
{
|
||||
userId = message.Author.Id,
|
||||
time = message.Timestamp.DateTime,
|
||||
quote = message.Content,
|
||||
image = image
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class QuoteObject {
|
||||
public ulong userId { get; set; }
|
||||
public string quote { get; set; }
|
||||
public DateTime time { get; set; }
|
||||
public string image { get; set; }
|
||||
}
|
||||
}
|
41
Geekbot.net/Commands/Roll.cs
Normal file
41
Geekbot.net/Commands/Roll.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Roll : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
private readonly Random rnd;
|
||||
|
||||
public Roll(IDatabase redis, Random RandomClient)
|
||||
{
|
||||
this.redis = redis;
|
||||
rnd = RandomClient;
|
||||
}
|
||||
|
||||
[Command("roll", RunMode = RunMode.Async)]
|
||||
[Summary("Roll a number between 1 and 100.")]
|
||||
public async Task RollCommand([Remainder] [Summary("stuff...")] string stuff = "nothing")
|
||||
{
|
||||
var number = rnd.Next(1, 100);
|
||||
var guess = 1000;
|
||||
int.TryParse(stuff, out guess);
|
||||
if (guess <= 100 && guess > 0)
|
||||
{
|
||||
await ReplyAsync($"{Context.Message.Author.Mention} you rolled {number}, your guess was {guess}");
|
||||
if (guess == number)
|
||||
{
|
||||
await ReplyAsync($"Congratulations {Context.User.Username}, your guess was correct!");
|
||||
redis.HashIncrement($"{Context.Guild.Id}:Rolls", Context.User.Id.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyAsync(Context.Message.Author.Mention + ", you rolled " + number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
Geekbot.net/Commands/Say.cs
Normal file
18
Geekbot.net/Commands/Say.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Say : ModuleBase
|
||||
{
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[Command("say", RunMode = RunMode.Async)]
|
||||
[Summary("Say Something.")]
|
||||
public async Task Echo([Remainder] [Summary("What?")] string echo)
|
||||
{
|
||||
await Context.Message.DeleteAsync();
|
||||
await ReplyAsync(echo);
|
||||
}
|
||||
}
|
||||
}
|
83
Geekbot.net/Commands/Ship.cs
Normal file
83
Geekbot.net/Commands/Ship.cs
Normal file
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Ship : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
private readonly Random rnd;
|
||||
|
||||
public Ship(IDatabase redis, Random RandomClient)
|
||||
{
|
||||
this.redis = redis;
|
||||
rnd = RandomClient;
|
||||
}
|
||||
|
||||
[Command("Ship", RunMode = RunMode.Async)]
|
||||
[Summary("Ask the Shipping meter")]
|
||||
public async Task Command([Summary("@User1")] IUser user1, [Summary("@User2")] IUser user2)
|
||||
{
|
||||
// Create a String
|
||||
var dbstring = "";
|
||||
if (user1.Id > user2.Id)
|
||||
dbstring = $"{user1.Id}-{user2.Id}";
|
||||
else
|
||||
dbstring = $"{user2.Id}-{user1.Id}";
|
||||
|
||||
var dbval = redis.HashGet($"{Context.Guild.Id}:Ships", dbstring);
|
||||
var shippingRate = 0;
|
||||
if (dbval.IsNullOrEmpty)
|
||||
{
|
||||
shippingRate = rnd.Next(1, 100);
|
||||
redis.HashSet($"{Context.Guild.Id}:Ships", dbstring, shippingRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
shippingRate = int.Parse(dbval.ToString());
|
||||
}
|
||||
|
||||
var reply = ":heartpulse: **Matchmaking** :heartpulse:\r\n";
|
||||
reply = reply + $":two_hearts: {user1.Mention} :heart: {user2.Mention} :two_hearts:\r\n";
|
||||
reply = reply + $"0% [{BlockCounter(shippingRate)}] 100% - {DeterminateSuccess(shippingRate)}";
|
||||
await ReplyAsync(reply);
|
||||
}
|
||||
|
||||
private string DeterminateSuccess(int rate)
|
||||
{
|
||||
if (rate < 20)
|
||||
return "Not gonna happen";
|
||||
if (rate >= 20 && rate < 40)
|
||||
return "Not such a good idea";
|
||||
if (rate >= 40 && rate < 60)
|
||||
return "There might be a chance";
|
||||
if (rate >= 60 && rate < 80)
|
||||
return "Almost a match, but could work";
|
||||
if (rate >= 80)
|
||||
return "It's a match";
|
||||
return "a";
|
||||
}
|
||||
|
||||
private string BlockCounter(int rate)
|
||||
{
|
||||
var amount = Math.Floor(decimal.Floor(rate / 10));
|
||||
Console.WriteLine(amount);
|
||||
var blocks = "";
|
||||
for (var i = 1; i <= 10; i++)
|
||||
if (i <= amount)
|
||||
{
|
||||
blocks = blocks + ":white_medium_small_square:";
|
||||
if (i == amount)
|
||||
blocks = blocks + $" {rate}% ";
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks = blocks + ":black_medium_small_square:";
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
}
|
168
Geekbot.net/Commands/UserInfo.cs
Normal file
168
Geekbot.net/Commands/UserInfo.cs
Normal file
|
@ -0,0 +1,168 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
using Serilog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class UserInfo : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
private readonly IErrorHandler errorHandler;
|
||||
private readonly ILogger logger;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
public UserInfo(IDatabase redis, IErrorHandler errorHandler, ILogger logger, IUserRepository userRepository)
|
||||
{
|
||||
this.redis = redis;
|
||||
this.errorHandler = errorHandler;
|
||||
this.logger = logger;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
[Command("stats", RunMode = RunMode.Async)]
|
||||
[Summary("Get information about this user")]
|
||||
public async Task User([Summary("@someone")] IUser user = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var userInfo = user ?? Context.Message.Author;
|
||||
var userGuildInfo = (IGuildUser) userInfo;
|
||||
var createdAt = userInfo.CreatedAt;
|
||||
var joinedAt = userGuildInfo.JoinedAt.Value;
|
||||
var age = Math.Floor((DateTime.Now - createdAt).TotalDays);
|
||||
var joinedDayAgo = Math.Floor((DateTime.Now - joinedAt).TotalDays);
|
||||
|
||||
var messages = (int) redis.HashGet($"{Context.Guild.Id}:Messages", userInfo.Id.ToString());
|
||||
var guildMessages = (int) redis.HashGet($"{Context.Guild.Id}:Messages", 0.ToString());
|
||||
var level = LevelCalc.GetLevelAtExperience(messages);
|
||||
|
||||
var percent = Math.Round((double) (100 * messages) / guildMessages, 2);
|
||||
|
||||
var eb = new EmbedBuilder();
|
||||
eb.WithAuthor(new EmbedAuthorBuilder()
|
||||
.WithIconUrl(userInfo.GetAvatarUrl())
|
||||
.WithName(userInfo.Username));
|
||||
eb.WithColor(new Color(221, 255, 119));
|
||||
|
||||
var karma = redis.HashGet($"{Context.Guild.Id}:Karma", userInfo.Id);
|
||||
var correctRolls = redis.HashGet($"{Context.Guild.Id}:Rolls", userInfo.Id.ToString());
|
||||
|
||||
eb.AddInlineField("Discordian Since", $"{createdAt.Day}.{createdAt.Month}.{createdAt.Year} ({age} days)")
|
||||
.AddInlineField("Joined Server", $"{joinedAt.Day}.{joinedAt.Month}.{joinedAt.Year} ({joinedDayAgo} days)")
|
||||
.AddInlineField("Karma", karma.ToString() ?? "0")
|
||||
.AddInlineField("Level", level)
|
||||
.AddInlineField("Messages Sent", messages)
|
||||
.AddInlineField("Server Total", $"{percent}%");
|
||||
|
||||
if (!correctRolls.IsNullOrEmpty)
|
||||
eb.AddInlineField("Guessed Rolls", correctRolls);
|
||||
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
|
||||
[Command("rank", RunMode = RunMode.Async)]
|
||||
[Summary("get user top 10")]
|
||||
public async Task Rank()
|
||||
{
|
||||
try
|
||||
{
|
||||
var messageList = redis.HashGetAll($"{Context.Guild.Id}:Messages");
|
||||
var sortedList = messageList.OrderByDescending(e => e.Value).ToList();
|
||||
var guildMessages = (int) sortedList.First().Value;
|
||||
sortedList.RemoveAt(0);
|
||||
|
||||
var highscoreUsers = new Dictionary<RankUserPolyfill, int>();
|
||||
var listLimiter = 1;
|
||||
var failedToRetrieveUser = false;
|
||||
foreach (var user in sortedList)
|
||||
{
|
||||
if (listLimiter > 10) break;
|
||||
try
|
||||
{
|
||||
var guildUser = userRepository.Get((ulong)user.Name);
|
||||
if (guildUser.Username != null)
|
||||
{
|
||||
highscoreUsers.Add(new RankUserPolyfill()
|
||||
{
|
||||
Username = guildUser.Username,
|
||||
Discriminator = guildUser.Discriminator
|
||||
}, (int) user.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
highscoreUsers.Add(new RankUserPolyfill()
|
||||
{
|
||||
Id = user.Name
|
||||
}, (int) user.Value);
|
||||
failedToRetrieveUser = true;
|
||||
}
|
||||
listLimiter++;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Warning(e, $"Could not retrieve user {user.Name}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var highScore = new StringBuilder();
|
||||
if (failedToRetrieveUser) highScore.AppendLine(":warning: I couldn't get all userdata, sorry! (bugfix coming soon:tm:)\n");
|
||||
highScore.AppendLine($":bar_chart: **Highscore for {Context.Guild.Name}**");
|
||||
var highscorePlace = 1;
|
||||
foreach (var user in highscoreUsers)
|
||||
{
|
||||
var percent = Math.Round((double) (100 * user.Value) / guildMessages, 2);
|
||||
if (user.Key.Username != null)
|
||||
{
|
||||
highScore.AppendLine(
|
||||
$"{NumerToEmoji(highscorePlace)} **{user.Key.Username}#{user.Key.Discriminator}** - {percent}% of total - {user.Value} messages");
|
||||
}
|
||||
else
|
||||
{
|
||||
highScore.AppendLine(
|
||||
$"{NumerToEmoji(highscorePlace)} **{user.Key.Id}** - {percent}% of total - {user.Value} messages");
|
||||
}
|
||||
highscorePlace++;
|
||||
}
|
||||
await ReplyAsync(highScore.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errorHandler.HandleCommandException(e, Context);
|
||||
}
|
||||
}
|
||||
|
||||
private string NumerToEmoji(int number)
|
||||
{
|
||||
var emojis = new string[] {":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:", ":keycap_ten:"};
|
||||
try
|
||||
{
|
||||
return emojis[number - 1];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Warning(e, $"Can't provide emoji number {number}");
|
||||
return ":zero:";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RankUserPolyfill
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string Discriminator { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
59
Geekbot.net/Commands/Youtube.cs
Normal file
59
Geekbot.net/Commands/Youtube.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Google.Apis.Services;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class Youtube : ModuleBase
|
||||
{
|
||||
private readonly IDatabase redis;
|
||||
|
||||
public Youtube(IDatabase redis)
|
||||
{
|
||||
this.redis = redis;
|
||||
}
|
||||
|
||||
[Command("yt", RunMode = RunMode.Async)]
|
||||
[Summary("Search for something on youtube.")]
|
||||
public async Task Yt([Remainder] [Summary("Title")] string searchQuery)
|
||||
{
|
||||
var key = redis.StringGet("youtubeKey");
|
||||
if (key.IsNullOrEmpty)
|
||||
{
|
||||
await ReplyAsync("No youtube key set, please tell my senpai to set one");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var youtubeService = new YouTubeService(new BaseClientService.Initializer
|
||||
{
|
||||
ApiKey = key.ToString(),
|
||||
ApplicationName = GetType().ToString()
|
||||
});
|
||||
|
||||
var searchListRequest = youtubeService.Search.List("snippet");
|
||||
searchListRequest.Q = searchQuery;
|
||||
searchListRequest.MaxResults = 2;
|
||||
|
||||
var searchListResponse = await searchListRequest.ExecuteAsync();
|
||||
|
||||
var result = searchListResponse.Items[0];
|
||||
|
||||
await ReplyAsync(
|
||||
$"\"{result.Snippet.Title}\" from \"{result.Snippet.ChannelTitle}\" https://youtu.be/{result.Id.VideoId}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await ReplyAsync("Something went wrong... informing my senpai...");
|
||||
var botOwner = Context.Guild.GetUserAsync(ulong.Parse(redis.StringGet("botOwner"))).Result;
|
||||
var dm = await botOwner.GetOrCreateDMChannelAsync();
|
||||
await dm.SendMessageAsync(
|
||||
$"Something went wrong while getting a video from youtube:\r\n```\r\n{e.Message}\r\n```");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
116
Geekbot.net/Commands/mal.cs
Normal file
116
Geekbot.net/Commands/mal.cs
Normal file
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Geekbot.net.Lib;
|
||||
|
||||
namespace Geekbot.net.Commands
|
||||
{
|
||||
public class mal : ModuleBase
|
||||
{
|
||||
private readonly IMalClient _malClient;
|
||||
private readonly IErrorHandler _errorHandler;
|
||||
|
||||
public mal(IMalClient malClient, IErrorHandler errorHandler)
|
||||
{
|
||||
_malClient = malClient;
|
||||
_errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
[Command("anime", RunMode = RunMode.Async)]
|
||||
[Summary("Show Info about an Anime.")]
|
||||
public async Task searchAnime([Remainder, Summary("AnimeName")] string animeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_malClient.isLoggedIn())
|
||||
{
|
||||
var anime = await _malClient.getAnime(animeName);
|
||||
if (anime != null)
|
||||
{
|
||||
var eb = new EmbedBuilder();
|
||||
|
||||
var description = System.Web.HttpUtility.HtmlDecode(anime.Synopsis)
|
||||
.Replace("<br />", "")
|
||||
.Replace("[i]", "*")
|
||||
.Replace("[/i]", "*");
|
||||
|
||||
eb.Title = anime.Title;
|
||||
eb.Description = description;
|
||||
eb.ImageUrl = anime.Image;
|
||||
eb.AddInlineField("Premiered", $"{anime.StartDate}");
|
||||
eb.AddInlineField("Ended", anime.EndDate == "0000-00-00" ? "???" : anime.EndDate);
|
||||
eb.AddInlineField("Status", anime.Status);
|
||||
eb.AddInlineField("Episodes", anime.Episodes);
|
||||
eb.AddInlineField("MAL Score", anime.Score);
|
||||
eb.AddInlineField("Type", anime.Type);
|
||||
eb.AddField("MAL Link", $"https://myanimelist.net/anime/{anime.Id}");
|
||||
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyAsync("No anime found with that name...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyAsync(
|
||||
"Unfortunally i'm not connected to MyAnimeList.net, please tell my senpai to connect me");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context, "Something went wrong...");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("manga", RunMode = RunMode.Async)]
|
||||
[Summary("Show Info about a Manga.")]
|
||||
public async Task searchManga([Remainder, Summary("MangaName")] string mangaName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_malClient.isLoggedIn())
|
||||
{
|
||||
var manga = await _malClient.getManga(mangaName);
|
||||
if (manga != null)
|
||||
{
|
||||
var eb = new EmbedBuilder();
|
||||
|
||||
var description = System.Web.HttpUtility.HtmlDecode(manga.Synopsis)
|
||||
.Replace("<br />", "")
|
||||
.Replace("[i]", "*")
|
||||
.Replace("[/i]", "*");
|
||||
|
||||
eb.Title = manga.Title;
|
||||
eb.Description = description;
|
||||
eb.ImageUrl = manga.Image;
|
||||
eb.AddInlineField("Premiered", $"{manga.StartDate}");
|
||||
eb.AddInlineField("Ended", manga.EndDate == "0000-00-00" ? "???" : manga.EndDate);
|
||||
eb.AddInlineField("Status", manga.Status);
|
||||
eb.AddInlineField("Volumes", manga.Volumes);
|
||||
eb.AddInlineField("Chapters", manga.Chapters);
|
||||
eb.AddInlineField("MAL Score", manga.Score);
|
||||
eb.AddField("MAL Link", $"https://myanimelist.net/manga/{manga.Id}");
|
||||
|
||||
await ReplyAsync("", false, eb.Build());
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyAsync("No manga found with that name...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyAsync(
|
||||
"Unfortunally i'm not connected to MyAnimeList.net, please tell my senpai to connect me");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_errorHandler.HandleCommandException(e, Context, "Something went wrong...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue