mirror of
https://github.com/NoiTheCat/BirthdayBot.git
synced 2024-11-21 21:54:36 +00:00
Renamed class; added user-friendly feedback on errors
-Renamed GuildSettings to GuildStateInformation as it is more accurate -Completely changed the behavior of the role error warning to provide a more useful help message to the user based on the error that was detected
This commit is contained in:
parent
f3e70f8459
commit
5ad193c059
5 changed files with 71 additions and 52 deletions
|
@ -69,10 +69,11 @@ Class BirthdayRoleUpdate
|
||||||
If gs.AnnounceChannelId.HasValue Then channel = guild.GetTextChannel(gs.AnnounceChannelId.Value)
|
If gs.AnnounceChannelId.HasValue Then channel = guild.GetTextChannel(gs.AnnounceChannelId.Value)
|
||||||
If gs.RoleId.HasValue Then role = guild.GetRole(gs.RoleId.Value)
|
If gs.RoleId.HasValue Then role = guild.GetRole(gs.RoleId.Value)
|
||||||
If role Is Nothing Then
|
If role Is Nothing Then
|
||||||
gs.RoleWarning = True
|
gs.RoleWarningNonexist = True
|
||||||
Return 0
|
Return 0
|
||||||
|
Else
|
||||||
|
gs.RoleWarningNonexist = False
|
||||||
End If
|
End If
|
||||||
gs.RoleWarning = False
|
|
||||||
End SyncLock
|
End SyncLock
|
||||||
|
|
||||||
' Determine who's currently having a birthday
|
' Determine who's currently having a birthday
|
||||||
|
@ -81,28 +82,29 @@ Class BirthdayRoleUpdate
|
||||||
|
|
||||||
' Set birthday roles, get list of users that had the role added
|
' Set birthday roles, get list of users that had the role added
|
||||||
' But first check if we are able to do so. Letting all requests fail instead will lead to rate limiting.
|
' But first check if we are able to do so. Letting all requests fail instead will lead to rate limiting.
|
||||||
Dim announceNames As IEnumerable(Of SocketGuildUser)
|
Dim correctRolePermissions = HasCorrectRolePermissions(guild, role)
|
||||||
If HasCorrectRolePermissions(guild, role) Then
|
Dim gotForbidden = False
|
||||||
|
|
||||||
|
Dim announceNames As IEnumerable(Of SocketGuildUser) = Nothing
|
||||||
|
If correctRolePermissions Then
|
||||||
Try
|
Try
|
||||||
announceNames = Await UpdateGuildBirthdayRoles(guild, role, birthdays)
|
announceNames = Await UpdateGuildBirthdayRoles(guild, role, birthdays)
|
||||||
Catch ex As Discord.Net.HttpException
|
Catch ex As Discord.Net.HttpException
|
||||||
If ex.HttpCode = HttpStatusCode.Forbidden Then
|
If ex.HttpCode = HttpStatusCode.Forbidden Then
|
||||||
announceNames = Nothing
|
gotForbidden = True
|
||||||
Else
|
Else
|
||||||
Throw
|
Throw
|
||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
Else
|
|
||||||
announceNames = Nothing
|
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If announceNames Is Nothing Then
|
' Update warning flag
|
||||||
SyncLock BotInstance.KnownGuilds
|
Dim updateError = Not correctRolePermissions Or gotForbidden
|
||||||
' Nothing on announceNAmes signals failure to apply roles. Set the warning message.
|
SyncLock BotInstance.KnownGuilds
|
||||||
BotInstance.KnownGuilds(guild.Id).RoleWarning = True
|
BotInstance.KnownGuilds(guild.Id).RoleWarningPermission = updateError
|
||||||
End SyncLock
|
End SyncLock
|
||||||
Return 0
|
' Quit now if the warning flag was set. Announcement data is not available.
|
||||||
End If
|
If updateError Then Return 0
|
||||||
|
|
||||||
If announceNames.Count <> 0 Then
|
If announceNames.Count <> 0 Then
|
||||||
' Send out announcement message
|
' Send out announcement message
|
||||||
|
|
|
@ -26,12 +26,12 @@ Class BirthdayBot
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
''' <summary>SyncLock when using. The lock object is itself.</summary>
|
''' <summary>SyncLock when using. The lock object is itself.</summary>
|
||||||
Friend ReadOnly Property KnownGuilds As Dictionary(Of ULong, GuildSettings)
|
Friend ReadOnly Property KnownGuilds As Dictionary(Of ULong, GuildStateInformation)
|
||||||
|
|
||||||
Public Sub New(conf As Configuration, dc As DiscordSocketClient)
|
Public Sub New(conf As Configuration, dc As DiscordSocketClient)
|
||||||
Config = conf
|
Config = conf
|
||||||
_client = dc
|
_client = dc
|
||||||
KnownGuilds = New Dictionary(Of ULong, GuildSettings)
|
KnownGuilds = New Dictionary(Of ULong, GuildStateInformation)
|
||||||
|
|
||||||
_worker = New BackgroundServiceRunner(Me)
|
_worker = New BackgroundServiceRunner(Me)
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ Class BirthdayBot
|
||||||
Private Function LoadGuild(g As SocketGuild) As Task Handles _client.JoinedGuild, _client.GuildAvailable
|
Private Function LoadGuild(g As SocketGuild) As Task Handles _client.JoinedGuild, _client.GuildAvailable
|
||||||
SyncLock KnownGuilds
|
SyncLock KnownGuilds
|
||||||
If Not KnownGuilds.ContainsKey(g.Id) Then
|
If Not KnownGuilds.ContainsKey(g.Id) Then
|
||||||
Dim gi = GuildSettings.LoadSettingsAsync(Config.DatabaseSettings, g.Id).GetAwaiter().GetResult()
|
Dim gi = GuildStateInformation.LoadSettingsAsync(Config.DatabaseSettings, g.Id).GetAwaiter().GetResult()
|
||||||
KnownGuilds.Add(g.Id, gi)
|
KnownGuilds.Add(g.Id, gi)
|
||||||
End If
|
End If
|
||||||
End SyncLock
|
End SyncLock
|
||||||
|
@ -114,7 +114,7 @@ Class BirthdayBot
|
||||||
End If
|
End If
|
||||||
|
|
||||||
' Ban and role warning check
|
' Ban and role warning check
|
||||||
Dim roleWarning As Boolean
|
Dim roleWarningText As String
|
||||||
SyncLock KnownGuilds
|
SyncLock KnownGuilds
|
||||||
Dim gi = KnownGuilds(channel.Guild.Id)
|
Dim gi = KnownGuilds(channel.Guild.Id)
|
||||||
|
|
||||||
|
@ -125,13 +125,13 @@ Class BirthdayBot
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
roleWarning = gi.RoleWarning
|
roleWarningText = gi.IssueRoleWarning
|
||||||
End SyncLock
|
End SyncLock
|
||||||
|
|
||||||
Try
|
Try
|
||||||
If roleWarning Then
|
If roleWarningText IsNot Nothing Then
|
||||||
Try
|
Try
|
||||||
Await channel.SendMessageAsync(RoleWarningMsg)
|
Await channel.SendMessageAsync(roleWarningText)
|
||||||
Catch ex As HttpException
|
Catch ex As HttpException
|
||||||
' Don't let this prevent the bot from continuing command execution.
|
' Don't let this prevent the bot from continuing command execution.
|
||||||
End Try
|
End Try
|
||||||
|
|
|
@ -26,7 +26,7 @@ Class Database
|
||||||
|
|
||||||
Private Sub SetupTables()
|
Private Sub SetupTables()
|
||||||
Using db = OpenConnectionAsync().GetAwaiter().GetResult()
|
Using db = OpenConnectionAsync().GetAwaiter().GetResult()
|
||||||
GuildSettings.SetUpDatabaseTable(db) ' Note: Call this first. (Foreign reference constraints.)
|
GuildStateInformation.SetUpDatabaseTable(db) ' Note: Call this first. (Foreign reference constraints.)
|
||||||
GuildUserSettings.SetUpDatabaseTable(db)
|
GuildUserSettings.SetUpDatabaseTable(db)
|
||||||
End Using
|
End Using
|
||||||
End Sub
|
End Sub
|
||||||
|
|
|
@ -4,11 +4,10 @@ Imports Npgsql
|
||||||
Imports NpgsqlTypes
|
Imports NpgsqlTypes
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Collection of GuildUserSettings instances. Holds cached information on guild users and overall
|
''' Holds various pieces of state information for a guild the bot is operating in.
|
||||||
''' guild options, and provides some database abstractions regarding them all.
|
''' Includes, among other things, a copy of the guild's settings and a list of all known users with birthdays.
|
||||||
''' Object instances are loaded when entering a guild and discarded when the bot leaves the guild.
|
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Friend Class GuildSettings
|
Friend Class GuildStateInformation
|
||||||
Public ReadOnly Property GuildId As ULong
|
Public ReadOnly Property GuildId As ULong
|
||||||
Private ReadOnly _db As Database
|
Private ReadOnly _db As Database
|
||||||
Private _bdayRole As ULong?
|
Private _bdayRole As ULong?
|
||||||
|
@ -19,33 +18,55 @@ Friend Class GuildSettings
|
||||||
Private _announceMsg As String
|
Private _announceMsg As String
|
||||||
Private _announceMsgPl As String
|
Private _announceMsgPl As String
|
||||||
Private _announcePing As Boolean
|
Private _announcePing As Boolean
|
||||||
Private _userCache As Dictionary(Of ULong, GuildUserSettings)
|
Private ReadOnly _userCache As Dictionary(Of ULong, GuildUserSettings)
|
||||||
|
|
||||||
Private _roleWarning As Boolean
|
|
||||||
Private _roleLastWarning As New DateTimeOffset(DateTime.MinValue, TimeSpan.Zero)
|
Private _roleLastWarning As New DateTimeOffset(DateTime.MinValue, TimeSpan.Zero)
|
||||||
Private Shared ReadOnly RoleWarningInterval As New TimeSpan(1, 0, 0)
|
Private Shared ReadOnly RoleWarningInterval As New TimeSpan(1, 0, 0)
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Flag for notifying servers that the bot is unable to manipulate its role.
|
''' Message for notifying servers that the bot is unable to manipulate its designated role for various reasons.
|
||||||
''' Can be set at any time. Reading this will only return True if it's been set as such,
|
''' The returned value is dependent on certain warning flags accessible in this class. To avoid bombarding users
|
||||||
''' and it is only returned after a set time has passed in order to not constantly show the message.
|
''' with the same message, this property only returns a non-Nothing value at most once per hour.
|
||||||
|
''' Otherwise, it shall always return Nothing if there is no warning to be issued.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Property RoleWarning As Boolean
|
Public ReadOnly Property IssueRoleWarning As String
|
||||||
Get
|
Get
|
||||||
If _roleWarning = True Then
|
If DateTimeOffset.UtcNow - _roleLastWarning > RoleWarningInterval Then
|
||||||
' Only report a warning every so often.
|
_roleLastWarning = DateTimeOffset.UtcNow
|
||||||
If DateTimeOffset.UtcNow - _roleLastWarning > RoleWarningInterval Then
|
Else
|
||||||
_roleLastWarning = DateTimeOffset.UtcNow
|
Return Nothing
|
||||||
Return True
|
|
||||||
Else
|
|
||||||
Return False
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
Return False
|
|
||||||
|
If RoleWarningUnset Or RoleWarningNonexist Then
|
||||||
|
Return "Warning: A birthday role must be configured before this bot can function properly. " +
|
||||||
|
"Update the designated role with `bb.config role (role name/ID)`."
|
||||||
|
End If
|
||||||
|
If RoleWarningPermission Then
|
||||||
|
Return "Warning: This bot is unable to set the birthday role onto users. " +
|
||||||
|
"Make sure that this bot has the Manage Roles permission and is not placed below the birthday role."
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return Nothing
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Role warning message: The birthday role cannot be accessed.
|
||||||
|
''' </summary>
|
||||||
|
Friend Property RoleWarningPermission As Boolean = False
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Role warning message: The birthday role no longer exists.
|
||||||
|
''' </summary>
|
||||||
|
Friend Property RoleWarningNonexist As Boolean = False
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' Role warning message: The birthday role is not set.
|
||||||
|
''' </summary>
|
||||||
|
Friend ReadOnly Property RoleWarningUnset As Boolean
|
||||||
|
Get
|
||||||
|
Return _bdayRole Is Nothing
|
||||||
End Get
|
End Get
|
||||||
Set(value As Boolean)
|
|
||||||
_roleWarning = value
|
|
||||||
End Set
|
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
|
@ -132,9 +153,6 @@ Friend Class GuildSettings
|
||||||
' Weird: if using a ternary operator with a ULong?, Nothing resolves to 0 despite Option Strict On.
|
' Weird: if using a ternary operator with a ULong?, Nothing resolves to 0 despite Option Strict On.
|
||||||
If Not reader.IsDBNull(1) Then
|
If Not reader.IsDBNull(1) Then
|
||||||
_bdayRole = CULng(reader.GetInt64(1))
|
_bdayRole = CULng(reader.GetInt64(1))
|
||||||
RoleWarning = False
|
|
||||||
Else
|
|
||||||
RoleWarning = True
|
|
||||||
End If
|
End If
|
||||||
If Not reader.IsDBNull(2) Then _announceCh = CULng(reader.GetInt64(2))
|
If Not reader.IsDBNull(2) Then _announceCh = CULng(reader.GetInt64(2))
|
||||||
_tz = If(reader.IsDBNull(3), Nothing, reader.GetString(3))
|
_tz = If(reader.IsDBNull(3), Nothing, reader.GetString(3))
|
||||||
|
@ -253,7 +271,6 @@ Friend Class GuildSettings
|
||||||
|
|
||||||
Public Async Function UpdateRoleAsync(roleId As ULong) As Task
|
Public Async Function UpdateRoleAsync(roleId As ULong) As Task
|
||||||
_bdayRole = roleId
|
_bdayRole = roleId
|
||||||
_roleWarning = False
|
|
||||||
_roleLastWarning = New DateTimeOffset
|
_roleLastWarning = New DateTimeOffset
|
||||||
Await UpdateDatabaseAsync()
|
Await UpdateDatabaseAsync()
|
||||||
End Function
|
End Function
|
||||||
|
@ -326,7 +343,7 @@ Friend Class GuildSettings
|
||||||
''' Retrieves an object instance representative of guild settings for the specified guild.
|
''' Retrieves an object instance representative of guild settings for the specified guild.
|
||||||
''' If settings for the given guild do not yet exist, a new value is created.
|
''' If settings for the given guild do not yet exist, a new value is created.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Friend Shared Async Function LoadSettingsAsync(dbsettings As Database, guild As ULong) As Task(Of GuildSettings)
|
Friend Shared Async Function LoadSettingsAsync(dbsettings As Database, guild As ULong) As Task(Of GuildStateInformation)
|
||||||
Using db = Await dbsettings.OpenConnectionAsync()
|
Using db = Await dbsettings.OpenConnectionAsync()
|
||||||
Using c = db.CreateCommand()
|
Using c = db.CreateCommand()
|
||||||
' Take note of ordinals for use in the constructor
|
' Take note of ordinals for use in the constructor
|
||||||
|
@ -336,7 +353,7 @@ Friend Class GuildSettings
|
||||||
c.Prepare()
|
c.Prepare()
|
||||||
Using r = Await c.ExecuteReaderAsync()
|
Using r = Await c.ExecuteReaderAsync()
|
||||||
If Await r.ReadAsync() Then
|
If Await r.ReadAsync() Then
|
||||||
Return New GuildSettings(r, dbsettings)
|
Return New GuildStateInformation(r, dbsettings)
|
||||||
End If
|
End If
|
||||||
End Using
|
End Using
|
||||||
End Using
|
End Using
|
|
@ -4,7 +4,7 @@ Imports NpgsqlTypes
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Representation of a user's birthday settings within a guild.
|
''' Representation of a user's birthday settings within a guild.
|
||||||
''' Instances are held and managed by <see cref="GuildSettings"/>.
|
''' Instances are held and managed by <see cref="GuildStateInformation"/>.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Class GuildUserSettings
|
Class GuildUserSettings
|
||||||
Private _month As Integer
|
Private _month As Integer
|
||||||
|
@ -125,7 +125,7 @@ Class GuildUserSettings
|
||||||
Friend Shared Sub SetUpDatabaseTable(db As NpgsqlConnection)
|
Friend Shared Sub SetUpDatabaseTable(db As NpgsqlConnection)
|
||||||
Using c = db.CreateCommand()
|
Using c = db.CreateCommand()
|
||||||
c.CommandText = $"create table if not exists {BackingTable} (" +
|
c.CommandText = $"create table if not exists {BackingTable} (" +
|
||||||
$"guild_id bigint not null references {GuildSettings.BackingTable}, " +
|
$"guild_id bigint not null references {GuildStateInformation.BackingTable}, " +
|
||||||
"user_id bigint not null, " +
|
"user_id bigint not null, " +
|
||||||
"birth_month integer not null, " +
|
"birth_month integer not null, " +
|
||||||
"birth_day integer not null, " +
|
"birth_day integer not null, " +
|
||||||
|
|
Loading…
Reference in a new issue