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.RoleId.HasValue Then role = guild.GetRole(gs.RoleId.Value)
|
||||
If role Is Nothing Then
|
||||
gs.RoleWarning = True
|
||||
gs.RoleWarningNonexist = True
|
||||
Return 0
|
||||
Else
|
||||
gs.RoleWarningNonexist = False
|
||||
End If
|
||||
gs.RoleWarning = False
|
||||
End SyncLock
|
||||
|
||||
' 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
|
||||
' 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)
|
||||
If HasCorrectRolePermissions(guild, role) Then
|
||||
Dim correctRolePermissions = HasCorrectRolePermissions(guild, role)
|
||||
Dim gotForbidden = False
|
||||
|
||||
Dim announceNames As IEnumerable(Of SocketGuildUser) = Nothing
|
||||
If correctRolePermissions Then
|
||||
Try
|
||||
announceNames = Await UpdateGuildBirthdayRoles(guild, role, birthdays)
|
||||
Catch ex As Discord.Net.HttpException
|
||||
If ex.HttpCode = HttpStatusCode.Forbidden Then
|
||||
announceNames = Nothing
|
||||
gotForbidden = True
|
||||
Else
|
||||
Throw
|
||||
End If
|
||||
End Try
|
||||
Else
|
||||
announceNames = Nothing
|
||||
End If
|
||||
|
||||
If announceNames Is Nothing Then
|
||||
' Update warning flag
|
||||
Dim updateError = Not correctRolePermissions Or gotForbidden
|
||||
SyncLock BotInstance.KnownGuilds
|
||||
' Nothing on announceNAmes signals failure to apply roles. Set the warning message.
|
||||
BotInstance.KnownGuilds(guild.Id).RoleWarning = True
|
||||
BotInstance.KnownGuilds(guild.Id).RoleWarningPermission = updateError
|
||||
End SyncLock
|
||||
Return 0
|
||||
End If
|
||||
' Quit now if the warning flag was set. Announcement data is not available.
|
||||
If updateError Then Return 0
|
||||
|
||||
If announceNames.Count <> 0 Then
|
||||
' Send out announcement message
|
||||
|
|
|
@ -26,12 +26,12 @@ Class BirthdayBot
|
|||
End Property
|
||||
|
||||
''' <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)
|
||||
Config = conf
|
||||
_client = dc
|
||||
KnownGuilds = New Dictionary(Of ULong, GuildSettings)
|
||||
KnownGuilds = New Dictionary(Of ULong, GuildStateInformation)
|
||||
|
||||
_worker = New BackgroundServiceRunner(Me)
|
||||
|
||||
|
@ -75,7 +75,7 @@ Class BirthdayBot
|
|||
Private Function LoadGuild(g As SocketGuild) As Task Handles _client.JoinedGuild, _client.GuildAvailable
|
||||
SyncLock KnownGuilds
|
||||
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)
|
||||
End If
|
||||
End SyncLock
|
||||
|
@ -114,7 +114,7 @@ Class BirthdayBot
|
|||
End If
|
||||
|
||||
' Ban and role warning check
|
||||
Dim roleWarning As Boolean
|
||||
Dim roleWarningText As String
|
||||
SyncLock KnownGuilds
|
||||
Dim gi = KnownGuilds(channel.Guild.Id)
|
||||
|
||||
|
@ -125,13 +125,13 @@ Class BirthdayBot
|
|||
End If
|
||||
End If
|
||||
|
||||
roleWarning = gi.RoleWarning
|
||||
roleWarningText = gi.IssueRoleWarning
|
||||
End SyncLock
|
||||
|
||||
Try
|
||||
If roleWarning Then
|
||||
If roleWarningText IsNot Nothing Then
|
||||
Try
|
||||
Await channel.SendMessageAsync(RoleWarningMsg)
|
||||
Await channel.SendMessageAsync(roleWarningText)
|
||||
Catch ex As HttpException
|
||||
' Don't let this prevent the bot from continuing command execution.
|
||||
End Try
|
||||
|
|
|
@ -26,7 +26,7 @@ Class Database
|
|||
|
||||
Private Sub SetupTables()
|
||||
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)
|
||||
End Using
|
||||
End Sub
|
||||
|
|
|
@ -4,11 +4,10 @@ Imports Npgsql
|
|||
Imports NpgsqlTypes
|
||||
|
||||
''' <summary>
|
||||
''' Collection of GuildUserSettings instances. Holds cached information on guild users and overall
|
||||
''' guild options, and provides some database abstractions regarding them all.
|
||||
''' Object instances are loaded when entering a guild and discarded when the bot leaves the guild.
|
||||
''' Holds various pieces of state information for a guild the bot is operating in.
|
||||
''' Includes, among other things, a copy of the guild's settings and a list of all known users with birthdays.
|
||||
''' </summary>
|
||||
Friend Class GuildSettings
|
||||
Friend Class GuildStateInformation
|
||||
Public ReadOnly Property GuildId As ULong
|
||||
Private ReadOnly _db As Database
|
||||
Private _bdayRole As ULong?
|
||||
|
@ -19,33 +18,55 @@ Friend Class GuildSettings
|
|||
Private _announceMsg As String
|
||||
Private _announceMsgPl As String
|
||||
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 Shared ReadOnly RoleWarningInterval As New TimeSpan(1, 0, 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 if it's been set as such,
|
||||
''' and it is only returned after a set time has passed in order to not constantly show the message.
|
||||
''' Message for notifying servers that the bot is unable to manipulate its designated role for various reasons.
|
||||
''' The returned value is dependent on certain warning flags accessible in this class. To avoid bombarding users
|
||||
''' 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>
|
||||
Public Property RoleWarning As Boolean
|
||||
Public ReadOnly Property IssueRoleWarning As String
|
||||
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
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
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
|
||||
Return False
|
||||
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
|
||||
Set(value As Boolean)
|
||||
_roleWarning = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
''' <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.
|
||||
If Not reader.IsDBNull(1) Then
|
||||
_bdayRole = CULng(reader.GetInt64(1))
|
||||
RoleWarning = False
|
||||
Else
|
||||
RoleWarning = True
|
||||
End If
|
||||
If Not reader.IsDBNull(2) Then _announceCh = CULng(reader.GetInt64(2))
|
||||
_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
|
||||
_bdayRole = roleId
|
||||
_roleWarning = False
|
||||
_roleLastWarning = New DateTimeOffset
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
|
@ -326,7 +343,7 @@ Friend Class GuildSettings
|
|||
''' 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.
|
||||
''' </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 c = db.CreateCommand()
|
||||
' Take note of ordinals for use in the constructor
|
||||
|
@ -336,7 +353,7 @@ Friend Class GuildSettings
|
|||
c.Prepare()
|
||||
Using r = Await c.ExecuteReaderAsync()
|
||||
If Await r.ReadAsync() Then
|
||||
Return New GuildSettings(r, dbsettings)
|
||||
Return New GuildStateInformation(r, dbsettings)
|
||||
End If
|
||||
End Using
|
||||
End Using
|
|
@ -4,7 +4,7 @@ Imports NpgsqlTypes
|
|||
|
||||
''' <summary>
|
||||
''' 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>
|
||||
Class GuildUserSettings
|
||||
Private _month As Integer
|
||||
|
@ -125,7 +125,7 @@ Class GuildUserSettings
|
|||
Friend Shared Sub SetUpDatabaseTable(db As NpgsqlConnection)
|
||||
Using c = db.CreateCommand()
|
||||
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, " +
|
||||
"birth_month integer not null, " +
|
||||
"birth_day integer not null, " +
|
||||
|
|
Loading…
Reference in a new issue