mirror of
https://github.com/NoiTheCat/BirthdayBot.git
synced 2024-11-22 05:54:36 +00:00
commit
2ae4d71e8b
6 changed files with 46 additions and 14 deletions
|
@ -14,6 +14,7 @@ public class BirthdayModule : BotModuleBase {
|
|||
public const string HelpCmdGet = "Gets a user's birthday.";
|
||||
public const string HelpCmdNearest = "Get a list of users who recently had or will have a birthday.";
|
||||
public const string HelpCmdExport = "Generates a text file with all known and available birthdays.";
|
||||
public const string ErrNotSetFk = $":x: The bot has not yet been set up. Please configure a birthday role."; // foreign key violation
|
||||
|
||||
// Note that these methods have largely been copied to BirthdayOverrideModule. Changes here should be reflected there as needed.
|
||||
|
||||
|
@ -47,10 +48,16 @@ public class BirthdayModule : BotModuleBase {
|
|||
user.BirthMonth = inmonth;
|
||||
user.BirthDay = inday;
|
||||
user.TimeZone = inzone;
|
||||
try {
|
||||
await db.SaveChangesAsync();
|
||||
} catch (Microsoft.EntityFrameworkCore.DbUpdateException e)
|
||||
when (e.InnerException is Npgsql.PostgresException ex && ex.SqlState == Npgsql.PostgresErrorCodes.ForeignKeyViolation) {
|
||||
await RespondAsync(ErrNotSetFk);
|
||||
return;
|
||||
}
|
||||
|
||||
await RespondAsync($":white_check_mark: Your birthday has been set to **{FormatDate(inmonth, inday)}**" +
|
||||
(inzone == null ? "" : $", with time zone {inzone}") + ".").ConfigureAwait(false);
|
||||
(inzone == null ? "" : $" at time zone **{inzone}**") + ".").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[SlashCommand("timezone", HelpCmdSetZone)]
|
||||
|
|
|
@ -29,7 +29,13 @@ public class BirthdayOverrideModule : BotModuleBase {
|
|||
if (user.IsNew) db.UserEntries.Add(user);
|
||||
user.BirthMonth = inmonth;
|
||||
user.BirthDay = inday;
|
||||
try {
|
||||
await db.SaveChangesAsync();
|
||||
} catch (Microsoft.EntityFrameworkCore.DbUpdateException e)
|
||||
when (e.InnerException is Npgsql.PostgresException ex && ex.SqlState == Npgsql.PostgresErrorCodes.ForeignKeyViolation) {
|
||||
await RespondAsync(BirthdayModule.ErrNotSetFk);
|
||||
return;
|
||||
}
|
||||
|
||||
await RespondAsync($":white_check_mark: {Common.FormatName(target, false)}'s birthday has been set to " +
|
||||
$"**{FormatDate(inmonth, inday)}**.").ConfigureAwait(false);
|
||||
|
|
|
@ -123,12 +123,20 @@ public class ConfigModule : BotModuleBase {
|
|||
public class SubCmdsConfigRole : BotModuleBase {
|
||||
[SlashCommand("set-birthday-role", HelpPfxModOnly + "Set the role given to users having a birthday.")]
|
||||
public async Task CmdSetBRole([Summary(description: HelpOptRole)]SocketRole role) {
|
||||
if (role.IsEveryone || role.IsManaged) {
|
||||
await RespondAsync(":x: This role cannot be used for this setting.", ephemeral: true);
|
||||
return;
|
||||
}
|
||||
await DoDatabaseUpdate(Context, s => s.RoleId = (long)role.Id);
|
||||
await RespondAsync($":white_check_mark: The birthday role has been set to **{role.Name}**.").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[SlashCommand("set-moderator-role", HelpPfxModOnly + "Designate a role whose members can configure the bot." + HelpPofxBlankUnset)]
|
||||
public async Task CmdSetModRole([Summary(description: HelpOptRole)]SocketRole? role = null) {
|
||||
if (role != null && (role.IsEveryone || role.IsManaged)) {
|
||||
await RespondAsync(":x: This role cannot be used for this setting.", ephemeral: true);
|
||||
return;
|
||||
}
|
||||
await DoDatabaseUpdate(Context, s => s.ModeratorRole = (long?)role?.Id);
|
||||
await RespondAsync(":white_check_mark: The moderator role has been " +
|
||||
(role == null ? "unset." : $"set to **{role.Name}**."));
|
||||
|
@ -188,7 +196,7 @@ public class ConfigModule : BotModuleBase {
|
|||
|
||||
using var db = new BotDatabaseContext();
|
||||
var guildconf = guild.GetConfigOrNew(db);
|
||||
await db.Entry(guildconf).Collection(t => t.UserEntries).LoadAsync();
|
||||
if (!guildconf.IsNew) await db.Entry(guildconf).Collection(t => t.UserEntries).LoadAsync();
|
||||
|
||||
var result = new StringBuilder();
|
||||
|
||||
|
@ -200,14 +208,16 @@ public class ConfigModule : BotModuleBase {
|
|||
bool hasMembers = Common.HasMostMembersDownloaded(guild);
|
||||
result.Append(DoTestFor("Bot has obtained the user list", () => hasMembers));
|
||||
result.AppendLine($" - Has `{guild.DownloadedMemberCount}` of `{guild.MemberCount}` members.");
|
||||
int bdayCount = -1;
|
||||
int bdayCount = default;
|
||||
result.Append(DoTestFor("Birthday processing", delegate {
|
||||
if (!hasMembers) return false;
|
||||
if (guildconf.IsNew) return false;
|
||||
bdayCount = BackgroundServices.BirthdayRoleUpdate.GetGuildCurrentBirthdays(guildconf.UserEntries, guildconf.TimeZone).Count;
|
||||
return true;
|
||||
}));
|
||||
if (hasMembers) result.AppendLine($" - `{bdayCount}` user(s) currently having a birthday.");
|
||||
else result.AppendLine(" - Previous step failed.");
|
||||
if (!hasMembers) result.AppendLine(" - Previous step failed.");
|
||||
else if (guildconf.IsNew) result.AppendLine(" - No data.");
|
||||
else result.AppendLine($" - `{bdayCount}` user(s) currently having a birthday.");
|
||||
result.AppendLine();
|
||||
|
||||
result.AppendLine(DoTestFor("Birthday role set with `bb.config role`", delegate {
|
||||
|
|
|
@ -40,6 +40,13 @@ class BirthdayRoleUpdate : BackgroundService {
|
|||
if (role == null
|
||||
|| !guild.CurrentUser.GuildPermissions.ManageRoles
|
||||
|| role.Position >= guild.CurrentUser.Hierarchy) continue;
|
||||
if (role.IsEveryone || role.IsManaged) {
|
||||
// Invalid role was configured. Clear the setting and quit.
|
||||
settings.RoleId = null;
|
||||
db.Update(settings);
|
||||
await db.SaveChangesAsync();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load up user configs and begin processing birthdays
|
||||
await db.Entry(settings).Collection(t => t.UserEntries).LoadAsync(CancellationToken.None);
|
||||
|
@ -132,10 +139,8 @@ class BirthdayRoleUpdate : BackgroundService {
|
|||
if (!toApply.Contains(user.Id)) removals.Add(user);
|
||||
else no_ops.Add(user.Id);
|
||||
}
|
||||
int removalAllowance = 15; // Limit removals per run, to not get continuously stuck on rate limits in misconfigured servers
|
||||
foreach (var user in removals) {
|
||||
await user.RemoveRoleAsync(r);
|
||||
if (--removalAllowance == 0) break;
|
||||
}
|
||||
|
||||
foreach (var target in toApply) {
|
||||
|
|
|
@ -92,14 +92,18 @@ public sealed class ShardInstance : IDisposable {
|
|||
case "Disconnected":
|
||||
case "Resumed previous session":
|
||||
case "Failed to resume previous session":
|
||||
case "Discord.WebSocket.GatewayReconnectException: Server requested a reconnect":
|
||||
case "Serializer Error": // The exception associated with this log appears a lot as of v3.2-ish
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Log("Discord.Net", $"{arg.Severity}: {arg.Message}");
|
||||
}
|
||||
|
||||
if (arg.Exception != null) Log("Discord.Net exception", arg.Exception.ToString());
|
||||
if (arg.Exception != null) {
|
||||
if (arg.Exception is GatewayReconnectException
|
||||
|| arg.Exception.Message == "WebSocket connection was closed") return Task.CompletedTask;
|
||||
|
||||
Log("Discord.Net exception", arg.Exception.ToString());
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ class ShardManager : IDisposable {
|
|||
ShardId = shardId,
|
||||
TotalShards = Config.ShardTotal,
|
||||
LogLevel = LogSeverity.Info,
|
||||
DefaultRetryMode = RetryMode.AlwaysRetry,
|
||||
DefaultRetryMode = RetryMode.Retry502 | RetryMode.RetryTimeouts,
|
||||
GatewayIntents = GatewayIntents.Guilds | GatewayIntents.GuildMembers | GatewayIntents.GuildMessages
|
||||
};
|
||||
var services = new ServiceCollection()
|
||||
|
|
Loading…
Reference in a new issue