diff --git a/.gitignore b/.gitignore index 4ce6fdd..800ef5b 100644 --- a/.gitignore +++ b/.gitignore @@ -337,4 +337,5 @@ ASALocalRun/ .localhistory/ # BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file +healthchecksdb +/Sean/Sean.db diff --git a/Sean/CommandHandler.cs b/Sean/CommandHandler.cs index 4a3872d..3fe317c 100644 --- a/Sean/CommandHandler.cs +++ b/Sean/CommandHandler.cs @@ -1,8 +1,13 @@ 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 @@ -31,6 +36,50 @@ namespace Sean _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 @@ -44,8 +93,118 @@ namespace Sean 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 arg1, ISocketMessageChannel arg2) => LogMe(); + + private Task _client_MessageUpdated(Cacheable arg1, SocketMessage arg2, ISocketMessageChannel arg3) => LogMe(); + + private Task _client_MessagesBulkDeleted(System.Collections.Generic.IReadOnlyCollection> arg1, ISocketMessageChannel arg2) => LogMe(); + private Task _client_MessageDeleted(Cacheable 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; @@ -79,13 +238,161 @@ namespace Sean // 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 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 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 } diff --git a/Sean/Migrations/20190529160453_InitialCreate.Designer.cs b/Sean/Migrations/20190529160453_InitialCreate.Designer.cs new file mode 100644 index 0000000..9ebd718 --- /dev/null +++ b/Sean/Migrations/20190529160453_InitialCreate.Designer.cs @@ -0,0 +1,38 @@ +// +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("UserId"); + + b.Property("Date"); + + b.Property("Name"); + + b.Property("Score"); + + b.HasKey("UserId", "Date"); + + b.ToTable("Scores"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sean/Migrations/20190529160453_InitialCreate.cs b/Sean/Migrations/20190529160453_InitialCreate.cs new file mode 100644 index 0000000..f28716f --- /dev/null +++ b/Sean/Migrations/20190529160453_InitialCreate.cs @@ -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(nullable: false), + Date = table.Column(nullable: false), + Score = table.Column(nullable: false), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Scores", x => new { x.UserId, x.Date }); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Scores"); + } + } +} diff --git a/Sean/Migrations/DbServiceModelSnapshot.cs b/Sean/Migrations/DbServiceModelSnapshot.cs new file mode 100644 index 0000000..b7be1e3 --- /dev/null +++ b/Sean/Migrations/DbServiceModelSnapshot.cs @@ -0,0 +1,36 @@ +// +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("UserId"); + + b.Property("Date"); + + b.Property("Name"); + + b.Property("Score"); + + b.HasKey("UserId", "Date"); + + b.ToTable("Scores"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sean/Models/ScoreUtilisateur.cs b/Sean/Models/ScoreUtilisateur.cs new file mode 100644 index 0000000..6471c3b --- /dev/null +++ b/Sean/Models/ScoreUtilisateur.cs @@ -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; } + } +} diff --git a/Sean/Modules/AwardsModule.cs b/Sean/Modules/AwardsModule.cs index c4e8c55..45265d1 100644 --- a/Sean/Modules/AwardsModule.cs +++ b/Sean/Modules/AwardsModule.cs @@ -1,41 +1,99 @@ -using Discord.Commands; +using Discord; +using Discord.Commands; using Discord.WebSocket; +using Microsoft.EntityFrameworkCore; +using Sean.Models; using Sean.Services; +using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace Sean.Modules { + [RequireContext(ContextType.Guild)] + public class AwardsModule : ModuleBase { #region Properties - public AwardsPersistencyService persistencyService { get; set; } + public DbService dbService { get; set; } #endregion Properties #region Methods [Command("blame")] [Summary("Blames the user and removes him one point")] [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; - int score = persistencyService.RemovePoint(user); - await ReplyAsync($"Nice job {userInfo.Username}#{userInfo.Discriminator}, your score is now {score}"); + await dbService.UpdateScore(user, -1); + if (user == Context.User) + await ReplyAsync($"{Context.User.Nick()} aime l'auto-flagellation..."); + else + await ReplyAsync($"{Context.User.Nick()} a quelque chose contre {user.Nick()}"); } [Command("board")] [Summary("Give the leader board")] [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")] [Summary("Greats the user and give him one point")] [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; - int score = persistencyService.AddPoint(user); - await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator} have now a score of {score}"); + if (user != Context.User) + { + 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 } diff --git a/Sean/Modules/DMModule.cs b/Sean/Modules/DMModule.cs new file mode 100644 index 0000000..8983629 --- /dev/null +++ b/Sean/Modules/DMModule.cs @@ -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 + { + #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 + } +} \ No newline at end of file diff --git a/Sean/Modules/PingModule.cs b/Sean/Modules/PingModule.cs index 751ea46..ad2d88e 100644 --- a/Sean/Modules/PingModule.cs +++ b/Sean/Modules/PingModule.cs @@ -1,4 +1,5 @@ -using Discord.Commands; +using Discord; +using Discord.Commands; using System.Threading.Tasks; namespace Sean.Modules @@ -9,6 +10,16 @@ namespace Sean.Modules [Command("ping")] [Summary("Ping 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 } } \ No newline at end of file diff --git a/Sean/Program.cs b/Sean/Program.cs index 47f51c2..6ad2514 100644 --- a/Sean/Program.cs +++ b/Sean/Program.cs @@ -3,6 +3,7 @@ using Discord.Commands; using Discord.WebSocket; using Microsoft.Extensions.DependencyInjection; using Sean.Services; +using Sentry; using System; using System.Threading.Tasks; @@ -24,7 +25,7 @@ namespace Sean .AddSingleton(client) .AddSingleton(commandService) .AddSingleton() - .AddSingleton() + .AddSingleton() .BuildServiceProvider(); public async Task MainAsync() { @@ -35,7 +36,7 @@ namespace Sean }; commandService = new CommandService(commandServiceConfig); - client = new DiscordSocketClient(); + client = new DiscordSocketClient(new DiscordSocketConfig { MessageCacheSize = 100, AlwaysDownloadUsers = true/*, LogLevel = LogSeverity.Debug */}); client.Log += Log; IServiceProvider provider = BuildServiceProvider(); @@ -46,11 +47,32 @@ namespace Sean await client.LoginAsync(TokenType.Bot, Environment.GetEnvironmentVariable("DiscordToken_Sean")); await client.StartAsync(); + client.Disconnected += Client_Disconnected; // Block this task until the program is closed. await Task.Delay(-1); } + + private Task Client_Disconnected(Exception arg) + { + Environment.Exit(0); + return Task.CompletedTask; + } + 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) { Console.WriteLine(msg.ToString()); diff --git a/Sean/Sean.csproj b/Sean/Sean.csproj index 7cf303f..9fef189 100644 --- a/Sean/Sean.csproj +++ b/Sean/Sean.csproj @@ -1,12 +1,22 @@ - + Exe - netcoreapp2.1 + netcoreapp2.2 + latest + + + + + + + + Never + diff --git a/Sean/Services/AwardsPersistencyService.cs b/Sean/Services/AwardsPersistencyService.cs deleted file mode 100644 index 7fab12a..0000000 --- a/Sean/Services/AwardsPersistencyService.cs +++ /dev/null @@ -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 scores = new Dictionary(); - #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 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 - } -} \ No newline at end of file diff --git a/Sean/Services/DbService.cs b/Sean/Services/DbService.cs new file mode 100644 index 0000000..cc47d74 --- /dev/null +++ b/Sean/Services/DbService.cs @@ -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 Scores { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite("Data Source=Sean.db"); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .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(); + } + + + } +} diff --git a/Sean/UserExtensions.cs b/Sean/UserExtensions.cs new file mode 100644 index 0000000..a67bc27 --- /dev/null +++ b/Sean/UserExtensions.cs @@ -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; + } + } +}