Octobot has various moderation commands such as /ban, /mute, /kick.
These commands add multiple features to Discord's built-in functions
(such as durations and logging). Some admins may want to force their
users to use Octobot's commands instead of Discord UI functions.
However, due to the current design, they can't take away the permissions
as that remove access to the respective command.
This PR adds the `ModeratorRole` option which allows anyone who has
`ManageMessages` permission and the role to perform any moderator
action.
If the role is not set, the Discord permissions are checked instead. If
the user doesn't have the role, but has the permission, they can still
run the command.
---------
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
This feature will improve the debugging experience for developers by
providing the information about *where exactly* a result has failed
---------
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
1) the method isn't actually async lulw
2) it always returns success, so might as well just be void
reduces complexity by a bit
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
This PR adds the base classes required for profiling code inside of
Octobot. The implementation of the profiler is similar to Minecraft,
however it is more detailed and provides per-event logs for each event.
This PR does not change any code to be profiled and this is intentional.
Changes required for profiling will come as separate PRs, one for
commands, one for responders, and one for background services.
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
Title. idk why I didn't think of this before.
Also, GuildDataService is now properly registered as an IHostedService,
so it receives start & shutdown events. So this PR gets rid of the
workaround that was needed for save-on-shutdown to function
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
Originally, these classes were services because I thought that all
DI-resolvable classes need to be services. However, this is not true, so
we can make these classes (notably Utility and GuildDataService) not
extend anything. `UtilityService` was renamed to `Utility` for
simplicity
---------
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
ReSharper inspections have been updated, causing new warnings to appear
in the codebase. This time, the "Use collection expressions" inspection
has been enabled for usecases where the collection is not empty. This PR
fixes the check failures caused by this inspection.
In this PR, I've added a "Report an issue" button and a few more
button-related changes:
- Add "Report an issue" button
- Add icon for "Octobot's source code"
- Rename `AboutTitleRepository` to `ButtonOpenRepository`
- Rename `OpenEventInfoButton` to `ButtonOpenEventInfo` to be consistent
with other language string names
- Rename `ColorsList.cs` to `Miscellaneous.cs`
- Add public const strings in `Octobot.cs` to get repository & issues links
---------
Signed-off-by: mctaylors <cantsendmails@mctaylors.ru>
This PR adds an extension method to make it easier to pass Result<Embed> to CreateMessageAsync
---------
Co-authored-by: Octol1ttle <l1ttleofficial@outlook.com>
Changes:
- Use timestamps from
[Splatunes](https://splatoonwiki.org/wiki/Splatune_(Splatoon_Original_Soundtrack))
- Increase track count to 20
- Replace Calamari Inkantation 3MIX with OG Calamari Inkantation due to long
duration
Signed-off-by: mctaylors <cantsendmails@mctaylors.ru>
This PR fixes an issue that is currently causing CI to fail in all pull
requests:
`Notice: "[CA1854] Prefer a 'TryGetValue' call over a Dictionary indexer
access guarded by a 'ContainsKey' check to avoid double lookup" on
/home/runner/work/Octobot/Octobot/src/Services/Update/ScheduledEventUpdateService.cs(107,4168)`
The issue is resolved by following the advice mentioned in the notice.
This PR fixes an issue that caused REST errors to occur in
MemberUpdateService if the bot tries to interact with a member it can't
interact with. The issue is fixed by returning from TickMemberDataAsync
early if the member cannot be interacted with. An error message was
planned, but it requires adding a lot of services and severely
increasing the complexity. Contributors may feel free to add one if they
deem so necessary.
Previously, any errors in guild data load will cause the bot to be
unusable in that guild. It didn't help that the end users had no
information that something was wrong! Now, any errors will be logged
better (with the full path to the file that couldn't be loaded), and the
users will receive a message saying that functionality is degraded
The old way to save objects was to serialize them directly into streams
opened by `File#Create`. This can cause problems if the serialization
isn't completed, because `File#Create` overwrites the file with an empty
one on the spot. Now, objects are first deserialized into a temporary
file, then the original is replaced by the temporary, then the temporary
is deleted.
Errors during guild data load would sometimes cause the bot to replace
the corrupted file with a default one whenever a save is triggered. Now,
guilds with load errors won't have their data saved to aid in debugging
---------
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
Signed-off-by: mctaylors <mctaylxrs@outlook.com>
This PR fixes an issue that prevented scheduled event status updates
from running again if they failed. This happened because, before each
update, the events would be synchronized. The `ScheduleOnStatusUpdated`
field would be set even if it's already `true`, which will cause it to
be set to `false` for unsuccessful updates. The issue is fixed by
surrounding the field set call with a condition that will prevent
setting the field from `true` to `false`
Closes #163
Discord's API sucks a lot. You ask it for a member, but it won't give
you a member. This is why this PR updates the
`GetEventNotificationMentions` method used to determine what roles and
users should get pinged for a scheduled event. Previously, the bot asked
Discord to provide the member for each subscriber to determine whether
or not they have the event notification role (to avoid pinging people
personally when the role would already ping them). With this pull
request, the bot uses MemberData, it's own member storage, for that
purpose (if you're wondering why, refer to the first two sentences)
This PR splits the extension methods contained in `Extensions.cs` into
separate classes in the `Octobot.Extensions` namespace. This was done
for multiple reasons:
1) The `Extensions.cs` violates SRP (Single Responsibility Principle) -
it takes upon itself every extension method for many types
2) Having a separate class for each extended type is a standard practice
- take a look at
[Remora.Discord](https://github.com/Remora/Remora.Discord/tree/main/Backend/Remora.Discord.Rest/Extensions)
or [osu!](https://github.com/ppy/osu/tree/master/osu.Game/Extensions)
3) Having all extension methods in one file makes it hard to find the
method you want
In this PR, I added `Markdown.Sanitize` for every `scheduledEvent.Name`
and `eventData.Name`. That means, every title in scheduled event embeds
will be sanitized.
I did that because in scheduled event list event title displays only as
sanitized string.
Signed-off-by: Macintosh II <mctaylxrs@outlook.com>
note: there are still instances of `IUser user` because I could not find
a better name for them
---------
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
I added a string interpolation for SongUpdateService for
better activity status configuration. So now you can add some characters
if you want, or even swap the song title and author.
Also songs are now displaying in Splatoon™ style.
---------
Signed-off-by: Macintosh II <95250141+mctaylors@users.noreply.github.com>
This PR moves all code related to synchronization of scheduled events to
ScheduledEventUpdateService. Just like #130, this reduces possible
points of failures, maintenance burden and reliance on gateway events
This PR makes it so that roles in MemberData are updated only in
MemberUpdateService. This reduces possible points of failures,
maintenance burden and reliance on gateway events
Because the Discord API sucks at providing data when needed, this PR
makes it so that events are synchronized every tick instead of on
gateway events. This fixes an issue where the bot won't know about a
scheduled event if it was created before the bot was started
We're moving!
---------
Signed-off-by: Macintosh II <mctaylxrs@outlook.com>
Signed-off-by: Macintosh II <95250141+mctaylors@users.noreply.github.com>
Co-authored-by: Octol1ttle <l1ttleofficial@outlook.com>
Flipping `>` to `<=` changed null handling semantics within the
operator, causing the unban/unmute code to always run
Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
If a user was muted using the `MuteRole` method and then banned, the
UnknownMember warning will flood your logs when `DateTimeOffset.UtcNow >
data.MutedUntil` becomes true, because there is no user in the server to
unmute.
---------
Signed-off-by: Macintosh II <95250141+mctaylors@users.noreply.github.com>
Signed-off-by: Macintosh II <mctaylxrs@outlook.com>
Signed-off-by: Macintosh II <95250141+mctaylors@users.noreply.github.com>
Co-authored-by: Octol1ttle <l1ttleofficial@outlook.com>
- Added support for `MuteRole`, now if you add any role to this setting,
then try to mute a member, all his roles will be removed except for the
one you set in this setting.
- Fixed `/unmute`, that tried to set target's display name to unmute
reason.
---------
Signed-off-by: Macintosh II <mctaylxrs@outlook.com>