Updated common files
This commit is contained in:
parent
b045015efb
commit
a63889b2f3
61 changed files with 188 additions and 227 deletions
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
||||||
public enum AddRemove
|
public enum AddRemove
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace EllieBot.Common.Attributes;
|
namespace EllieBot.Common.Attributes;
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,5 @@ namespace EllieBot.Common;
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class DIIgnoreAttribute : Attribute
|
public class DIIgnoreAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.Attributes;
|
namespace EllieBot.Common.Attributes;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
public sealed class EllieOptionsAttribute<TOption> : Attribute
|
public sealed class EllieOptionsAttribute<TOption> : Attribute
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace EllieBot.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace EllieBot.Common.Attributes;
|
namespace EllieBot.Common.Attributes;
|
||||||
|
|
||||||
|
@ -16,4 +16,4 @@ public sealed class OwnerOnlyAttribute : PreconditionAttribute
|
||||||
? PreconditionResult.FromSuccess()
|
? PreconditionResult.FromSuccess()
|
||||||
: PreconditionResult.FromError("Not owner"));
|
: PreconditionResult.FromError("Not owner"));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace EllieBot.Common.Attributes;
|
namespace EllieBot.Common.Attributes;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Discord;
|
namespace Discord;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using EllieBot.Common.Yml;
|
using EllieBot.Common.Yml;
|
||||||
using YamlDotNet.Serialization;
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace EllieBot.Common.Attributes;
|
namespace EllieBot.Common.Attributes;
|
||||||
|
|
|
@ -44,13 +44,13 @@ public sealed partial class BotConfig : ICloneable<BotConfig>
|
||||||
or all owners? (this might cause the bot to lag if there's a lot of owners specified)
|
or all owners? (this might cause the bot to lag if there's a lot of owners specified)
|
||||||
""")]
|
""")]
|
||||||
public bool ForwardToAllOwners { get; set; }
|
public bool ForwardToAllOwners { get; set; }
|
||||||
|
|
||||||
[Comment("""
|
[Comment("""
|
||||||
Any messages sent by users in Bot's DM to be forwarded to the specified channel.
|
Any messages sent by users in Bot's DM to be forwarded to the specified channel.
|
||||||
This option will only work when ForwardToAllOwners is set to false
|
This option will only work when ForwardToAllOwners is set to false
|
||||||
""")]
|
""")]
|
||||||
public ulong? ForwardToChannel { get; set; }
|
public ulong? ForwardToChannel { get; set; }
|
||||||
|
|
||||||
[Comment("""
|
[Comment("""
|
||||||
Should the bot ignore messages from other bots?
|
Should the bot ignore messages from other bots?
|
||||||
Settings this to false might get your bot banned if it gets into a spam loop with another bot.
|
Settings this to false might get your bot banned if it gets into a spam loop with another bot.
|
||||||
|
@ -155,11 +155,11 @@ public sealed partial class BotConfig : ICloneable<BotConfig>
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Comment(@"Whether the prefix will be a suffix, or prefix.
|
// [Comment(@"Whether the prefix will be a suffix, or prefix.
|
||||||
// For example, if your prefix is ! you will run a command called 'cash' by typing either
|
// For example, if your prefix is ! you will run a command called 'cash' by typing either
|
||||||
// '!cash @Someone' if your prefixIsSuffix: false or
|
// '!cash @Someone' if your prefixIsSuffix: false or
|
||||||
// 'cash @Someone!' if your prefixIsSuffix: true")]
|
// 'cash @Someone!' if your prefixIsSuffix: true")]
|
||||||
// public bool PrefixIsSuffix { get; set; }
|
// public bool PrefixIsSuffix { get; set; }
|
||||||
|
|
||||||
// public string Prefixed(string text) => PrefixIsSuffix
|
// public string Prefixed(string text) => PrefixIsSuffix
|
||||||
// ? text + Prefix
|
// ? text + Prefix
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.Configs;
|
namespace EllieBot.Common.Configs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base interface for available config serializers
|
/// Base interface for available config serializers
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using EllieBot.Common.Yml;
|
using EllieBot.Common.Yml;
|
||||||
|
|
||||||
namespace Ellie.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
||||||
public sealed class Creds : IBotCredentials
|
public sealed class Creds : IBotCredentials
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ public sealed class Creds : IBotCredentials
|
||||||
**DO NOT ADD PEOPLE YOU DON'T TRUST**
|
**DO NOT ADD PEOPLE YOU DON'T TRUST**
|
||||||
""")]
|
""")]
|
||||||
public ICollection<ulong> OwnerIds { get; set; }
|
public ICollection<ulong> OwnerIds { get; set; }
|
||||||
|
|
||||||
[Comment("Keep this on 'true' unless you're sure your bot shouldn't use privileged intents or you're waiting to be accepted")]
|
[Comment("Keep this on 'true' unless you're sure your bot shouldn't use privileged intents or you're waiting to be accepted")]
|
||||||
public bool UsePrivilegedIntents { get; set; }
|
public bool UsePrivilegedIntents { get; set; }
|
||||||
|
|
||||||
|
@ -29,15 +29,24 @@ public sealed class Creds : IBotCredentials
|
||||||
""")]
|
""")]
|
||||||
public int TotalShards { get; set; }
|
public int TotalShards { get; set; }
|
||||||
|
|
||||||
[Comment(
|
[Comment("""
|
||||||
|
Pledge 5$ or more on https://patreon.com/elliebot and connect your discord account to Patreon.
|
||||||
|
Go to https://dashy.elliebot.net and login with your discord account
|
||||||
|
Go to the Keys page and click "Generate New Key" and copy it here
|
||||||
|
You and anyone else with the permission to run `.prompt` command will be able to use natural language to run bot's commands.
|
||||||
|
For example '@Bot how's the weather in Paris' will return the current weather in Paris as if you were to run `.weather Paris` command
|
||||||
|
""")]
|
||||||
|
public string EllieAiToken { get; set; }
|
||||||
|
|
||||||
|
[Comment(
|
||||||
"""
|
"""
|
||||||
Login to https://console.cloud.google.com, create a new project, go to APIs & Services -> Library -> YouTube Data API and enable it.
|
Login to https://console.cloud.google.com, create a new project, go to APIs & Services -> Library -> YouTube Data API and enable it.
|
||||||
Then, go to APIs and Services -> Credentials and click Create credentials -> API key.
|
Then, go to APIs and Services -> Credentials and click Create credentials -> API key.
|
||||||
Used only for Youtube Data Api (at the moment).
|
Used only for Youtube Data Api (at the moment).
|
||||||
""")]
|
""")]
|
||||||
public string GoogleApiKey { get; set; }
|
public string GoogleApiKey { get; set; }
|
||||||
|
|
||||||
[Comment(
|
[Comment(
|
||||||
"""
|
"""
|
||||||
Create a new custom search here https://programmablesearchengine.google.com/cse/create/new
|
Create a new custom search here https://programmablesearchengine.google.com/cse/create/new
|
||||||
Enable SafeSearch
|
Enable SafeSearch
|
||||||
|
@ -64,16 +73,16 @@ public sealed class Creds : IBotCredentials
|
||||||
[Comment("""Official cleverbot api key.""")]
|
[Comment("""Official cleverbot api key.""")]
|
||||||
public string CleverbotApiKey { get; set; }
|
public string CleverbotApiKey { get; set; }
|
||||||
|
|
||||||
[Comment(@"Official GPT-3 api key.")]
|
[Comment(@"OpenAi api key.")]
|
||||||
public string Gpt3ApiKey { get; set; }
|
public string Gpt3ApiKey { get; set; }
|
||||||
|
|
||||||
[Comment("""
|
[Comment("""
|
||||||
Which cache implementation should bot use.
|
Which cache implementation should bot use.
|
||||||
'memory' - Cache will be in memory of the bot's process itself. Only use this on bots with a single shard. When the bot is restarted the cache is reset.
|
'memory' - Cache will be in memory of the bot's process itself. Only use this on bots with a single shard. When the bot is restarted the cache is reset.
|
||||||
'redis' - Uses redis (which needs to be separately downloaded and installed). The cache will persist through bot restarts. You can configure connection string in creds.yml
|
'redis' - Uses redis (which needs to be separately downloaded and installed). The cache will persist through bot restarts. You can configure connection string in creds.yml
|
||||||
""")]
|
""")]
|
||||||
public BotCacheImplemenation BotCache { get; set; }
|
public BotCacheImplemenation BotCache { get; set; }
|
||||||
|
|
||||||
[Comment("""
|
[Comment("""
|
||||||
Redis connection string. Don't change if you don't know what you're doing.
|
Redis connection string. Don't change if you don't know what you're doing.
|
||||||
Only used if botCache is set to 'redis'
|
Only used if botCache is set to 'redis'
|
||||||
|
@ -110,10 +119,10 @@ public sealed class Creds : IBotCredentials
|
||||||
Used for cryptocurrency related commands.
|
Used for cryptocurrency related commands.
|
||||||
""")]
|
""")]
|
||||||
public string CoinmarketcapApiKey { get; set; }
|
public string CoinmarketcapApiKey { get; set; }
|
||||||
|
|
||||||
// [Comment(@"https://polygon.io/dashboard/api-keys api key. Free plan allows for 5 queries per minute.
|
// [Comment(@"https://polygon.io/dashboard/api-keys api key. Free plan allows for 5 queries per minute.
|
||||||
// Used for stocks related commands.")]
|
// Used for stocks related commands.")]
|
||||||
// public string PolygonIoApiKey { get; set; }
|
// public string PolygonIoApiKey { get; set; }
|
||||||
|
|
||||||
[Comment("""Api key used for Osu related commands. Obtain this key at https://osu.ppy.sh/p/api""")]
|
[Comment("""Api key used for Osu related commands. Obtain this key at https://osu.ppy.sh/p/api""")]
|
||||||
public string OsuApiKey { get; set; }
|
public string OsuApiKey { get; set; }
|
||||||
|
@ -171,7 +180,7 @@ public sealed class Creds : IBotCredentials
|
||||||
RestartCommand = new RestartConfig();
|
RestartCommand = new RestartConfig();
|
||||||
Google = new GoogleApiConfig();
|
Google = new GoogleApiConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DbOptions
|
public class DbOptions
|
||||||
: IDbOptions
|
: IDbOptions
|
||||||
{
|
{
|
||||||
|
@ -270,3 +279,6 @@ public class GoogleApiConfig : IGoogleApiConfig
|
||||||
public string SearchId { get; init; }
|
public string SearchId { get; init; }
|
||||||
public string ImageSearchId { get; init; }
|
public string ImageSearchId { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using MessageType = Discord.MessageType;
|
using MessageType = Discord.MessageType;
|
||||||
|
|
||||||
namespace EllieBot.Modules.Administration;
|
namespace EllieBot.Modules.Administration;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
||||||
public class DownloadTracker : IEService
|
public class DownloadTracker : IEService
|
||||||
|
|
|
@ -91,7 +91,7 @@ public abstract class EllieModule : ModuleBase
|
||||||
|
|
||||||
if (validate is not null && !validate(arg.Content))
|
if (validate is not null && !validate(arg.Content))
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
if (userInputTask.TrySetResult(arg.Content))
|
if (userInputTask.TrySetResult(arg.Content))
|
||||||
userMsg.DeleteAfter(1);
|
userMsg.DeleteAfter(1);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ public enum LogType
|
||||||
VoicePresence,
|
VoicePresence,
|
||||||
UserMuted,
|
UserMuted,
|
||||||
UserWarned,
|
UserWarned,
|
||||||
|
|
||||||
ThreadDeleted,
|
ThreadDeleted,
|
||||||
ThreadCreated
|
ThreadCreated
|
||||||
}
|
}
|
|
@ -17,14 +17,14 @@ public partial class PermCheckResult
|
||||||
{
|
{
|
||||||
public bool IsAllowed
|
public bool IsAllowed
|
||||||
=> IsT0;
|
=> IsT0;
|
||||||
|
|
||||||
public bool IsCooldown
|
public bool IsCooldown
|
||||||
=> IsT1;
|
=> IsT1;
|
||||||
|
|
||||||
public bool IsGlobalBlock
|
public bool IsGlobalBlock
|
||||||
=> IsT2;
|
=> IsT2;
|
||||||
|
|
||||||
public bool IsDisallowed
|
public bool IsDisallowed
|
||||||
=> IsT3;
|
=> IsT3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
||||||
public interface IPlaceholderProvider
|
public interface IPlaceholderProvider
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Cloneable;
|
||||||
namespace EllieBot.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
||||||
[Cloneable]
|
[Cloneable]
|
||||||
public partial class ImageUrls : ICloneable<ImageUrls>
|
public partial class ImageUrls : ICloneable<ImageUrls>
|
||||||
{
|
{
|
||||||
[Comment("DO NOT CHANGE")]
|
[Comment("DO NOT CHANGE")]
|
||||||
public int Version { get; set; } = 3;
|
public int Version { get; set; } = 3;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot;
|
namespace EllieBot;
|
||||||
|
|
||||||
public abstract class EllieInteractionBase
|
public abstract class EllieInteractionBase
|
||||||
{
|
{
|
||||||
|
@ -85,6 +85,9 @@ public abstract class EllieInteractionBase
|
||||||
|
|
||||||
public Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
public Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
||||||
=> _onAction(smc);
|
=> _onAction(smc);
|
||||||
|
|
||||||
|
public void SetCompleted()
|
||||||
|
=> _interactionCompletedSource.TrySetResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class EllieModalSubmitHandler
|
public sealed class EllieModalSubmitHandler
|
||||||
|
|
|
@ -20,9 +20,9 @@ public interface IEllieInteractionService
|
||||||
SelectMenuBuilder menu,
|
SelectMenuBuilder menu,
|
||||||
Func<SocketMessageComponent, Task> onTrigger,
|
Func<SocketMessageComponent, Task> onTrigger,
|
||||||
bool singleUse = true);
|
bool singleUse = true);
|
||||||
|
|
||||||
EllieInteractionBase Create(
|
EllieInteractionBase Create(
|
||||||
ulong userId,
|
ulong userId,
|
||||||
ButtonBuilder button,
|
ButtonBuilder button,
|
||||||
ModalBuilder modal,
|
ModalBuilder modal,
|
||||||
Func<SocketModal, Task> onTrigger,
|
Func<SocketModal, Task> onTrigger,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot;
|
namespace EllieBot;
|
||||||
|
|
||||||
public sealed class EllieButtonInteractionHandler : EllieInteractionBase
|
public sealed class EllieButtonInteractionHandler : EllieInteractionBase
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,6 @@ public sealed class EllieButtonInteractionHandler : EllieInteractionBase
|
||||||
|
|
||||||
public ButtonBuilder Button { get; }
|
public ButtonBuilder Button { get; }
|
||||||
|
|
||||||
public override void AddTo(ComponentBuilder cb)
|
public override void AddTo(ComponentBuilder cb)
|
||||||
=> cb.WithButton(Button);
|
=> cb.WithButton(Button);
|
||||||
}
|
}
|
|
@ -7,8 +7,8 @@ namespace EllieBot.Common.JsonConverters;
|
||||||
public class CultureInfoConverter : JsonConverter<CultureInfo>
|
public class CultureInfoConverter : JsonConverter<CultureInfo>
|
||||||
{
|
{
|
||||||
public override CultureInfo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override CultureInfo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
=> new(reader.GetString() ?? "en_US");
|
=> new(reader.GetString() ?? "en-US");
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, CultureInfo value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, CultureInfo value, JsonSerializerOptions options)
|
||||||
=> writer.WriteStringValue(value.Name);
|
=> writer.WriteStringValue(value.Name);
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
public class NumberToStringConverter : JsonConverter<object>
|
||||||
|
{
|
||||||
|
public override bool CanConvert(Type typeToConvert)
|
||||||
|
=> typeof(string) == typeToConvert;
|
||||||
|
|
||||||
|
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
switch (reader.TokenType)
|
||||||
|
{
|
||||||
|
case JsonTokenType.Number:
|
||||||
|
return reader.TryGetInt64(out var l)
|
||||||
|
? l.ToString()
|
||||||
|
: reader.GetDouble().ToString(CultureInfo.InvariantCulture);
|
||||||
|
case JsonTokenType.String:
|
||||||
|
return reader.GetString() ?? string.Empty;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
using var document = JsonDocument.ParseValue(ref reader);
|
||||||
|
return document.RootElement.Clone().ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
|
||||||
|
=> writer.WriteStringValue(value.ToString());
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ public static class Linq2DbExpressions
|
||||||
[ExpressionMethod(nameof(GuildOnShardExpression))]
|
[ExpressionMethod(nameof(GuildOnShardExpression))]
|
||||||
public static bool GuildOnShard(ulong guildId, int totalShards, int shardId)
|
public static bool GuildOnShard(ulong guildId, int totalShards, int shardId)
|
||||||
=> throw new NotSupportedException();
|
=> throw new NotSupportedException();
|
||||||
|
|
||||||
private static Expression<Func<ulong, int, int, bool>> GuildOnShardExpression()
|
private static Expression<Func<ulong, int, int, bool>> GuildOnShardExpression()
|
||||||
=> (guildId, totalShards, shardId)
|
=> (guildId, totalShards, shardId)
|
||||||
=> guildId / 4194304 % (ulong)totalShards == (ulong)shardId;
|
=> guildId / 4194304 % (ulong)totalShards == (ulong)shardId;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.ModuleBehaviors;
|
namespace EllieBot.Common.ModuleBehaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executed if no command was found for this message
|
/// Executed if no command was found for this message
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.ModuleBehaviors;
|
namespace EllieBot.Common.ModuleBehaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implemented by modules to handle non-bot messages received
|
/// Implemented by modules to handle non-bot messages received
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.ModuleBehaviors;
|
namespace EllieBot.Common.ModuleBehaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This interface's method is executed after the command successfully finished execution.
|
/// This interface's method is executed after the command successfully finished execution.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.ModuleBehaviors;
|
namespace EllieBot.Common.ModuleBehaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This interface's method is executed after a command was found but before it was executed.
|
/// This interface's method is executed after a command was found but before it was executed.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.ModuleBehaviors;
|
namespace EllieBot.Common.ModuleBehaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implemented by services which may transform input before a command is searched for
|
/// Implemented by services which may transform input before a command is searched for
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common.ModuleBehaviors;
|
namespace EllieBot.Common.ModuleBehaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All services which need to execute something after
|
/// All services which need to execute something after
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
|
|
||||||
namespace EllieBot.Extensions;
|
namespace EllieBot.Extensions;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public static class DryIocExtensions
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IContainer AddSingleton<TSvc, TImpl>(this IContainer container, TImpl obj)
|
public static IContainer AddSingleton<TSvc, TImpl>(this IContainer container, TImpl obj)
|
||||||
where TImpl : TSvc
|
where TImpl : TSvc
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ public static class DryIocExtensions
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IContainer AddSingleton<TImpl>(this IContainer container, Func<IResolverContext, TImpl> factory)
|
public static IContainer AddSingleton<TImpl>(this IContainer container, Func<IResolverContext, TImpl> factory)
|
||||||
{
|
{
|
||||||
container.RegisterDelegate(factory);
|
container.RegisterDelegate(factory);
|
|
@ -1,5 +1,12 @@
|
||||||
namespace EllieBot.Modules.Patronage;
|
namespace EllieBot.Modules.Patronage;
|
||||||
|
|
||||||
|
public enum LimitedFeatureName
|
||||||
|
{
|
||||||
|
ChatBot,
|
||||||
|
ReactionRole,
|
||||||
|
Prune,
|
||||||
|
|
||||||
|
}
|
||||||
public readonly struct FeatureLimitKey
|
public readonly struct FeatureLimitKey
|
||||||
{
|
{
|
||||||
public string PrettyName { get; init; }
|
public string PrettyName { get; init; }
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace EllieBot.Modules.Patronage;
|
|
||||||
|
|
||||||
public readonly struct FeatureQuotaStats
|
|
||||||
{
|
|
||||||
public (uint Cur, uint Max) Hourly { get; init; }
|
|
||||||
public (uint Cur, uint Max) Daily { get; init; }
|
|
||||||
public (uint Cur, uint Max) Monthly { get; init; }
|
|
||||||
}
|
|
|
@ -31,26 +31,15 @@ public interface IPatronageService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId">UserId for which to get the patron data for.</param>
|
/// <param name="userId">UserId for which to get the patron data for.</param>
|
||||||
/// <returns>A patron with the specifeid userId</returns>
|
/// <returns>A patron with the specifeid userId</returns>
|
||||||
public Task<Patron> GetPatronAsync(ulong userId);
|
public Task<Patron?> GetPatronAsync(ulong userId);
|
||||||
|
|
||||||
/// <summary>
|
Task<bool> LimitHitAsync(LimitedFeatureName key, ulong userId, int amount = 1);
|
||||||
/// Gets the quota statistic for the user/patron specified by the userId
|
Task<bool> LimitForceHit(LimitedFeatureName key, ulong userId, int amount);
|
||||||
/// </summary>
|
Task<QuotaLimit> GetUserLimit(LimitedFeatureName name, ulong userId);
|
||||||
/// <param name="userId">UserId of the user for which to get the quota statistic for</param>
|
|
||||||
/// <returns>Quota stats for the specified user</returns>
|
|
||||||
Task<UserQuotaStats> GetUserQuotaStatistic(ulong userId);
|
|
||||||
|
|
||||||
|
|
||||||
Task<FeatureLimit> TryGetFeatureLimitAsync(FeatureLimitKey key, ulong userId, int? defaultValue);
|
Task<Dictionary<LimitedFeatureName, (int, QuotaLimit)>> LimitStats(ulong userId);
|
||||||
|
|
||||||
ValueTask<OneOf<(uint Hourly, uint Daily, uint Monthly), QuotaLimit>> TryIncrementQuotaCounterAsync(
|
|
||||||
ulong userId,
|
|
||||||
bool isSelf,
|
|
||||||
FeatureType featureType,
|
|
||||||
string featureName,
|
|
||||||
uint? maybeHourly,
|
|
||||||
uint? maybeDaily,
|
|
||||||
uint? maybeMonthly);
|
|
||||||
|
|
||||||
PatronConfigData GetConfig();
|
PatronConfigData GetConfig();
|
||||||
|
int PercentBonus(Patron? user);
|
||||||
|
int PercentBonus(long amount);
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ public readonly struct Patron
|
||||||
public ulong UserId { get; init; }
|
public ulong UserId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Amount the Patron is currently pledging or paid
|
/// Amount the Patron is currently pledging or paid in cents
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Amount { get; init; }
|
public int Amount { get; init; }
|
||||||
|
|
||||||
|
|
|
@ -7,31 +7,11 @@ namespace EllieBot.Modules.Patronage;
|
||||||
public partial class PatronConfigData : ICloneable<PatronConfigData>
|
public partial class PatronConfigData : ICloneable<PatronConfigData>
|
||||||
{
|
{
|
||||||
[Comment("DO NOT CHANGE")]
|
[Comment("DO NOT CHANGE")]
|
||||||
public int Version { get; set; } = 2;
|
public int Version { get; set; } = 3;
|
||||||
|
|
||||||
[Comment("Whether the patronage feature is enabled")]
|
[Comment("Whether the patronage feature is enabled")]
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
[Comment("List of patron only features and relevant quota data")]
|
[Comment("Who can do how much of what")]
|
||||||
public FeatureQuotas Quotas { get; set; }
|
public Dictionary<int, Dictionary<LimitedFeatureName, QuotaLimit>> Limits { get; set; } = new();
|
||||||
|
|
||||||
public PatronConfigData()
|
|
||||||
{
|
|
||||||
Quotas = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FeatureQuotas
|
|
||||||
{
|
|
||||||
[Comment("Dictionary of feature names with their respective limits. Set to null for unlimited")]
|
|
||||||
public Dictionary<string, Dictionary<PatronTier, int?>> Features { get; set; } = new();
|
|
||||||
|
|
||||||
[Comment("Dictionary of commands with their respective quota data")]
|
|
||||||
public Dictionary<string, Dictionary<PatronTier, Dictionary<QuotaPer, uint>?>> Commands { get; set; } = new();
|
|
||||||
|
|
||||||
[Comment("Dictionary of groups with their respective quota data")]
|
|
||||||
public Dictionary<string, Dictionary<PatronTier, Dictionary<QuotaPer, uint>?>> Groups { get; set; } = new();
|
|
||||||
|
|
||||||
[Comment("Dictionary of modules with their respective quota data")]
|
|
||||||
public Dictionary<string, Dictionary<PatronTier, Dictionary<QuotaPer, uint>?>> Modules { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -8,15 +8,6 @@ public static class PatronExtensions
|
||||||
_ => $"Patron Tier {tier}",
|
_ => $"Patron Tier {tier}",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string ToFullName(this QuotaPer per)
|
|
||||||
=> per switch
|
|
||||||
{
|
|
||||||
QuotaPer.PerDay => "per day",
|
|
||||||
QuotaPer.PerHour => "per hour",
|
|
||||||
QuotaPer.PerMonth => "per month",
|
|
||||||
_ => "Unknown",
|
|
||||||
};
|
|
||||||
|
|
||||||
public static DateTime DayOfNextMonth(this DateTime date, int day)
|
public static DateTime DayOfNextMonth(this DateTime date, int day)
|
||||||
{
|
{
|
||||||
var nextMonth = date.AddMonths(1);
|
var nextMonth = date.AddMonths(1);
|
||||||
|
|
|
@ -10,57 +10,16 @@ public readonly struct QuotaLimit
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Amount of usages reached, which is the limit
|
/// Amount of usages reached, which is the limit
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Quota { get; init; }
|
public int Quota { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Which period is this quota limit for (hourly, daily, monthly, etc...)
|
/// Which period is this quota limit for (hourly, daily, monthly, etc...)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public QuotaPer QuotaPeriod { get; init; }
|
public QuotaPer QuotaPeriod { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
public QuotaLimit(int quota, QuotaPer quotaPeriod)
|
||||||
/// When does this quota limit reset
|
|
||||||
/// </summary>
|
|
||||||
public DateTime ResetsAt { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Type of the feature this quota limit is for
|
|
||||||
/// </summary>
|
|
||||||
public FeatureType FeatureType { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Name of the feature this quota limit is for
|
|
||||||
/// </summary>
|
|
||||||
public string Feature { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether it is the user's own quota (true), or server owners (false)
|
|
||||||
/// </summary>
|
|
||||||
public bool IsOwnQuota { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Respresent information about the feature limit
|
|
||||||
/// </summary>
|
|
||||||
public readonly struct FeatureLimit
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether this limit comes from the patronage system
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPatronLimit { get; init; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Maximum limit allowed
|
|
||||||
/// </summary>
|
|
||||||
public int? Quota { get; init; } = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Name of the limit
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
public FeatureLimit()
|
|
||||||
{
|
{
|
||||||
|
Quota = quota;
|
||||||
|
QuotaPeriod = quotaPeriod;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,4 +5,5 @@ public enum QuotaPer
|
||||||
PerHour,
|
PerHour,
|
||||||
PerDay,
|
PerDay,
|
||||||
PerMonth,
|
PerMonth,
|
||||||
|
Total,
|
||||||
}
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
namespace EllieBot.Modules.Patronage;
|
|
||||||
|
|
||||||
public readonly struct UserQuotaStats
|
|
||||||
{
|
|
||||||
private static readonly IReadOnlyDictionary<string, FeatureQuotaStats> _emptyDictionary
|
|
||||||
= new Dictionary<string, FeatureQuotaStats>();
|
|
||||||
public PatronTier Tier { get; init; }
|
|
||||||
= PatronTier.None;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, FeatureQuotaStats> Features { get; init; }
|
|
||||||
= _emptyDictionary;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, FeatureQuotaStats> Commands { get; init; }
|
|
||||||
= _emptyDictionary;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, FeatureQuotaStats> Groups { get; init; }
|
|
||||||
= _emptyDictionary;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, FeatureQuotaStats> Modules { get; init; }
|
|
||||||
= _emptyDictionary;
|
|
||||||
|
|
||||||
public UserQuotaStats()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Common.Pokemon;
|
namespace EllieBot.Common.Pokemon;
|
||||||
|
|
||||||
public class SearchPokemonAbility
|
public class SearchPokemonAbility
|
||||||
|
|
|
@ -95,7 +95,7 @@ public sealed partial class ReplacementPatternStore
|
||||||
Register(_rngRegex,
|
Register(_rngRegex,
|
||||||
match =>
|
match =>
|
||||||
{
|
{
|
||||||
var rng = new EllieRandom();
|
var rng = new NadekoRandom();
|
||||||
if (!int.TryParse(match.Groups["from"].ToString(), out var from))
|
if (!int.TryParse(match.Groups["from"].ToString(), out var from))
|
||||||
from = 0;
|
from = 0;
|
||||||
if (!int.TryParse(match.Groups["to"].ToString(), out var to))
|
if (!int.TryParse(match.Groups["to"].ToString(), out var to))
|
||||||
|
|
|
@ -33,15 +33,15 @@ public sealed class MessageSenderService : IMessageSenderService, IEService
|
||||||
=> new ResponseBuilder(_bs, _bcs, _client)
|
=> new ResponseBuilder(_bs, _bcs, _client)
|
||||||
.Channel(smc.Channel);
|
.Channel(smc.Channel);
|
||||||
|
|
||||||
public EllieEmbedBuilder CreateEmbed()
|
public NadekoEmbedBuilder CreateEmbed()
|
||||||
=> new EllieEmbedBuilder(_bcs);
|
=> new NadekoEmbedBuilder(_bcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EllieEmbedBuilder : EmbedBuilder
|
public class NadekoEmbedBuilder : EmbedBuilder
|
||||||
{
|
{
|
||||||
private readonly BotConfig _bc;
|
private readonly BotConfig _bc;
|
||||||
|
|
||||||
public EllieEmbedBuilder(BotConfigService bcs)
|
public NadekoEmbedBuilder(BotConfigService bcs)
|
||||||
{
|
{
|
||||||
_bc = bcs.Data;
|
_bc = bcs.Data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@ public partial class ResponseBuilder
|
||||||
private readonly ResponseBuilder _builder;
|
private readonly ResponseBuilder _builder;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private int currentPage;
|
private int currentPage;
|
||||||
|
|
||||||
|
private EllieButtonInteractionHandler left;
|
||||||
|
private EllieButtonInteractionHandler right;
|
||||||
|
private EllieInteractionBase? extra;
|
||||||
|
|
||||||
public PaginationSender(
|
public PaginationSender(
|
||||||
SourcedPaginatedResponseBuilder<T> paginationBuilder,
|
SourcedPaginatedResponseBuilder<T> paginationBuilder,
|
||||||
|
@ -106,6 +110,8 @@ public partial class ResponseBuilder
|
||||||
|
|
||||||
return (leftBtnInter, maybeInter, rightBtnInter);
|
return (leftBtnInter, maybeInter, rightBtnInter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(left, extra, right) = await GetInteractions();
|
||||||
|
|
||||||
async Task UpdatePageAsync(SocketMessageComponent smc)
|
async Task UpdatePageAsync(SocketMessageComponent smc)
|
||||||
{
|
{
|
||||||
|
@ -114,21 +120,25 @@ public partial class ResponseBuilder
|
||||||
if (_paginationBuilder.AddPaginatedFooter)
|
if (_paginationBuilder.AddPaginatedFooter)
|
||||||
toSend.AddPaginatedFooter(currentPage, lastPage);
|
toSend.AddPaginatedFooter(currentPage, lastPage);
|
||||||
|
|
||||||
var (left, extra, right) = (await GetInteractions());
|
left.SetCompleted();
|
||||||
|
right.SetCompleted();
|
||||||
|
extra?.SetCompleted();
|
||||||
|
(left, extra, right) = (await GetInteractions());
|
||||||
|
|
||||||
var cb = new ComponentBuilder();
|
var cb = new ComponentBuilder();
|
||||||
left.AddTo(cb);
|
left.AddTo(cb);
|
||||||
right.AddTo(cb);
|
right.AddTo(cb);
|
||||||
extra?.AddTo(cb);
|
extra?.AddTo(cb);
|
||||||
|
|
||||||
await smc.ModifyOriginalResponseAsync(x =>
|
await smc.ModifyOriginalResponseAsync(x =>
|
||||||
{
|
{
|
||||||
x.Embed = toSend.Build();
|
x.Embed = toSend.Build();
|
||||||
x.Components = cb.Build();
|
x.Components = cb.Build();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await Task.WhenAll(left.RunAsync(smc.Message), extra?.RunAsync(smc.Message) ?? Task.CompletedTask, right.RunAsync(smc.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
var (left, extra, right) = await GetInteractions();
|
|
||||||
|
|
||||||
var cb = new ComponentBuilder();
|
var cb = new ComponentBuilder();
|
||||||
left.AddTo(cb);
|
left.AddTo(cb);
|
||||||
|
@ -144,9 +154,11 @@ public partial class ResponseBuilder
|
||||||
|
|
||||||
if (lastPage == 0 && _paginationBuilder.InteractionFunc is null)
|
if (lastPage == 0 && _paginationBuilder.InteractionFunc is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await Task.WhenAll(left.RunAsync(msg), extra?.RunAsync(msg) ?? Task.CompletedTask, right.RunAsync(msg));
|
await Task.WhenAll(left.RunAsync(msg), extra?.RunAsync(msg) ?? Task.CompletedTask, right.RunAsync(msg));
|
||||||
|
|
||||||
|
await Task.Delay(30_000);
|
||||||
|
|
||||||
await msg.ModifyAsync(mp => mp.Components = new ComponentBuilder().Build());
|
await msg.ModifyAsync(mp => mp.Components = new ComponentBuilder().Build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
using LinqToDB.Extensions;
|
using LinqToDB.Extensions;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using EllieBot.Modules.Music;
|
using EllieBot.Modules.Music;
|
||||||
|
@ -33,7 +33,7 @@ public static class ServiceCollectionExtensions
|
||||||
|
|
||||||
public static IContainer AddConfigServices(this IContainer svcs, Assembly a)
|
public static IContainer AddConfigServices(this IContainer svcs, Assembly a)
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach (var type in a.GetTypes()
|
foreach (var type in a.GetTypes()
|
||||||
.Where(x => !x.IsAbstract && x.IsAssignableToGenericType(typeof(ConfigServiceBase<>))))
|
.Where(x => !x.IsAbstract && x.IsAssignableToGenericType(typeof(ConfigServiceBase<>))))
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ public static class ServiceCollectionExtensions
|
||||||
getServiceTypes: type => type.GetImplementedTypes(ReflectionTools.AsImplementedType.SourceType),
|
getServiceTypes: type => type.GetImplementedTypes(ReflectionTools.AsImplementedType.SourceType),
|
||||||
getImplFactory: type => ReflectionFactory.Of(type, Reuse.Singleton));
|
getImplFactory: type => ReflectionFactory.Of(type, Reuse.Singleton));
|
||||||
}
|
}
|
||||||
|
|
||||||
return svcs;
|
return svcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ public static class ServiceCollectionExtensions
|
||||||
});
|
});
|
||||||
|
|
||||||
var prov = proxySvcs.BuildServiceProvider();
|
var prov = proxySvcs.BuildServiceProvider();
|
||||||
|
|
||||||
svcs.RegisterDelegate<IHttpClientFactory>(_ => prov.GetRequiredService<IHttpClientFactory>());
|
svcs.RegisterDelegate<IHttpClientFactory>(_ => prov.GetRequiredService<IHttpClientFactory>());
|
||||||
svcs.RegisterDelegate<HttpClient>(_ => prov.GetRequiredService<HttpClient>());
|
svcs.RegisterDelegate<HttpClient>(_ => prov.GetRequiredService<HttpClient>());
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public static class ServiceCollectionExtensions
|
||||||
typeof(IInputTransformer),
|
typeof(IInputTransformer),
|
||||||
typeof(IEService)
|
typeof(IEService)
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (var svc in a.GetTypes()
|
foreach (var svc in a.GetTypes()
|
||||||
.Where(type => type.IsClass && types.Any(t => type.IsAssignableTo(t)) && !type.HasAttribute<DIIgnoreAttribute>()
|
.Where(type => type.IsClass && types.Any(t => type.IsAssignableTo(t)) && !type.HasAttribute<DIIgnoreAttribute>()
|
||||||
#if GLOBAL_ELLIE
|
#if GLOBAL_ELLIE
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace EllieBot.Services;
|
||||||
|
|
||||||
public class CommandHandler : IEService, IReadyExecutor, ICommandHandler
|
public class CommandHandler : IEService, IReadyExecutor, ICommandHandler
|
||||||
{
|
{
|
||||||
private const int GLOBAL_COMMANDS_COOLDOWN = 750;
|
private const int GLOBAL_COMMANDS_COOLDOWN = 200;
|
||||||
|
|
||||||
private const float ONE_THOUSANDTH = 1.0f / 1000;
|
private const float ONE_THOUSANDTH = 1.0f / 1000;
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ public class CommandHandler : IEService, IReadyExecutor, ICommandHandler
|
||||||
var blockTime = Environment.TickCount - startTime;
|
var blockTime = Environment.TickCount - startTime;
|
||||||
|
|
||||||
var messageContent = await _behaviorHandler.RunInputTransformersAsync(guild, usrMsg);
|
var messageContent = await _behaviorHandler.RunInputTransformersAsync(guild, usrMsg);
|
||||||
|
|
||||||
var prefix = GetPrefix(guild?.Id);
|
var prefix = GetPrefix(guild?.Id);
|
||||||
var isPrefixCommand = messageContent.StartsWith(".prefix", StringComparison.InvariantCultureIgnoreCase);
|
var isPrefixCommand = messageContent.StartsWith(".prefix", StringComparison.InvariantCultureIgnoreCase);
|
||||||
// execute the command and measure the time it took
|
// execute the command and measure the time it took
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Services;
|
namespace EllieBot.Services;
|
||||||
|
|
||||||
public interface IBehaviorHandler
|
public interface IBehaviorHandler
|
||||||
|
@ -7,7 +7,7 @@ public interface IBehaviorHandler
|
||||||
Task AddRangeAsync(IEnumerable<ICustomBehavior> behavior);
|
Task AddRangeAsync(IEnumerable<ICustomBehavior> behavior);
|
||||||
Task<bool> RemoveAsync(ICustomBehavior behavior);
|
Task<bool> RemoveAsync(ICustomBehavior behavior);
|
||||||
Task RemoveRangeAsync(IEnumerable<ICustomBehavior> behs);
|
Task RemoveRangeAsync(IEnumerable<ICustomBehavior> behs);
|
||||||
|
|
||||||
Task<bool> RunExecOnMessageAsync(SocketGuild guild, IUserMessage usrMsg);
|
Task<bool> RunExecOnMessageAsync(SocketGuild guild, IUserMessage usrMsg);
|
||||||
Task<string> RunInputTransformersAsync(SocketGuild guild, IUserMessage usrMsg);
|
Task<string> RunInputTransformersAsync(SocketGuild guild, IUserMessage usrMsg);
|
||||||
Task<bool> RunPreCommandAsync(ICommandContext context, CommandInfo cmd);
|
Task<bool> RunPreCommandAsync(ICommandContext context, CommandInfo cmd);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace EllieBot.Services;
|
namespace EllieBot.Services;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace EllieBot.Common;
|
namespace EllieBot.Common;
|
||||||
|
|
||||||
public interface ITimezoneService
|
public interface ITimezoneService
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class YtdlOperation
|
||||||
}
|
}
|
||||||
catch (Win32Exception)
|
catch (Win32Exception)
|
||||||
{
|
{
|
||||||
Log.Error("youtube-dl is likely not installed. " + "Please install it before running the command again");
|
Log.Error("youtube-dl is likely not installed. Please install it before running the command again");
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -49,21 +49,21 @@ public sealed class BotConfigService : ConfigServiceBase<BotConfig>
|
||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.Version < 4)
|
if (data.Version < 4)
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Version = 4;
|
c.Version = 4;
|
||||||
c.CheckForUpdates = true;
|
c.CheckForUpdates = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.Version < 5)
|
if(data.Version < 5)
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Version = 5;
|
c.Version = 5;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.Version < 7)
|
if(data.Version < 7)
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
c.Version = 7;
|
c.Version = 7;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public static class ConfigParsers
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool InsensitiveEnum<T>(string input, out T output)
|
public static bool InsensitiveEnum<T>(string input, out T output)
|
||||||
where T : struct
|
where T: struct
|
||||||
=> Enum.TryParse(input, true, out output);
|
=> Enum.TryParse(input, true, out output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
using EllieBot.Common.Configs;
|
using EllieBot.Common.Configs;
|
||||||
using EllieBot.Common.Yml;
|
using EllieBot.Common.Yml;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace EllieBot.Services;
|
namespace NadekoBot.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base service for all settings services
|
/// Base service for all settings services
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Services;
|
namespace EllieBot.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Services;
|
namespace EllieBot.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Common.Yml;
|
namespace EllieBot.Common.Yml;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
|
|
@ -5,7 +5,6 @@ using YamlDotNet.Serialization.EventEmitters;
|
||||||
|
|
||||||
namespace EllieBot.Common.Yml;
|
namespace EllieBot.Common.Yml;
|
||||||
|
|
||||||
|
|
||||||
public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter
|
public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter
|
||||||
{
|
{
|
||||||
public MultilineScalarFlowStyleEmitter(IEventEmitter nextEmitter)
|
public MultilineScalarFlowStyleEmitter(IEventEmitter nextEmitter)
|
||||||
|
|
|
@ -27,4 +27,14 @@ public static class CommandContextExtensions
|
||||||
|
|
||||||
public static Task WarningAsync(this ICommandContext ctx)
|
public static Task WarningAsync(this ICommandContext ctx)
|
||||||
=> ctx.ReactAsync(MsgType.Pending);
|
=> ctx.ReactAsync(MsgType.Pending);
|
||||||
|
|
||||||
|
|
||||||
|
public static Task OkAsync(this IUserMessage msg)
|
||||||
|
=> msg.AddReactionAsync(_okEmoji);
|
||||||
|
|
||||||
|
public static Task ErrorAsync(this IUserMessage msg)
|
||||||
|
=> msg.AddReactionAsync(_errorEmoji);
|
||||||
|
|
||||||
|
public static Task WarningAsync(this IUserMessage msg)
|
||||||
|
=> msg.AddReactionAsync(_warnEmoji);
|
||||||
}
|
}
|
|
@ -229,6 +229,7 @@ public static class Extensions
|
||||||
public static IEnumerable<IRole> GetRoles(this IGuildUser user)
|
public static IEnumerable<IRole> GetRoles(this IGuildUser user)
|
||||||
=> user.RoleIds.Select(r => user.Guild.GetRole(r)).Where(r => r is not null);
|
=> user.RoleIds.Select(r => user.Guild.GetRole(r)).Where(r => r is not null);
|
||||||
|
|
||||||
|
// todo remove
|
||||||
public static void Lap(this Stopwatch sw, string checkpoint)
|
public static void Lap(this Stopwatch sw, string checkpoint)
|
||||||
{
|
{
|
||||||
Log.Information("Checkpoint {CheckPoint}: {Time}ms", checkpoint, sw.Elapsed.TotalMilliseconds);
|
Log.Information("Checkpoint {CheckPoint}: {Time}ms", checkpoint, sw.Elapsed.TotalMilliseconds);
|
||||||
|
|
Loading…
Reference in a new issue