Silence user command, along with many improvements and bug fixes

This commit is contained in:
Deukhoofd 2018-03-31 18:05:54 +02:00
parent b3c878db04
commit 6af6bc9629
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
10 changed files with 202 additions and 23 deletions

View File

@ -1,4 +1,5 @@
using DeukBot4.Utilities; using System.Threading.Tasks;
using DeukBot4.Utilities;
using Npgsql; using Npgsql;
namespace DeukBot4.Database.ServerSettings namespace DeukBot4.Database.ServerSettings
@ -14,7 +15,7 @@ namespace DeukBot4.Database.ServerSettings
public ulong ServerId { get; } public ulong ServerId { get; }
public ulong MutedRoleId { get; } public ulong MutedRoleId { get; }
public void SetMutedRoleId(ulong id) public async Task SetMutedRoleId(ulong id)
{ {
using (var conn = new DatabaseConnection()) using (var conn = new DatabaseConnection())
{ {
@ -24,7 +25,7 @@ namespace DeukBot4.Database.ServerSettings
cmd.CommandText = "UPDATE server_settings SET muted_role = @val WHERE server_id = @key"; cmd.CommandText = "UPDATE server_settings SET muted_role = @val WHERE server_id = @key";
cmd.Parameters.AddWithValue("val", id.ToLong()); cmd.Parameters.AddWithValue("val", id.ToLong());
cmd.Parameters.AddWithValue("key", ServerId.ToLong()); cmd.Parameters.AddWithValue("key", ServerId.ToLong());
cmd.ExecuteNonQuery(); await cmd.ExecuteNonQueryAsync();
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using DeukBot4.Utilities; using DeukBot4.Utilities;
using Discord; using Discord;
using Npgsql; using Npgsql;
@ -16,7 +17,7 @@ namespace DeukBot4.Database.ServerSettings
using (var cmd = new NpgsqlCommand()) using (var cmd = new NpgsqlCommand())
{ {
cmd.Connection = conn; cmd.Connection = conn;
cmd.CommandText = "SELECT server_id muted_role FROM server_settings"; cmd.CommandText = "SELECT server_id, muted_role FROM server_settings";
var reader = cmd.ExecuteReader(); var reader = cmd.ExecuteReader();
while (reader.Read()) while (reader.Read())
{ {

View File

@ -21,14 +21,14 @@ namespace DeukBot4
public static async Task Log(object o, LogSeverity severity) public static async Task Log(object o, LogSeverity severity)
{ {
Console.ForegroundColor = Colors[severity]; Console.ForegroundColor = Colors[severity];
Console.WriteLine($"[{severity}] {DateTime.UtcNow.ToShortTimeString()}: {o.ToString()}"); Console.WriteLine($"[{severity}] {DateTime.UtcNow:u}: {o.ToString()}");
Console.ResetColor(); Console.ResetColor();
} }
public static async Task LogDiscord(LogMessage message) public static async Task LogDiscord(LogMessage message)
{ {
Console.ForegroundColor = Colors[message.Severity]; Console.ForegroundColor = Colors[message.Severity];
Console.WriteLine($"[{message.Severity}] {DateTime.UtcNow.ToShortTimeString()}: {message.Message}"); Console.WriteLine($"[{message.Severity}] {DateTime.UtcNow:u}: {message.Message}");
Console.ResetColor(); Console.ResetColor();
} }

View File

@ -1,6 +1,10 @@
using System.Threading.Tasks; using System;
using System.Linq;
using System.Threading.Tasks;
using DeukBot4.Database.ServerSettings;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure; using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using DeukBot4.MessageHandlers.Permissions; using DeukBot4.MessageHandlers.Permissions;
using DeukBot4.Utilities;
using Discord; using Discord;
using Discord.WebSocket; using Discord.WebSocket;
@ -55,6 +59,13 @@ namespace DeukBot4.MessageHandlers.CommandHandler
} }
[Command("ban", PermissionLevel.Moderator)] [Command("ban", PermissionLevel.Moderator)]
[CommandHelp("Bans a user from the server",
"Bans a user from the server. Will not work on people with a helper role, or higher.\n" +
"Usage: \n" +
"``ban {User Mention} {optional: Reason}``\n" +
"``ban {User ID} {optional: Reason}``")]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Remainder)]
[BlockUsageInPm, RequireParameterMatch]
public async Task BanUser(CommandRequest request) public async Task BanUser(CommandRequest request)
{ {
// get the server channel object out of message. Return if it's somehow not a server channel // get the server channel object out of message. Return if it's somehow not a server channel
@ -90,5 +101,73 @@ namespace DeukBot4.MessageHandlers.CommandHandler
await channel.Guild.AddBanAsync(user, 0, reason); await channel.Guild.AddBanAsync(user, 0, reason);
await request.SendMessageAsync($"User was banned: {user.Username}"); await request.SendMessageAsync($"User was banned: {user.Username}");
} }
[Command("silence", PermissionLevel.Helper)]
[Command("mute", PermissionLevel.Helper)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Timespan)]
[CommandParameters(ParameterMatcher.ParameterType.User, ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm]
public async Task SilenceUser(CommandRequest request)
{
// get the server channel object out of message. Return if it's somehow not a server channel
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
// get the id of the user, this parses the string to an id
var user = await request.Parameters[0].AsDiscordUser(channel.Guild);
if (user == null)
{
await request.SendMessageAsync("I can't find that user on the server");
return;
}
var silencedRoleId = ServerSettingHandler.GetSettings(channel.GuildId).MutedRoleId;
if (silencedRoleId == 0)
{
await request.SendMessageAsync(
"No silenced role has been set. The server owner should do ``!silencedrole {role id}`` to set one first.");
return;
}
var silencedRole = channel.Guild.GetRole(silencedRoleId);
if (silencedRole == null)
{
await request.SendMessageAsync(
"Can't find the silenced role. Has it been deleted?");
return;
}
await user.AddRoleAsync(silencedRole);
TimeSpan span;
if (request.Parameters[1].Type == ParameterMatcher.ParameterType.Number)
{
var minutes = request.Parameters[1].AsInt();
if (!minutes.HasValue)
return;
span = TimeSpan.FromMinutes(minutes.Value);
}
else if (request.Parameters[1].Type == ParameterMatcher.ParameterType.Timespan)
{
var sp = TimespanParser.Parse(request.Parameters[1].AsString());
if (sp.HasValue)
{
span = sp.Value;
}
else
{
Console.WriteLine("this");
return;
}
}
else
{
return;
}
await Task.Delay(span);
await user.RemoveRoleAsync(silencedRole);
}
} }
} }

View File

@ -2,6 +2,7 @@
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using DeukBot4.Database; using DeukBot4.Database;
using DeukBot4.Database.ServerSettings;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure; using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using DeukBot4.MessageHandlers.Permissions; using DeukBot4.MessageHandlers.Permissions;
using Discord; using Discord;
@ -31,28 +32,32 @@ namespace DeukBot4.MessageHandlers.CommandHandler
} }
[Command("adminrole", PermissionLevel.ServerOwner)] [Command("adminrole", PermissionLevel.ServerOwner)]
[CommandParameters(new []{ParameterMatcher.ParameterType.Number})] [CommandParameters(ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm]
public async Task SetAdminRole(CommandRequest request) public async Task SetAdminRole(CommandRequest request)
{ {
await SetRolePermission(request, PermissionLevel.Admin); await SetRolePermission(request, PermissionLevel.Admin);
} }
[Command("moderatorrole", PermissionLevel.ServerOwner)] [Command("moderatorrole", PermissionLevel.ServerOwner)]
[CommandParameters(new []{ParameterMatcher.ParameterType.Number})] [CommandParameters(ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm]
public async Task SetModRole(CommandRequest request) public async Task SetModRole(CommandRequest request)
{ {
await SetRolePermission(request, PermissionLevel.Moderator); await SetRolePermission(request, PermissionLevel.Moderator);
} }
[Command("helperrole", PermissionLevel.ServerOwner)] [Command("helperrole", PermissionLevel.ServerOwner)]
[CommandParameters(new []{ParameterMatcher.ParameterType.Number})] [CommandParameters(ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm]
public async Task SetHelperRole(CommandRequest request) public async Task SetHelperRole(CommandRequest request)
{ {
await SetRolePermission(request, PermissionLevel.Helper); await SetRolePermission(request, PermissionLevel.Helper);
} }
[Command("blockedrole", PermissionLevel.ServerOwner)] [Command("blockedrole", PermissionLevel.ServerOwner)]
[CommandParameters(new []{ParameterMatcher.ParameterType.Number})] [CommandParameters(ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm]
public async Task SetBannedRole(CommandRequest request) public async Task SetBannedRole(CommandRequest request)
{ {
await SetRolePermission(request, PermissionLevel.Banned); await SetRolePermission(request, PermissionLevel.Banned);
@ -98,5 +103,31 @@ namespace DeukBot4.MessageHandlers.CommandHandler
} }
} }
[Command("silencedrole", PermissionLevel.ServerOwner)]
[CommandParameters(ParameterMatcher.ParameterType.Number)]
[BlockUsageInPm, RequireParameterMatch]
public async Task SetSilencedRole(CommandRequest request)
{
var val = request.Parameters[0].AsUlong();
if (!val.HasValue)
{
await request.SendMessageAsync("Invalid role ID");
return;
}
if (!(request.OriginalMessage.Channel is IGuildChannel channel))
return;
var role = channel.Guild.GetRole(val.Value);
if (role == null)
{
await request.SendMessageAsync("No role by that ID exists on the server");
return;
}
var setting = ServerSettingHandler.GetSettings(channel.GuildId);
await setting.SetMutedRoleId(val.Value);
}
} }
} }

View File

@ -16,7 +16,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
public Command Command { get; } public Command Command { get; }
public SocketMessage OriginalMessage { get; } public SocketMessage OriginalMessage { get; }
public RequestParameter[] Parameters { get; private set; } public RequestParameter[] Parameters { get; }
public PermissionLevel RequestPermissions { get; } public PermissionLevel RequestPermissions { get; }
private CommandRequest(SocketMessage message, Command command, PermissionLevel requestPermissions, RequestParameter[] parameters) private CommandRequest(SocketMessage message, Command command, PermissionLevel requestPermissions, RequestParameter[] parameters)

