Port the karma commands to / commands

This commit is contained in:
Daan Boerlage 2021-11-06 19:08:42 +01:00
parent 6d39c2d33f
commit 4395d9e9dd
Signed by: daan
GPG key ID: FCE070E1E4956606
9 changed files with 384 additions and 146 deletions

View file

@ -0,0 +1,76 @@
using System;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Geekbot.Commands.Karma;
using Geekbot.Core;
using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
namespace Geekbot.Bot.Commands.User
{
[DisableInDirectMessage]
public class Karma : GeekbotCommandBase
{
private readonly DatabaseContext _database;
public Karma(DatabaseContext database, IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager)
{
_database = database;
}
[Command("good", RunMode = RunMode.Async)]
[Summary("Increase Someones Karma")]
public async Task Good([Summary("@someone")] IUser user)
{
await ChangeKarma(user, KarmaChange.Up);
}
[Command("bad", RunMode = RunMode.Async)]
[Summary("Decrease Someones Karma")]
public async Task Bad([Summary("@someone")] IUser user)
{
await ChangeKarma(user, KarmaChange.Down);
}
[Command("neutral", RunMode = RunMode.Async)]
[Summary("Do nothing to someones Karma")]
public async Task Neutral([Summary("@someone")] IUser user)
{
await ChangeKarma(user, KarmaChange.Same);
}
private async Task ChangeKarma(IUser user, KarmaChange change)
{
try
{
var author = new Core.Interactions.Resolved.User()
{
Id = Context.User.Id.ToString(),
Username = Context.User.Username,
Discriminator = Context.User.Discriminator,
Avatar = Context.User.AvatarId,
};
var targetUser = new Core.Interactions.Resolved.User()
{
Id = user.Id.ToString(),
Username = user.Username,
Discriminator = user.Discriminator,
Avatar = user.AvatarId,
};
var karma = new Geekbot.Commands.Karma.Karma(_database, Context.Guild.Id.AsLong());
var res = await karma.ChangeKarma(author, targetUser, change);
await ReplyAsync(string.Empty, false, res.ToDiscordNetEmbed().Build());
}
catch (Exception e)
{
await ErrorHandler.HandleCommandException(e, Context);
}
}
}
}

View file

@ -1,137 +0,0 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Geekbot.Core;
using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.User.Karma
{
[DisableInDirectMessage]
public class Karma : GeekbotCommandBase
{
private readonly DatabaseContext _database;
public Karma(DatabaseContext database, IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager)
{
_database = database;
}
[Command("good", RunMode = RunMode.Async)]
[Summary("Increase Someones Karma")]
public async Task Good([Summary("@someone")] IUser user)
{
await ChangeKarma(user, KarmaChange.Up);
}
[Command("bad", RunMode = RunMode.Async)]
[Summary("Decrease Someones Karma")]
public async Task Bad([Summary("@someone")] IUser user)
{
await ChangeKarma(user, KarmaChange.Down);
}
[Command("neutral", RunMode = RunMode.Async)]
[Summary("Do nothing to someones Karma")]
public async Task Neutral([Summary("@someone")] IUser user)
{
await ChangeKarma(user, KarmaChange.Same);
}
private async Task ChangeKarma(IUser user, KarmaChange change)
{
try
{
// Get the user
var actor = await GetUser(Context.User.Id);
// Check if the user can change karma
if (user.Id == Context.User.Id)
{
var message = change switch
{
KarmaChange.Up => Localization.Karma.CannotChangeOwnUp,
KarmaChange.Same => Localization.Karma.CannotChangeOwnSame,
KarmaChange.Down => Localization.Karma.CannotChangeOwnDown,
_ => throw new ArgumentOutOfRangeException(nameof(change), change, null)
};
await ReplyAsync(string.Format(message, Context.User.Username));
return;
}
if (actor.TimeOut.AddMinutes(3) > DateTimeOffset.Now)
{
var formatedWaitTime = DateLocalization.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3));
await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime));
return;
}
// Get the values for the change direction
var (title, amount) = change switch
{
KarmaChange.Up => (Localization.Karma.Increased, 1),
KarmaChange.Same => (Localization.Karma.Neutral, 0),
KarmaChange.Down => (Localization.Karma.Decreased, -1),
_ => throw new ArgumentOutOfRangeException(nameof(change), change, null)
};
// Change it
var target = await GetUser(user.Id);
target.Karma += amount;
_database.Karma.Update(target);
actor.TimeOut = DateTimeOffset.Now;
_database.Karma.Update(actor);
await _database.SaveChangesAsync();
// Respond
var eb = new EmbedBuilder()
{
Author = new EmbedAuthorBuilder()
{
Name = user.Username,
IconUrl = user.GetAvatarUrl()
},
Title = title,
Color = new Color(138, 219, 146)
};
eb.AddInlineField(Localization.Karma.By, Context.User.Username);
eb.AddInlineField(Localization.Karma.Amount, amount.ToString());
eb.AddInlineField(Localization.Karma.Current, target.Karma.ToString());
await ReplyAsync("", false, eb.Build());
}
catch (Exception e)
{
await ErrorHandler.HandleCommandException(e, Context);
}
}
private async Task<KarmaModel> GetUser(ulong userId)
{
var user = _database.Karma.FirstOrDefault(u => u.GuildId.Equals(Context.Guild.Id.AsLong()) && u.UserId.Equals(userId.AsLong())) ?? await CreateNewRow(userId);
return user;
}
private async Task<KarmaModel> CreateNewRow(ulong userId)
{
var user = new KarmaModel()
{
GuildId = Context.Guild.Id.AsLong(),
UserId = userId.AsLong(),
Karma = 0,
TimeOut = DateTimeOffset.MinValue
};
var newUser = _database.Karma.Add(user).Entity;
await _database.SaveChangesAsync();
return newUser;
}
}
}

