mirror of
https://github.com/TeamOctolings/Octobot.git
synced 2025-04-20 00:43:36 +03:00
Fix issues reported by ReSharper, implement GuildData (only GuildConfiguration)
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
This commit is contained in:
parent
3e9940f0ca
commit
cca2965205
10 changed files with 201 additions and 116 deletions
3
.github/workflows/resharper.yml
vendored
3
.github/workflows/resharper.yml
vendored
|
@ -18,9 +18,6 @@ jobs:
|
|||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
|
40
Boyfriend.cs
40
Boyfriend.cs
|
@ -1,3 +1,4 @@
|
|||
using Boyfriend.Data.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
@ -17,20 +18,11 @@ using Remora.Rest.Core;
|
|||
namespace Boyfriend;
|
||||
|
||||
public class Boyfriend {
|
||||
public static ILogger<Boyfriend> Logger = null!;
|
||||
public static IConfiguration GuildConfiguration = null!;
|
||||
|
||||
public static readonly AllowedMentions NoMentions = new(
|
||||
Array.Empty<MentionType>(), Array.Empty<Snowflake>(), Array.Empty<Snowflake>());
|
||||
|
||||
public static async Task Main(string[] args) {
|
||||
var host = CreateHostBuilder(args).UseConsoleLifetime().Build();
|
||||
|
||||
var services = host.Services;
|
||||
Logger = services.GetRequiredService<ILogger<Boyfriend>>();
|
||||
GuildConfiguration = services.GetRequiredService<IConfigurationBuilder>().AddJsonFile("guild_configs.json")
|
||||
.Build();
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
|
@ -47,12 +39,10 @@ public class Boyfriend {
|
|||
}
|
||||
).ConfigureServices(
|
||||
(_, services) => {
|
||||
var responderTypes = typeof(Boyfriend).Assembly
|
||||
.GetExportedTypes()
|
||||
.Where(t => t.IsResponder());
|
||||
foreach (var responderType in responderTypes) services.AddResponder(responderType);
|
||||
|
||||
services.AddDiscordCaching();
|
||||
services.Configure<DiscordGatewayClientOptions>(
|
||||
options => options.Intents |= GatewayIntents.MessageContents
|
||||
| GatewayIntents.GuildMembers
|
||||
| GatewayIntents.GuildScheduledEvents);
|
||||
services.Configure<CacheSettings>(
|
||||
settings => {
|
||||
settings.SetDefaultAbsoluteExpiration(TimeSpan.FromHours(1));
|
||||
|
@ -61,16 +51,16 @@ public class Boyfriend {
|
|||
settings.SetSlidingExpiration<IMessage>(TimeSpan.FromDays(7));
|
||||
});
|
||||
|
||||
services.AddTransient<IConfigurationBuilder, ConfigurationBuilder>();
|
||||
|
||||
services.Configure<DiscordGatewayClientOptions>(
|
||||
options => options.Intents |= GatewayIntents.MessageContents
|
||||
| GatewayIntents.GuildMembers
|
||||
| GatewayIntents.GuildScheduledEvents);
|
||||
|
||||
services.AddDiscordCommands();
|
||||
services.AddInteractivity();
|
||||
services.AddInteractionGroup<InteractionResponders>();
|
||||
services.AddTransient<IConfigurationBuilder, ConfigurationBuilder>()
|
||||
.AddDiscordCaching()
|
||||
.AddDiscordCommands()
|
||||
.AddInteractivity()
|
||||
.AddInteractionGroup<InteractionResponders>()
|
||||
.AddSingleton<GuildDataService>();
|
||||
var responderTypes = typeof(Boyfriend).Assembly
|
||||
.GetExportedTypes()
|
||||
.Where(t => t.IsResponder());
|
||||
foreach (var responderType in responderTypes) services.AddResponder(responderType);
|
||||
}
|
||||
).ConfigureLogging(
|
||||
c => c.AddConsole()
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>2.0.0</Version>
|
||||
<Title>Boyfriend</Title>
|
||||
<Authors>Octol1ttle, mctaylors</Authors>
|
||||
<Copyright>AGPLv3</Copyright>
|
||||
|
@ -21,7 +21,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="DiffPlex" Version="1.7.1"/>
|
||||
<PackageReference Include="Humanizer.Core.ru" Version="2.14.1"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0-preview.3.23174.8"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1"/>
|
||||
<PackageReference Include="Remora.Discord" Version="2023.3.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
32
Data/GuildConfiguration.cs
Normal file
32
Data/GuildConfiguration.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace Boyfriend.Data;
|
||||
|
||||
public class GuildConfiguration {
|
||||
private static readonly Dictionary<string, CultureInfo> CultureInfoCache = new() {
|
||||
{ "en", new CultureInfo("en-US") },
|
||||
{ "ru", new CultureInfo("ru-RU") },
|
||||
{ "mctaylors-ru", new CultureInfo("tt-RU") }
|
||||
};
|
||||
|
||||
public string Prefix { get; set; } = "!";
|
||||
public string Language { get; set; } = "en";
|
||||
public string? WelcomeMessage { get; set; }
|
||||
public bool ReceiveStartupMessages { get; set; }
|
||||
public bool RemoveRolesOnMute { get; set; }
|
||||
public bool ReturnRolesOnRejoin { get; set; }
|
||||
public bool AutoStartEvents { get; set; }
|
||||
public ulong? PublicFeedbackChannel { get; set; }
|
||||
public ulong? PrivateFeedbackChannel { get; set; }
|
||||
public ulong? EventNotificationChannel { get; set; }
|
||||
public ulong? StarterRole { get; set; }
|
||||
public ulong? MuteRole { get; set; }
|
||||
public ulong? EventNotificationRole { get; set; }
|
||||
|
||||
public List<NotificationReceiver> EventStartedReceivers { get; set; }
|
||||
= new() { NotificationReceiver.Interested, NotificationReceiver.Role };
|
||||
|
||||
public TimeSpan EventEarlyNotificationOffset { get; set; } = TimeSpan.Zero;
|
||||
|
||||
public CultureInfo Culture => CultureInfoCache[Language];
|
||||
}
|
11
Data/GuildData.cs
Normal file
11
Data/GuildData.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Boyfriend.Data;
|
||||
|
||||
public class GuildData {
|
||||
public readonly GuildConfiguration Configuration;
|
||||
public readonly string ConfigurationPath;
|
||||
|
||||
public GuildData(GuildConfiguration configuration, string configurationPath) {
|
||||
Configuration = configuration;
|
||||
ConfigurationPath = configurationPath;
|
||||
}
|
||||
}
|
6
Data/NotificationReceiver.cs
Normal file
6
Data/NotificationReceiver.cs
Normal file
|
@ -0,0 +1,6 @@
|
|||
namespace Boyfriend.Data;
|
||||
|
||||
public enum NotificationReceiver {
|
||||
Interested,
|
||||
Role
|
||||
}
|
49
Data/Services/GuildDataService.cs
Normal file
49
Data/Services/GuildDataService.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Remora.Rest.Core;
|
||||
|
||||
namespace Boyfriend.Data.Services;
|
||||
|
||||
public class GuildDataService : IHostedService {
|
||||
private readonly Dictionary<Snowflake, GuildData> _datas = new();
|
||||
|
||||
public Task StartAsync(CancellationToken ct) {
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken ct) {
|
||||
var tasks = new List<Task>();
|
||||
foreach (var data in _datas.Values) {
|
||||
await using var stream = File.OpenWrite(data.ConfigurationPath);
|
||||
tasks.Add(JsonSerializer.SerializeAsync(stream, data.Configuration, cancellationToken: ct));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private async Task<GuildData> GetData(Snowflake guildId, CancellationToken ct = default) {
|
||||
return _datas.TryGetValue(guildId, out var data) ? data : await InitializeData(guildId, ct);
|
||||
}
|
||||
|
||||
private async Task<GuildData> InitializeData(Snowflake guildId, CancellationToken ct = default) {
|
||||
var idString = $"{guildId}";
|
||||
var memberDataDir = $"{guildId}/MemberData";
|
||||
var configurationPath = $"{guildId}/Configuration.json";
|
||||
if (!Directory.Exists(idString)) Directory.CreateDirectory(idString);
|
||||
if (!Directory.Exists(memberDataDir)) Directory.CreateDirectory(memberDataDir);
|
||||
if (!File.Exists(configurationPath)) await File.WriteAllTextAsync(configurationPath, "{}", ct);
|
||||
|
||||
await using var stream = File.OpenRead(configurationPath);
|
||||
var configuration
|
||||
= JsonSerializer.DeserializeAsync<GuildConfiguration>(
|
||||
stream, cancellationToken: ct);
|
||||
|
||||
var data = new GuildData(await configuration ?? new GuildConfiguration(), configurationPath);
|
||||
_datas.Add(guildId, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<GuildConfiguration> GetConfiguration(Snowflake guildId, CancellationToken ct = default) {
|
||||
return (await GetData(guildId, ct)).Configuration;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Drawing;
|
||||
using Boyfriend.Data.Services;
|
||||
using DiffPlex;
|
||||
using DiffPlex.DiffBuilder;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -21,29 +22,35 @@ namespace Boyfriend;
|
|||
|
||||
public class GuildCreateResponder : IResponder<IGuildCreate> {
|
||||
private readonly IDiscordRestChannelAPI _channelApi;
|
||||
private readonly GuildDataService _dataService;
|
||||
private readonly ILogger<GuildCreateResponder> _logger;
|
||||
private readonly IDiscordRestUserAPI _userApi;
|
||||
|
||||
public GuildCreateResponder(IDiscordRestChannelAPI channelApi, IDiscordRestUserAPI userApi) {
|
||||
public GuildCreateResponder(
|
||||
IDiscordRestChannelAPI channelApi, GuildDataService dataService, IDiscordRestUserAPI userApi,
|
||||
ILogger<GuildCreateResponder> logger) {
|
||||
_channelApi = channelApi;
|
||||
_dataService = dataService;
|
||||
_userApi = userApi;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Result> RespondAsync(IGuildCreate gatewayEvent, CancellationToken ct = default) {
|
||||
if (!gatewayEvent.Guild.IsT0) return Result.FromSuccess(); // is IAvailableGuild
|
||||
|
||||
var guild = gatewayEvent.Guild.AsT0;
|
||||
Boyfriend.Logger.LogInformation("Joined guild \"{Name}\"", guild.Name);
|
||||
_logger.LogInformation("Joined guild \"{Name}\"", guild.Name);
|
||||
|
||||
var channelResult = guild.ID.GetConfigChannel("PrivateFeedbackChannel");
|
||||
if (!channelResult.IsDefined(out var channel)) return Result.FromSuccess();
|
||||
var guildConfig = await _dataService.GetConfiguration(guild.ID, ct);
|
||||
if (!guildConfig.ReceiveStartupMessages)
|
||||
return Result.FromSuccess();
|
||||
if (guildConfig.PrivateFeedbackChannel is null)
|
||||
return Result.FromSuccess();
|
||||
|
||||
var currentUserResult = await _userApi.GetCurrentUserAsync(ct);
|
||||
if (!currentUserResult.IsDefined(out var currentUser)) return Result.FromError(currentUserResult);
|
||||
|
||||
if (!guild.GetConfigBool("ReceiveStartupMessages").IsDefined(out var shouldSendStartupMessage)
|
||||
|| !shouldSendStartupMessage) return Result.FromSuccess();
|
||||
|
||||
Messages.Culture = guild.ID.GetGuildCulture();
|
||||
Messages.Culture = guildConfig.Culture;
|
||||
var i = Random.Shared.Next(1, 4);
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
|
@ -56,7 +63,7 @@ public class GuildCreateResponder : IResponder<IGuildCreate> {
|
|||
if (!embed.IsDefined(out var built)) return Result.FromError(embed);
|
||||
|
||||
return (Result)await _channelApi.CreateMessageAsync(
|
||||
channel, embeds: new[] { built }, ct: ct);
|
||||
guildConfig.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built }, ct: ct);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,22 +71,24 @@ public class MessageDeletedResponder : IResponder<IMessageDelete> {
|
|||
private readonly IDiscordRestAuditLogAPI _auditLogApi;
|
||||
private readonly CacheService _cacheService;
|
||||
private readonly IDiscordRestChannelAPI _channelApi;
|
||||
private readonly GuildDataService _dataService;
|
||||
private readonly IDiscordRestUserAPI _userApi;
|
||||
|
||||
public MessageDeletedResponder(
|
||||
IDiscordRestAuditLogAPI auditLogApi, CacheService cacheService, IDiscordRestChannelAPI channelApi,
|
||||
IDiscordRestUserAPI userApi) {
|
||||
GuildDataService dataService, IDiscordRestUserAPI userApi) {
|
||||
_auditLogApi = auditLogApi;
|
||||
_cacheService = cacheService;
|
||||
_channelApi = channelApi;
|
||||
_dataService = dataService;
|
||||
_userApi = userApi;
|
||||
}
|
||||
|
||||
public async Task<Result> RespondAsync(IMessageDelete gatewayEvent, CancellationToken ct = default) {
|
||||
if (!gatewayEvent.GuildID.IsDefined(out var guildId)) return Result.FromSuccess();
|
||||
|
||||
var channelResult = guildId.GetConfigChannel("PrivateFeedbackChannel");
|
||||
if (!channelResult.IsDefined(out var logChannel)) return Result.FromSuccess();
|
||||
var guildConfiguration = await _dataService.GetConfiguration(guildId, ct);
|
||||
if (guildConfiguration.PrivateFeedbackChannel is null) return Result.FromSuccess();
|
||||
|
||||
var messageResult = await _cacheService.TryGetValueAsync<IMessage>(
|
||||
new KeyHelpers.MessageCacheKey(gatewayEvent.ChannelID, gatewayEvent.ID), ct);
|
||||
|
@ -101,7 +110,7 @@ public class MessageDeletedResponder : IResponder<IMessageDelete> {
|
|||
if (!userResult.IsDefined(out user)) return Result.FromError(userResult);
|
||||
}
|
||||
|
||||
Messages.Culture = guildId.GetGuildCulture();
|
||||
Messages.Culture = guildConfiguration.Culture;
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
.WithSmallTitle(
|
||||
|
@ -118,22 +127,29 @@ public class MessageDeletedResponder : IResponder<IMessageDelete> {
|
|||
if (!embed.IsDefined(out var built)) return Result.FromError(embed);
|
||||
|
||||
return (Result)await _channelApi.CreateMessageAsync(
|
||||
logChannel, embeds: new[] { built }, allowedMentions: Boyfriend.NoMentions, ct: ct);
|
||||
guildConfiguration.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built },
|
||||
allowedMentions: Boyfriend.NoMentions, ct: ct);
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageEditedResponder : IResponder<IMessageUpdate> {
|
||||
private readonly CacheService _cacheService;
|
||||
private readonly IDiscordRestChannelAPI _channelApi;
|
||||
private readonly GuildDataService _dataService;
|
||||
|
||||
public MessageEditedResponder(CacheService cacheService, IDiscordRestChannelAPI channelApi) {
|
||||
public MessageEditedResponder(
|
||||
CacheService cacheService, IDiscordRestChannelAPI channelApi, GuildDataService dataService) {
|
||||
_cacheService = cacheService;
|
||||
_channelApi = channelApi;
|
||||
_dataService = dataService;
|
||||
}
|
||||
|
||||
public async Task<Result> RespondAsync(IMessageUpdate gatewayEvent, CancellationToken ct = default) {
|
||||
if (!gatewayEvent.GuildID.IsDefined(out var guildId))
|
||||
return Result.FromSuccess();
|
||||
var guildConfiguration = await _dataService.GetConfiguration(guildId, ct);
|
||||
if (guildConfiguration.PrivateFeedbackChannel is null)
|
||||
return Result.FromSuccess();
|
||||
if (!gatewayEvent.Content.IsDefined(out var newContent))
|
||||
return Result.FromSuccess();
|
||||
|
||||
|
@ -148,18 +164,12 @@ public class MessageEditedResponder : IResponder<IMessageUpdate> {
|
|||
var messageResult = await _cacheService.TryGetValueAsync<IMessage>(
|
||||
cacheKey, ct);
|
||||
if (!messageResult.IsDefined(out var message)) return Result.FromError(messageResult);
|
||||
if (string.IsNullOrWhiteSpace(message.Content)
|
||||
|| string.IsNullOrWhiteSpace(newContent)
|
||||
|| message.Content == newContent) return Result.FromSuccess();
|
||||
if (message.Content == newContent) return Result.FromSuccess();
|
||||
|
||||
await _cacheService.EvictAsync<IMessage>(cacheKey, ct);
|
||||
var newMessageResult = await _channelApi.GetChannelMessageAsync(channelId, messageId, ct);
|
||||
if (!newMessageResult.IsDefined(out var newMessage)) return Result.FromError(newMessageResult);
|
||||
// No need to await the recache since we don't depend on it
|
||||
_ = _cacheService.CacheAsync(cacheKey, newMessage, ct);
|
||||
|
||||
var logChannelResult = guildId.GetConfigChannel("PrivateFeedbackChannel");
|
||||
if (!logChannelResult.IsDefined(out var logChannel)) return Result.FromSuccess();
|
||||
await _cacheService.CacheAsync(cacheKey, newMessage, ct);
|
||||
|
||||
var currentUserResult = await _cacheService.TryGetValueAsync<IUser>(
|
||||
new KeyHelpers.CurrentUserCacheKey(), ct);
|
||||
|
@ -167,7 +177,7 @@ public class MessageEditedResponder : IResponder<IMessageUpdate> {
|
|||
|
||||
var diff = new SideBySideDiffBuilder(Differ.Instance).BuildDiffModel(message.Content, newContent, true, true);
|
||||
|
||||
Messages.Culture = guildId.GetGuildCulture();
|
||||
Messages.Culture = guildConfiguration.Culture;
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
.WithSmallTitle(
|
||||
|
@ -181,30 +191,35 @@ public class MessageEditedResponder : IResponder<IMessageUpdate> {
|
|||
if (!embed.IsDefined(out var built)) return Result.FromError(embed);
|
||||
|
||||
return (Result)await _channelApi.CreateMessageAsync(
|
||||
logChannel, embeds: new[] { built }, allowedMentions: Boyfriend.NoMentions, ct: ct);
|
||||
guildConfiguration.PrivateFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built },
|
||||
allowedMentions: Boyfriend.NoMentions, ct: ct);
|
||||
}
|
||||
}
|
||||
|
||||
public class GuildMemberAddResponder : IResponder<IGuildMemberAdd> {
|
||||
private readonly CacheService _cacheService;
|
||||
private readonly IDiscordRestChannelAPI _channelApi;
|
||||
private readonly GuildDataService _dataService;
|
||||
|
||||
public GuildMemberAddResponder(CacheService cacheService, IDiscordRestChannelAPI channelApi) {
|
||||
public GuildMemberAddResponder(
|
||||
CacheService cacheService, IDiscordRestChannelAPI channelApi, GuildDataService dataService) {
|
||||
_cacheService = cacheService;
|
||||
_channelApi = channelApi;
|
||||
_dataService = dataService;
|
||||
}
|
||||
|
||||
public async Task<Result> RespondAsync(IGuildMemberAdd gatewayEvent, CancellationToken ct = default) {
|
||||
if (!gatewayEvent.GuildID.GetConfigString("WelcomeMessage").IsDefined(out var welcomeMessage)
|
||||
|| welcomeMessage is "off" or "disable" or "disabled")
|
||||
var guildConfiguration = await _dataService.GetConfiguration(gatewayEvent.GuildID, ct);
|
||||
if (guildConfiguration.PublicFeedbackChannel is null)
|
||||
return Result.FromSuccess();
|
||||
if (guildConfiguration.WelcomeMessage is null or "off" or "disable" or "disabled")
|
||||
return Result.FromSuccess();
|
||||
if (welcomeMessage is "default" or "reset") {
|
||||
Messages.Culture = gatewayEvent.GuildID.GetGuildCulture();
|
||||
welcomeMessage = Messages.DefaultWelcomeMessage;
|
||||
}
|
||||
|
||||
if (!gatewayEvent.GuildID.GetConfigChannel("PublicFeedbackChannel").IsDefined(out var channel))
|
||||
return Result.FromSuccess();
|
||||
Messages.Culture = guildConfiguration.Culture;
|
||||
var welcomeMessage = guildConfiguration.WelcomeMessage is "default" or "reset"
|
||||
? Messages.DefaultWelcomeMessage
|
||||
: guildConfiguration.WelcomeMessage;
|
||||
|
||||
if (!gatewayEvent.User.IsDefined(out var user))
|
||||
return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.User)));
|
||||
|
||||
|
@ -221,25 +236,30 @@ public class GuildMemberAddResponder : IResponder<IGuildMemberAdd> {
|
|||
if (!embed.IsDefined(out var built)) return Result.FromError(embed);
|
||||
|
||||
return (Result)await _channelApi.CreateMessageAsync(
|
||||
channel, embeds: new[] { built }, allowedMentions: Boyfriend.NoMentions, ct: ct);
|
||||
guildConfiguration.PublicFeedbackChannel.ToDiscordSnowflake(), embeds: new[] { built },
|
||||
allowedMentions: Boyfriend.NoMentions, ct: ct);
|
||||
}
|
||||
}
|
||||
|
||||
public class GuildScheduledEventCreateResponder : IResponder<IGuildScheduledEventCreate> {
|
||||
private readonly CacheService _cacheService;
|
||||
private readonly IDiscordRestChannelAPI _channelApi;
|
||||
private readonly GuildDataService _dataService;
|
||||
private readonly IDiscordRestUserAPI _userApi;
|
||||
|
||||
public GuildScheduledEventCreateResponder(
|
||||
CacheService cacheService, IDiscordRestChannelAPI channelApi, IDiscordRestUserAPI userApi) {
|
||||
CacheService cacheService, IDiscordRestChannelAPI channelApi, GuildDataService dataService,
|
||||
IDiscordRestUserAPI userApi) {
|
||||
_cacheService = cacheService;
|
||||
_channelApi = channelApi;
|
||||
_dataService = dataService;
|
||||
_userApi = userApi;
|
||||
}
|
||||
|
||||
public async Task<Result> RespondAsync(IGuildScheduledEventCreate gatewayEvent, CancellationToken ct = default) {
|
||||
var channelResult = gatewayEvent.GuildID.GetConfigChannel("EventNotificationChannel");
|
||||
if (!channelResult.IsDefined(out var channel)) return Result.FromSuccess();
|
||||
var guildConfiguration = await _dataService.GetConfiguration(gatewayEvent.GuildID, ct);
|
||||
if (guildConfiguration.EventNotificationChannel is null)
|
||||
return Result.FromSuccess();
|
||||
|
||||
var currentUserResult = await _cacheService.TryGetValueAsync<IUser>(
|
||||
new KeyHelpers.CurrentUserCacheKey(), ct);
|
||||
|
@ -250,7 +270,7 @@ public class GuildScheduledEventCreateResponder : IResponder<IGuildScheduledEven
|
|||
var creatorResult = await creatorId.Value.TryGetUserAsync(_cacheService, _userApi, ct);
|
||||
if (!creatorResult.IsDefined(out var creator)) return Result.FromError(creatorResult);
|
||||
|
||||
Messages.Culture = gatewayEvent.GuildID.GetGuildCulture();
|
||||
Messages.Culture = guildConfiguration.Culture;
|
||||
|
||||
string embedDescription;
|
||||
var eventDescription = gatewayEvent.Description is { HasValue: true, Value: not null }
|
||||
|
@ -308,6 +328,7 @@ public class GuildScheduledEventCreateResponder : IResponder<IGuildScheduledEven
|
|||
);
|
||||
|
||||
return (Result)await _channelApi.CreateMessageAsync(
|
||||
channel, embeds: new[] { built }, components: new[] { new ActionRowComponent(new[] { button }) }, ct: ct);
|
||||
guildConfiguration.EventNotificationChannel.ToDiscordSnowflake(), embeds: new[] { built },
|
||||
components: new[] { new ActionRowComponent(new[] { button }) }, ct: ct);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using System.Globalization;
|
||||
using System.Text;
|
||||
using DiffPlex.DiffBuilder.Model;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Remora.Discord.API;
|
||||
using Remora.Discord.API.Abstractions.Objects;
|
||||
using Remora.Discord.API.Abstractions.Rest;
|
||||
|
@ -16,34 +14,6 @@ using Remora.Results;
|
|||
namespace Boyfriend;
|
||||
|
||||
public static class Extensions {
|
||||
private static readonly Dictionary<string, CultureInfo> CultureInfoCache = new() {
|
||||
{ "en", new CultureInfo("en-US") },
|
||||
{ "ru", new CultureInfo("ru-RU") },
|
||||
{ "mctaylors-ru", new CultureInfo("tt-RU") }
|
||||
};
|
||||
|
||||
public static Result<bool> GetConfigBool(this IGuild guild, string key) {
|
||||
var value = Boyfriend.GuildConfiguration.GetValue<bool?>($"GuildConfigs:{guild.ID}:{key}");
|
||||
return value is not null ? Result<bool>.FromSuccess(value.Value) : Result<bool>.FromError(new NotFoundError());
|
||||
}
|
||||
|
||||
public static Result<Snowflake> GetConfigChannel(this Snowflake guildId, string key) {
|
||||
var value = Boyfriend.GuildConfiguration.GetValue<ulong?>($"GuildConfigs:{guildId}:{key}");
|
||||
return value is not null
|
||||
? Result<Snowflake>.FromSuccess(DiscordSnowflake.New(value.Value))
|
||||
: Result<Snowflake>.FromError(new NotFoundError());
|
||||
}
|
||||
|
||||
public static Result<string> GetConfigString(this Snowflake guildId, string key) {
|
||||
var value = Boyfriend.GuildConfiguration.GetValue<string?>($"GuildConfigs:{guildId}:{key}");
|
||||
return value is not null ? Result<string>.FromSuccess(value) : Result<string>.FromError(new NotFoundError());
|
||||
}
|
||||
|
||||
public static CultureInfo GetGuildCulture(this Snowflake guildId) {
|
||||
var value = Boyfriend.GuildConfiguration.GetValue<string?>($"GuildConfigs:{guildId}:Language");
|
||||
return value is not null ? CultureInfoCache[value] : CultureInfoCache["en"];
|
||||
}
|
||||
|
||||
public static async Task<Result<IUser>> TryGetUserAsync(
|
||||
this Snowflake userId, CacheService cacheService, IDiscordRestUserAPI userApi, CancellationToken ct) {
|
||||
var cachedUserResult = await cacheService.TryGetValueAsync<IUser>(
|
||||
|
@ -118,4 +88,8 @@ public static class Extensions {
|
|||
public static string GetTag(this IUser user) {
|
||||
return $"{user.Username}#{user.Discriminator:0000}";
|
||||
}
|
||||
|
||||
public static Snowflake ToDiscordSnowflake(this ulong? id) {
|
||||
return DiscordSnowflake.New(id ?? 0);
|
||||
}
|
||||
}
|
||||
|
|
35
Messages.Designer.cs
generated
35
Messages.Designer.cs
generated
|
@ -7,36 +7,41 @@
|
|||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Boyfriend {
|
||||
using System;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[DebuggerNonUserCode()]
|
||||
[CompilerGenerated()]
|
||||
internal class Messages {
|
||||
|
||||
private static System.Resources.ResourceManager resourceMan;
|
||||
private static ResourceManager resourceMan;
|
||||
|
||||
private static System.Globalization.CultureInfo resourceCulture;
|
||||
private static CultureInfo resourceCulture;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Messages() {
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Resources.ResourceManager ResourceManager {
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
internal static ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.Equals(null, resourceMan)) {
|
||||
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Boyfriend.Messages", typeof(Messages).Assembly);
|
||||
if (Equals(null, resourceMan)) {
|
||||
ResourceManager temp = new ResourceManager("Boyfriend.Messages", typeof(Messages).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Globalization.CultureInfo Culture {
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
internal static CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue