mirror of
https://github.com/NoiTheCat/BirthdayBot.git
synced 2024-11-21 21:54:36 +00:00
Various other improvements
-Revised help command text -Added case when using bb.config without parameters -Added message if regular user attempts to use bb.config -Role set warning now only is sent out periodically -Performance improvements in initial command parsing -Implemented moderated mode setting -Renamed "ban" to "block" -Bumped up version number
This commit is contained in:
parent
756a63c954
commit
0df0fb5a64
7 changed files with 170 additions and 98 deletions
|
@ -2,16 +2,17 @@
|
|||
Option Explicit On
|
||||
Imports BirthdayBot.CommandsCommon
|
||||
Imports Discord
|
||||
Imports Discord.Net
|
||||
Imports Discord.WebSocket
|
||||
|
||||
Class BirthdayBot
|
||||
Const RoleWarningMsg As String =
|
||||
"Note: This bot does not have a role set or is unable to use the role specified. " +
|
||||
"Update the designated role with `bb.config role (role name/ID). This bot cannot function without it."
|
||||
"Update the designated role with `bb.config role (role name/ID)`. This bot cannot function without it."
|
||||
|
||||
Private ReadOnly _dispatchCommands As Dictionary(Of String, CommandHandler)
|
||||
Private ReadOnly _cmdsUser As UserCommands
|
||||
Private ReadOnly _cmdsHelp As HelpCommands
|
||||
Private ReadOnly _cmdsHelp As HelpInfoCommands
|
||||
Private ReadOnly _cmdsMods As ManagerCommands
|
||||
|
||||
Private WithEvents _client As DiscordSocketClient
|
||||
|
@ -40,7 +41,7 @@ Class BirthdayBot
|
|||
For Each item In _cmdsUser.Commands
|
||||
_dispatchCommands.Add(item.Item1, item.Item2)
|
||||
Next
|
||||
_cmdsHelp = New HelpCommands(Me, conf)
|
||||
_cmdsHelp = New HelpInfoCommands(Me, conf)
|
||||
For Each item In _cmdsHelp.Commands
|
||||
_dispatchCommands.Add(item.Item1, item.Item2)
|
||||
Next
|
||||
|
@ -102,15 +103,22 @@ Class BirthdayBot
|
|||
Dim channel = CType(msg.Channel, SocketTextChannel)
|
||||
Dim author = CType(msg.Author, SocketGuildUser)
|
||||
|
||||
Dim roleWarning As Boolean
|
||||
' Determine if it's something we're listening for.
|
||||
' Doing this first before the block check because a block check triggers a database query.
|
||||
Dim command As CommandHandler = Nothing
|
||||
If Not _dispatchCommands.TryGetValue(csplit(0).Substring(CommandPrefix.Length), command) Then
|
||||
Return
|
||||
End If
|
||||
|
||||
' Ban and role warning check
|
||||
Dim roleWarning As Boolean
|
||||
Dim isManager = author.GuildPermissions.ManageGuild
|
||||
SyncLock KnownGuilds
|
||||
Dim gi = KnownGuilds(channel.Guild.Id)
|
||||
|
||||
' Skip ban check if user is a manager
|
||||
If Not author.GuildPermissions.ManageGuild Then
|
||||
If gi.IsUserBannedAsync(author.Id).GetAwaiter().GetResult() Then
|
||||
If Not isManager Then
|
||||
If gi.IsUserBlockedAsync(author.Id).GetAwaiter().GetResult() Then
|
||||
Return
|
||||
End If
|
||||
End If
|
||||
|
@ -118,18 +126,24 @@ Class BirthdayBot
|
|||
roleWarning = gi.RoleWarning
|
||||
End SyncLock
|
||||
|
||||
Dim h As CommandHandler = Nothing
|
||||
If _dispatchCommands.TryGetValue(csplit(0).Substring(CommandPrefix.Length), h) Then
|
||||
Try
|
||||
Await h(csplit, channel, author)
|
||||
If roleWarning Then
|
||||
Try
|
||||
If roleWarning Then
|
||||
Try
|
||||
Await channel.SendMessageAsync(RoleWarningMsg)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Catch ex As HttpException
|
||||
' Don't let this prevent the bot from continuing command execution.
|
||||
End Try
|
||||
End If
|
||||
Await command(csplit, channel, author)
|
||||
Catch ex As Exception
|
||||
If TypeOf ex Is HttpException Then Return
|
||||
Log("Error", ex.ToString())
|
||||
Try
|
||||
channel.SendMessageAsync(":x: An unknown error occurred. It has been reported to the bot owner.").Wait()
|
||||
Log("Error", ex.ToString())
|
||||
Catch ex2 As HttpException
|
||||
' Fail silently.
|
||||
End Try
|
||||
End If
|
||||
End Try
|
||||
End If
|
||||
End If
|
||||
End Function
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>BirthdayBot</RootNamespace>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Version>0.1.0</Version>
|
||||
<AssemblyVersion>0.1.0.0</AssemblyVersion>
|
||||
<Version>0.3.0</Version>
|
||||
<AssemblyVersion>0.3.0.0</AssemblyVersion>
|
||||
<Authors>Noikoio</Authors>
|
||||
<Company />
|
||||
<Description>Discord bot for birthday reminders.</Description>
|
||||
|
|
|
@ -18,10 +18,31 @@ Friend Class GuildSettings
|
|||
Private _modded As Boolean
|
||||
Private _userCache As Dictionary(Of ULong, GuildUserSettings)
|
||||
|
||||
Private _roleWarning As Boolean
|
||||
Private _roleLastWarning As New DateTimeOffset(DateTime.MinValue, TimeSpan.Zero)
|
||||
Private Shared ReadOnly RoleWarningInterval As New TimeSpan(0, 10, 0)
|
||||
|
||||
''' <summary>
|
||||
''' Flag for notifying servers that the bot is unable to manipulate its role.
|
||||
''' Can be set at any time. Reading this will only return True once every 10 minutes, if at all.
|
||||
''' </summary>
|
||||
Public Property RoleWarning As Boolean
|
||||
Get
|
||||
If _roleWarning = True Then
|
||||
' Only report a warning every so often.
|
||||
If DateTimeOffset.UtcNow - _roleLastWarning > RoleWarningInterval Then
|
||||
_roleLastWarning = DateTimeOffset.UtcNow
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End If
|
||||
Return False
|
||||
End Get
|
||||
Set(value As Boolean)
|
||||
_roleWarning = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Gets a list of cached users. Use sparingly.
|
||||
|
@ -67,14 +88,10 @@ Friend Class GuildSettings
|
|||
''' Gets or sets if the server is in moderated mode.
|
||||
''' Updating this value updates the database.
|
||||
''' </summary>
|
||||
Public Property IsModerated As Boolean
|
||||
Public ReadOnly Property IsModerated As Boolean
|
||||
Get
|
||||
Return _modded
|
||||
End Get
|
||||
Set(value As Boolean)
|
||||
_modded = value
|
||||
UpdateDatabaseAsync()
|
||||
End Set
|
||||
End Property
|
||||
|
||||
' Called by LoadSettingsAsync. Double-check ordinals when changes are made.
|
||||
|
@ -132,10 +149,11 @@ Friend Class GuildSettings
|
|||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Checks if the given user is banned from issuing commands.
|
||||
''' Checks if the given user is blocked from issuing commands.
|
||||
''' If the server is in moderated mode, this always returns True.
|
||||
''' Does not check if the user is a manager.
|
||||
''' </summary>
|
||||
Public Async Function IsUserBannedAsync(userId As ULong) As Task(Of Boolean)
|
||||
Public Async Function IsUserBlockedAsync(userId As ULong) As Task(Of Boolean)
|
||||
If IsModerated Then Return True
|
||||
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
|
@ -154,10 +172,9 @@ Friend Class GuildSettings
|
|||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Bans the specified user from issuing commands.
|
||||
''' Does not check if the given user is already banned.
|
||||
''' Blocks the specified user from issuing commands.
|
||||
''' </summary>
|
||||
Public Async Function BanUserAsync(userId As ULong) As Task
|
||||
Public Async Function BlockUserAsync(userId As ULong) As Task
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
Using c = db.CreateCommand()
|
||||
c.CommandText = $"insert into {BackingTableBans} (guild_id, user_id) " +
|
||||
|
@ -172,8 +189,7 @@ Friend Class GuildSettings
|
|||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Removes the specified user from the ban list.
|
||||
''' Does not check if the given user was not banned to begin with.
|
||||
''' Removes the specified user from the block list.
|
||||
''' </summary>
|
||||
Public Async Function UnbanUserAsync(userId As ULong) As Task
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
|
@ -204,6 +220,11 @@ Friend Class GuildSettings
|
|||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
|
||||
Public Async Function UpdateModeratedModeAsync(isModerated As Boolean) As Task
|
||||
_modded = isModerated
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
|
||||
#Region "Database"
|
||||
Public Const BackingTable = "settings"
|
||||
Public Const BackingTableBans = "banned_users"
|
||||
|
|
|
@ -10,6 +10,7 @@ Imports NodaTime
|
|||
Friend MustInherit Class CommandsCommon
|
||||
Public Const CommandPrefix = "bb."
|
||||
Public Const GenericError = ":x: Invalid usage. Consult the help command."
|
||||
Public Const BadUserError = ":x: Unable to find user. Specify their `@` mention or their ID."
|
||||
Public Const ExpectedNoParametersError = ":x: This command does not take parameters. Did you mean to use another?"
|
||||
|
||||
Delegate Function CommandHandler(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
|
@ -42,6 +43,11 @@ Friend MustInherit Class CommandsCommon
|
|||
Discord = inst.DiscordClient
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' On command dispatcher initialization, it will retrieve all available commands through here.
|
||||
''' </summary>
|
||||
Public MustOverride ReadOnly Property Commands As IEnumerable(Of (String, CommandHandler))
|
||||
|
||||
''' <summary>
|
||||
''' Checks given time zone input. Returns a valid string for use with NodaTime.
|
||||
''' </summary>
|
||||
|
@ -59,7 +65,24 @@ Friend MustInherit Class CommandsCommon
|
|||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' On command dispatcher initialization, it will retrieve all available commands through here.
|
||||
''' Given user input where a user-like parameter is expected, attempts to resolve to an ID value.
|
||||
''' Input must be a mention or explicit ID. No name resolution is done here.
|
||||
''' </summary>
|
||||
Public MustOverride ReadOnly Property Commands As IEnumerable(Of (String, CommandHandler))
|
||||
Protected Function TryGetUserId(input As String, ByRef result As ULong) As Boolean
|
||||
Dim doParse As String
|
||||
Dim m = UserMention.Match(input)
|
||||
If m.Success Then
|
||||
doParse = m.Groups(1).Value
|
||||
Else
|
||||
doParse = input
|
||||
End If
|
||||
|
||||
Dim resultVal As ULong
|
||||
If ULong.TryParse(doParse, resultVal) Then
|
||||
result = resultVal
|
||||
Return True
|
||||
End If
|
||||
|
||||
Return False
|
||||
End Function
|
||||
End Class
|
||||
|
|
|
@ -3,7 +3,7 @@ Option Explicit On
|
|||
Imports Discord
|
||||
Imports Discord.WebSocket
|
||||
|
||||
Friend Class HelpCommands
|
||||
Friend Class HelpInfoCommands
|
||||
Inherits CommandsCommon
|
||||
|
||||
Private ReadOnly _helpEmbed As Embed
|
||||
|
@ -25,28 +25,20 @@ Friend Class HelpCommands
|
|||
End Property
|
||||
|
||||
Private Function CreateHelpEmbed() As (EmbedBuilder, EmbedBuilder)
|
||||
Dim title = "Help & About"
|
||||
Dim description = "Birthday Bot: A utility to assist with acknowledging birthdays and other annual events." + vbLf +
|
||||
"**Currently a work in progress. There will be bugs. Features may change or be removed.**"
|
||||
Dim footer As New EmbedFooterBuilder With {
|
||||
.Text = Discord.CurrentUser.Username,
|
||||
.IconUrl = Discord.CurrentUser.GetAvatarUrl()
|
||||
}
|
||||
|
||||
Dim cpfx = $"●`{CommandPrefix}"
|
||||
' Normal section
|
||||
Dim cmdField As New EmbedFieldBuilder With {
|
||||
.Name = "Commands",
|
||||
.Value =
|
||||
$"{cpfx}help`, `{CommandPrefix}info`, `{CommandPrefix}tzdata`" + vbLf +
|
||||
$" » Various help messages." + vbLf +
|
||||
$"{cpfx}help`, `{CommandPrefix}info`, `{CommandPrefix}help-tzdata`" + vbLf +
|
||||
$" » Various help and informational messages." + vbLf +
|
||||
$"{cpfx}set (date) [zone]`" + vbLf +
|
||||
$" » Registers your birth date, with optional time zone." + vbLf +
|
||||
$" »» Examples: `{CommandPrefix}set jan-31 America/New_York`, `{CommandPrefix}set 15-aug Europe/Stockholm`." + vbLf +
|
||||
$"{cpfx}set-tz (zone)`" + vbLf +
|
||||
$" » Sets your local time zone. Only accepts certain values. See `{CommandPrefix}tzdata`." + vbLf +
|
||||
$" » Registers your birth date. Time zone is optional." + vbLf +
|
||||
$" »» Examples: `{CommandPrefix}set jan-31`, `{CommandPrefix}set 15-aug America/Los_Angeles`." + vbLf +
|
||||
$"{cpfx}zone (zone)`" + vbLf +
|
||||
$" » Sets your local time zone. See `{CommandPrefix}help-tzdata`." + vbLf +
|
||||
$"{cpfx}remove`" + vbLf +
|
||||
$" » Removes all your information from this bot."
|
||||
$" » Removes your information from this bot."
|
||||
}
|
||||
|
||||
' Manager section
|
||||
|
@ -55,36 +47,27 @@ Friend Class HelpCommands
|
|||
.Name = "Commands for server managers",
|
||||
.Value =
|
||||
$"{mpfx}role (role name or ID)`" + vbLf +
|
||||
" » Specifies which role to apply to users having birthdays." + vbLf +
|
||||
" » Configures the role to apply to users having birthdays." + vbLf +
|
||||
$"{mpfx}channel (channel name or ID)`" + vbLf +
|
||||
" » Sets the birthday and event announcement channel. Leave blank to disable announcements." + vbLf +
|
||||
$"{mpfx}set-tz (time zone name)`" + vbLf +
|
||||
" » Sets the default time zone to use with all dates. Leave blank to revert to default." + vbLf +
|
||||
$" » Only accepts certain values. See `{CommandPrefix}tzdata`." + vbLf +
|
||||
$"{mpfx}ban/unban (user mention or ID)`" + vbLf +
|
||||
" » Restricts or reallows access to this bot for the given user." + vbLf +
|
||||
$"{mpfx}ban-all/unban-all`" + vbLf +
|
||||
" » Restricts or reallows access to this bot for all users. Server managers are exempt." + vbLf +
|
||||
$"{cpfx}override (user ID) (regular command)`" + vbLf +
|
||||
" » Performs a command on behalf of the given user."
|
||||
" » Configures the channel to use for announcements. Leave blank to disable." + vbLf +
|
||||
$"{mpfx}zone (time zone name)`" + vbLf +
|
||||
" » Sets the default time zone for all dates that don't have their own zone set." + vbLf +
|
||||
$" »» See `{CommandPrefix}help-tzdata`. Leave blank to set to UTC." + vbLf +
|
||||
$"{mpfx}block/unblock (user mention or ID)`" + vbLf +
|
||||
" » Prevents or allows usage of bot commands to the given user." + vbLf +
|
||||
$"{mpfx}moderated on/off`" + vbLf +
|
||||
" » Prevents or allows usage of bot commands to all users excluding managers." + vbLf +
|
||||
$"{cpfx}override (user mention or ID) (command)`" + vbLf +
|
||||
" » Performs a command on behalf of the given user." + vbLf +
|
||||
" »» Command may be either `set`, `zone`, or `remove` plus appropriate parameters."
|
||||
}
|
||||
|
||||
Dim helpNoManager As New EmbedBuilder
|
||||
With helpNoManager
|
||||
.Footer = footer
|
||||
.Title = title
|
||||
.Description = description
|
||||
.AddField(cmdField)
|
||||
End With
|
||||
helpNoManager.AddField(cmdField)
|
||||
|
||||
Dim helpManager As New EmbedBuilder
|
||||
With helpManager
|
||||
.Footer = footer
|
||||
.Title = title
|
||||
.Description = description
|
||||
.AddField(cmdField)
|
||||
.AddField(managerField)
|
||||
End With
|
||||
helpManager.AddField(cmdField)
|
||||
helpManager.AddField(managerField)
|
||||
|
||||
Return (helpNoManager, helpManager)
|
||||
End Function
|
|
@ -22,17 +22,24 @@ Friend Class ManagerCommands
|
|||
_subcommands = New Dictionary(Of String, ConfigSubcommand) From {
|
||||
{"role", AddressOf ScmdRole},
|
||||
{"channel", AddressOf ScmdChannel},
|
||||
{"set-tz", AddressOf ScmdSetTz},
|
||||
{"ban", AddressOf ScmdBanUnban},
|
||||
{"unban", AddressOf ScmdBanUnban},
|
||||
{"ban-all", AddressOf ScmdSetModerated},
|
||||
{"unban-all", AddressOf ScmdSetModerated}
|
||||
{"zone", AddressOf ScmdZone},
|
||||
{"block", AddressOf ScmdBlock},
|
||||
{"unblock", AddressOf ScmdBlock},
|
||||
{"moderated", AddressOf ScmdModerated}
|
||||
}
|
||||
End Sub
|
||||
|
||||
Private Async Function CmdConfigDispatch(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
' Managers only past this point. (This may have already been checked.)
|
||||
If Not reqUser.GuildPermissions.ManageGuild Then Return
|
||||
' Managers only past this point.
|
||||
If Not reqUser.GuildPermissions.ManageGuild Then
|
||||
Await reqChannel.SendMessageAsync(":x: This command may only be used by those with the `Manage Server` permission.")
|
||||
Return
|
||||
End If
|
||||
|
||||
If param.Length <> 3 Then
|
||||
Await reqChannel.SendMessageAsync(GenericError)
|
||||
Return
|
||||
End If
|
||||
|
||||
' Subcommands get a subset of the parameters, to make things a little easier.
|
||||
Dim confparam(param.Length - 2) As String ' subtract 2???
|
||||
|
@ -137,7 +144,7 @@ Friend Class ManagerCommands
|
|||
End Function
|
||||
|
||||
' Guild default time zone set/unset
|
||||
Private Async Function ScmdSetTz(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
Private Async Function ScmdZone(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
If param.Length = 1 Then
|
||||
' No extra parameter. Unset guild default time zone.
|
||||
SyncLock Instance.KnownGuilds
|
||||
|
@ -175,49 +182,73 @@ Friend Class ManagerCommands
|
|||
End Function
|
||||
|
||||
' Block/unblock individual non-manager users from using commands.
|
||||
Private Async Function ScmdBanUnban(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
Private Async Function ScmdBlock(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
If param.Length <> 2 Then
|
||||
Await reqChannel.SendMessageAsync(GenericError)
|
||||
Return
|
||||
End If
|
||||
|
||||
Dim doBan As Boolean = param(0).ToLower() = "ban" ' True = ban, False = unban
|
||||
Dim doBan As Boolean = param(0).ToLower() = "block" ' True = block, False = unblock
|
||||
|
||||
' Parameter must be a mention or explicit ID. No name resolution.
|
||||
Dim input = param(1)
|
||||
Dim m = UserMention.Match(param(1))
|
||||
If m.Success Then input = m.Groups(1).Value
|
||||
Dim inputId As ULong
|
||||
If Not ULong.TryParse(input, inputId) Then
|
||||
Await reqChannel.SendMessageAsync(":x: Unable to find user. Specify their `@` mention or their ID.")
|
||||
If Not TryGetUserId(param(1), inputId) Then
|
||||
Await reqChannel.SendMessageAsync(BadUserError)
|
||||
Return
|
||||
End If
|
||||
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
Dim isBanned = gi.IsUserBannedAsync(inputId).GetAwaiter().GetResult()
|
||||
Dim isBanned = gi.IsUserBlockedAsync(inputId).GetAwaiter().GetResult()
|
||||
|
||||
If doBan Then
|
||||
If Not isBanned Then
|
||||
gi.BanUserAsync(inputId).Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User has been banned from using the bot").Wait()
|
||||
gi.BlockUserAsync(inputId).Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User has been blocked.").Wait()
|
||||
Else
|
||||
reqChannel.SendMessageAsync(":white_check_mark: The specified user is already banned.").Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User is already blocked.").Wait()
|
||||
End If
|
||||
Else
|
||||
If isBanned Then
|
||||
gi.UnbanUserAsync(inputId).Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User may now use the bot").Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User is now unblocked.").Wait()
|
||||
Else
|
||||
reqChannel.SendMessageAsync(":white_check_mark: The specified user is not banned.").Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: The specified user has not been blocked.").Wait()
|
||||
End If
|
||||
End If
|
||||
End SyncLock
|
||||
End Function
|
||||
|
||||
' "ban/unban all" - Sets/unsets moderated mode.
|
||||
Private Async Function ScmdSetModerated(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
Throw New NotImplementedException()
|
||||
' "moderated on/off" - Sets/unsets moderated mode.
|
||||
Private Async Function ScmdModerated(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
If param.Length <> 2 Then
|
||||
Await reqChannel.SendMessageAsync(GenericError)
|
||||
Return
|
||||
End If
|
||||
|
||||
Dim parameter = param(1).ToLower()
|
||||
Dim modSet As Boolean
|
||||
If parameter = "on" Then
|
||||
modSet = True
|
||||
ElseIf parameter = "off" Then
|
||||
modSet = False
|
||||
Else
|
||||
Await reqChannel.SendMessageAsync(GenericError)
|
||||
Return
|
||||
End If
|
||||
|
||||
Dim currentSet As Boolean
|
||||
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
currentSet = gi.IsModerated
|
||||
gi.UpdateModeratedModeAsync(modSet).Wait()
|
||||
End SyncLock
|
||||
|
||||
If currentSet = modSet Then
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: Moderated mode is already {parameter}.")
|
||||
Else
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: Moderated mode has been turned {parameter}.")
|
||||
End If
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ Class UserCommands
|
|||
Get
|
||||
Return New List(Of (String, CommandHandler)) From {
|
||||
("set", AddressOf CmdSet),
|
||||
("set-tz", AddressOf CmdSetTz),
|
||||
("zone", AddressOf CmdZone),
|
||||
("remove", AddressOf CmdRemove)
|
||||
}
|
||||
End Get
|
||||
|
@ -124,7 +124,7 @@ Class UserCommands
|
|||
End If
|
||||
End Function
|
||||
|
||||
Private Async Function CmdSetTz(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
Private Async Function CmdZone(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
If param.Count <> 2 Then
|
||||
Await reqChannel.SendMessageAsync(GenericError)
|
||||
Return
|
||||
|
|
Loading…
Reference in a new issue