forked from TeamInklings/Octobot
Tidy up project structure, fix bug with edit logging (#47)
The project structure has been changed because the previous one had everything in 1 folder. From this PR onwards, the following is true: - The source code is stored in `src/` - `*.resx` and `Messages.Designer.cs` is stored in `locale/` - Documentation is stored on the wiki and in `docs/` - Miscellaneous files, such as dotfiles, are stored in the root folder of the repository This PR additionally fixes an issue that would cause logs of edited messages to not be syntax highlighted. This happened because the responder of edited messages was changed to use the universal `InBlockCode` extension method which did not support syntax highlighting until this PR This PR additionally changes CODEOWNERS to be more reliable. Previously, it would be possible for some PRs to be unable to be approved because the only person who can approve them is the same person who opened the PR. --------- Signed-off-by: Octol1ttle <l1ttleofficial@outlook.com>
This commit is contained in:
parent
2dd9f023ef
commit
3eb17b96c5
29 changed files with 180 additions and 179 deletions
90
src/Data/GuildConfiguration.cs
Normal file
90
src/Data/GuildConfiguration.cs
Normal file
|
@ -0,0 +1,90 @@
|
|||
using System.Globalization;
|
||||
using Remora.Discord.API.Abstractions.Objects;
|
||||
|
||||
namespace Boyfriend.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Stores per-guild settings that can be set by a member
|
||||
/// with <see cref="DiscordPermission.ManageGuild" /> using the /settings command
|
||||
/// </summary>
|
||||
public class GuildConfiguration {
|
||||
/// <summary>
|
||||
/// Represents a scheduled event notification receiver.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used to selectively mention guild members when a scheduled event has started or is about to start.
|
||||
/// </remarks>
|
||||
public enum NotificationReceiver {
|
||||
Interested,
|
||||
Role
|
||||
}
|
||||
|
||||
public static readonly Dictionary<string, CultureInfo> CultureInfoCache = new() {
|
||||
{ "en", new CultureInfo("en-US") },
|
||||
{ "ru", new CultureInfo("ru-RU") },
|
||||
{ "mctaylors-ru", new CultureInfo("tt-RU") }
|
||||
};
|
||||
|
||||
public string Language { get; set; } = "en";
|
||||
|
||||
/// <summary>
|
||||
/// Controls what message should be sent in <see cref="PublicFeedbackChannel" /> when a new member joins the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <list type="bullet">
|
||||
/// <item>No message will be sent if set to "off", "disable" or "disabled".</item>
|
||||
/// <item><see cref="Messages.DefaultWelcomeMessage" /> will be sent if set to "default" or "reset"</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <seealso cref="GuildMemberAddResponder" />
|
||||
public string WelcomeMessage { get; set; } = "default";
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether or not the <see cref="Messages.Ready" /> message should be sent
|
||||
/// in <see cref="PrivateFeedbackChannel" /> on startup.
|
||||
/// </summary>
|
||||
/// <seealso cref="GuildCreateResponder" />
|
||||
public bool ReceiveStartupMessages { get; set; }
|
||||
|
||||
public bool RemoveRolesOnMute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether or not a guild member's roles are returned if he/she leaves and then joins back.
|
||||
/// </summary>
|
||||
/// <remarks>Roles will not be returned if the member left the guild because of /ban or /kick.</remarks>
|
||||
public bool ReturnRolesOnRejoin { get; set; }
|
||||
|
||||
public bool AutoStartEvents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls what channel should all public messages be sent to.
|
||||
/// </summary>
|
||||
public ulong PublicFeedbackChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls what channel should all private, moderator-only messages be sent to.
|
||||
/// </summary>
|
||||
public ulong PrivateFeedbackChannel { get; set; }
|
||||
|
||||
public ulong EventNotificationChannel { get; set; }
|
||||
public ulong DefaultRole { get; set; }
|
||||
public ulong MuteRole { get; set; }
|
||||
public ulong EventNotificationRole { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls what guild members should be mentioned when a scheduled event has started or is about to start.
|
||||
/// </summary>
|
||||
/// <seealso cref="NotificationReceiver" />
|
||||
public List<NotificationReceiver> EventStartedReceivers { get; set; }
|
||||
= new() { NotificationReceiver.Interested, NotificationReceiver.Role };
|
||||
|
||||
/// <summary>
|
||||
/// Controls the amount of time before a scheduled event to send a reminder in <see cref="EventNotificationChannel" />.
|
||||
/// </summary>
|
||||
public TimeSpan EventEarlyNotificationOffset { get; set; } = TimeSpan.Zero;
|
||||
|
||||
// Do not convert this to a property, else serialization will be attempted
|
||||
public CultureInfo GetCulture() {
|
||||
return CultureInfoCache[Language];
|
||||
}
|
||||
}
|
41
src/Data/GuildData.cs
Normal file
41
src/Data/GuildData.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using System.Globalization;
|
||||
using Remora.Rest.Core;
|
||||
|
||||
namespace Boyfriend.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Stores information about a guild. This information is not accessible via the Discord API.
|
||||
/// </summary>
|
||||
/// <remarks>This information is stored on disk as a JSON file.</remarks>
|
||||
public class GuildData {
|
||||
public readonly GuildConfiguration Configuration;
|
||||
public readonly string ConfigurationPath;
|
||||
|
||||
public readonly Dictionary<ulong, MemberData> MemberData;
|
||||
public readonly string MemberDataPath;
|
||||
|
||||
public readonly Dictionary<ulong, ScheduledEventData> ScheduledEvents;
|
||||
public readonly string ScheduledEventsPath;
|
||||
|
||||
public GuildData(
|
||||
GuildConfiguration configuration, string configurationPath,
|
||||
Dictionary<ulong, ScheduledEventData> scheduledEvents, string scheduledEventsPath,
|
||||
Dictionary<ulong, MemberData> memberData, string memberDataPath) {
|
||||
Configuration = configuration;
|
||||
ConfigurationPath = configurationPath;
|
||||
ScheduledEvents = scheduledEvents;
|
||||
ScheduledEventsPath = scheduledEventsPath;
|
||||
MemberData = memberData;
|
||||
MemberDataPath = memberDataPath;
|
||||
}
|
||||
|
||||
public CultureInfo Culture => Configuration.GetCulture();
|
||||
|
||||
public MemberData GetMemberData(Snowflake userId) {
|
||||
if (MemberData.TryGetValue(userId.Value, out var existing)) return existing;
|
||||
|
||||
var newData = new MemberData(userId.Value, null);
|
||||
MemberData.Add(userId.Value, newData);
|
||||
return newData;
|
||||
}
|
||||
}
|
18
src/Data/MemberData.cs
Normal file
18
src/Data/MemberData.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using Remora.Rest.Core;
|
||||
|
||||
namespace Boyfriend.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Stores information about a member
|
||||
/// </summary>
|
||||
public class MemberData {
|
||||
public MemberData(ulong id, DateTimeOffset? bannedUntil) {
|
||||
Id = id;
|
||||
BannedUntil = bannedUntil;
|
||||
}
|
||||
|
||||
public ulong Id { get; }
|
||||
public DateTimeOffset? BannedUntil { get; set; }
|
||||
public List<Snowflake> Roles { get; set; } = new();
|
||||
public List<Reminder> Reminders { get; } = new();
|
||||
}
|
9
src/Data/Reminder.cs
Normal file
9
src/Data/Reminder.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using Remora.Rest.Core;
|
||||
|
||||
namespace Boyfriend.Data;
|
||||
|
||||
public struct Reminder {
|
||||
public DateTimeOffset RemindAt;
|
||||
public string Text;
|
||||
public Snowflake Channel;
|
||||
}
|
17
src/Data/ScheduledEventData.cs
Normal file
17
src/Data/ScheduledEventData.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using Remora.Discord.API.Abstractions.Objects;
|
||||
|
||||
namespace Boyfriend.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Stores information about scheduled events. This information is not provided by the Discord API.
|
||||
/// </summary>
|
||||
/// <remarks>This information is stored on disk as a JSON file.</remarks>
|
||||
public class ScheduledEventData {
|
||||
public ScheduledEventData(GuildScheduledEventStatus status) {
|
||||
Status = status;
|
||||
}
|
||||
|
||||
public bool EarlyNotificationSent { get; set; }
|
||||
public DateTimeOffset? ActualStartTime { get; set; }
|
||||
public GuildScheduledEventStatus Status { get; set; }
|
||||
}
|
Reference in a new issue