Ajout d'une base sqlite, gestion des réactions directes ou sur commandes blame/reward, ajout de tops sur périodes, ...
This commit is contained in:
parent
e75cb67fe7
commit
e97e40e7f3
1
.gitignore
vendored
1
.gitignore
vendored
@ -338,3 +338,4 @@ ASALocalRun/
|
|||||||
|
|
||||||
# BeatPulse healthcheck temp database
|
# BeatPulse healthcheck temp database
|
||||||
healthchecksdb
|
healthchecksdb
|
||||||
|
/Sean/Sean.db
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sean.Models;
|
||||||
|
using Sean.Services;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Sean
|
namespace Sean
|
||||||
@ -31,6 +36,50 @@ namespace Sean
|
|||||||
_client.MessageReceived += HandleCommandAsync;
|
_client.MessageReceived += HandleCommandAsync;
|
||||||
_client.ReactionAdded += HandleReactionAddedAsync;
|
_client.ReactionAdded += HandleReactionAddedAsync;
|
||||||
_client.ReactionRemoved += HandleReactionRemovedAsync;
|
_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
|
// Here we discover all of the command modules in the entry
|
||||||
// assembly and load them. Starting from Discord.NET 2.0, a
|
// assembly and load them. Starting from Discord.NET 2.0, a
|
||||||
@ -44,8 +93,118 @@ namespace Sean
|
|||||||
services: _services);
|
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)
|
private async Task HandleCommandAsync(SocketMessage messageParam)
|
||||||
{
|
{
|
||||||
|
await LogMe();
|
||||||
// Don't process the command if it was a system message
|
// Don't process the command if it was a system message
|
||||||
var message = messageParam as SocketUserMessage;
|
var message = messageParam as SocketUserMessage;
|
||||||
if (message == null) return;
|
if (message == null) return;
|
||||||
@ -79,13 +238,161 @@ namespace Sean
|
|||||||
// if (!result.IsSuccess)
|
// if (!result.IsSuccess)
|
||||||
// await context.Channel.SendMessageAsync(result.ErrorReason);
|
// 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)
|
private async Task HandleReactionAddedAsync(Cacheable<IUserMessage, ulong> message, ISocketMessageChannel channel, SocketReaction reaction)
|
||||||
{
|
{
|
||||||
await channel.SendMessageAsync($"Ajout de {reaction.Emote.Name}");
|
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)
|
private async Task HandleReactionRemovedAsync(Cacheable<IUserMessage, ulong> message, ISocketMessageChannel channel, SocketReaction reaction)
|
||||||
{
|
{
|
||||||
await channel.SendMessageAsync($"Retrait de {reaction.Emote.Name}");
|
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
|
#endregion Methods
|
||||||
}
|
}
|
||||||
|
38
Sean/Migrations/20190529160453_InitialCreate.Designer.cs
generated
Normal file
38
Sean/Migrations/20190529160453_InitialCreate.Designer.cs
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Sean.Services;
|
||||||
|
|
||||||
|
namespace Sean.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DbService))]
|
||||||
|
[Migration("20190529160453_InitialCreate")]
|
||||||
|
partial class InitialCreate
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sean.Models.ScoreUtilisateur", b =>
|
||||||
|
{
|
||||||
|
b.Property<ulong>("UserId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<int>("Score");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "Date");
|
||||||
|
|
||||||
|
b.ToTable("Scores");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
Sean/Migrations/20190529160453_InitialCreate.cs
Normal file
31
Sean/Migrations/20190529160453_InitialCreate.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Sean.Migrations
|
||||||
|
{
|
||||||
|
public partial class InitialCreate : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Scores",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<ulong>(nullable: false),
|
||||||
|
Date = table.Column<DateTime>(nullable: false),
|
||||||
|
Score = table.Column<int>(nullable: false),
|
||||||
|
Name = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Scores", x => new { x.UserId, x.Date });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Scores");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Sean/Migrations/DbServiceModelSnapshot.cs
Normal file
36
Sean/Migrations/DbServiceModelSnapshot.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Sean.Services;
|
||||||
|
|
||||||
|
namespace Sean.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DbService))]
|
||||||
|
partial class DbServiceModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sean.Models.ScoreUtilisateur", b =>
|
||||||
|
{
|
||||||
|
b.Property<ulong>("UserId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<int>("Score");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "Date");
|
||||||
|
|
||||||
|
b.ToTable("Scores");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
Sean/Models/ScoreUtilisateur.cs
Normal file
14
Sean/Models/ScoreUtilisateur.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Sean.Models
|
||||||
|
{
|
||||||
|
public class ScoreUtilisateur
|
||||||
|
{
|
||||||
|
public ulong UserId { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
public int Score { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,41 +1,99 @@
|
|||||||
using Discord.Commands;
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sean.Models;
|
||||||
using Sean.Services;
|
using Sean.Services;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Sean.Modules
|
namespace Sean.Modules
|
||||||
{
|
{
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
|
||||||
public class AwardsModule : ModuleBase<SocketCommandContext>
|
public class AwardsModule : ModuleBase<SocketCommandContext>
|
||||||
{
|
{
|
||||||
#region Properties
|
#region Properties
|
||||||
public AwardsPersistencyService persistencyService { get; set; }
|
public DbService dbService { get; set; }
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
[Command("blame")]
|
[Command("blame")]
|
||||||
[Summary("Blames the user and removes him one point")]
|
[Summary("Blames the user and removes him one point")]
|
||||||
[Alias("bash")]
|
[Alias("bash")]
|
||||||
public async Task BlameUserAsync([Summary("The user to blame")] SocketUser user)
|
public async Task BlameUserAsync([Summary("The user to blame")] SocketUser user, [Remainder]string commentaire = "")
|
||||||
{
|
{
|
||||||
var userInfo = user;
|
await dbService.UpdateScore(user, -1);
|
||||||
int score = persistencyService.RemovePoint(user);
|
if (user == Context.User)
|
||||||
await ReplyAsync($"Nice job {userInfo.Username}#{userInfo.Discriminator}, your score is now {score}");
|
await ReplyAsync($"{Context.User.Nick()} aime l'auto-flagellation...");
|
||||||
|
else
|
||||||
|
await ReplyAsync($"{Context.User.Nick()} a quelque chose contre {user.Nick()}");
|
||||||
}
|
}
|
||||||
[Command("board")]
|
[Command("board")]
|
||||||
[Summary("Give the leader board")]
|
[Summary("Give the leader board")]
|
||||||
[Alias("top")]
|
[Alias("top")]
|
||||||
public async Task BoardAsync()
|
public async Task BoardAsync([Remainder] string portee = "")
|
||||||
{
|
{
|
||||||
await ReplyAsync(persistencyService.LeaderBoard());
|
string duree = string.Empty;
|
||||||
|
DateTime depuis;
|
||||||
|
switch (portee)
|
||||||
|
{
|
||||||
|
case "week": duree = "de la semaine"; depuis = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek); break;
|
||||||
|
case "month": duree = "du mois"; depuis = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); break;
|
||||||
|
case "year": duree = "de l'année"; depuis = new DateTime(DateTime.Now.Year, 1, 1); break;
|
||||||
|
case "ever": duree = "de tous les temps"; depuis = DateTime.MinValue; break;
|
||||||
|
default: duree = "du jour"; depuis = DateTime.Today; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmbedBuilder builder = new EmbedBuilder
|
||||||
|
{
|
||||||
|
Title = $"Le top des nazes {duree} !",
|
||||||
|
ThumbnailUrl = "https://icon-icons.com/descargaimagen.php?id=62269&root=716/PNG/512/&file=Cup_icon-icons.com_62269.png"
|
||||||
|
};
|
||||||
|
builder.Footer = new EmbedFooterBuilder { Text = "Allez, au boulot, on peut encore faire pire !" };
|
||||||
|
int place = 1;
|
||||||
|
var liste = await dbService.Scores.Where(s => s.Date >= depuis).GroupBy(s => s.Score).OrderByDescending(s => s.Key).ToListAsync();
|
||||||
|
foreach (var groupe in liste)
|
||||||
|
{
|
||||||
|
string nom = string.Empty;
|
||||||
|
if (place == 1) nom += ":first_place: ";
|
||||||
|
else if (place == 2) nom += ":second_place: ";
|
||||||
|
else if (place == 3) nom += ":third_place: ";
|
||||||
|
else if (place == liste.Count) nom += ":poop: ";
|
||||||
|
|
||||||
|
nom += string.Join(", ", groupe.Select(g => g.Name));
|
||||||
|
builder.AddField(nom, groupe.Key, true);
|
||||||
|
place++;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ReplyAsync(embed: builder.Build());
|
||||||
|
}
|
||||||
|
|
||||||
[Command("great")]
|
[Command("great")]
|
||||||
[Summary("Greats the user and give him one point")]
|
[Summary("Greats the user and give him one point")]
|
||||||
[Alias("reward")]
|
[Alias("reward")]
|
||||||
public async Task GreatUserAsync([Summary("The user to great")] SocketUser user)
|
public async Task GreatUserAsync([Summary("The user to great")] SocketUser user, [Remainder]string commentaire = "")
|
||||||
{
|
{
|
||||||
var userInfo = user;
|
if (user != Context.User)
|
||||||
int score = persistencyService.AddPoint(user);
|
{
|
||||||
await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator} have now a score of {score}");
|
await dbService.UpdateScore(user, 1);
|
||||||
|
await ReplyAsync($"{Context.User.Nick()} fayotte envers {user.Nick()}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await dbService.UpdateScore(user, -1);
|
||||||
|
await ReplyAsync($"{Context.User.Nick()} voudrait s'auto-congratuler... Désolé, ce sera une punition !");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[Command("help")]
|
||||||
|
[Summary("Help !")]
|
||||||
|
public async Task HelpAsync()
|
||||||
|
{
|
||||||
|
IDMChannel channel = await Context.User.GetOrCreateDMChannelAsync();
|
||||||
|
await channel.SendMessageAsync($"D'après le site wikipedia.fr, Help! est une chanson des Beatles parue en single en juillet 1965, puis utilisée comme chanson-titre de leur cinquième album et du film dont ils sont les vedettes... Oh, tu m'as pris pour l'assistant Google ?");
|
||||||
}
|
}
|
||||||
#endregion Methods
|
#endregion Methods
|
||||||
}
|
}
|
||||||
|
37
Sean/Modules/DMModule.cs
Normal file
37
Sean/Modules/DMModule.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
using Sean.Services;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sean.Modules
|
||||||
|
{
|
||||||
|
[RequireContext(ContextType.DM)]
|
||||||
|
|
||||||
|
public class DMModule : ModuleBase<SocketCommandContext>
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
[Command("echo")]
|
||||||
|
[Summary("Echoes parameter")]
|
||||||
|
[Alias("say")]
|
||||||
|
public async Task EchoAsync([Summary("The text to echo")] [Remainder]string text)
|
||||||
|
{
|
||||||
|
await ReplyAsync(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("exit")]
|
||||||
|
[Summary("Quit")]
|
||||||
|
[Alias("quit")]
|
||||||
|
public async Task ExitAsync()
|
||||||
|
{
|
||||||
|
foreach (SocketGuild guild in Context.Client.Guilds)
|
||||||
|
{
|
||||||
|
await guild.DefaultChannel.SendMessageAsync("Ciao les nazes !");
|
||||||
|
}
|
||||||
|
await Context.Client.StopAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Methods
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using Discord.Commands;
|
using Discord;
|
||||||
|
using Discord.Commands;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Sean.Modules
|
namespace Sean.Modules
|
||||||
@ -9,6 +10,16 @@ namespace Sean.Modules
|
|||||||
[Command("ping")]
|
[Command("ping")]
|
||||||
[Summary("Ping pong !")]
|
[Summary("Ping pong !")]
|
||||||
public Task PongAsync() => ReplyAsync("Pong !");
|
public Task PongAsync() => ReplyAsync("Pong !");
|
||||||
|
|
||||||
|
[Command("hey")]
|
||||||
|
[Summary("Asks for a private channel with the bot")]
|
||||||
|
[Alias("listen")]
|
||||||
|
public async Task HeyAsync()
|
||||||
|
{
|
||||||
|
IDMChannel channel = await Context.User.GetOrCreateDMChannelAsync();
|
||||||
|
await channel.SendMessageAsync("Your command, master ?");
|
||||||
|
await ReplyAsync("Jude !");
|
||||||
|
}
|
||||||
#endregion Methods
|
#endregion Methods
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ using Discord.Commands;
|
|||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Sean.Services;
|
using Sean.Services;
|
||||||
|
using Sentry;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ namespace Sean
|
|||||||
.AddSingleton(client)
|
.AddSingleton(client)
|
||||||
.AddSingleton(commandService)
|
.AddSingleton(commandService)
|
||||||
.AddSingleton<CommandHandler>()
|
.AddSingleton<CommandHandler>()
|
||||||
.AddSingleton<AwardsPersistencyService>()
|
.AddSingleton<DbService>()
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
public async Task MainAsync()
|
public async Task MainAsync()
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ namespace Sean
|
|||||||
};
|
};
|
||||||
|
|
||||||
commandService = new CommandService(commandServiceConfig);
|
commandService = new CommandService(commandServiceConfig);
|
||||||
client = new DiscordSocketClient();
|
client = new DiscordSocketClient(new DiscordSocketConfig { MessageCacheSize = 100, AlwaysDownloadUsers = true/*, LogLevel = LogSeverity.Debug */});
|
||||||
client.Log += Log;
|
client.Log += Log;
|
||||||
|
|
||||||
IServiceProvider provider = BuildServiceProvider();
|
IServiceProvider provider = BuildServiceProvider();
|
||||||
@ -46,11 +47,32 @@ namespace Sean
|
|||||||
await client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken_Sean"));
|
await client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken_Sean"));
|
||||||
await client.StartAsync();
|
await client.StartAsync();
|
||||||
|
|
||||||
|
client.Disconnected += Client_Disconnected;
|
||||||
// Block this task until the program is closed.
|
// Block this task until the program is closed.
|
||||||
await Task.Delay(-1);
|
await Task.Delay(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task Client_Disconnected(Exception arg)
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
=> new Program().MainAsync().GetAwaiter().GetResult();
|
{
|
||||||
|
using (SentrySdk.Init(Environment.GetEnvironmentVariable("SentryURL_Sean")))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
new Program().MainAsync().GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
SentrySdk.CaptureException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Task Log(LogMessage msg)
|
private Task Log(LogMessage msg)
|
||||||
{
|
{
|
||||||
Console.WriteLine(msg.ToString());
|
Console.WriteLine(msg.ToString());
|
||||||
|
@ -1,12 +1,22 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="2.1.0" />
|
<PackageReference Include="Discord.Net" Version="2.1.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.4" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
|
||||||
|
<PackageReference Include="Sentry" Version="1.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Sean.db">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
using Discord;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Sean.Services
|
|
||||||
{
|
|
||||||
public class AwardsPersistencyService
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
private Dictionary<string, int> scores = new Dictionary<string, int>();
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public int AddPoint(IUser user)
|
|
||||||
{
|
|
||||||
if (!scores.ContainsKey($"{user.Username}#{user.Discriminator}"))
|
|
||||||
scores.Add($"{user.Username}#{user.Discriminator}", 1);
|
|
||||||
else
|
|
||||||
scores[$"{user.Username}#{user.Discriminator}"]++;
|
|
||||||
return scores[$"{user.Username}#{user.Discriminator}"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LeaderBoard()
|
|
||||||
{
|
|
||||||
string board = string.Empty;
|
|
||||||
foreach (KeyValuePair<string, int> score in scores.OrderByDescending(s => s.Value))
|
|
||||||
{
|
|
||||||
board += $@"{score.Key} => {score.Value}" + Environment.NewLine;
|
|
||||||
}
|
|
||||||
return board;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RemovePoint(IUser user)
|
|
||||||
{
|
|
||||||
if (!scores.ContainsKey($"{user.Username}#{user.Discriminator}"))
|
|
||||||
scores.Add($"{user.Username}#{user.Discriminator}", -1);
|
|
||||||
else
|
|
||||||
scores[$"{user.Username}#{user.Discriminator}"]--;
|
|
||||||
return scores[$"{user.Username}#{user.Discriminator}"];
|
|
||||||
}
|
|
||||||
#endregion Methods
|
|
||||||
}
|
|
||||||
}
|
|
42
Sean/Services/DbService.cs
Normal file
42
Sean/Services/DbService.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Discord;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sean.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sean.Services
|
||||||
|
{
|
||||||
|
public class DbService : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<ScoreUtilisateur> Scores { get; set; }
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseSqlite("Data Source=Sean.db");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<ScoreUtilisateur>()
|
||||||
|
.HasKey(o => new { o.UserId, o.Date });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateScore(IUser user, int change)
|
||||||
|
{
|
||||||
|
ScoreUtilisateur score = await Scores.SingleOrDefaultAsync(s => s.UserId == user.Id && s.Date == DateTime.Today);
|
||||||
|
if (score == default)
|
||||||
|
{
|
||||||
|
score = new ScoreUtilisateur { UserId = user.Id, Date = DateTime.Today, Score = change, Name = user.Nick() };
|
||||||
|
await Scores.AddAsync(score);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
score.Score += change;
|
||||||
|
|
||||||
|
await SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
17
Sean/UserExtensions.cs
Normal file
17
Sean/UserExtensions.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Discord;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Sean
|
||||||
|
{
|
||||||
|
public static class UserExtensions
|
||||||
|
{
|
||||||
|
public static string Nick(this IUser user) {
|
||||||
|
if (user is IGuildUser gu)
|
||||||
|
return gu.Nickname ?? gu.Username;
|
||||||
|
else
|
||||||
|
return user.Username;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user