From 85450824a61ea09b77e497eaeaf57544e2a7ed97 Mon Sep 17 00:00:00 2001 From: Samuele Lorefice Date: Tue, 7 Nov 2023 04:34:04 +0100 Subject: [PATCH] Implemented database basic functions, added ToFormattedString to Card class, improved commands sending to the guild manager on discord, added toString to user class --- Card.cs | 15 +++++-- DbManager.cs | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++- Program.cs | 73 +++++++++++++++++++++++++++++----- User.cs | 16 +++++++- 4 files changed, 197 insertions(+), 17 deletions(-) diff --git a/Card.cs b/Card.cs index be4f28a..0a12f5d 100644 --- a/Card.cs +++ b/Card.cs @@ -13,8 +13,16 @@ public class Card { public int CurrentHealth { get; set; } public User Owner { get; set; } - public override string ToString() { - return $"{Name} ATK: {Attack} DEF: {Defense} HP: {CurrentHealth}/{MaxHealth}"; + + public override string ToString() => $"{Name} - Atk {Attack} Def {Defense} HP {CurrentHealth}/{MaxHealth}"; + + public string ToFormattedString() { + var cardStr = $"**{Name}**\n" + + $"**Class:** *COMING SOON*\n"+ + $"**ATK:** {Attack}\n" + + $"**DEF:** {Defense}\n" + + $"**HP:** {CurrentHealth}/{MaxHealth}\n"; + return cardStr; } public Card(string name, int attack, int defense, int maxHealth) { @@ -24,5 +32,4 @@ public class Card { MaxHealth = maxHealth; CurrentHealth = maxHealth; } -} - +} \ No newline at end of file diff --git a/DbManager.cs b/DbManager.cs index a3a688d..828e428 100644 --- a/DbManager.cs +++ b/DbManager.cs @@ -16,7 +16,113 @@ public class DbManager : DbContext { dbpath = fullPath; } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder.UseSqlite($"Data Source={dbpath}"); + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlite($"Data Source={dbpath}"); + #region Players Functions + + public List GetAllPlayers() => Players.ToList(); + public User? GetPlayerById(ulong id) => Players.Find(id); + + public void AddPlayer(User player) { + Players.Add(player); + SaveChanges(); + } + + public void RemovePlayer(User player) { + Players.Remove(player); + SaveChanges(); + } + + public void UpdatePlayer(User player) { + Players.Update(player); + SaveChanges(); + } + #endregion + + #region Cards Functions + public List GetAllCards() => Cards.ToList(); + public Card? GetCardById(int id) => Cards.Find(id); + + public void AddCard(Card card) { + Cards.Add(card); + SaveChanges(); + } + + public void RemoveCard(Card card) { + Cards.Remove(card); + SaveChanges(); + } + + public void UpdateCard(Card card) { + Cards.Update(card); + SaveChanges(); + } + + public List GetCardsByPlayerId(ulong id) => Cards.Where(card => card.Owner.Id == id).ToList(); + public List GetCardsByPlayer(User player) => Cards.Where(card => card.Owner == player).ToList(); + public List GetCardsByPlayerId(ulong id, int limit) => Cards.Where(card => card.Owner.Id == id).Take(limit).ToList(); + public List GetCardsByPlayer(User player, int limit) => Cards.Where(card => card.Owner == player).Take(limit).ToList(); + public List GetCardsByPlayerId(ulong id, int limit, int offset) => Cards.Where(card => card.Owner.Id == id).Skip(offset).Take(limit).ToList(); + public List GetCardsByPlayer(User player, int limit, int offset) => Cards.Where(card => card.Owner == player).Skip(offset).Take(limit).ToList(); + //probably gonna add extra options filtered by card class or something like that in the future + + #endregion + + #region Matches Functions + public IEnumerable GetAllMatches() => Matches; + + public Match? GetMatchById(int id) => Matches.Find(id); + + public void AddMatch(Match match) { + Matches.Add(match); + SaveChanges(); + } + + public void RemoveMatch(Match match) { + Matches.Remove(match); + SaveChanges(); + } + + public void UpdateMatch(Match match) { + Matches.Update(match); + SaveChanges(); + } + + //By player + public List GetMatchesByPlayerId(ulong id) => Matches.Where(match => match.PlayerA.Id == id || match.PlayerB.Id == id).ToList(); + public List GetMatchesByPlayer(User player) => Matches.Where(match => match.PlayerA == player || match.PlayerB == player).ToList(); + public List GetMatchesByPlayerId(ulong id, int limit) => Matches.Where(match => match.PlayerA.Id == id || match.PlayerB.Id == id).Take(limit).ToList(); + public List GetMatchesByPlayer(User player, int limit) => Matches.Where(match => match.PlayerA == player || match.PlayerB == player).Take(limit).ToList(); + public List GetMatchesByPlayerId(ulong id, int limit, int offset) => Matches.Where(match => match.PlayerA.Id == id || match.PlayerB.Id == id).Skip(offset).Take(limit).ToList(); + public List GetMatchesByPlayer(User player, int limit, int offset) => Matches.Where(match => match.PlayerA == player || match.PlayerB == player).Skip(offset).Take(limit).ToList(); + + //By status + public List GetMatchesByStatus(EStatus status) => Matches.Where(match => match.Status == status).ToList(); + public List GetMatchesByStatus(EStatus status, int limit) => Matches.Where(match => match.Status == status).Take(limit).ToList(); + public List GetMatchesByStatus(EStatus status, int limit, int offset) => Matches.Where(match => match.Status == status).Skip(offset).Take(limit).ToList(); + + //By card + public List GetMatchesByCardId(int id)=> Matches.Where(match => match.PlayerACard.Id == id || match.PlayerBCard.Id == id).ToList(); + public List GetMatchesByCard(Card card) => Matches.Where(match => match.PlayerACard == card || match.PlayerBCard == card).ToList(); + public List GetMatchesByCardId(int id, int limit) => Matches.Where(match => match.PlayerACard.Id == id || match.PlayerBCard.Id == id).Take(limit).ToList(); + public List GetMatchesByCard(Card card, int limit) => Matches.Where(match => match.PlayerACard == card || match.PlayerBCard == card).Take(limit).ToList(); + public List GetMatchesByCardId(int id, int limit, int offset) => Matches.Where(match => match.PlayerACard.Id == id || match.PlayerBCard.Id == id).Skip(offset).Take(limit).ToList(); + public List GetMatchesByCard(Card card, int limit, int offset) => Matches.Where(match => match.PlayerACard == card || match.PlayerBCard == card).Skip(offset).Take(limit).ToList(); + + //By player and status + public List GetMatchesByStatusAndPlayerId(EStatus status, ulong id) => Matches.Where(match => match.Status == status && (match.PlayerA.Id == id || match.PlayerB.Id == id)).ToList(); + public List GetMatchesByStatusAndPlayer(EStatus status, User player) => Matches.Where(match => match.Status == status && (match.PlayerA == player || match.PlayerB == player)).ToList(); + public List GetMatchesByStatusAndPlayerId(EStatus status, ulong id, int limit) => Matches.Where(match => match.Status == status && (match.PlayerA.Id == id || match.PlayerB.Id == id)).Take(limit).ToList(); + public List GetMatchesByStatusAndPlayer(EStatus status, User player, int limit) => Matches.Where(match => match.Status == status && (match.PlayerA == player || match.PlayerB == player)).Take(limit).ToList(); + public List GetMatchesByStatusAndPlayerId(EStatus status, ulong id, int limit, int offset) => Matches.Where(match => match.Status == status && (match.PlayerA.Id == id || match.PlayerB.Id == id)).Skip(offset).Take(limit).ToList(); + public List GetMatchesByStatusAndPlayer(EStatus status, User player, int limit, int offset) => Matches.Where(match => match.Status == status && (match.PlayerA == player || match.PlayerB == player)).Skip(offset).Take(limit).ToList(); + + //By card and status + public List GetMatchesByCardIdAndStatus(int id, EStatus status) => Matches.Where(match => match.Status == status && (match.PlayerACard.Id == id || match.PlayerBCard.Id == id)).ToList(); + public List GetMatchesByCardAndStatus(Card card, EStatus status) => Matches.Where(match => match.Status == status && (match.PlayerACard == card || match.PlayerBCard == card)).ToList(); + public List GetMatchesByCardIdAndStatus(int id, EStatus status, int limit) => Matches.Where(match => match.Status == status && (match.PlayerACard.Id == id || match.PlayerBCard.Id == id)).Take(limit).ToList(); + public List GetMatchesByCardAndStatus(Card card, EStatus status, int limit) => Matches.Where(match => match.Status == status && (match.PlayerACard == card || match.PlayerBCard == card)).Take(limit).ToList(); + public List GetMatchesByCardIdAndStatus(int id, EStatus status, int limit, int offset) => Matches.Where(match => match.Status == status && (match.PlayerACard.Id == id || match.PlayerBCard.Id == id)).Skip(offset).Take(limit).ToList(); + public List GetMatchesByCardAndStatus(Card card, EStatus status, int limit, int offset) => Matches.Where(match => match.Status == status && (match.PlayerACard == card || match.PlayerBCard == card)).Skip(offset).Take(limit).ToList(); + #endregion } \ No newline at end of file diff --git a/Program.cs b/Program.cs index 0f85e26..eb4aac1 100644 --- a/Program.cs +++ b/Program.cs @@ -8,7 +8,8 @@ namespace IsleBot; public class IsleBot { private Config config; private DiscordSocketClient client; - Random rng = new Random(); + Random rng = new(); + private DbManager db = new(); public static Task Main(string[] args) { var config = JsonConvert.DeserializeObject(File.ReadAllText("Config.json")); @@ -26,10 +27,12 @@ public class IsleBot { ); client.Log += Log; + client.Connected += () => { Console.WriteLine("Connection Estabilished"); return Task.CompletedTask; }; + client.Disconnected += (e) => { Console.WriteLine("Connection Lost"); return Task.CompletedTask; @@ -48,18 +51,43 @@ public class IsleBot { private async Task Client_OnReady() { client.Guilds.ToList().ForEach(guild => { - var guildGetCard = new SlashCommandBuilder() - .WithName("get-card") - .WithDescription("Get/Replace your current card"); + // Guild Commands + List guildCommands = new(); - var attackCommand = new SlashCommandBuilder() + guildCommands.Add(new SlashCommandBuilder() + .WithName("register-player") + .WithDescription("Register yourself as a player") + .Build()); + + guildCommands.Add(new SlashCommandBuilder() + .WithName("profile") + .WithDescription("See your profile") + .Build()); + + guildCommands.Add(new SlashCommandBuilder() + .WithName("get-card") + .WithDescription("Get/Replace your current card") + .Build()); + + guildCommands.Add(new SlashCommandBuilder() .WithName("attack") .WithDescription("Attack a player") - .AddOption("target", ApplicationCommandOptionType.User, "The target of the attack"); + .AddOption("target", ApplicationCommandOptionType.User, "The target of the attack") + .Build()); try { - guild.CreateApplicationCommandAsync(guildGetCard.Build()); - guild.CreateApplicationCommandAsync(attackCommand.Build()); + var commands = guild.GetApplicationCommandsAsync().Result.ToList(); + /* + guildCommands.ForEach(command => { + //if the command already exists and is duplicated + if(commands.FindAll(oldCommand => oldCommand.Name == (string)command.Name)?.Count > 1) { + guild.DeleteApplicationCommandsAsync(); //delete all commands + //else if the command doesn't already exists + }else if(commands.Find(oldCommand => oldCommand.Name == (string)command.Name) == null) { + guild.CreateApplicationCommandAsync(command); //create it + }//otherise, do nothing. + });*/ + guild.BulkOverwriteApplicationCommandAsync(guildCommands.ToArray()); } catch (HttpException exception) { var json = JsonConvert.SerializeObject(exception.Errors, Formatting.Indented); Console.WriteLine(json); @@ -69,9 +97,32 @@ public class IsleBot { private async Task SlashCommandHandler(SocketSlashCommand command) { switch (command.Data.Name) { + case "register-player": + if (db.GetPlayerById(command.User.Id) == null) { + var user = new User(command.User.Id, command.User.GlobalName); + db.AddPlayer(user); + await command.RespondAsync("You are now registered. In future you will also be able to see your profile page."); + } else { + await command.RespondAsync("You are already registered. In future you will also be able to see your profile page."); + } + break; + case "profile": + if(CheckIfPlayerExists(command.User.Id) == false) { + await command.RespondAsync("You are not registered. Use /register-player to register yourself."); + } else { + await command.RespondAsync(db.GetPlayerById(command.User.Id)!.ToString()); + } + break; case "get-card": var card = GenerateCard(); - await command.RespondAsync("You got a new card!\n " + card); + if (CheckIfPlayerExists(command.User.Id) == false) { + await command.RespondAsync("You are not registered. Use /register-player to register yourself."); + } else { + var player = db.GetPlayerById(command.User.Id)!; + player.Cards.Add(card); + db.UpdatePlayer(player); + await command.RespondAsync($"You got a new card: \n{card.ToFormattedString()}"); + } break; case "attack": var target = command.Data.Options.First().Value as SocketUser; @@ -80,6 +131,10 @@ public class IsleBot { } } + private bool CheckIfPlayerExists(ulong id) { + return db.GetPlayerById(id) != null; + } + private Card GenerateCard() { var card = new Card($"Test Card N. {rng.Next(0, 1000)}", rng.Next(1, 20), rng.Next(0, 10), diff --git a/User.cs b/User.cs index 8a04590..d272261 100644 --- a/User.cs +++ b/User.cs @@ -4,16 +4,28 @@ namespace IsleBot; public class User { [DataMember(IsRequired = true)] - public int Id { get; private set; } + public ulong Id { get; private set; } public string UserName { get; set; } public List Cards { get; set; } //public List Matches { get; set; } - public User(int id, string userName) { + public User(ulong id, string userName) { Id = id; UserName = userName; Cards = new List(); } + + public override string ToString() { + var profileStr = $"**{UserName}**\n"+ + $"**Total Cards:** {Cards.Count}\n" + + $"\n"; + + foreach (var card in Cards.Take(5)) { + profileStr += card.ToFormattedString() + "\n"; + } + + return profileStr; + } } \ No newline at end of file