Change build settings, fix minor problems
This commit is contained in:
parent
e1a39f964f
commit
94d4a27e85
13 changed files with 163 additions and 91 deletions
107
.editorconfig
107
.editorconfig
|
@ -75,59 +75,59 @@ dotnet_style_allow_statement_immediately_after_block_experimental = true
|
||||||
#### C# Coding Conventions ####
|
#### C# Coding Conventions ####
|
||||||
|
|
||||||
# var preferences
|
# var preferences
|
||||||
csharp_style_var_elsewhere = false
|
csharp_style_var_elsewhere = false:silent
|
||||||
csharp_style_var_for_built_in_types = false
|
csharp_style_var_for_built_in_types = true:suggestion
|
||||||
csharp_style_var_when_type_is_apparent = false
|
csharp_style_var_when_type_is_apparent = false:silent
|
||||||
|
|
||||||
# Expression-bodied members
|
# Expression-bodied members
|
||||||
csharp_style_expression_bodied_accessors = true
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
csharp_style_expression_bodied_constructors = true
|
csharp_style_expression_bodied_constructors = true:silent
|
||||||
csharp_style_expression_bodied_indexers = true
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
csharp_style_expression_bodied_lambdas = true
|
csharp_style_expression_bodied_lambdas = true:silent
|
||||||
csharp_style_expression_bodied_local_functions = true
|
csharp_style_expression_bodied_local_functions = true:silent
|
||||||
csharp_style_expression_bodied_methods = true
|
csharp_style_expression_bodied_methods = true:silent
|
||||||
csharp_style_expression_bodied_operators = true
|
csharp_style_expression_bodied_operators = true:silent
|
||||||
csharp_style_expression_bodied_properties = true
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
|
||||||
# Pattern matching preferences
|
# Pattern matching preferences
|
||||||
csharp_style_pattern_matching_over_as_with_null_check = true
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
csharp_style_pattern_matching_over_is_with_cast_check = true
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
csharp_style_prefer_not_pattern = true
|
csharp_style_prefer_not_pattern = true:suggestion
|
||||||
csharp_style_prefer_pattern_matching = true:suggestion
|
csharp_style_prefer_pattern_matching = true:suggestion
|
||||||
csharp_style_prefer_switch_expression = true
|
csharp_style_prefer_switch_expression = true:suggestion
|
||||||
|
|
||||||
# Null-checking preferences
|
# Null-checking preferences
|
||||||
csharp_style_conditional_delegate_call = true
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
|
||||||
# Modifier preferences
|
# Modifier preferences
|
||||||
csharp_prefer_static_local_function = true
|
csharp_prefer_static_local_function = true:suggestion
|
||||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
|
||||||
|
|
||||||
# Code-block preferences
|
# Code-block preferences
|
||||||
csharp_prefer_braces = when_multiline
|
csharp_prefer_braces = when_multiline:silent
|
||||||
csharp_prefer_simple_using_statement = true
|
csharp_prefer_simple_using_statement = true:suggestion
|
||||||
csharp_style_namespace_declarations = file_scoped
|
csharp_style_namespace_declarations = file_scoped:suggestion
|
||||||
|
|
||||||
# Expression-level preferences
|
# Expression-level preferences
|
||||||
csharp_prefer_simple_default_expression = true
|
csharp_prefer_simple_default_expression = true:suggestion
|
||||||
csharp_style_deconstructed_variable_declaration = true
|
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||||
csharp_style_implicit_object_creation_when_type_is_apparent = true
|
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||||
csharp_style_inlined_variable_declaration = true
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
csharp_style_pattern_local_over_anonymous_function = true
|
csharp_style_pattern_local_over_anonymous_function = true
|
||||||
csharp_style_prefer_index_operator = true
|
csharp_style_prefer_index_operator = true:suggestion
|
||||||
csharp_style_prefer_null_check_over_type_check = true
|
csharp_style_prefer_null_check_over_type_check = true:suggestion
|
||||||
csharp_style_prefer_range_operator = true
|
csharp_style_prefer_range_operator = true:suggestion
|
||||||
csharp_style_throw_expression = true
|
csharp_style_throw_expression = true:suggestion
|
||||||
csharp_style_unused_value_assignment_preference = discard_variable
|
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||||
csharp_style_unused_value_expression_statement_preference = discard_variable
|
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||||
|
|
||||||
# 'using' directive preferences
|
# 'using' directive preferences
|
||||||
csharp_using_directive_placement = outside_namespace
|
csharp_using_directive_placement = outside_namespace:silent
|
||||||
|
|
||||||
# New line preferences
|
# New line preferences
|
||||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
|
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false:suggestion
|
||||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
|
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion
|
||||||
csharp_style_allow_embedded_statements_on_same_line_experimental = true
|
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
|
||||||
|
|
||||||
#### C# Formatting Rules ####
|
#### C# Formatting Rules ####
|
||||||
|
|
||||||
|
@ -217,3 +217,42 @@ dotnet_naming_style.begins_with_i.required_prefix = I
|
||||||
dotnet_naming_style.begins_with_i.required_suffix =
|
dotnet_naming_style.begins_with_i.required_suffix =
|
||||||
dotnet_naming_style.begins_with_i.word_separator =
|
dotnet_naming_style.begins_with_i.word_separator =
|
||||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||||
|
csharp_style_prefer_local_over_anonymous_function = true:suggestion
|
||||||
|
csharp_style_prefer_tuple_swap = true:suggestion
|
||||||
|
csharp_style_prefer_extended_property_pattern = true:suggestion
|
||||||
|
|
||||||
|
[*.{cs,vb}]
|
||||||
|
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||||
|
tab_width = 4
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = crlf
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||||
|
dotnet_style_prefer_auto_properties = true:suggestion
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
dotnet_style_namespace_match_folder = true:suggestion
|
||||||
|
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||||
|
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||||
|
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||||
|
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||||
|
dotnet_style_readonly_field = true:suggestion
|
||||||
|
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||||
|
dotnet_style_predefined_type_for_member_access = true:silent
|
||||||
|
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||||
|
dotnet_style_allow_multiple_blank_lines_experimental = false:suggestion
|
||||||
|
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
|
||||||
|
dotnet_code_quality_unused_parameters = all:suggestion
|
||||||
|
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||||
|
dotnet_style_qualification_for_field = false:silent
|
||||||
|
dotnet_style_qualification_for_property = false:silent
|
||||||
|
dotnet_style_qualification_for_method = false:silent
|
||||||
|
dotnet_style_qualification_for_event = false:silent
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
.vs/
|
.vs/
|
||||||
*.user
|
*.user
|
||||||
|
output/
|
|
@ -3,15 +3,16 @@
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper class for managing rate limit data.
|
/// Helper class for managing rate limit data.
|
||||||
/// More accurately, this class holds entries, not allowing the same entry to be held more than once until a specified
|
/// More accurately, this class holds entries, not allowing the same entry to be held more than once until a specified
|
||||||
/// amount of time has paspsed since the entry was originally tracked; useful for a rate limit system.
|
/// amount of time has passed since the entry was originally tracked; useful for a rate limit system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class RateLimit<T> {
|
class RateLimit<T> where T : notnull {
|
||||||
public const ushort DefaultTimeout = 20; // Skeeter's a cool guy and you can't convince me otherwise.
|
public const ushort DefaultTimeout = 20; // Skeeter's a cool guy and you can't convince me otherwise.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Time until an entry within this instance expires, in seconds.
|
||||||
|
/// </summary>
|
||||||
public uint Timeout { get; }
|
public uint Timeout { get; }
|
||||||
#pragma warning disable CS8714
|
|
||||||
private Dictionary<T, DateTime> Entries { get; } = new Dictionary<T, DateTime>();
|
private Dictionary<T, DateTime> Entries { get; } = new Dictionary<T, DateTime>();
|
||||||
#pragma warning restore CS8714
|
|
||||||
|
|
||||||
public RateLimit() : this(DefaultTimeout) { }
|
public RateLimit() : this(DefaultTimeout) { }
|
||||||
public RateLimit(uint timeout) => Timeout = timeout;
|
public RateLimit(uint timeout) => Timeout = timeout;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
@ -7,6 +7,9 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Authors>NoiTheCat</Authors>
|
<Authors>NoiTheCat</Authors>
|
||||||
<Description>A set of standard modules for use with RegexBot.</Description>
|
<Description>A set of standard modules for use with RegexBot.</Description>
|
||||||
|
<BaseOutputPath>$(SolutionDir)\output</BaseOutputPath>
|
||||||
|
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||||
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -25,13 +25,9 @@ public class FilterList {
|
||||||
/// <exception cref="FormatException">
|
/// <exception cref="FormatException">
|
||||||
/// Thrown if there is a problem with input. The exception message specifies the reason.
|
/// Thrown if there is a problem with input. The exception message specifies the reason.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public FilterList(
|
public FilterList(JObject config, string whitelistKey = "whitelist", string blacklistKey = "blacklist", string exemptKey = "exempt") {
|
||||||
JObject config,
|
if (whitelistKey != null && config[whitelistKey] != null &&
|
||||||
string whitelistKey = "whitelist",
|
blacklistKey != null && config[blacklistKey] != null) {
|
||||||
string blacklistKey = "blacklist",
|
|
||||||
string exemptKey = "exempt") {
|
|
||||||
if ((whitelistKey != null && config[whitelistKey] != null) &&
|
|
||||||
(blacklistKey != null && config[blacklistKey] != null)) {
|
|
||||||
throw new FormatException($"Cannot have both '{whitelistKey}' and '{blacklistKey}' defined at once.");
|
throw new FormatException($"Cannot have both '{whitelistKey}' and '{blacklistKey}' defined at once.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,12 +79,12 @@ public class FilterList {
|
||||||
public bool IsFiltered(SocketMessage msg, bool keepId) {
|
public bool IsFiltered(SocketMessage msg, bool keepId) {
|
||||||
if (Mode == FilterMode.None) return false;
|
if (Mode == FilterMode.None) return false;
|
||||||
|
|
||||||
bool inFilter = FilteredList.IsListMatch(msg, keepId);
|
var isInFilter = FilteredList.IsListMatch(msg, keepId);
|
||||||
if (Mode == FilterMode.Whitelist) {
|
if (Mode == FilterMode.Whitelist) {
|
||||||
if (!inFilter) return true;
|
if (!isInFilter) return true;
|
||||||
return FilterExemptions.IsListMatch(msg, keepId);
|
return FilterExemptions.IsListMatch(msg, keepId);
|
||||||
} else if (Mode == FilterMode.Blacklist) {
|
} else if (Mode == FilterMode.Blacklist) {
|
||||||
if (!inFilter) return false;
|
if (!isInFilter) return false;
|
||||||
return !FilterExemptions.IsListMatch(msg, keepId);
|
return !FilterExemptions.IsListMatch(msg, keepId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace RegexBot.Data;
|
||||||
|
|
||||||
public class BotDatabaseContext : DbContext {
|
public class BotDatabaseContext : DbContext {
|
||||||
private static string? _npgsqlConnectionString;
|
private static string? _npgsqlConnectionString;
|
||||||
internal static string NpgsqlConnectionString {
|
internal static string PostgresConnectionString {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
get {
|
get {
|
||||||
if (_npgsqlConnectionString != null) return _npgsqlConnectionString;
|
if (_npgsqlConnectionString != null) return _npgsqlConnectionString;
|
||||||
|
@ -24,7 +24,7 @@ public class BotDatabaseContext : DbContext {
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
=> optionsBuilder
|
=> optionsBuilder
|
||||||
.UseNpgsql(NpgsqlConnectionString)
|
.UseNpgsql(PostgresConnectionString)
|
||||||
.UseSnakeCaseNamingConvention();
|
.UseSnakeCaseNamingConvention();
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using RegexBot.Data;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace RegexBot;
|
namespace RegexBot;
|
||||||
|
@ -19,11 +20,6 @@ class InstanceConfig {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal string[] Assemblies { get; }
|
internal string[] Assemblies { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Connection string for accessing the PostgreSQL database.
|
|
||||||
/// </summary>
|
|
||||||
internal string PostgresConnString { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Webhook URL for bot log reporting.
|
/// Webhook URL for bot log reporting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -37,7 +33,7 @@ class InstanceConfig {
|
||||||
internal InstanceConfig(string[] cmdline) {
|
internal InstanceConfig(string[] cmdline) {
|
||||||
var opts = Options.ParseOptions(cmdline);
|
var opts = Options.ParseOptions(cmdline);
|
||||||
|
|
||||||
string path = opts.ConfigFile;
|
var path = opts.ConfigFile;
|
||||||
if (path == null) { // default: config.json in working directory
|
if (path == null) { // default: config.json in working directory
|
||||||
path = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)
|
path = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)
|
||||||
+ "." + Path.DirectorySeparatorChar + "config.json";
|
+ "." + Path.DirectorySeparatorChar + "config.json";
|
||||||
|
@ -60,9 +56,10 @@ class InstanceConfig {
|
||||||
if (string.IsNullOrEmpty(BotToken))
|
if (string.IsNullOrEmpty(BotToken))
|
||||||
throw new Exception($"'{nameof(BotToken)}' is not properly specified in configuration.");
|
throw new Exception($"'{nameof(BotToken)}' is not properly specified in configuration.");
|
||||||
|
|
||||||
PostgresConnString = conf[nameof(PostgresConnString)]?.Value<string>()!;
|
var pginput = conf[nameof(BotDatabaseContext.PostgresConnectionString)]?.Value<string>()!;
|
||||||
if (string.IsNullOrEmpty(PostgresConnString))
|
if (string.IsNullOrEmpty(pginput))
|
||||||
throw new Exception($"'{nameof(PostgresConnString)}' is not properly specified in configuration.");
|
throw new Exception($"'{nameof(BotDatabaseContext.PostgresConnectionString)}' is not properly specified in configuration.");
|
||||||
|
BotDatabaseContext.PostgresConnectionString = pginput;
|
||||||
|
|
||||||
InstanceLogTarget = conf[nameof(InstanceLogTarget)]?.Value<string>()!;
|
InstanceLogTarget = conf[nameof(InstanceLogTarget)]?.Value<string>()!;
|
||||||
if (string.IsNullOrEmpty(InstanceLogTarget))
|
if (string.IsNullOrEmpty(InstanceLogTarget))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace RegexBot;
|
namespace RegexBot;
|
||||||
|
|
||||||
|
@ -42,12 +43,14 @@ static class ModuleLoader {
|
||||||
select type;
|
select type;
|
||||||
k._svcLogging.DoLog(false, nameof(ModuleLoader), $"Scanning {asm.GetName().Name}");
|
k._svcLogging.DoLog(false, nameof(ModuleLoader), $"Scanning {asm.GetName().Name}");
|
||||||
|
|
||||||
|
var newreport = new StringBuilder("---> Found module(s):");
|
||||||
var newmods = new List<RegexbotModule>();
|
var newmods = new List<RegexbotModule>();
|
||||||
foreach (var t in eligibleTypes) {
|
foreach (var t in eligibleTypes) {
|
||||||
var mod = Activator.CreateInstance(t, k)!;
|
var mod = Activator.CreateInstance(t, k)!;
|
||||||
k._svcLogging.DoLog(false, nameof(ModuleLoader), $"---> Loading module {t.FullName}");
|
newreport.Append($" {t.Name}");
|
||||||
newmods.Add((RegexbotModule)mod);
|
newmods.Add((RegexbotModule)mod);
|
||||||
}
|
}
|
||||||
|
k._svcLogging.DoLog(false, nameof(ModuleLoader), newreport.ToString());
|
||||||
return newmods;
|
return newmods;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,8 @@
|
||||||
<Version>0.0.1</Version>
|
<Version>0.0.1</Version>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
|
<BaseOutputPath>$(SolutionDir)\output</BaseOutputPath>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
<DebugSymbols>false</DebugSymbols>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -24,13 +21,15 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageReference Include="Discord.Net" Version="3.6.1" />
|
<PackageReference Include="Discord.Net" Version="3.7.0" />
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="6.0.0" />
|
<PackageReference Include="EFCore.NamingConventions" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.5" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.5">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.5">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.5" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Npgsql" Version="6.0.4" />
|
<PackageReference Include="Npgsql" Version="6.0.4" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.4" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.4" />
|
||||||
|
|
|
@ -32,11 +32,10 @@ public partial class RegexbotClient {
|
||||||
_svcCommonFunctions = new Services.CommonFunctions.CommonFunctionsService(this);
|
_svcCommonFunctions = new Services.CommonFunctions.CommonFunctionsService(this);
|
||||||
_svcEntityCache = new Services.EntityCache.EntityCacheService(this);
|
_svcEntityCache = new Services.EntityCache.EntityCacheService(this);
|
||||||
|
|
||||||
|
var ver = Assembly.GetExecutingAssembly().GetName().Version!;
|
||||||
|
_svcLogging.DoLog(true, nameof(RegexBot), $"{nameof(RegexBot)} v{ver:3} - https://github.com/NoiTheCat/RegexBot");
|
||||||
|
|
||||||
// Load externally defined functionality
|
// Load externally defined functionality
|
||||||
Modules = ModuleLoader.Load(Config, this);
|
Modules = ModuleLoader.Load(Config, this);
|
||||||
|
|
||||||
// Everything's ready to go. Print the welcome message here.
|
|
||||||
var ver = Assembly.GetExecutingAssembly().GetName().Version!.ToString(3);
|
|
||||||
_svcLogging.DoLog(true, nameof(RegexBot), $"{nameof(RegexBot)} v{ver} - https://github.com/NoiTheCat/RegexBot");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Discord.Net;
|
using Discord.Net;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using static RegexBot.RegexbotClient;
|
|
||||||
|
|
||||||
namespace RegexBot.Services.CommonFunctions;
|
namespace RegexBot.Services.CommonFunctions;
|
||||||
|
|
||||||
|
@ -16,14 +15,15 @@ internal class CommonFunctionsService : Service {
|
||||||
public CommonFunctionsService(RegexbotClient bot) : base(bot) { }
|
public CommonFunctionsService(RegexbotClient bot) : base(bot) { }
|
||||||
|
|
||||||
#region Guild member removal
|
#region Guild member removal
|
||||||
/// <summary>
|
// Hooked (indirectly)
|
||||||
/// Common processing for kicks and bans. Called by DoKickAsync and DoBanAsync.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="logReason">The reason to insert into the Audit Log.</param>
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static")]
|
||||||
internal async Task<BanKickResult> BanOrKickAsync(
|
internal async Task<BanKickResult> BanOrKickAsync(RemovalType t,
|
||||||
RemovalType t, SocketGuild guild, string source, ulong target, int banPurgeDays,
|
SocketGuild guild,
|
||||||
string logReason, bool sendDmToTarget) {
|
string source,
|
||||||
|
ulong target,
|
||||||
|
int banPurgeDays,
|
||||||
|
string? logReason,
|
||||||
|
bool sendDmToTarget) {
|
||||||
if (t == RemovalType.None) throw new ArgumentException("Removal type must be 'ban' or 'kick'.");
|
if (t == RemovalType.None) throw new ArgumentException("Removal type must be 'ban' or 'kick'.");
|
||||||
if (string.IsNullOrWhiteSpace(logReason)) logReason = "Reason not specified.";
|
if (string.IsNullOrWhiteSpace(logReason)) logReason = "Reason not specified.";
|
||||||
var dmSuccess = true;
|
var dmSuccess = true;
|
||||||
|
@ -42,9 +42,9 @@ internal class CommonFunctionsService : Service {
|
||||||
|
|
||||||
// Perform the action
|
// Perform the action
|
||||||
try {
|
try {
|
||||||
if (t == RemovalType.Ban) await guild.AddBanAsync(target, banPurgeDays);
|
if (t == RemovalType.Ban) await guild.AddBanAsync(target, banPurgeDays, logReason);
|
||||||
else await utarget!.KickAsync(logReason);
|
else await utarget!.KickAsync(logReason);
|
||||||
// TODO !! Insert ban reason! For kick also: Figure out a way to specify invoker.
|
// TODO for kick: Figure out a way to specify invoker.
|
||||||
} catch (HttpException ex) {
|
} catch (HttpException ex) {
|
||||||
return new BanKickResult(ex, dmSuccess, false, t, target);
|
return new BanKickResult(ex, dmSuccess, false, t, target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ namespace RegexBot;
|
||||||
partial class RegexbotClient {
|
partial class RegexbotClient {
|
||||||
private readonly CommonFunctionsService _svcCommonFunctions;
|
private readonly CommonFunctionsService _svcCommonFunctions;
|
||||||
|
|
||||||
public enum RemovalType { None, Ban, Kick }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to ban the given user from the specified guild. It is greatly preferred to call this method
|
/// Attempts to ban the given user from the specified guild. It is greatly preferred to call this method
|
||||||
/// instead of manually executing the equivalent method found in Discord.Net. It notifies other services
|
/// instead of manually executing the equivalent method found in Discord.Net. It notifies other services
|
||||||
|
@ -19,8 +17,12 @@ partial class RegexbotClient {
|
||||||
/// <param name="purgeDays">Number of days of prior post history to delete on ban. Must be between 0-7.</param>
|
/// <param name="purgeDays">Number of days of prior post history to delete on ban. Must be between 0-7.</param>
|
||||||
/// <param name="reason">Reason for the action. Sent to the Audit Log and user (if specified).</param>
|
/// <param name="reason">Reason for the action. Sent to the Audit Log and user (if specified).</param>
|
||||||
/// <param name="sendDMToTarget">Specify whether to send a direct message to the target user informing them of the action.</param>
|
/// <param name="sendDMToTarget">Specify whether to send a direct message to the target user informing them of the action.</param>
|
||||||
public Task<BanKickResult> BanAsync(SocketGuild guild, string source, ulong targetUser,
|
public Task<BanKickResult> BanAsync(SocketGuild guild,
|
||||||
int purgeDays, string reason, bool sendDMToTarget)
|
string source,
|
||||||
|
ulong targetUser,
|
||||||
|
int purgeDays,
|
||||||
|
string? reason,
|
||||||
|
bool sendDMToTarget)
|
||||||
=> _svcCommonFunctions.BanOrKickAsync(RemovalType.Ban, guild, source, targetUser, purgeDays, reason, sendDMToTarget);
|
=> _svcCommonFunctions.BanOrKickAsync(RemovalType.Ban, guild, source, targetUser, purgeDays, reason, sendDMToTarget);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -28,8 +30,12 @@ partial class RegexbotClient {
|
||||||
/// EntityCache lookup to determine the target.
|
/// EntityCache lookup to determine the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="targetSearch">The EntityCache search string.</param>
|
/// <param name="targetSearch">The EntityCache search string.</param>
|
||||||
public async Task<BanKickResult> BanAsync(SocketGuild guild, string source, string targetSearch,
|
public async Task<BanKickResult> BanAsync(SocketGuild guild,
|
||||||
int purgeDays, string reason, bool sendDMToTarget) {
|
string source,
|
||||||
|
string targetSearch,
|
||||||
|
int purgeDays,
|
||||||
|
string? reason,
|
||||||
|
bool sendDMToTarget) {
|
||||||
var result = EcQueryGuildUser(guild.Id, targetSearch);
|
var result = EcQueryGuildUser(guild.Id, targetSearch);
|
||||||
if (result == null) return new BanKickResult(null, false, true, RemovalType.Ban, 0);
|
if (result == null) return new BanKickResult(null, false, true, RemovalType.Ban, 0);
|
||||||
return await BanAsync(guild, source, (ulong)result.UserId, purgeDays, reason, sendDMToTarget);
|
return await BanAsync(guild, source, (ulong)result.UserId, purgeDays, reason, sendDMToTarget);
|
||||||
|
@ -52,15 +58,23 @@ partial class RegexbotClient {
|
||||||
/// Specify whether to send a direct message to the target user informing them of the action
|
/// Specify whether to send a direct message to the target user informing them of the action
|
||||||
/// (that is, a ban/kick message).
|
/// (that is, a ban/kick message).
|
||||||
/// </param>
|
/// </param>
|
||||||
public Task<BanKickResult> KickAsync(SocketGuild guild, string source, ulong targetUser, string reason, bool sendDMToTarget)
|
public Task<BanKickResult> KickAsync(SocketGuild guild,
|
||||||
=> _svcCommonFunctions.BanOrKickAsync(RemovalType.Ban, guild, source, targetUser, 0, reason, sendDMToTarget);
|
string source,
|
||||||
|
ulong targetUser,
|
||||||
|
string? reason,
|
||||||
|
bool sendDMToTarget)
|
||||||
|
=> _svcCommonFunctions.BanOrKickAsync(RemovalType.Kick, guild, source, targetUser, default, reason, sendDMToTarget);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Similar to <see cref="KickAsync(SocketGuild, string, ulong, string, bool)"/>, but making use of an
|
/// Similar to <see cref="KickAsync(SocketGuild, string, ulong, string, bool)"/>, but making use of an
|
||||||
/// EntityCache lookup to determine the target.
|
/// EntityCache lookup to determine the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="targetSearch">The EntityCache search string.</param>
|
/// <param name="targetSearch">The EntityCache search string.</param>
|
||||||
public async Task<BanKickResult> KickAsync(SocketGuild guild, string source, string targetSearch, string reason, bool sendDMToTarget) {
|
public async Task<BanKickResult> KickAsync(SocketGuild guild,
|
||||||
|
string source,
|
||||||
|
string targetSearch,
|
||||||
|
string? reason,
|
||||||
|
bool sendDMToTarget) {
|
||||||
var result = EcQueryGuildUser(guild.Id, targetSearch);
|
var result = EcQueryGuildUser(guild.Id, targetSearch);
|
||||||
if (result == null) return new BanKickResult(null, false, true, RemovalType.Kick, 0);
|
if (result == null) return new BanKickResult(null, false, true, RemovalType.Kick, 0);
|
||||||
return await KickAsync(guild, source, (ulong)result.UserId, reason, sendDMToTarget);
|
return await KickAsync(guild, source, (ulong)result.UserId, reason, sendDMToTarget);
|
||||||
|
|
20
RegexBot/Services/CommonFunctions/RemovalType.cs
Normal file
20
RegexBot/Services/CommonFunctions/RemovalType.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Despite specific to CommonFunctionsService, this enum is meant to be visible by modules too,
|
||||||
|
// thus it is placed within the root namespace.
|
||||||
|
namespace RegexBot;
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies possible outcomes for the removal of a user from a guild.
|
||||||
|
/// </summary>
|
||||||
|
public enum RemovalType {
|
||||||
|
/// <summary>
|
||||||
|
/// Default value. Not used in any actual circumstances.
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that the type of removal includes placing the user on the guild's ban list.
|
||||||
|
/// </summary>
|
||||||
|
Ban,
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that the user is removed from the server via kick.
|
||||||
|
/// </summary>
|
||||||
|
Kick
|
||||||
|
}
|
Loading…
Reference in a new issue