View file

@ -1,9 +0,0 @@
namespace Geekbot.Bot.Commands.User.Karma
{
public enum KarmaChange
{
Up,
Same,
Down
}
}

111
src/Commands/Karma/Karma.cs Normal file
View file

@ -0,0 +1,111 @@
using System.Drawing;
using Geekbot.Core;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.Interactions.Embed;
using Geekbot.Core.Interactions.Resolved;
using Localization = Geekbot.Core.Localization;
namespace Geekbot.Commands.Karma;
public class Karma
{
private readonly DatabaseContext _database;
private readonly long _guildId;
public Karma(DatabaseContext database, long guildId)
{
_database = database;
_guildId = guildId;
}
public async Task<Embed> ChangeKarma(User author, User targetUser, KarmaChange change)
{
// Get the user
var authorRecord = await GetUser(long.Parse(author.Id));
// Check if the user can change karma
if (targetUser == author)
{
var message = change switch
{
KarmaChange.Up => Localization.Karma.CannotChangeOwnUp,
KarmaChange.Same => Localization.Karma.CannotChangeOwnSame,
KarmaChange.Down => Localization.Karma.CannotChangeOwnDown,
_ => throw new ArgumentOutOfRangeException(nameof(change), change, null)
};
return CreateErrorEmbed(string.Format(message, author.Username));
}
if (authorRecord.TimeOut.AddMinutes(3) > DateTimeOffset.Now)
{
var formatedWaitTime = DateLocalization.FormatDateTimeAsRemaining(authorRecord.TimeOut.AddMinutes(3));
return CreateErrorEmbed(string.Format(Localization.Karma.WaitUntill, author.Username, formatedWaitTime));
}
// Get the values for the change direction
var (title, amount) = change switch
{
KarmaChange.Up => (Localization.Karma.Increased, 1),
KarmaChange.Same => (Localization.Karma.Neutral, 0),
KarmaChange.Down => (Localization.Karma.Decreased, -1),
_ => throw new ArgumentOutOfRangeException(nameof(change), change, null)
};
// Change it
var targetUserRecord = await GetUser(long.Parse(targetUser.Id));
targetUserRecord.Karma += amount;
_database.Karma.Update(targetUserRecord);
authorRecord.TimeOut = DateTimeOffset.Now;
_database.Karma.Update(authorRecord);
await _database.SaveChangesAsync();
// Respond
var eb = new Embed()
{
Author = new ()
{
Name = targetUser.Username,
IconUrl = targetUser.GetAvatarUrl()
},
Title = title,
};
eb.SetColor(Color.PaleGreen);
eb.AddInlineField(Localization.Karma.By, author.Username);
eb.AddInlineField(Localization.Karma.Amount, amount.ToString());
eb.AddInlineField(Localization.Karma.Current, targetUserRecord.Karma.ToString());
return eb;
}
private Embed CreateErrorEmbed(string errorMessage)
{
var eb = new Embed()
{
Description = errorMessage
};
eb.SetColor(Color.Red);
return eb;
}
private async Task<KarmaModel> GetUser(long userId)
{
var user = _database.Karma.FirstOrDefault(u => u.GuildId.Equals(_guildId) && u.UserId.Equals(userId)) ?? await CreateNewRow(userId);
return user;
}
private async Task<KarmaModel> CreateNewRow(long userId)
{
var user = new KarmaModel()
{
GuildId = _guildId,
UserId = userId,
Karma = 0,
TimeOut = DateTimeOffset.MinValue
};
var newUser = _database.Karma.Add(user).Entity;
await _database.SaveChangesAsync();
return newUser;
}
}

View file

@ -0,0 +1,8 @@
namespace Geekbot.Commands.Karma;
public enum KarmaChange
{
Up,
Same,
Down
}

78
src/Web/Commands/Karma.cs Normal file
View file