View File

@ -2,6 +2,7 @@
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Discord.Net.Udp;
namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
{ {
@ -13,6 +14,7 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
Number, Number,
Remainder, Remainder,
User, User,
Timespan,
} }
public static string[] GenerateRegex(Command command) public static string[] GenerateRegex(Command command)
@ -23,24 +25,31 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
var commandParameterType = command.ParameterTypes[index]; var commandParameterType = command.ParameterTypes[index];
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.Append(GetParameterRegex(commandParameterType[index])); for (var i = 0; i < commandParameterType.Length; i++)
{
var parameterType = commandParameterType[i];
builder.Append(GetParameterRegex(parameterType, i + 1));
}
arr[index] = builder.ToString(); arr[index] = builder.ToString();
} }
return arr; return arr;
} }
private static string GetParameterRegex(ParameterType type) private static string GetParameterRegex(ParameterType type, int index)
{ {
switch (type) switch (type)
{ {
case ParameterType.Word: case ParameterType.Word:
return " *(\\w+)"; return $" *(?<{index}>\\w+)";
case ParameterType.Number: case ParameterType.Number:
return " *(\\d+)"; return $" *(?<{index}>\\d+)(?:$| |\n)";
case ParameterType.Remainder: case ParameterType.Remainder:
return " *(.*)"; return $" *(?<{index}>.*)";
case ParameterType.User: case ParameterType.User:
return " *<@(?<id>\\d+)>|(?<id>\\d+)"; return $" *(?:<@(?<{index}>\\d+)>|(?<{index}>\\d+)(?:$| |\n))";
case ParameterType.Timespan:
return $" *(?<{index}>\\d+[smhd])";
default: default:
throw new ArgumentOutOfRangeException(nameof(type), type, null); throw new ArgumentOutOfRangeException(nameof(type), type, null);
} }
@ -48,12 +57,29 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
public static RequestParameter[] GetParameterValues(Command command, string parameterString) public static RequestParameter[] GetParameterValues(Command command, string parameterString)
{ {
foreach (var pattern in command.ParametersMatchers) for (var index = 0; index < command.ParametersMatchers.Length; index++)
{ {
var matches = Regex.Match(parameterString, pattern); var parameterTypes = command.ParameterTypes[index];
var pattern = command.ParametersMatchers[index];
Match matches;
try
{
matches = Regex.Match(parameterString, pattern);
}
catch (Exception e)
{
Logger.LogError(e.ToString());
return command.RequireParameterMatch ? null : new RequestParameter[0];
}
if (matches.Success) if (matches.Success)
{ {
return matches.Groups.Skip(1).Select(x => new RequestParameter(x.Value)).ToArray(); var arr = new RequestParameter[matches.Groups.Count - 1];
for (var i = 1; i < matches.Groups.Count; i++)
{
var group = matches.Groups[i];
arr[i - 1] = new RequestParameter(group.Value, parameterTypes[i - 1]);
}
return arr;
} }
} }

View File

@ -7,10 +7,12 @@ namespace DeukBot4.MessageHandlers.CommandHandler.RequestStructure
{ {
public class RequestParameter public class RequestParameter
{ {
public ParameterMatcher.ParameterType Type { get; }
private readonly string _value; private readonly string _value;
public RequestParameter(string value) public RequestParameter(string value, ParameterMatcher.ParameterType type)
{ {
Type = type;
_value = value; _value = value;
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using DeukBot4.Database; using DeukBot4.Database;
using DeukBot4.Database.ServerSettings;
using DeukBot4.MessageHandlers; using DeukBot4.MessageHandlers;
using DeukBot4.MessageHandlers.CommandHandler; using DeukBot4.MessageHandlers.CommandHandler;
using Discord; using Discord;
@ -26,6 +27,7 @@ namespace DeukBot4
DatabaseConnection.ConnectionString = Settings.DatabaseConnectionString; DatabaseConnection.ConnectionString = Settings.DatabaseConnectionString;
DatabaseInitializer.Initialize(); DatabaseInitializer.Initialize();
ServerSettingHandler.OnBotStartUp();
CommandHandler.Build(); CommandHandler.Build();
Client = new DiscordSocketClient(); Client = new DiscordSocketClient();

View File

@ -0,0 +1,37 @@
using System;
using System.Linq;
namespace DeukBot4.Utilities
{
public static class TimespanParser
{
public static TimeSpan? Parse(string s)
{
var timeIndicator = s.Last();
var numberStr = s.Remove(s.Length - 1, 1);
if (!int.TryParse(numberStr, out var number))
{
return null;
}
switch (timeIndicator)
{
case 's':
return TimeSpan.FromSeconds(number);
break;
case 'm':
return TimeSpan.FromMinutes(number);
break;
case 'h':
return TimeSpan.FromHours(number);
break;
case 'd':
return TimeSpan.FromDays(number);
break;
default:
return null;
}
}
}
}