Sean/Sean/CommandHandler.cs

399 lines
17 KiB
C#

using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using Sean.Models;
using Sean.Services;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace Sean
{
public class CommandHandler
{
#region Fields
private readonly DiscordSocketClient _client;
private readonly CommandService _commands;
private readonly IServiceProvider _services;
#endregion Fields
#region Constructors
public CommandHandler(IServiceProvider services, DiscordSocketClient client, CommandService commands)
{
_commands = commands;
_client = client;
_services = services;
}
#endregion Constructors
#region Methods
public async Task InstallCommandsAsync()
{
// Hook the MessageReceived event into our command handler
_client.MessageReceived += HandleCommandAsync;
_client.ReactionAdded += HandleReactionAddedAsync;
_client.ReactionRemoved += HandleReactionRemovedAsync;
_client.Ready += _client_Ready;
_client.ChannelCreated += _client_ChannelCreated;
_client.ChannelDestroyed += _client_ChannelDestroyed;
_client.ChannelUpdated += _client_ChannelUpdated;
_client.Connected += _client_Connected;
_client.CurrentUserUpdated += _client_CurrentUserUpdated;
_client.Disconnected += _client_Disconnected;
_client.GuildAvailable += _client_GuildAvailable;
_client.GuildMembersDownloaded += _client_GuildMembersDownloaded;
_client.GuildMemberUpdated += _client_GuildMemberUpdated;
_client.GuildUnavailable += _client_GuildUnavailable;
_client.GuildUpdated += _client_GuildUpdated;
_client.JoinedGuild += _client_JoinedGuild;
_client.LatencyUpdated += _client_LatencyUpdated;
_client.LeftGuild += _client_LeftGuild;
_client.LoggedIn += _client_LoggedIn;
_client.LoggedOut += _client_LoggedOut;
_client.MessageDeleted += _client_MessageDeleted;
_client.MessagesBulkDeleted += _client_MessagesBulkDeleted;
_client.MessageUpdated += _client_MessageUpdated;
_client.ReactionsCleared += _client_ReactionsCleared;
_client.RecipientAdded += _client_RecipientAdded;
_client.RecipientRemoved += _client_RecipientRemoved;
_client.RoleCreated += _client_RoleCreated;
_client.RoleDeleted += _client_RoleDeleted;
_client.RoleUpdated += _client_RoleUpdated;
_client.UserBanned += _client_UserBanned;
_client.UserIsTyping += _client_UserIsTyping;
_client.UserJoined += _client_UserJoined;
_client.UserLeft += _client_UserLeft;
_client.UserUnbanned += _client_UserUnbanned;
_client.UserUpdated += _client_UserUpdated;
_client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated;
_client.VoiceServerUpdated += _client_VoiceServerUpdated;
// Here we discover all of the command modules in the entry
// assembly and load them. Starting from Discord.NET 2.0, a
// service provider is required to be passed into the
// module registration method to inject the
// required dependencies.
//
// If you do not use Dependency Injection, pass null.
// See Dependency Injection guide for more information.
await _commands.AddModulesAsync(assembly: Assembly.GetEntryAssembly(),
services: _services);
}
private Task _client_VoiceServerUpdated(SocketVoiceServer arg) => LogMe();
private Task _client_UserVoiceStateUpdated(SocketUser arg1, SocketVoiceState arg2, SocketVoiceState arg3) => LogMe();
private Task _client_UserUpdated(SocketUser arg1, SocketUser arg2) => LogMe(message: $"Avant : {arg1}, après : {arg2}");
private Task _client_UserUnbanned(SocketUser arg1, SocketGuild arg2) => LogMe();
private Task _client_UserLeft(SocketGuildUser arg) => LogMe();
private Task _client_UserJoined(SocketGuildUser arg) => LogMe();
private Task _client_UserIsTyping(SocketUser arg1, ISocketMessageChannel arg2) => LogMe();
private Task _client_UserBanned(SocketUser arg1, SocketGuild arg2) => LogMe();
private Task _client_RoleUpdated(SocketRole arg1, SocketRole arg2) => LogMe();
private Task _client_RoleDeleted(SocketRole arg) => LogMe();
private Task _client_RoleCreated(SocketRole arg) => LogMe();
private Task _client_RecipientRemoved(SocketGroupUser arg) => LogMe();
private Task _client_RecipientAdded(SocketGroupUser arg) => LogMe();
private Task _client_ReactionsCleared(Cacheable<IUserMessage, ulong> arg1, ISocketMessageChannel arg2) => LogMe();
private Task _client_MessageUpdated(Cacheable<IMessage, ulong> arg1, SocketMessage arg2, ISocketMessageChannel arg3) => LogMe();
private Task _client_MessagesBulkDeleted(System.Collections.Generic.IReadOnlyCollection<Cacheable<IMessage, ulong>> arg1, ISocketMessageChannel arg2) => LogMe();
private Task _client_MessageDeleted(Cacheable<IMessage, ulong> arg1, ISocketMessageChannel arg2) => LogMe();
private Task _client_LoggedOut() => LogMe();
private Task _client_LoggedIn() => LogMe();
private Task _client_LeftGuild(SocketGuild arg) => LogMe();
private Task _client_LatencyUpdated(int arg1, int arg2) => LogMe();
private Task _client_JoinedGuild(SocketGuild arg) => LogMe();
private Task _client_GuildUpdated(SocketGuild arg1, SocketGuild arg2) => LogMe();
private Task _client_GuildUnavailable(SocketGuild arg) => LogMe();
private async Task _client_GuildMemberUpdated(SocketGuildUser arg1, SocketGuildUser arg2)
{
await LogMe();
//message: $"Avant : {arg1.Id} - {arg1.Nickname}, après : {arg2.Id} - {arg2.Nickname}");
// if (arg1.Nickname != arg2.Nickname)
// {
// IDMChannel chan = await arg2.GetOrCreateDMChannelAsync();
// await chan.SendMessageAsync("Bien essayé petit malin, tu crois qu'on ne te reconnaîtra pas ? :-P");
// }
}
private async Task UpdateUserAsync(SocketGuildUser user)
{
DbService db = _services.GetService(typeof(DbService)) as DbService;
ScoreUtilisateur score = await db.Scores.SingleOrDefaultAsync(s => s.UserId == user.Id && s.Date == DateTime.Today);
if (score == default)
{
score = new ScoreUtilisateur { UserId = user.Id, Date = DateTime.Today, Name = user.Nick(), Score = 0 };
await db.Scores.AddAsync(score);
}
else
{
if (score.Name != user.Nick())
score.Name = user.Nick();
}
await db.SaveChangesAsync();
}
private async Task _client_GuildMembersDownloaded(SocketGuild arg)
{
await LogMe();
foreach (SocketGuildUser user in arg.Users)
{
await UpdateUserAsync(user);
}
}
private Task _client_GuildAvailable(SocketGuild arg) => LogMe();
private Task _client_Disconnected(Exception arg) => LogMe();
private Task _client_CurrentUserUpdated(SocketSelfUser arg1, SocketSelfUser arg2) => LogMe();
private Task _client_Connected() => LogMe();
private Task _client_ChannelUpdated(SocketChannel arg1, SocketChannel arg2) => LogMe();
private Task _client_ChannelDestroyed(SocketChannel arg) => LogMe();
private Task _client_ChannelCreated(SocketChannel arg) => LogMe();
private Task LogMe([CallerMemberName] string name = "", string message = "called")
{
Console.WriteLine($"{name} : {message}"); return Task.CompletedTask;
}
private async Task _client_Ready()
{
await LogMe();
foreach (SocketGuild g in _client.Guilds)
{
foreach (SocketTextChannel c in g.TextChannels)
{
await c.SendMessageAsync("I'm back !");
}
}
}
private async Task HandleCommandAsync(SocketMessage messageParam)
{
await LogMe();
// Don't process the command if it was a system message
var message = messageParam as SocketUserMessage;
if (message == null) return;
// Create a number to track where the prefix ends and the command begins
int argPos = 0;
// Determine if the message is a command based on the prefix and make sure no bots trigger commands
if (!(message.HasCharPrefix('!', ref argPos) ||
message.HasMentionPrefix(_client.CurrentUser, ref argPos)) ||
message.Author.IsBot)
return;
// Create a WebSocket-based command context based on the message
var context = new SocketCommandContext(_client, message);
// Execute the command with the command context we just
// created, along with the service provider for precondition checks.
// Keep in mind that result does not indicate a return value
// rather an object stating if the command executed successfully.
var result = await _commands.ExecuteAsync(
context: context,
argPos: argPos,
services: _services);
// Optionally, we may inform the user if the command fails
// to be executed; however, this may not always be desired,
// as it may clog up the request queue should a user spam a
// command.
// if (!result.IsSuccess)
// await context.Channel.SendMessageAsync(result.ErrorReason);
}
private bool IsBlame(IMessage m) => m.Content.StartsWith("!blame") || m.Content.StartsWith("!bash");
private bool IsReward(IMessage m) => m.Content.StartsWith("!great") || m.Content.StartsWith("!reward");
private async Task HandleReactionAddedAsync(Cacheable<IUserMessage, ulong> message, ISocketMessageChannel channel, SocketReaction reaction)
{
await LogMe();
DbService db = _services.GetService(typeof(DbService)) as DbService;
IMessage m = message.HasValue ? message.Value : await channel.GetMessageAsync(message.Id);
if (reaction.Emote.Name == "👍")
{
if (reaction.User.Value != m.Author)
{
if (IsBlame(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, -1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} n'a pas aimé non plus !");
}
else if (IsReward(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, 1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} valide aussi !");
}
else
{
await db.UpdateScore(m.Author, 1);
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} fayotte envers {m.Author.Nick()}");
}
}
else
{
await db.UpdateScore(m.Author, -1);
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} voudrait s'auto-congratuler... Désolé, ce sera une punition !");
}
}
else if (reaction.Emote.Name == "👎")
{
if (reaction.User.Value != m.Author)
{
if (IsBlame(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, 1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} n'est pas d'accord !");
}
else if (IsReward(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, -1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} n'a pas apprécié, lui !");
}
else
{
await db.UpdateScore(m.Author, -1);
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} a quelque chose contre {m.Author.Nick()}");
}
}
else
{
await db.UpdateScore(m.Author, -1);
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} aime l'auto-flagellation...");
}
}
}
private async Task HandleReactionRemovedAsync(Cacheable<IUserMessage, ulong> message, ISocketMessageChannel channel, SocketReaction reaction)
{
await LogMe();
IUser userReaction = reaction.User.IsSpecified ? reaction.User.Value : await channel.GetUserAsync(reaction.UserId);
IMessage m = message.HasValue ? message.Value : await channel.GetMessageAsync(message.Id);
DbService db = _services.GetService(typeof(DbService)) as DbService;
if (reaction.Emote.Name == "👍")
{
if (userReaction != m.Author)
{
if (IsBlame(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, 1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} n'était pas vraiment pour la punition, en fait...");
}
else if (IsReward(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, -1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} n'approuve pas, finalement !");
}
else
{
await db.UpdateScore(m.Author, -1);
await channel.SendMessageAsync($"{userReaction.Nick()} n'assume pas sa gentillesse envers {m.Author.Nick()}");
}
}
else
{
await channel.SendMessageAsync($"{userReaction.Nick()} bien essayé, mais la punition est déjà tombée !");
}
}
else if (reaction.Emote.Name == "👎")
{
if (reaction.User.Value != m.Author)
{
if (IsBlame(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, -1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} ne désapprouve plus vraiment...");
}
else if (IsReward(m))
{
foreach (ulong id in m.MentionedUserIds)
{
IUser userMentionne = await channel.GetUserAsync(id);
await db.UpdateScore(userMentionne, 1);
}
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} a peut êre un peu apprécié, finalement...");
}
else
{
await db.UpdateScore(m.Author, 1);
await channel.SendMessageAsync($"{reaction.User.Value.Nick()} n'assume pas sa méchanceté contre {m.Author.Nick()}");
}
}
else
{
await channel.SendMessageAsync($"{userReaction.Nick()} trop tard pour réfléchir... Encore quelques coups de fouet ?");
}
}
}
#endregion Methods
}
}