@ -0,0 +1,78 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Geekbot.Commands.Karma;
using Geekbot.Core.Database;
using Geekbot.Core.Interactions;
using Geekbot.Core.Interactions.ApplicationCommand;
using Geekbot.Core.Interactions.Request;
using Geekbot.Core.Interactions.Response;
namespace Geekbot.Web.Commands;
public class Karma : InteractionBase
{
private readonly DatabaseContext _database;
public Karma(DatabaseContext database)
{
_database = database;
}
private struct Options
{
internal const string Type = "type";
internal const string Good = "good";
internal const string Bad = "bad";
internal const string Neutral = "neutral";
internal const string User = "user";
}
public override Command GetCommandInfo() => new ()
{
Name = "karma",
Description = "Interact with someones karma",
Type = CommandType.ChatInput,
Options = new()
{
new()
{
Name = Options.Type,
Description = "Give someone karma",
Type = OptionType.String,
Required = true,
Choices = new[] { Options.Good, Options.Neutral, Options.Bad }
.Select(s => new OptionChoice() { Name = s, Value = s }).ToList()
},
new ()
{
Name = Options.User,
Description = "The User",
Type = OptionType.User,
Required = true,
}
}
};
public override async Task<InteractionResponse> Exec(Interaction interaction)
{
var karmaType = interaction.Data.Options.Find(o => o.Name == Options.Type);
var targetUserId = interaction.Data.Options.Find(o => o.Name == Options.User);
var karmaChange = karmaType.Value.GetString() switch
{
Options.Good => KarmaChange.Up,
Options.Neutral => KarmaChange.Same,
Options.Bad => KarmaChange.Down,
_ => throw new ArgumentOutOfRangeException()
};
var author = interaction.Member.User;
var targetUser = interaction.Data.Resolved.Users[targetUserId.Value.GetString()];
var karma = new Geekbot.Commands.Karma.Karma(_database, long.Parse(interaction.GuildId));
var res = await karma.ChangeKarma(author, targetUser, karmaChange);
return SimpleResponse(res);
}
}

View file

@ -0,0 +1,37 @@
using System.Threading.Tasks;
using Geekbot.Commands.Karma;
using Geekbot.Core.Database;
using Geekbot.Core.Interactions;
using Geekbot.Core.Interactions.ApplicationCommand;
using Geekbot.Core.Interactions.Request;
using Geekbot.Core.Interactions.Response;
namespace Geekbot.Web.Commands;
public class KarmaUserBad : InteractionBase
{
private readonly DatabaseContext _database;
public KarmaUserBad(DatabaseContext database)
{
_database = database;
}
public override Command GetCommandInfo() => new ()
{
Name = "Give bad karma",
Type = CommandType.User,
};
public override async Task<InteractionResponse> Exec(Interaction interaction)
{
var author = interaction.Member.User;
var targetUserId = interaction.Data.TargetId;
var targetUser = interaction.Data.Resolved.Users[targetUserId];
var karma = new Geekbot.Commands.Karma.Karma(_database, long.Parse(interaction.GuildId));
var res = await karma.ChangeKarma(author, targetUser, KarmaChange.Down);
return SimpleResponse(res);
}
}

View file

@ -0,0 +1,37 @@
using System.Threading.Tasks;
using Geekbot.Commands.Karma;
using Geekbot.Core.Database;
using Geekbot.Core.Interactions;
using Geekbot.Core.Interactions.ApplicationCommand;
using Geekbot.Core.Interactions.Request;
using Geekbot.Core.Interactions.Response;
namespace Geekbot.Web.Commands;
public class KarmaUserGood : InteractionBase
{
private readonly DatabaseContext _database;
public KarmaUserGood(DatabaseContext database)
{
_database = database;
}
public override Command GetCommandInfo() => new ()
{
Name = "Give good karma",
Type = CommandType.User,
};
public override async Task<InteractionResponse> Exec(Interaction interaction)
{
var author = interaction.Member.User;
var targetUserId = interaction.Data.TargetId;
var targetUser = interaction.Data.Resolved.Users[targetUserId];
var karma = new Geekbot.Commands.Karma.Karma(_database, long.Parse(interaction.GuildId));
var res = await karma.ChangeKarma(author, targetUser, KarmaChange.Up);
return SimpleResponse(res);
}
}

View file

@ -0,0 +1,37 @@
using System.Threading.Tasks;
using Geekbot.Commands.Karma;
using Geekbot.Core.Database;
using Geekbot.Core.Interactions;
using Geekbot.Core.Interactions.ApplicationCommand;
using Geekbot.Core.Interactions.Request;
using Geekbot.Core.Interactions.Response;
namespace Geekbot.Web.Commands;
public class KarmaUserNeutral : InteractionBase
{
private readonly DatabaseContext _database;
public KarmaUserNeutral(DatabaseContext database)
{
_database = database;
}
public override Command GetCommandInfo() => new ()
{
Name = "Give neutral karma",
Type = CommandType.User,
};
public override async Task<InteractionResponse> Exec(Interaction interaction)
{
var author = interaction.Member.User;
var targetUserId = interaction.Data.TargetId;
var targetUser = interaction.Data.Resolved.Users[targetUserId];
var karma = new Geekbot.Commands.Karma.Karma(_database, long.Parse(interaction.GuildId));
var res = await karma.ChangeKarma(author, targetUser, KarmaChange.Same);
return SimpleResponse(res);
}
}