399 lines
17 KiB
C#
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
|
|
}
|
|
} |