mirror of
https://github.com/NoiTheCat/BirthdayBot.git
synced 2024-11-21 21:54:36 +00:00
Remove huge lock on cache
This commit is contained in:
parent
92f4c42b5b
commit
0c4d39e24d
9 changed files with 227 additions and 234 deletions
|
@ -40,7 +40,7 @@ Class BackgroundServiceRunner
|
|||
' Delay a bit before we start (or continue) work.
|
||||
Await Task.Delay(Interval * 1000, WorkerCancel.Token)
|
||||
|
||||
' Start background tasks.
|
||||
' Execute background tasks.
|
||||
Dim tasks As New List(Of Task)
|
||||
For Each service In Workers
|
||||
tasks.Add(service.OnTick(_tickCount))
|
||||
|
|
|
@ -58,23 +58,25 @@ Class BirthdayRoleUpdate
|
|||
Dim channel As SocketTextChannel = Nothing
|
||||
Dim announce As (String, String)
|
||||
Dim announceping As Boolean
|
||||
SyncLock BotInstance.KnownGuilds
|
||||
If Not BotInstance.KnownGuilds.ContainsKey(guild.Id) Then Return 0
|
||||
Dim gs = BotInstance.KnownGuilds(guild.Id)
|
||||
tz = gs.TimeZone
|
||||
users = gs.Users
|
||||
announce = gs.AnnounceMessages
|
||||
announceping = gs.AnnouncePing
|
||||
|
||||
If gs.AnnounceChannelId.HasValue Then channel = guild.GetTextChannel(gs.AnnounceChannelId.Value)
|
||||
If gs.RoleId.HasValue Then role = guild.GetRole(gs.RoleId.Value)
|
||||
If Not BotInstance.GuildCache.ContainsKey(guild.Id) Then Return 0 ' guild not yet fully loaded; skip processing
|
||||
|
||||
Dim gs = BotInstance.GuildCache(guild.Id)
|
||||
With gs
|
||||
tz = .TimeZone
|
||||
users = .Users
|
||||
announce = .AnnounceMessages
|
||||
announceping = .AnnouncePing
|
||||
|
||||
If .AnnounceChannelId.HasValue Then channel = guild.GetTextChannel(gs.AnnounceChannelId.Value)
|
||||
If .RoleId.HasValue Then role = guild.GetRole(gs.RoleId.Value)
|
||||
If role Is Nothing Then
|
||||
gs.RoleWarningNonexist = True
|
||||
.RoleWarningNonexist = True
|
||||
Return 0
|
||||
Else
|
||||
gs.RoleWarningNonexist = False
|
||||
.RoleWarningNonexist = False
|
||||
End If
|
||||
End SyncLock
|
||||
End With
|
||||
|
||||
' Determine who's currently having a birthday
|
||||
Dim birthdays = GetGuildCurrentBirthdays(users, tz)
|
||||
|
@ -100,9 +102,7 @@ Class BirthdayRoleUpdate
|
|||
|
||||
' Update warning flag
|
||||
Dim updateError = Not correctRolePermissions Or gotForbidden
|
||||
SyncLock BotInstance.KnownGuilds
|
||||
BotInstance.KnownGuilds(guild.Id).RoleWarningPermission = updateError
|
||||
End SyncLock
|
||||
BotInstance.GuildCache(guild.Id).RoleWarningPermission = updateError
|
||||
' Quit now if the warning flag was set. Announcement data is not available.
|
||||
If updateError Then Return 0
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ Class GuildStatistics
|
|||
End Sub
|
||||
|
||||
Public Overrides Async Function OnTick(tick As Integer) As Task
|
||||
' Activate roughly every 5 hours (interval: 45)
|
||||
If tick Mod 400 <> 2 Then Return
|
||||
' Activate roughly every 2 hours (interval: 45)
|
||||
If tick Mod 160 <> 2 Then Return
|
||||
|
||||
Dim count = BotInstance.DiscordClient.Guilds.Count
|
||||
Log($"Currently in {count} guild(s).")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Imports BirthdayBot.CommandsCommon
|
||||
Imports System.Collections.Concurrent
|
||||
Imports BirthdayBot.CommandsCommon
|
||||
Imports Discord
|
||||
Imports Discord.Net
|
||||
Imports Discord.WebSocket
|
||||
|
@ -25,13 +26,12 @@ Class BirthdayBot
|
|||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>SyncLock when using. The lock object is itself.</summary>
|
||||
Friend ReadOnly Property KnownGuilds As Dictionary(Of ULong, GuildStateInformation)
|
||||
Friend ReadOnly Property GuildCache As ConcurrentDictionary(Of ULong, GuildStateInformation)
|
||||
|
||||
Public Sub New(conf As Configuration, dc As DiscordSocketClient)
|
||||
Config = conf
|
||||
_client = dc
|
||||
KnownGuilds = New Dictionary(Of ULong, GuildStateInformation)
|
||||
GuildCache = New ConcurrentDictionary(Of ULong, GuildStateInformation)
|
||||
|
||||
_worker = New BackgroundServiceRunner(Me)
|
||||
|
||||
|
@ -72,20 +72,16 @@ Class BirthdayBot
|
|||
_client.Dispose()
|
||||
End Function
|
||||
|
||||
Private Function LoadGuild(g As SocketGuild) As Task Handles _client.JoinedGuild, _client.GuildAvailable
|
||||
SyncLock KnownGuilds
|
||||
If Not KnownGuilds.ContainsKey(g.Id) Then
|
||||
Dim gi = GuildStateInformation.LoadSettingsAsync(Config.DatabaseSettings, g.Id).GetAwaiter().GetResult()
|
||||
KnownGuilds.Add(g.Id, gi)
|
||||
End If
|
||||
End SyncLock
|
||||
Return Task.CompletedTask
|
||||
Private Async Function LoadGuild(g As SocketGuild) As Task Handles _client.JoinedGuild, _client.GuildAvailable
|
||||
If Not GuildCache.ContainsKey(g.Id) Then
|
||||
Dim gi = Await GuildStateInformation.LoadSettingsAsync(Config.DatabaseSettings, g.Id)
|
||||
GuildCache.TryAdd(g.Id, gi)
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Function DiscardGuild(g As SocketGuild) As Task Handles _client.LeftGuild
|
||||
SyncLock KnownGuilds
|
||||
KnownGuilds.Remove(g.Id)
|
||||
End SyncLock
|
||||
Dim rm As GuildStateInformation = Nothing
|
||||
GuildCache.TryRemove(g.Id, rm)
|
||||
Return Task.CompletedTask
|
||||
End Function
|
||||
|
||||
|
@ -115,18 +111,14 @@ Class BirthdayBot
|
|||
|
||||
' Ban and role warning check
|
||||
Dim roleWarningText As String
|
||||
SyncLock KnownGuilds
|
||||
Dim gi = KnownGuilds(channel.Guild.Id)
|
||||
|
||||
' Skip ban check if user is a manager
|
||||
If Not gi.IsUserModerator(author) Then
|
||||
If gi.IsUserBlockedAsync(author.Id).GetAwaiter().GetResult() Then
|
||||
Return
|
||||
End If
|
||||
Dim gi = GuildCache(channel.Guild.Id)
|
||||
' Skip ban check if user is a manager
|
||||
If Not gi.IsUserModerator(author) Then
|
||||
If gi.IsUserBlockedAsync(author.Id).GetAwaiter().GetResult() Then
|
||||
Return
|
||||
End If
|
||||
|
||||
roleWarningText = gi.IssueRoleWarning
|
||||
End SyncLock
|
||||
End If
|
||||
roleWarningText = gi.IssueRoleWarning
|
||||
|
||||
Try
|
||||
If roleWarningText IsNot Nothing Then
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>BirthdayBot</RootNamespace>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Version>1.1.2</Version>
|
||||
<Version>1.2.0</Version>
|
||||
<Authors>Noiiko</Authors>
|
||||
<Company />
|
||||
<Description>Discord bot for birthday reminders.</Description>
|
||||
|
|
|
@ -31,22 +31,24 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property IssueRoleWarning As String
|
||||
Get
|
||||
If DateTimeOffset.UtcNow - _roleLastWarning > RoleWarningInterval Then
|
||||
_roleLastWarning = DateTimeOffset.UtcNow
|
||||
Else
|
||||
SyncLock Me
|
||||
If DateTimeOffset.UtcNow - _roleLastWarning > RoleWarningInterval Then
|
||||
_roleLastWarning = DateTimeOffset.UtcNow
|
||||
Else
|
||||
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
|
||||
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 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
|
||||
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 SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -65,7 +67,9 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Friend ReadOnly Property RoleWarningUnset As Boolean
|
||||
Get
|
||||
Return _bdayRole Is Nothing
|
||||
SyncLock Me
|
||||
Return _bdayRole Is Nothing
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -75,9 +79,11 @@ Friend Class GuildStateInformation
|
|||
Public ReadOnly Property Users As IEnumerable(Of GuildUserSettings)
|
||||
Get
|
||||
Dim items As New List(Of GuildUserSettings)
|
||||
For Each item In _userCache.Values
|
||||
items.Add(item)
|
||||
Next
|
||||
SyncLock Me
|
||||
For Each item In _userCache.Values
|
||||
items.Add(item)
|
||||
Next
|
||||
End SyncLock
|
||||
Return items
|
||||
End Get
|
||||
End Property
|
||||
|
@ -87,7 +93,9 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property RoleId As ULong?
|
||||
Get
|
||||
Return _bdayRole
|
||||
SyncLock Me
|
||||
Return _bdayRole
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -96,7 +104,9 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property AnnounceChannelId As ULong?
|
||||
Get
|
||||
Return _announceCh
|
||||
SyncLock Me
|
||||
Return _announceCh
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -105,7 +115,9 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property TimeZone As String
|
||||
Get
|
||||
Return _tz
|
||||
SyncLock Me
|
||||
Return _tz
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -114,7 +126,9 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property IsModerated As Boolean
|
||||
Get
|
||||
Return _moderated
|
||||
SyncLock Me
|
||||
Return _moderated
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -123,7 +137,9 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property ModeratorRole As ULong?
|
||||
Get
|
||||
Return _modRole
|
||||
SyncLock Me
|
||||
Return _modRole
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -132,17 +148,20 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public ReadOnly Property AnnounceMessages As (String, String)
|
||||
Get
|
||||
Return (_announceMsg, _announceMsgPl)
|
||||
SyncLock Me
|
||||
Return (_announceMsg, _announceMsgPl)
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Gets whether to ping users in the announcement message instead of displaying their names.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property AnnouncePing As Boolean
|
||||
Get
|
||||
Return _announcePing
|
||||
SyncLock Me
|
||||
Return _announcePing
|
||||
End SyncLock
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
@ -174,17 +193,22 @@ Friend Class GuildStateInformation
|
|||
''' Gets user information from this guild. If the user doesn't exist in the backing database,
|
||||
''' a new instance is created which is capable of adding the user to the database.
|
||||
''' </summary>
|
||||
''' <param name="userId"></param>
|
||||
''' <remarks>
|
||||
''' For users with the Known property set to False, be sure to call
|
||||
''' <see cref="GuildUserSettings.DeleteAsync(Database)"/> if the resulting object is otherwise unused.
|
||||
''' </remarks>
|
||||
Public Function GetUser(userId As ULong) As GuildUserSettings
|
||||
If _userCache.ContainsKey(userId) Then
|
||||
Return _userCache(userId)
|
||||
End If
|
||||
SyncLock Me
|
||||
If _userCache.ContainsKey(userId) Then
|
||||
Return _userCache(userId)
|
||||
End If
|
||||
|
||||
' No result. Create a blank entry and add it to the list, in case it
|
||||
' gets referenced later regardless of if having been updated or not.
|
||||
Dim blank As New GuildUserSettings(_GuildId, userId)
|
||||
_userCache.Add(userId, blank)
|
||||
Return blank
|
||||
' No result. Create a blank entry and add it to the list, in case it
|
||||
' gets updated and then referenced later.
|
||||
Dim blank As New GuildUserSettings(_GuildId, userId)
|
||||
_userCache.Add(userId, blank)
|
||||
Return blank
|
||||
End SyncLock
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
|
@ -192,12 +216,13 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public Async Function DeleteUserAsync(userId As ULong) As Task
|
||||
Dim user As GuildUserSettings = Nothing
|
||||
If _userCache.TryGetValue(userId, user) Then
|
||||
Await user.DeleteAsync(_db)
|
||||
Else
|
||||
Return
|
||||
End If
|
||||
_userCache.Remove(userId)
|
||||
SyncLock Me
|
||||
If Not _userCache.TryGetValue(userId, user) Then
|
||||
Return
|
||||
End If
|
||||
_userCache.Remove(userId)
|
||||
End SyncLock
|
||||
Await user.DeleteAsync(_db)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
|
@ -208,6 +233,8 @@ Friend Class GuildStateInformation
|
|||
Public Async Function IsUserBlockedAsync(userId As ULong) As Task(Of Boolean)
|
||||
If IsModerated Then Return True
|
||||
|
||||
' Block list is not cached, thus doing a database lookup
|
||||
' TODO cache block list?
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
Using c = db.CreateCommand()
|
||||
c.CommandText = $"select * from {BackingTableBans} " +
|
||||
|
@ -229,9 +256,11 @@ Friend Class GuildStateInformation
|
|||
''' </summary>
|
||||
Public Function IsUserModerator(user As SocketGuildUser) As Boolean
|
||||
If user.GuildPermissions.ManageGuild Then Return True
|
||||
If ModeratorRole.HasValue Then
|
||||
If user.Roles.Where(Function(r) r.Id = ModeratorRole.Value).Count > 0 Then Return True
|
||||
End If
|
||||
SyncLock Me
|
||||
If ModeratorRole.HasValue Then
|
||||
If user.Roles.Where(Function(r) r.Id = ModeratorRole.Value).Count > 0 Then Return True
|
||||
End If
|
||||
End SyncLock
|
||||
|
||||
IsUserModerator = False
|
||||
End Function
|
||||
|
@ -240,6 +269,7 @@ Friend Class GuildStateInformation
|
|||
''' Adds the specified user to the block list, preventing them from issuing commands.
|
||||
''' </summary>
|
||||
Public Async Function BlockUserAsync(userId As ULong) As Task
|
||||
' TODO cache block list?
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
Using c = db.CreateCommand()
|
||||
c.CommandText = $"insert into {BackingTableBans} (guild_id, user_id) " +
|
||||
|
@ -257,6 +287,7 @@ Friend Class GuildStateInformation
|
|||
''' Removes the specified user from the block list.
|
||||
''' </summary>
|
||||
Public Async Function UnbanUserAsync(userId As ULong) As Task
|
||||
' TODO cache block list?
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
Using c = db.CreateCommand()
|
||||
c.CommandText = $"delete from {BackingTableBans} where " +
|
||||
|
@ -269,46 +300,60 @@ Friend Class GuildStateInformation
|
|||
End Using
|
||||
End Function
|
||||
|
||||
Public Async Function UpdateRoleAsync(roleId As ULong) As Task
|
||||
_bdayRole = roleId
|
||||
_roleLastWarning = New DateTimeOffset
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
Public Sub UpdateRole(roleId As ULong)
|
||||
SyncLock Me
|
||||
_bdayRole = roleId
|
||||
_roleLastWarning = New DateTimeOffset
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Public Async Function UpdateAnnounceChannelAsync(channelId As ULong?) As Task
|
||||
_announceCh = channelId
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
Public Sub UpdateAnnounceChannel(channelId As ULong?)
|
||||
SyncLock Me
|
||||
_announceCh = channelId
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Public Async Function UpdateTimeZoneAsync(tzString As String) As Task
|
||||
_tz = tzString
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
Public Sub UpdateTimeZone(tzString As String)
|
||||
SyncLock Me
|
||||
_tz = tzString
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Public Async Function UpdateModeratedModeAsync(isModerated As Boolean) As Task
|
||||
_moderated = isModerated
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
Public Sub UpdateModeratedMode(isModerated As Boolean)
|
||||
SyncLock Me
|
||||
_moderated = isModerated
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Public Async Function UpdateModeratorRoleAsync(roleId As ULong?) As Task
|
||||
_modRole = roleId
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
Public Sub UpdateModeratorRole(roleId As ULong?)
|
||||
SyncLock Me
|
||||
_modRole = roleId
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Public Async Function UpdateAnnounceMessageAsync(message As String, plural As Boolean) As Task
|
||||
If plural Then
|
||||
_announceMsgPl = message
|
||||
Else
|
||||
_announceMsg = message
|
||||
End If
|
||||
Public Sub UpdateAnnounceMessage(message As String, plural As Boolean)
|
||||
SyncLock Me
|
||||
If plural Then
|
||||
_announceMsgPl = message
|
||||
Else
|
||||
_announceMsg = message
|
||||
End If
|
||||
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
Public Async Function UpdateAnnouncePingAsync(value As Boolean) As Task
|
||||
_announcePing = value
|
||||
Await UpdateDatabaseAsync()
|
||||
End Function
|
||||
Public Sub UpdateAnnouncePing(value As Boolean)
|
||||
SyncLock Me
|
||||
_announcePing = value
|
||||
UpdateDatabase()
|
||||
End SyncLock
|
||||
End Sub
|
||||
|
||||
#Region "Database"
|
||||
Public Const BackingTable = "settings"
|
||||
|
@ -374,8 +419,8 @@ Friend Class GuildStateInformation
|
|||
''' Updates the backing database with values from this instance
|
||||
''' This is a non-asynchronous operation. That may be bad.
|
||||
''' </summary>
|
||||
Private Async Function UpdateDatabaseAsync() As Task
|
||||
Using db = Await _db.OpenConnectionAsync()
|
||||
Private Sub UpdateDatabase()
|
||||
Using db = _db.OpenConnectionAsync().GetAwaiter().GetResult()
|
||||
Using c = db.CreateCommand()
|
||||
c.CommandText = $"update {BackingTable} set " +
|
||||
"role_id = @RoleId, " +
|
||||
|
@ -433,9 +478,9 @@ Friend Class GuildStateInformation
|
|||
End With
|
||||
c.Parameters.Add("@AnnouncePing", NpgsqlDbType.Boolean).Value = _announcePing
|
||||
c.Prepare()
|
||||
Await c.ExecuteNonQueryAsync()
|
||||
c.ExecuteNonQuery()
|
||||
End Using
|
||||
End Using
|
||||
End Function
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
|
|
|
@ -24,11 +24,7 @@ Class ListingCommands
|
|||
' Creates a file with all birthdays.
|
||||
Private Async Function CmdList(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
' For now, we're restricting this command to moderators only. This may turn into an option later.
|
||||
Dim reqMod As Boolean
|
||||
SyncLock Instance.KnownGuilds
|
||||
reqMod = Instance.KnownGuilds(reqChannel.Guild.Id).IsUserModerator(reqUser)
|
||||
End SyncLock
|
||||
If Not reqMod Then
|
||||
If Not Instance.GuildCache(reqChannel.Guild.Id).IsUserModerator(reqUser) Then
|
||||
Await reqChannel.SendMessageAsync(":x: Only bot moderators may use this command.")
|
||||
Return
|
||||
End If
|
||||
|
@ -126,10 +122,7 @@ Class ListingCommands
|
|||
''' Users currently not in the guild are not included in the result.
|
||||
''' </summary>
|
||||
Private Async Function LoadList(guild As SocketGuild, escapeFormat As Boolean) As Task(Of List(Of ListItem))
|
||||
Dim ping As Boolean
|
||||
SyncLock Instance.KnownGuilds
|
||||
ping = Instance.KnownGuilds(guild.Id).AnnouncePing
|
||||
End SyncLock
|
||||
Dim ping = Instance.GuildCache(guild.Id).AnnouncePing
|
||||
|
||||
Using db = Await BotConfig.DatabaseSettings.OpenConnectionAsync()
|
||||
Using c = db.CreateCommand()
|
||||
|
|
|
@ -42,11 +42,7 @@ Friend Class ManagerCommands
|
|||
Private Async Function CmdConfigDispatch(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
' Ignore those without the proper permissions.
|
||||
' Requires either the manage guild permission or to be in the moderators role
|
||||
Dim allowed As Boolean
|
||||
SyncLock Instance.KnownGuilds
|
||||
allowed = Instance.KnownGuilds(reqUser.Guild.Id).IsUserModerator(reqUser)
|
||||
End SyncLock
|
||||
If Not allowed Then
|
||||
If Not Instance.GuildCache(reqUser.Guild.Id).IsUserModerator(reqUser) Then
|
||||
Await reqChannel.SendMessageAsync(":x: This command may only be used by bot moderators.")
|
||||
Return
|
||||
End If
|
||||
|
@ -88,9 +84,7 @@ Friend Class ManagerCommands
|
|||
ElseIf role.Id = reqChannel.Guild.EveryoneRole.Id Then
|
||||
Await reqChannel.SendMessageAsync(":x: You cannot set that as the birthday role.")
|
||||
Else
|
||||
SyncLock Instance.KnownGuilds
|
||||
Instance.KnownGuilds(guild.Id).UpdateRoleAsync(role.Id).Wait()
|
||||
End SyncLock
|
||||
Instance.GuildCache(guild.Id).UpdateRole(role.Id)
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: The birthday role has been set as **{role.Name}**.")
|
||||
End If
|
||||
End Function
|
||||
|
@ -116,9 +110,7 @@ Friend Class ManagerCommands
|
|||
Return
|
||||
End If
|
||||
|
||||
SyncLock Instance.KnownGuilds
|
||||
Instance.KnownGuilds(reqChannel.Guild.Id).UpdateAnnouncePingAsync(setting).Wait()
|
||||
End SyncLock
|
||||
Instance.GuildCache(reqChannel.Guild.Id).UpdateAnnouncePing(setting)
|
||||
Await reqChannel.SendMessageAsync(result)
|
||||
End Function
|
||||
|
||||
|
@ -126,18 +118,15 @@ Friend Class ManagerCommands
|
|||
Private Async Function ScmdChannel(param As String(), reqChannel As SocketTextChannel) As Task
|
||||
If param.Length = 1 Then
|
||||
' No extra parameter. Unset announcement channel.
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
Dim gi = Instance.GuildCache(reqChannel.Guild.Id)
|
||||
|
||||
' Extra detail: Show a unique message if a channel hadn't been set prior.
|
||||
If Not gi.AnnounceChannelId.HasValue Then
|
||||
reqChannel.SendMessageAsync(":x: There is no announcement channel set. Nothing to unset.").Wait()
|
||||
Return
|
||||
End If
|
||||
|
||||
gi.UpdateAnnounceChannelAsync(Nothing).Wait()
|
||||
End SyncLock
|
||||
' Extra detail: Show a unique message if a channel hadn't been set prior.
|
||||
If Not gi.AnnounceChannelId.HasValue Then
|
||||
reqChannel.SendMessageAsync(":x: There is no announcement channel set. Nothing to unset.").Wait()
|
||||
Return
|
||||
End If
|
||||
|
||||
gi.UpdateAnnounceChannel(Nothing)
|
||||
Await reqChannel.SendMessageAsync(":white_check_mark: The announcement channel has been unset.")
|
||||
Else
|
||||
' Parameter check: This needs a channel mention to function.
|
||||
|
@ -156,10 +145,8 @@ Friend Class ManagerCommands
|
|||
End If
|
||||
|
||||
' Update the value
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
gi.UpdateAnnounceChannelAsync(chId).Wait()
|
||||
End SyncLock
|
||||
Dim gi = Instance.GuildCache(reqChannel.Guild.Id)
|
||||
gi.UpdateAnnounceChannel(chId)
|
||||
|
||||
' Report the success
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: The announcement channel is now set to <#{chId}>.")
|
||||
|
@ -178,9 +165,7 @@ Friend Class ManagerCommands
|
|||
If role Is Nothing Then
|
||||
Await reqChannel.SendMessageAsync(RoleInputError)
|
||||
Else
|
||||
SyncLock Instance.KnownGuilds
|
||||
Instance.KnownGuilds(guild.Id).UpdateModeratorRoleAsync(role.Id).Wait()
|
||||
End SyncLock
|
||||
Instance.GuildCache(guild.Id).UpdateModeratorRole(role.Id)
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: The moderator role is now **{role.Name}**.")
|
||||
End If
|
||||
End Function
|
||||
|
@ -189,17 +174,15 @@ Friend Class ManagerCommands
|
|||
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
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
Dim gi = Instance.GuildCache(reqChannel.Guild.Id)
|
||||
|
||||
' Extra detail: Show a unique message if there is no set zone.
|
||||
If Not gi.AnnounceChannelId.HasValue Then
|
||||
reqChannel.SendMessageAsync(":x: A default zone is not set. Nothing to unset.").Wait()
|
||||
Return
|
||||
End If
|
||||
' Extra detail: Show a unique message if there is no set zone.
|
||||
If Not gi.AnnounceChannelId.HasValue Then
|
||||
reqChannel.SendMessageAsync(":x: A default zone is not set. Nothing to unset.").Wait()
|
||||
Return
|
||||
End If
|
||||
|
||||
gi.UpdateTimeZoneAsync(Nothing).Wait()
|
||||
End SyncLock
|
||||
gi.UpdateTimeZone(Nothing)
|
||||
|
||||
Await reqChannel.SendMessageAsync(":white_check_mark: The default time zone preference has been removed.")
|
||||
Else
|
||||
|
@ -213,10 +196,7 @@ Friend Class ManagerCommands
|
|||
End Try
|
||||
|
||||
' Update value
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
gi.UpdateTimeZoneAsync(zone).Wait()
|
||||
End SyncLock
|
||||
Instance.GuildCache(reqChannel.Guild.Id).UpdateTimeZone(zone)
|
||||
|
||||
' Report the success
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: The server's time zone has been set to **{zone}**.")
|
||||
|
@ -238,26 +218,23 @@ Friend Class ManagerCommands
|
|||
Return
|
||||
End If
|
||||
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim gi = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
Dim isBanned = gi.IsUserBlockedAsync(inputId).GetAwaiter().GetResult()
|
||||
|
||||
If doBan Then
|
||||
If Not isBanned Then
|
||||
gi.BlockUserAsync(inputId).Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User has been blocked.").Wait()
|
||||
Else
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User is already blocked.").Wait()
|
||||
End If
|
||||
Dim gi = Instance.GuildCache(reqChannel.Guild.Id)
|
||||
Dim isBanned = Await gi.IsUserBlockedAsync(inputId)
|
||||
If doBan Then
|
||||
If Not isBanned Then
|
||||
Await gi.BlockUserAsync(inputId)
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User has been blocked.").Wait()
|
||||
Else
|
||||
If isBanned Then
|
||||
gi.UnbanUserAsync(inputId).Wait()
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User is now unblocked.").Wait()
|
||||
Else
|
||||
reqChannel.SendMessageAsync(":white_check_mark: The specified user has not been blocked.").Wait()
|
||||
End If
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User is already blocked.").Wait()
|
||||
End If
|
||||
End SyncLock
|
||||
Else
|
||||
If isBanned Then
|
||||
Await gi.UnbanUserAsync(inputId)
|
||||
reqChannel.SendMessageAsync(":white_check_mark: User is now unblocked.").Wait()
|
||||
Else
|
||||
reqChannel.SendMessageAsync(":white_check_mark: The specified user has not been blocked.").Wait()
|
||||
End If
|
||||
End If
|
||||
End Function
|
||||
|
||||
' "moderated on/off" - Sets/unsets moderated mode.
|
||||
|
@ -278,13 +255,9 @@ Friend Class ManagerCommands
|
|||
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
|
||||
Dim gi = Instance.GuildCache(reqChannel.Guild.Id)
|
||||
Dim currentSet = gi.IsModerated
|
||||
gi.UpdateModeratedMode(modSet)
|
||||
|
||||
If currentSet = modSet Then
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: Moderated mode is already {parameter}.")
|
||||
|
@ -307,9 +280,7 @@ Friend Class ManagerCommands
|
|||
clear = True
|
||||
End If
|
||||
|
||||
SyncLock Instance.KnownGuilds
|
||||
Instance.KnownGuilds(reqChannel.Guild.Id).UpdateAnnounceMessageAsync(newmsg, plural).Wait()
|
||||
End SyncLock
|
||||
Instance.GuildCache(reqChannel.Guild.Id).UpdateAnnounceMessage(newmsg, plural)
|
||||
Const report = ":white_check_mark: The {0} birthday announcement message has been {1}."
|
||||
Await reqChannel.SendMessageAsync(String.Format(report, If(plural, "plural", "singular"), If(clear, "reset", "updated")))
|
||||
End Function
|
||||
|
@ -318,9 +289,7 @@ Friend Class ManagerCommands
|
|||
' Execute command as another user
|
||||
Private Async Function CmdOverride(param As String(), reqChannel As SocketTextChannel, reqUser As SocketGuildUser) As Task
|
||||
' Moderators only. As with config, silently drop if this check fails.
|
||||
SyncLock Instance.KnownGuilds
|
||||
If Not Instance.KnownGuilds(reqUser.Guild.Id).IsUserModerator(reqUser) Then Return
|
||||
End SyncLock
|
||||
If Not Instance.GuildCache(reqUser.Guild.Id).IsUserModerator(reqUser) Then Return
|
||||
|
||||
If param.Length <> 3 Then
|
||||
Await reqChannel.SendMessageAsync(GenericError)
|
||||
|
|
|
@ -104,11 +104,9 @@ Class UserCommands
|
|||
' Parsing successful. Update user information.
|
||||
Dim known As Boolean ' Extra detail: Bot's response changes if the user was previously unknown.
|
||||
Try
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim user = Instance.KnownGuilds(reqChannel.Guild.Id).GetUser(reqUser.Id)
|
||||
known = user.IsKnown
|
||||
user.UpdateAsync(bmonth, bday, btz, BotConfig.DatabaseSettings).Wait()
|
||||
End SyncLock
|
||||
Dim user = Instance.GuildCache(reqChannel.Guild.Id).GetUser(reqUser.Id)
|
||||
known = user.IsKnown
|
||||
Await user.UpdateAsync(bmonth, bday, btz, BotConfig.DatabaseSettings)
|
||||
Catch ex As Exception
|
||||
Log("Error", ex.ToString())
|
||||
reqChannel.SendMessageAsync(":x: An unknown error occurred. The bot owner has been notified.").Wait()
|
||||
|
@ -128,21 +126,20 @@ Class UserCommands
|
|||
End If
|
||||
|
||||
Dim btz As String = Nothing
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim user = Instance.KnownGuilds(reqChannel.Guild.Id).GetUser(reqUser.Id)
|
||||
If Not user.IsKnown Then
|
||||
reqChannel.SendMessageAsync(":x: Can't set your time zone if your birth date isn't registered.").Wait()
|
||||
Return
|
||||
End If
|
||||
Dim user = Instance.GuildCache(reqChannel.Guild.Id).GetUser(reqUser.Id)
|
||||
If Not user.IsKnown Then
|
||||
Await reqChannel.SendMessageAsync(":x: Can't set your time zone if your birth date isn't registered.")
|
||||
Return
|
||||
End If
|
||||
|
||||
Try
|
||||
btz = ParseTimeZone(param(1))
|
||||
Catch ex As Exception
|
||||
reqChannel.SendMessageAsync(ex.Message).Wait()
|
||||
Return
|
||||
End Try
|
||||
Await user.UpdateAsync(user.BirthMonth, user.BirthDay, btz, BotConfig.DatabaseSettings)
|
||||
|
||||
Try
|
||||
btz = ParseTimeZone(param(1))
|
||||
Catch ex As Exception
|
||||
reqChannel.SendMessageAsync(ex.Message).Wait()
|
||||
Return
|
||||
End Try
|
||||
user.UpdateAsync(user.BirthMonth, user.BirthDay, btz, BotConfig.DatabaseSettings).Wait()
|
||||
End SyncLock
|
||||
Await reqChannel.SendMessageAsync($":white_check_mark: Your time zone has been updated to **{btz}**.")
|
||||
End Function
|
||||
|
||||
|
@ -155,13 +152,10 @@ Class UserCommands
|
|||
|
||||
' Extra detail: Send a notification if the user isn't actually known by the bot.
|
||||
Dim known As Boolean
|
||||
SyncLock Instance.KnownGuilds
|
||||
Dim g = Instance.KnownGuilds(reqChannel.Guild.Id)
|
||||
known = g.GetUser(reqUser.Id).IsKnown
|
||||
If known Then
|
||||
g.DeleteUserAsync(reqUser.Id).Wait()
|
||||
End If
|
||||
End SyncLock
|
||||
Dim g = Instance.GuildCache(reqChannel.Guild.Id)
|
||||
known = g.GetUser(reqUser.Id).IsKnown
|
||||
' Delete database and cache entry
|
||||
Await g.DeleteUserAsync(reqUser.Id)
|
||||
If Not known Then
|
||||
Await reqChannel.SendMessageAsync(":white_check_mark: I don't have your information. Nothing to remove.")
|
||||
Else
|
||||
|
|
Loading…
Reference in a new issue