Updates and changes to project files
- Set up vscode tasks - Update Readme and License - Minor style and documentation changes
This commit is contained in:
parent
2160b0fa4e
commit
13324999cc
9 changed files with 130 additions and 54 deletions
26
.vscode/launch.json
vendored
Normal file
26
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||||
|
"name": ".NET Core Launch (console)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/output/Debug/net6.0/RegexBot.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/RegexBot",
|
||||||
|
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||||
|
"console": "internalConsole",
|
||||||
|
"stopAtEntry": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
41
.vscode/tasks.json
vendored
Normal file
41
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/RegexBot.sln",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/RegexBot.sln",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"--project",
|
||||||
|
"${workspaceFolder}/RegexBot.sln"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 Noikoio <noikoio1 AT gmail.com>
|
Copyright (c) 2018-2022 Noi <noithecat AT protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
22
README.md
22
README.md
|
@ -1,22 +0,0 @@
|
||||||
# RegexBot
|
|
||||||
**This branch contains code that is still a major work in progress, and is unusable in its current state. See the master branch for the current working version.**
|
|
||||||
|
|
||||||
RegexBot is a self-hosted Discord moderation bot that takes some inspiration from Reddit's Automoderator. It provides a number of features to assist in watching over the tedious details in a busy server with no hidden details, arbitrary restrictions, or unmodifiable behavior. Its configuration allows for a very high level of flexibility, ensuring that the bot behaves in accordance to the exact needs of your server.
|
|
||||||
|
|
||||||
### Feature overview for 3.0:
|
|
||||||
* Modular structure allows for extra features to be written, further enhancing the bot's customizability wherever it may be deployed.
|
|
||||||
* Versatile JSON-based configuration, support for separate servers.
|
|
||||||
* High detail logging and record-keeping prevents gaps in moderation that might occur with large public bots.
|
|
||||||
|
|
||||||
### Feature overview for RegexBotModule 3.0:
|
|
||||||
* Create rules based on regular expression patterns
|
|
||||||
* Follow up with custom responses ranging from sending a DM to disciplinary action
|
|
||||||
* Create pattern-based triggers to provide information and fun to your users
|
|
||||||
* Adjustable rate limits per-trigger to prevent spam
|
|
||||||
* Specify multiple different responses to display at random when triggered
|
|
||||||
* Make things interesting by setting triggers that only activate at random
|
|
||||||
* Individual rules and triggers can be whitelisted or blacklisted per-user, per-channel, or per-role
|
|
||||||
* Exemptions to these filters can be applied for additional flexibility
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
Coming soon.
|
|
34
Readme.md
Normal file
34
Readme.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# RegexBot
|
||||||
|
**This branch is still a major work in progress, and is highly incomplete. See the legacy branch for the current working version.**
|
||||||
|
|
||||||
|
RegexBot is a Discord moderation bot framework of sorts, inspired by the terrible state of Discord moderation tools a few years ago
|
||||||
|
combined with my tendency to overengineer things until they into pseudo-libraries of their own right.
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Provides a sort of in-between interface to Discord.Net that allows modules to be written for it, its benefits being:
|
||||||
|
* Putting together disparate bot features under a common interface.
|
||||||
|
* Reducing duplicate code potentially leading to an inconsistent user experience.
|
||||||
|
* Versatile JSON-based configuration.
|
||||||
|
* High detail logging and record-keeping prevents gaps in moderation that might occur with large public bots.
|
||||||
|
|
||||||
|
This repository also contains...
|
||||||
|
|
||||||
|
# RegexBot-Modules
|
||||||
|
An optional set of features to add to RegexBot, some of them inspired by Reddit's Automoderator.
|
||||||
|
|
||||||
|
This module provides a number of features to assist in watching over the tedious details in a busy server with no hidden details,
|
||||||
|
arbitrary restrictions, or unmodifiable behavior. Its configuration allows for a very high level of flexibility, ensuring that the bot
|
||||||
|
behaves in accordance to the exact needs of your server.
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Create rules based on regular expression patterns
|
||||||
|
* Follow up with custom responses ranging from sending a DM to disciplinary action
|
||||||
|
* Create pattern-based triggers to provide information and fun to your users
|
||||||
|
* Adjustable rate limits per-trigger to prevent spam
|
||||||
|
* Specify multiple different responses to display at random when triggered
|
||||||
|
* Make things interesting by setting triggers that only activate at random
|
||||||
|
* Individual rules and triggers can be whitelisted or blacklisted per-user, per-channel, or per-role
|
||||||
|
* Exemptions to these filters can be applied for additional flexibility
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
Coming soon?
|
32
RegexBot.sln
32
RegexBot.sln
|
@ -1,34 +1,28 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 17.0.32112.339
|
VisualStudioVersion = 16.0.30114.105
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegexBot", "RegexBot\RegexBot.csproj", "{6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegexBot", "RegexBot\RegexBot.csproj", "{F7CDACE1-C74E-451E-A9C2-ED717BF72C1C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegexBot-Modules", "RegexBot-Modules\RegexBot-Modules.csproj", "{03111D82-30ED-4FDF-A512-87BDC05C6DA1}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegexBot-Modules", "RegexBot-Modules\RegexBot-Modules.csproj", "{347A1912-4F7D-419B-A159-6671791568CC}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3} = {6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6FA3A92F-F1FC-4BA8-8018-1A05CB4C7FA3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{03111D82-30ED-4FDF-A512-87BDC05C6DA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{03111D82-30ED-4FDF-A512-87BDC05C6DA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{03111D82-30ED-4FDF-A512-87BDC05C6DA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{03111D82-30ED-4FDF-A512-87BDC05C6DA1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
SolutionGuid = {C823EC9C-CF20-4437-8B99-72158A6DD113}
|
{F7CDACE1-C74E-451E-A9C2-ED717BF72C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F7CDACE1-C74E-451E-A9C2-ED717BF72C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F7CDACE1-C74E-451E-A9C2-ED717BF72C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F7CDACE1-C74E-451E-A9C2-ED717BF72C1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{347A1912-4F7D-419B-A159-6671791568CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{347A1912-4F7D-419B-A159-6671791568CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{347A1912-4F7D-419B-A159-6671791568CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{347A1912-4F7D-419B-A159-6671791568CC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -115,8 +115,10 @@ public class EntityList : IEnumerable<EntityName> {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsEmpty() => _innerList.Count == 0;
|
public bool IsEmpty() => _innerList.Count == 0;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public override string ToString() => $"Entity list contains {_innerList.Count} item(s).";
|
public override string ToString() => $"Entity list contains {_innerList.Count} item(s).";
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public IEnumerator<EntityName> GetEnumerator() => _innerList.GetEnumerator();
|
public IEnumerator<EntityName> GetEnumerator() => _innerList.GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class EntityName {
|
||||||
input = input[1..]; // Remove prefix
|
input = input[1..]; // Remove prefix
|
||||||
|
|
||||||
// Input contains ID/Label separator?
|
// Input contains ID/Label separator?
|
||||||
int separator = input.IndexOf("::");
|
var separator = input.IndexOf("::");
|
||||||
if (separator != -1) {
|
if (separator != -1) {
|
||||||
Name = input[(separator + 2)..];
|
Name = input[(separator + 2)..];
|
||||||
if (ulong.TryParse(input.AsSpan(0, separator), out var parseOut)) {
|
if (ulong.TryParse(input.AsSpan(0, separator), out var parseOut)) {
|
||||||
|
@ -93,7 +93,7 @@ public class EntityName {
|
||||||
/// Returns a string representation of this item in proper EntityName format.
|
/// Returns a string representation of this item in proper EntityName format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
char pf = Prefix(Type);
|
var pf = Prefix(Type);
|
||||||
|
|
||||||
if (Id.HasValue && Name != null)
|
if (Id.HasValue && Name != null)
|
||||||
return $"{pf}{Id.Value}::{Name}";
|
return $"{pf}{Id.Value}::{Name}";
|
||||||
|
@ -109,14 +109,14 @@ public class EntityName {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="guild">The guild in which to search for the role.</param>
|
/// <param name="guild">The guild in which to search for the role.</param>
|
||||||
/// <param name="updateMissingID">
|
/// <param name="updateMissingID">
|
||||||
/// Specifies if this EntityName instance should keep the snowflake ID of the
|
/// Specifies if this EntityName instance should cache the snowflake ID of the
|
||||||
/// corresponding role found in this guild, if it is not already known by this instance.
|
/// corresponding role found in this guild if it is not already known by this instance.
|
||||||
/// </param>
|
/// </param>
|
||||||
public SocketRole? FindRoleIn(SocketGuild guild, bool updateMissingID = false) {
|
public SocketRole? FindRoleIn(SocketGuild guild, bool updateMissingID = false) {
|
||||||
if (Type != EntityType.Role)
|
if (Type != EntityType.Role)
|
||||||
throw new ArgumentException("This EntityName instance must correspond to a Role.");
|
throw new ArgumentException("This EntityName instance must correspond to a Role.");
|
||||||
|
|
||||||
bool dirty = false; // flag for updating ID if possible regardless of updateMissingId setting
|
var dirty = false; // flag for updating ID if possible regardless of updateMissingId setting
|
||||||
if (Id.HasValue) {
|
if (Id.HasValue) {
|
||||||
var role = guild.GetRole(Id.Value);
|
var role = guild.GetRole(Id.Value);
|
||||||
if (role != null) return role;
|
if (role != null) return role;
|
||||||
|
@ -134,14 +134,14 @@ public class EntityName {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="guild">The guild in which to search for the user.</param>
|
/// <param name="guild">The guild in which to search for the user.</param>
|
||||||
/// <param name="updateMissingID">
|
/// <param name="updateMissingID">
|
||||||
/// Specifies if this EntityName instance should keep the snowflake ID of the
|
/// Specifies if this EntityName instance should cache the snowflake ID of the
|
||||||
/// corresponding user found in this guild, if it is not already known by this instance.
|
/// corresponding user found in this guild if it is not already known by this instance.
|
||||||
/// </param>
|
/// </param>
|
||||||
public SocketGuildUser? FindUserIn(SocketGuild guild, bool updateMissingID = false) {
|
public SocketGuildUser? FindUserIn(SocketGuild guild, bool updateMissingID = false) {
|
||||||
if (Type != EntityType.User)
|
if (Type != EntityType.User)
|
||||||
throw new ArgumentException("This EntityName instance must correspond to a User.");
|
throw new ArgumentException("This EntityName instance must correspond to a User.");
|
||||||
|
|
||||||
bool dirty = false; // flag for updating ID if possible regardless of updateMissingId setting
|
var dirty = false; // flag for updating ID if possible regardless of updateMissingId setting
|
||||||
if (Id.HasValue) {
|
if (Id.HasValue) {
|
||||||
var user = guild.GetUser(Id.Value);
|
var user = guild.GetUser(Id.Value);
|
||||||
if (user != null) return user;
|
if (user != null) return user;
|
||||||
|
@ -159,14 +159,14 @@ public class EntityName {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="guild">The guild in which to search for the channel.</param>
|
/// <param name="guild">The guild in which to search for the channel.</param>
|
||||||
/// <param name="updateMissingID">
|
/// <param name="updateMissingID">
|
||||||
/// Specifies if this EntityName instance should keep the snowflake ID of the
|
/// Specifies if this EntityName instance should cache the snowflake ID of the
|
||||||
/// corresponding channel found in this guild, if it is not already known by this instance.
|
/// corresponding channel found in this guild if it is not already known by this instance.
|
||||||
/// </param>
|
/// </param>
|
||||||
public SocketTextChannel? FindChannelIn(SocketGuild guild, bool updateMissingID = false) {
|
public SocketTextChannel? FindChannelIn(SocketGuild guild, bool updateMissingID = false) {
|
||||||
if (Type != EntityType.Channel)
|
if (Type != EntityType.Channel)
|
||||||
throw new ArgumentException("This EntityName instance must correspond to a Channel.");
|
throw new ArgumentException("This EntityName instance must correspond to a Channel.");
|
||||||
|
|
||||||
bool dirty = false; // flag for updating ID if possible regardless of updateMissingId setting
|
var dirty = false; // flag for updating ID if possible regardless of updateMissingId setting
|
||||||
if (Id.HasValue) {
|
if (Id.HasValue) {
|
||||||
var channel = guild.GetTextChannel(Id.Value);
|
var channel = guild.GetTextChannel(Id.Value);
|
||||||
if (channel != null) return channel;
|
if (channel != null) return channel;
|
||||||
|
|
|
@ -71,7 +71,8 @@ public abstract class RegexbotModule {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Emits a log message to the bot console that is associated with the specified guild.
|
/// Emits a log message to the bot console that is associated with the specified guild.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// /// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
/// <param name="guild">The guld for which this log message is associated with.</param>
|
||||||
|
/// <param name="message">The log message to send. Multi-line messages are acceptable.</param>
|
||||||
protected void Log(SocketGuild guild, string? message) {
|
protected void Log(SocketGuild guild, string? message) {
|
||||||
var gname = guild.Name ?? $"Guild ID {guild.Id}";
|
var gname = guild.Name ?? $"Guild ID {guild.Id}";
|
||||||
Bot._svcLogging.DoLog(false, $"{Name}] [{gname}", message);
|
Bot._svcLogging.DoLog(false, $"{Name}] [{gname}", message);
|
||||||
|
|
Loading…
Reference in a new issue