mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 09:48:26 -04:00
NadekoBot.Extensions should now be fully annotated with nullable reference types as well as many classes from NadekoBot.Common
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Immutable;
|
||||
#nullable disable
|
||||
using System.Collections.Immutable;
|
||||
using NadekoBot.Common.Configs;
|
||||
using NadekoBot.Db;
|
||||
using Discord.Interactions;
|
||||
@@ -194,34 +195,42 @@ public class CommandHandler : INService
|
||||
}
|
||||
}
|
||||
|
||||
private async Task MessageReceivedHandler(SocketMessage msg)
|
||||
private Task MessageReceivedHandler(SocketMessage msg)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (msg.Author.IsBot || !_bot.IsReady) //no bots, wait until bot connected and initialized
|
||||
return;
|
||||
//no bots, wait until bot connected and initialized
|
||||
if (msg.Author.IsBot || !_bot.IsReady)
|
||||
return Task.CompletedTask;
|
||||
|
||||
if (msg is not SocketUserMessage usrMsg)
|
||||
return;
|
||||
if (msg is not SocketUserMessage usrMsg)
|
||||
return Task.CompletedTask;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
#if !GLOBAL_NADEKO
|
||||
// track how many messagges each user is sending
|
||||
UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old);
|
||||
// track how many messagges each user is sending
|
||||
UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old);
|
||||
#endif
|
||||
|
||||
var channel = msg.Channel;
|
||||
var guild = (msg.Channel as SocketTextChannel)?.Guild;
|
||||
var channel = msg.Channel;
|
||||
var guild = (msg.Channel as SocketTextChannel)?.Guild;
|
||||
|
||||
await TryRunCommand(guild, channel, usrMsg).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error in CommandHandler");
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
Log.Warning(ex.InnerException, "Inner Exception of the error in CommandHandler");
|
||||
await TryRunCommand(guild, channel, usrMsg)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error in CommandHandler");
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
Log.Warning(ex.InnerException, "Inner Exception of the error in CommandHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task TryRunCommand(SocketGuild guild, ISocketMessageChannel channel, IUserMessage usrMsg)
|
||||
@@ -374,4 +383,4 @@ public class CommandHandler : INService
|
||||
|
||||
return (true, null, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,71 +0,0 @@
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public class GreetGrouper<T>
|
||||
{
|
||||
private readonly Dictionary<ulong, HashSet<T>> group;
|
||||
private readonly object locker = new();
|
||||
|
||||
public GreetGrouper()
|
||||
=> group = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a group, if group already exists, adds the specified user
|
||||
/// </summary>
|
||||
/// <param name="guildId">Id of the server for which to create group for</param>
|
||||
/// <param name="toAddIfExists">User to add if group already exists</param>
|
||||
/// <returns></returns>
|
||||
public bool CreateOrAdd(ulong guildId, T toAddIfExists)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (group.TryGetValue(guildId, out var list))
|
||||
{
|
||||
list.Add(toAddIfExists);
|
||||
return false;
|
||||
}
|
||||
|
||||
group[guildId] = new();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the specified amount of items from the group. If all items are removed, group will be removed.
|
||||
/// </summary>
|
||||
/// <param name="guildId">Id of the group</param>
|
||||
/// <param name="count">Maximum number of items to retrieve</param>
|
||||
/// <param name="items">Items retrieved</param>
|
||||
/// <returns>Whether the group has no more items left and is deleted</returns>
|
||||
public bool ClearGroup(ulong guildId, int count, out IEnumerable<T> items)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (group.TryGetValue(guildId, out var set))
|
||||
{
|
||||
// if we want more than there are, return everything
|
||||
if (count >= set.Count)
|
||||
{
|
||||
items = set;
|
||||
group.Remove(guildId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// if there are more in the group than what's needed
|
||||
// take the requested number, remove them from the set
|
||||
// and return them
|
||||
var toReturn = set.TakeWhile(item => count-- != 0).ToList();
|
||||
foreach (var item in toReturn)
|
||||
set.Remove(item);
|
||||
|
||||
items = toReturn;
|
||||
// returning falsemeans group is not yet deleted
|
||||
// because there are items left
|
||||
return false;
|
||||
}
|
||||
|
||||
items = Enumerable.Empty<T>();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
#nullable disable
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Services.Database;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
@@ -53,4 +54,4 @@ public class DbService
|
||||
}
|
||||
|
||||
public NadekoContext GetDbContext() => GetDbContextInternal();
|
||||
}
|
||||
}
|
||||
|
@@ -1,621 +0,0 @@
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Db;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public class GreetSettingsService : INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
|
||||
public ConcurrentDictionary<ulong, GreetSettings> GuildConfigsCache { get; }
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
private readonly GreetGrouper<IGuildUser> greets = new();
|
||||
private readonly GreetGrouper<IUser> byes = new();
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
public bool GroupGreets => _bss.Data.GroupGreets;
|
||||
|
||||
public GreetSettingsService(DiscordSocketClient client,
|
||||
Bot bot,
|
||||
DbService db,
|
||||
BotConfigService bss,
|
||||
IEmbedBuilderService eb)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
_bss = bss;
|
||||
_eb = eb;
|
||||
|
||||
GuildConfigsCache = new(bot.AllGuildConfigs.ToDictionary(g => g.GuildId, GreetSettings.Create));
|
||||
|
||||
_client.UserJoined += UserJoined;
|
||||
_client.UserLeft += UserLeft;
|
||||
|
||||
bot.JoinedGuild += Bot_JoinedGuild;
|
||||
_client.LeftGuild += _client_LeftGuild;
|
||||
|
||||
_client.GuildMemberUpdated += ClientOnGuildMemberUpdated;
|
||||
}
|
||||
|
||||
private Task ClientOnGuildMemberUpdated(Cacheable<SocketGuildUser, ulong> optOldUser, SocketGuildUser newUser)
|
||||
{
|
||||
// if user is a new booster
|
||||
// or boosted again the same server
|
||||
if ((optOldUser.Value is { PremiumSince: null }
|
||||
&& newUser is { PremiumSince: not null })
|
||||
|| (optOldUser.Value?.PremiumSince is { } oldDate
|
||||
&& newUser?.PremiumSince is { } newDate
|
||||
&& newDate > oldDate))
|
||||
{
|
||||
var conf = GetOrAddSettingsForGuild(newUser.Guild.Id);
|
||||
if (!conf.SendBoostMessage) return Task.CompletedTask;
|
||||
|
||||
_ = Task.Run(TriggerBoostMessage(conf, newUser));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Func<Task> TriggerBoostMessage(GreetSettings conf, SocketGuildUser user) => async () =>
|
||||
{
|
||||
var channel = user.Guild.GetTextChannel(conf.BoostMessageChannelId);
|
||||
if (channel is null)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(conf.BoostMessage))
|
||||
return;
|
||||
|
||||
var toSend = SmartText.CreateFrom(conf.BoostMessage);
|
||||
var rep = new ReplacementBuilder()
|
||||
.WithDefault(user, channel, user.Guild, _client)
|
||||
.Build();
|
||||
|
||||
try
|
||||
{
|
||||
var toDelete = await channel.SendAsync(rep.Replace(toSend));
|
||||
if (conf.BoostMessageDeleteAfter > 0)
|
||||
{
|
||||
toDelete.DeleteAfter(conf.BoostMessageDeleteAfter);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error sending boost message.");
|
||||
}
|
||||
};
|
||||
|
||||
private Task _client_LeftGuild(SocketGuild arg)
|
||||
{
|
||||
GuildConfigsCache.TryRemove(arg.Id, out _);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task Bot_JoinedGuild(GuildConfig gc)
|
||||
{
|
||||
GuildConfigsCache.AddOrUpdate(gc.GuildId,
|
||||
GreetSettings.Create(gc),
|
||||
delegate { return GreetSettings.Create(gc); });
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UserLeft(SocketGuild guild, SocketUser user)
|
||||
{
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var conf = GetOrAddSettingsForGuild(guild.Id);
|
||||
|
||||
if (!conf.SendChannelByeMessage) return;
|
||||
var channel = guild.TextChannels.FirstOrDefault(c => c.Id == conf.ByeMessageChannelId);
|
||||
|
||||
if (channel is null) //maybe warn the server owner that the channel is missing
|
||||
return;
|
||||
|
||||
if (GroupGreets)
|
||||
{
|
||||
// if group is newly created, greet that user right away,
|
||||
// but any user which joins in the next 5 seconds will
|
||||
// be greeted in a group greet
|
||||
if (byes.CreateOrAdd(guild.Id, user))
|
||||
{
|
||||
// greet single user
|
||||
await ByeUsers(conf, channel, new[] {user});
|
||||
var groupClear = false;
|
||||
while(!groupClear)
|
||||
{
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
groupClear = byes.ClearGroup(guild.Id, 5, out var toBye);
|
||||
await ByeUsers(conf, channel, toBye);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ByeUsers(conf, channel, new[] {user});
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public string GetDmGreetMsg(ulong id)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
return uow.GuildConfigsForId(id, set => set)?.DmGreetMessageText;
|
||||
}
|
||||
|
||||
public string GetGreetMsg(ulong gid)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
return uow.GuildConfigsForId(gid, set => set).ChannelGreetMessageText;
|
||||
}
|
||||
|
||||
public string GetBoostMessage(ulong gid)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
return uow.GuildConfigsForId(gid, set => set).BoostMessage;
|
||||
}
|
||||
|
||||
private Task ByeUsers(GreetSettings conf, ITextChannel channel, IUser user)
|
||||
=> ByeUsers(conf, channel, new[] {user});
|
||||
private async Task ByeUsers(GreetSettings conf, ITextChannel channel, IEnumerable<IUser> users)
|
||||
{
|
||||
if (!users.Any())
|
||||
return;
|
||||
|
||||
var rep = new ReplacementBuilder()
|
||||
.WithChannel(channel)
|
||||
.WithClient(_client)
|
||||
.WithServer(_client, (SocketGuild) channel.Guild)
|
||||
.WithManyUsers(users)
|
||||
.Build();
|
||||
|
||||
var text = SmartText.CreateFrom(conf.ChannelByeMessageText);
|
||||
text = rep.Replace(text);
|
||||
try
|
||||
{
|
||||
var toDelete = await channel.SendAsync(text);
|
||||
if (conf.AutoDeleteByeMessagesTimer > 0)
|
||||
{
|
||||
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error embeding bye message");
|
||||
}
|
||||
}
|
||||
|
||||
private Task GreetUsers(GreetSettings conf, ITextChannel channel, IGuildUser user)
|
||||
=> GreetUsers(conf, channel, new[] {user});
|
||||
|
||||
private async Task GreetUsers(GreetSettings conf, ITextChannel channel, IEnumerable<IGuildUser> users)
|
||||
{
|
||||
if (!users.Any())
|
||||
return;
|
||||
|
||||
var rep = new ReplacementBuilder()
|
||||
.WithChannel(channel)
|
||||
.WithClient(_client)
|
||||
.WithServer(_client, (SocketGuild) channel.Guild)
|
||||
.WithManyUsers(users)
|
||||
.Build();
|
||||
|
||||
var text = SmartText.CreateFrom(conf.ChannelGreetMessageText);
|
||||
text = rep.Replace(text);
|
||||
try
|
||||
{
|
||||
var toDelete = await channel.SendAsync(text).ConfigureAwait(false);
|
||||
if (conf.AutoDeleteGreetMessagesTimer > 0)
|
||||
{
|
||||
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error embeding greet message");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> GreetDmUser(GreetSettings conf, IDMChannel channel, IGuildUser user)
|
||||
{
|
||||
var rep = new ReplacementBuilder()
|
||||
.WithDefault(user, channel, (SocketGuild)user.Guild, _client)
|
||||
.Build();
|
||||
|
||||
var text = SmartText.CreateFrom(conf.DmGreetMessageText);
|
||||
rep.Replace(text);
|
||||
try
|
||||
{
|
||||
await channel.SendAsync(text).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Task UserJoined(IGuildUser user)
|
||||
{
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||
|
||||
if (conf.SendChannelGreetMessage)
|
||||
{
|
||||
var channel = await user.Guild.GetTextChannelAsync(conf.GreetMessageChannelId);
|
||||
if (channel != null)
|
||||
{
|
||||
if (GroupGreets)
|
||||
{
|
||||
// if group is newly created, greet that user right away,
|
||||
// but any user which joins in the next 5 seconds will
|
||||
// be greeted in a group greet
|
||||
if (greets.CreateOrAdd(user.GuildId, user))
|
||||
{
|
||||
// greet single user
|
||||
await GreetUsers(conf, channel, new[] {user});
|
||||
var groupClear = false;
|
||||
while(!groupClear)
|
||||
{
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
groupClear = greets.ClearGroup(user.GuildId, 5, out var toGreet);
|
||||
await GreetUsers(conf, channel, toGreet);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await GreetUsers(conf, channel, new[] {user});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (conf.SendDmGreetMessage)
|
||||
{
|
||||
var channel = await user.CreateDMChannelAsync();
|
||||
|
||||
if (channel is not null)
|
||||
{
|
||||
await GreetDmUser(conf, channel, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public string GetByeMessage(ulong gid)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
return uow.GuildConfigsForId(gid, set => set).ChannelByeMessageText;
|
||||
}
|
||||
|
||||
public GreetSettings GetOrAddSettingsForGuild(ulong guildId)
|
||||
{
|
||||
if (GuildConfigsCache.TryGetValue(guildId, out var settings) &&
|
||||
settings != null)
|
||||
return settings;
|
||||
|
||||
using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set);
|
||||
settings = GreetSettings.Create(gc);
|
||||
}
|
||||
|
||||
GuildConfigsCache.TryAdd(guildId, settings);
|
||||
return settings;
|
||||
}
|
||||
|
||||
public async Task<bool> SetSettings(ulong guildId, GreetSettings settings)
|
||||
{
|
||||
if (settings.AutoDeleteByeMessagesTimer is > 600 or < 0 ||
|
||||
settings.AutoDeleteGreetMessagesTimer is > 600 or < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.DmGreetMessageText = settings.DmGreetMessageText?.SanitizeMentions();
|
||||
conf.ChannelGreetMessageText = settings.ChannelGreetMessageText?.SanitizeMentions();
|
||||
conf.ChannelByeMessageText = settings.ChannelByeMessageText?.SanitizeMentions();
|
||||
|
||||
conf.AutoDeleteGreetMessagesTimer = settings.AutoDeleteGreetMessagesTimer;
|
||||
conf.AutoDeleteGreetMessages = settings.AutoDeleteGreetMessagesTimer > 0;
|
||||
|
||||
conf.AutoDeleteByeMessagesTimer = settings.AutoDeleteByeMessagesTimer;
|
||||
conf.AutoDeleteByeMessages = settings.AutoDeleteByeMessagesTimer > 0;
|
||||
|
||||
conf.GreetMessageChannelId = settings.GreetMessageChannelId;
|
||||
conf.ByeMessageChannelId = settings.ByeMessageChannelId;
|
||||
|
||||
conf.SendChannelGreetMessage = settings.SendChannelGreetMessage;
|
||||
conf.SendChannelByeMessage = settings.SendChannelByeMessage;
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> SetGreet(ulong guildId, ulong channelId, bool? value = null)
|
||||
{
|
||||
bool enabled;
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
enabled = conf.SendChannelGreetMessage = value ?? !conf.SendChannelGreetMessage;
|
||||
conf.GreetMessageChannelId = channelId;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public bool SetGreetMessage(ulong guildId, ref string message)
|
||||
{
|
||||
message = message?.SanitizeMentions();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
|
||||
bool greetMsgEnabled;
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.ChannelGreetMessageText = message;
|
||||
greetMsgEnabled = conf.SendChannelGreetMessage;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
uow.SaveChanges();
|
||||
return greetMsgEnabled;
|
||||
}
|
||||
|
||||
public async Task<bool> SetGreetDm(ulong guildId, bool? value = null)
|
||||
{
|
||||
bool enabled;
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
enabled = conf.SendDmGreetMessage = value ?? !conf.SendDmGreetMessage;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
#region Get Enabled Status
|
||||
public bool GetGreetDmEnabled(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
return conf.SendDmGreetMessage;
|
||||
}
|
||||
|
||||
public bool GetGreetEnabled(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
return conf.SendChannelGreetMessage;
|
||||
}
|
||||
|
||||
public bool GetByeEnabled(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
return conf.SendChannelByeMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Test Messages
|
||||
|
||||
public Task ByeTest(ITextChannel channel, IGuildUser user)
|
||||
{
|
||||
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||
return ByeUsers(conf, channel, user);
|
||||
}
|
||||
|
||||
public Task GreetTest(ITextChannel channel, IGuildUser user)
|
||||
{
|
||||
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||
return GreetUsers(conf, channel, user);
|
||||
}
|
||||
|
||||
public Task<bool> GreetDmTest(IDMChannel channel, IGuildUser user)
|
||||
{
|
||||
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||
return GreetDmUser(conf, channel, user);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool SetGreetDmMessage(ulong guildId, ref string message)
|
||||
{
|
||||
message = message?.SanitizeMentions();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
|
||||
bool greetMsgEnabled;
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.DmGreetMessageText = message;
|
||||
greetMsgEnabled = conf.SendDmGreetMessage;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
uow.SaveChanges();
|
||||
return greetMsgEnabled;
|
||||
}
|
||||
|
||||
public async Task<bool> SetBye(ulong guildId, ulong channelId, bool? value = null)
|
||||
{
|
||||
bool enabled;
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
enabled = conf.SendChannelByeMessage = value ?? !conf.SendChannelByeMessage;
|
||||
conf.ByeMessageChannelId = channelId;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public bool SetByeMessage(ulong guildId, ref string message)
|
||||
{
|
||||
message = message?.SanitizeMentions();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
|
||||
bool byeMsgEnabled;
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.ChannelByeMessageText = message;
|
||||
byeMsgEnabled = conf.SendChannelByeMessage;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
uow.SaveChanges();
|
||||
return byeMsgEnabled;
|
||||
}
|
||||
|
||||
public async Task SetByeDel(ulong guildId, int timer)
|
||||
{
|
||||
if (timer is < 0 or > 600)
|
||||
return;
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.AutoDeleteByeMessagesTimer = timer;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd, (key, old) => toAdd);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task SetGreetDel(ulong id, int timer)
|
||||
{
|
||||
if (timer is < 0 or > 600)
|
||||
return;
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(id, set => set);
|
||||
conf.AutoDeleteGreetMessagesTimer = timer;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(id, toAdd, (key, old) => toAdd);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public bool SetBoostMessage(ulong guildId, ref string message)
|
||||
{
|
||||
message = message?.SanitizeMentions();
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.BoostMessage = message;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd,(_, _) => toAdd);
|
||||
|
||||
uow.SaveChanges();
|
||||
return conf.SendBoostMessage;
|
||||
}
|
||||
|
||||
public async Task SetBoostDel(ulong guildId, int timer)
|
||||
{
|
||||
if (timer is < 0 or > 600)
|
||||
throw new ArgumentOutOfRangeException(nameof(timer));
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.BoostMessageDeleteAfter = timer;
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd,(_, _) => toAdd);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleBoost(ulong guildId, ulong channelId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
conf.SendBoostMessage = !conf.SendBoostMessage;
|
||||
conf.BoostMessageChannelId = channelId;
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
var toAdd = GreetSettings.Create(conf);
|
||||
GuildConfigsCache.AddOrUpdate(guildId, toAdd,(_, _) => toAdd);
|
||||
return conf.SendBoostMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public class GreetSettings
|
||||
{
|
||||
public int AutoDeleteGreetMessagesTimer { get; set; }
|
||||
public int AutoDeleteByeMessagesTimer { get; set; }
|
||||
|
||||
public ulong GreetMessageChannelId { get; set; }
|
||||
public ulong ByeMessageChannelId { get; set; }
|
||||
|
||||
public bool SendDmGreetMessage { get; set; }
|
||||
public string DmGreetMessageText { get; set; }
|
||||
|
||||
public bool SendChannelGreetMessage { get; set; }
|
||||
public string ChannelGreetMessageText { get; set; }
|
||||
|
||||
public bool SendChannelByeMessage { get; set; }
|
||||
public string ChannelByeMessageText { get; set; }
|
||||
|
||||
public bool SendBoostMessage { get; set; }
|
||||
public string BoostMessage { get; set; }
|
||||
public int BoostMessageDeleteAfter { get; set; }
|
||||
public ulong BoostMessageChannelId { get; set; }
|
||||
|
||||
public static GreetSettings Create(GuildConfig g) => new()
|
||||
{
|
||||
AutoDeleteByeMessagesTimer = g.AutoDeleteByeMessagesTimer,
|
||||
AutoDeleteGreetMessagesTimer = g.AutoDeleteGreetMessagesTimer,
|
||||
GreetMessageChannelId = g.GreetMessageChannelId,
|
||||
ByeMessageChannelId = g.ByeMessageChannelId,
|
||||
SendDmGreetMessage = g.SendDmGreetMessage,
|
||||
DmGreetMessageText = g.DmGreetMessageText,
|
||||
SendChannelGreetMessage = g.SendChannelGreetMessage,
|
||||
ChannelGreetMessageText = g.ChannelGreetMessageText,
|
||||
SendChannelByeMessage = g.SendChannelByeMessage,
|
||||
ChannelByeMessageText = g.ChannelByeMessageText,
|
||||
|
||||
SendBoostMessage = g.SendBoostMessage,
|
||||
BoostMessage = g.BoostMessage,
|
||||
BoostMessageDeleteAfter = g.BoostMessageDeleteAfter,
|
||||
BoostMessageChannelId = g.BoostMessageChannelId
|
||||
};
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface IBehaviourExecutor
|
||||
{
|
||||
@@ -8,4 +9,4 @@ public interface IBehaviourExecutor
|
||||
Task RunLateExecutorsAsync(SocketGuild guild, IUserMessage usrMsg);
|
||||
|
||||
public void Initialize();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface ICoordinator
|
||||
{
|
||||
@@ -16,4 +17,4 @@ public class ShardStatus
|
||||
public DateTime LastUpdate { get; set; }
|
||||
public int ShardId { get; set; }
|
||||
public int GuildCount { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface ICurrencyService
|
||||
{
|
||||
@@ -8,4 +9,4 @@ public interface ICurrencyService
|
||||
Task<bool> RemoveAsync(ulong userId, string reason, long amount, bool gamble = false);
|
||||
Task<bool> RemoveAsync(IUser userId, string reason, long amount, bool sendMessage = false, bool gamble = false);
|
||||
Task RemoveBulkAsync(IEnumerable<ulong> userIds, IEnumerable<string> reasons, IEnumerable<long> amounts, bool gamble = false);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using StackExchange.Redis;
|
||||
#nullable disable
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -25,4 +26,4 @@ public interface IDataCache
|
||||
Task<TOut> GetOrAddCachedDataAsync<TParam, TOut>(string key, Func<TParam, Task<TOut>> factory, TParam param, TimeSpan expiry) where TOut : class;
|
||||
DateTime GetLastCurrencyDecay();
|
||||
void SetLastCurrencyDecay();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Common.Configs;
|
||||
#nullable disable
|
||||
using NadekoBot.Common.Configs;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -74,4 +75,4 @@ public sealed class DiscordEmbedBuilderWrapper : IEmbedBuilder
|
||||
_embed = eb;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Google.Apis.Customsearch.v1.Data;
|
||||
#nullable disable
|
||||
using Google.Apis.Customsearch.v1.Data;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -29,4 +30,4 @@ public struct ImageResult
|
||||
this.Image = image;
|
||||
this.Link = link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface IImageCache
|
||||
{
|
||||
@@ -25,4 +26,4 @@ public interface IImageCache
|
||||
byte[] GetCard(string key);
|
||||
|
||||
Task Reload();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Common.Pokemon;
|
||||
#nullable disable
|
||||
using NadekoBot.Common.Pokemon;
|
||||
using NadekoBot.Modules.Games.Common.Trivia;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -9,4 +10,4 @@ public interface ILocalDataCache
|
||||
IReadOnlyDictionary<string, SearchPokemonAbility> PokemonAbilities { get; }
|
||||
IReadOnlyDictionary<int, string> PokemonMap { get; }
|
||||
TriviaQuestion[] TriviaQuestions { get; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -15,4 +16,4 @@ public interface ILocalization
|
||||
void SetDefaultCulture(CultureInfo ci);
|
||||
void SetGuildCulture(IGuild guild, CultureInfo ci);
|
||||
void SetGuildCulture(ulong guildId, CultureInfo ci);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// All services must implement this interface in order to be auto-discovered by the DI system
|
||||
/// </summary>
|
||||
public interface INService
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface IStatsService
|
||||
{
|
||||
@@ -52,4 +53,4 @@ public interface IStatsService
|
||||
/// Gets total amount of private memory currently in use by the bot, in Megabytes.
|
||||
/// </summary>
|
||||
double GetPrivateMemory();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
#nullable disable
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -86,4 +87,4 @@ public sealed class BehaviorExecutor : IBehaviourExecutor, INService
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
#nullable disable
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using NadekoBot.Common.Yml;
|
||||
using Newtonsoft.Json;
|
||||
@@ -173,4 +174,4 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
||||
}
|
||||
|
||||
public IBotCredentials GetCreds() => _creds;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Services.Database;
|
||||
#nullable disable
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Gambling.Services;
|
||||
@@ -143,4 +144,4 @@ public class CurrencyService : ICurrencyService, INService
|
||||
|
||||
public Task<bool> RemoveAsync(IUser user, string reason, long amount, bool sendMessage = false, bool gamble = false)
|
||||
=> InternalRemoveAsync(user.Id, user.Username, user.Discriminator, user.AvatarId, reason, amount, gamble);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using SixLabors.Fonts;
|
||||
#nullable disable
|
||||
using SixLabors.Fonts;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -59,4 +60,4 @@ public class FontProvider : INService
|
||||
/// </summary>
|
||||
public Font RipFont { get; }
|
||||
public List<FontFamily> FallBackFonts { get; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Google;
|
||||
#nullable disable
|
||||
using Google;
|
||||
using Google.Apis.Customsearch.v1;
|
||||
using Google.Apis.Services;
|
||||
using Google.Apis.Urlshortener.v1;
|
||||
@@ -378,4 +379,4 @@ public class GoogleApiService : IGoogleApiService, INService
|
||||
Languages.TryGetValue(language, out var mode);
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using NadekoBot.Db;
|
||||
|
||||
@@ -107,4 +108,4 @@ public class Localization : ILocalization, INService
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
#nullable disable
|
||||
using Newtonsoft.Json;
|
||||
using StackExchange.Redis;
|
||||
using System.Net;
|
||||
|
||||
@@ -205,4 +206,4 @@ public class RedisCache : IDataCache
|
||||
|
||||
db.StringSet($"{_redisKey}_last_currency_decay", JsonConvert.SerializeObject(DateTime.UtcNow));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public static class RedisImageExtensions
|
||||
{
|
||||
@@ -7,4 +8,4 @@ public static class RedisImageExtensions
|
||||
|
||||
public static Uri ToNewCdn(this Uri uri)
|
||||
=> new(uri.ToString().Replace(OldCdnUrl, NewCdnUrl));
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
#nullable disable
|
||||
using Newtonsoft.Json;
|
||||
using StackExchange.Redis;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Common.Yml;
|
||||
@@ -275,4 +276,4 @@ public sealed class RedisImagesCache : IImageCache, IReadyExecutor
|
||||
|
||||
private RedisKey GetRedisKey(ImageKeys key)
|
||||
=> _creds.RedisKey() + "_image_" + key;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Common.Pokemon;
|
||||
#nullable disable
|
||||
using NadekoBot.Common.Pokemon;
|
||||
using NadekoBot.Modules.Games.Common.Trivia;
|
||||
using Newtonsoft.Json;
|
||||
using StackExchange.Redis;
|
||||
@@ -89,4 +90,4 @@ public class RedisLocalDataCache : ILocalDataCache
|
||||
|
||||
private void Set(string key, object obj)
|
||||
=> _con.GetDatabase().StringSet($"{_creds.RedisKey()}_localdata_{key}", JsonConvert.SerializeObject(obj));
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Grpc.Core;
|
||||
#nullable disable
|
||||
using Grpc.Core;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Coordinator;
|
||||
|
||||
@@ -129,4 +130,4 @@ public class RemoteGrpcCoordinator : ICoordinator, IReadyExecutor
|
||||
ConnState.Connected => ConnectionState.Connected,
|
||||
_ => ConnectionState.Disconnected
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
#nullable disable
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -53,4 +54,4 @@ public class SingleProcessCoordinator : ICoordinator
|
||||
|
||||
public Task Reload()
|
||||
=> Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
#nullable disable
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -68,4 +69,4 @@ public class SoundCloudUser
|
||||
{
|
||||
[JsonProperty("username")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Immutable;
|
||||
#nullable disable
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -15,4 +16,4 @@ public class StartingGuildsService : IEnumerable<ulong>, INService
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() =>
|
||||
_guilds.GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
#nullable disable
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -169,4 +170,4 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
||||
_currentProcess.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#nullable disable
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
@@ -70,4 +71,4 @@ public class YtdlOperation
|
||||
while((line = await process.StandardOutput.ReadLineAsync()) != null)
|
||||
yield return line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Text;
|
||||
#nullable disable
|
||||
using System.Text;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
|
||||
@@ -32,4 +33,4 @@ public static class LogSetup
|
||||
return ConsoleTheme.None;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using NadekoBot.Common.Configs;
|
||||
#nullable disable
|
||||
using NadekoBot.Common.Configs;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -35,4 +36,4 @@ public sealed class BotConfigService : ConfigServiceBase<BotConfig>
|
||||
ModifyConfig(c => c.Version = 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -42,4 +43,4 @@ public static class ConfigPrinters
|
||||
|
||||
public static string Color(Rgba32 color)
|
||||
=> ((uint) ((color.B << 0) | (color.G << 8) | (color.R << 16))).ToString("X6");
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Linq.Expressions;
|
||||
#nullable disable
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using NadekoBot.Common.Yml;
|
||||
using NadekoBot.Common.Configs;
|
||||
@@ -195,4 +196,4 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
Save();
|
||||
PublishChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public interface IConfigMigrator
|
||||
{
|
||||
public void EnsureMigrated();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Interface that all services which deal with configs should implement
|
||||
@@ -39,4 +40,4 @@ public interface IConfigService
|
||||
/// <param name="newValue">Value to set the property to</param>
|
||||
/// <returns>Success</returns>
|
||||
bool SetSetting(string prop, string newValue);
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate which describes a parser which can convert string input into given data type
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">Data type to convert string to</typeparam>
|
||||
public delegate bool SettingParser<TData>(string input, out TData output);
|
||||
public delegate bool SettingParser<TData>(string input, out TData output);
|
||||
|
@@ -1,7 +1,8 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public static class StandardConversions
|
||||
{
|
||||
public static double CelsiusToFahrenheit(double cel)
|
||||
=> (cel * 1.8f) + 32;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
@@ -12,4 +13,4 @@ public interface IBotStrings
|
||||
void Reload();
|
||||
CommandStrings GetCommandStrings(string commandName, ulong? guildId = null);
|
||||
CommandStrings GetCommandStrings(string commandName, CultureInfo cultureInfo);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Implemented by classes which provide localized strings in their own ways
|
||||
@@ -24,4 +25,4 @@ public interface IBotStringsProvider
|
||||
/// <param name="localeName">Language name</param>
|
||||
/// <param name="commandName">Command name</param>
|
||||
CommandStrings GetCommandStrings(string localeName, string commandName);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Basic interface used for classes implementing strings loading mechanism
|
||||
@@ -12,4 +13,4 @@ public interface IStringsSource
|
||||
Dictionary<string, Dictionary<string, string>> GetResponseStrings();
|
||||
|
||||
Dictionary<string, Dictionary<string, CommandStrings>> GetCommandStrings();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -99,4 +100,4 @@ public class CommandStrings
|
||||
public string Desc { get; set; }
|
||||
[YamlMember(Alias = "args")]
|
||||
public string[] Args { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
namespace NadekoBot.Services;
|
||||
#nullable disable
|
||||
namespace NadekoBot.Services;
|
||||
|
||||
public class LocalBotStringsProvider : IBotStringsProvider
|
||||
{
|
||||
@@ -39,4 +40,4 @@ public class LocalBotStringsProvider : IBotStringsProvider
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
#nullable disable
|
||||
using Newtonsoft.Json;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -69,4 +70,4 @@ public class LocalFileStringsSource : IStringsSource
|
||||
var secondDotIndex = fileName.LastIndexOf('.');
|
||||
return fileName.Substring(dotIndex, secondDotIndex - dotIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Web;
|
||||
#nullable disable
|
||||
using System.Web;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace NadekoBot.Services;
|
||||
@@ -72,4 +73,4 @@ public class RedisBotStringsProvider : IBotStringsProvider
|
||||
redisDb.HashSet($"{_creds.RedisKey()}:commands:{localeName}", hashFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user