diff --git a/PluralKit.Bot/Commands/CommandTree.cs b/PluralKit.Bot/Commands/CommandTree.cs index 03d13e44..f23655b3 100644 --- a/PluralKit.Bot/Commands/CommandTree.cs +++ b/PluralKit.Bot/Commands/CommandTree.cs @@ -25,6 +25,7 @@ namespace PluralKit.Bot public static Command SystemFrontHistory = new Command("system fronthistory", "system [system] fronthistory", "Shows a system's front history"); public static Command SystemFrontPercent = new Command("system frontpercent", "system [system] frontpercent [timespan]", "Shows a system's front breakdown"); public static Command SystemPrivacy = new Command("system privacy", "system privacy ", "Changes your system's privacy settings"); + public static Command SystemPing = new Command("system ping", "system ping ", "Changes your system's ping preferences"); public static Command Autoproxy = new Command("autoproxy", "autoproxy [off|front|latch|member]", "Sets your system's autoproxy mode for this server"); public static Command MemberInfo = new Command("member", "member ", "Looks up information about a member"); public static Command MemberNew = new Command("member new", "member new ", "Creates a new member"); @@ -204,6 +205,8 @@ namespace PluralKit.Bot await ctx.Execute(SystemFrontPercent, m => m.SystemFrontPercent(ctx, ctx.System)); else if (ctx.Match("privacy")) await ctx.Execute(SystemPrivacy, m => m.SystemPrivacy(ctx)); + else if (ctx.Match("ping")) + await ctx.Execute(SystemPing, m => m.SystemPing(ctx)); else if (ctx.Match("commands", "help")) await PrintCommandList(ctx, "systems", SystemCommands); else if (!ctx.HasNext()) // Bare command @@ -365,4 +368,4 @@ namespace PluralKit.Bot return $"System with ID `{input}` not found."; } } -} \ No newline at end of file +} diff --git a/PluralKit.Bot/Commands/SystemEdit.cs b/PluralKit.Bot/Commands/SystemEdit.cs index 6da3b48e..8998631a 100644 --- a/PluralKit.Bot/Commands/SystemEdit.cs +++ b/PluralKit.Bot/Commands/SystemEdit.cs @@ -312,6 +312,29 @@ namespace PluralKit.Bot await ctx.Reply($"System {subjectStr} privacy has been set to **{levelStr}**. Other accounts will now {levelExplanation} your system {subjectStr}."); } + public async Task SystemPing(Context ctx) + { + ctx.CheckSystem(); + + if (!ctx.HasNext()) + { + if (ctx.System.PingsEnabled) {await ctx.Reply("Reaction pings are currently **enabled** for your system. To disable reaction pings, type `pk;s ping disable`.");} + else {await ctx.Reply("Reaction pings are currently **disabled** for your system. To enable reaction pings, type `pk;s ping enable`.");} + } + else { + if (ctx.Match("on", "enable")) { + ctx.System.PingsEnabled = true; + await _data.SaveSystem(ctx.System); + await ctx.Reply("Reaction pings have now been enabled."); + } + if (ctx.Match("off", "disable")) { + ctx.System.PingsEnabled = false; + await _data.SaveSystem(ctx.System); + await ctx.Reply("Reaction pings have now been disabled."); + } + } + } + public async Task FindTimeZone(Context ctx, string zoneStr) { // First, if we're given a flag emoji, we extract the flag emoji code from it. zoneStr = Core.StringUtils.ExtractCountryFlag(zoneStr) ?? zoneStr; @@ -370,4 +393,4 @@ namespace PluralKit.Bot }); } } -} \ No newline at end of file +} diff --git a/PluralKit.Bot/Services/ProxyService.cs b/PluralKit.Bot/Services/ProxyService.cs index e47216fc..25c449b5 100644 --- a/PluralKit.Bot/Services/ProxyService.cs +++ b/PluralKit.Bot/Services/ProxyService.cs @@ -285,9 +285,22 @@ namespace PluralKit.Bot var requiredPerms = Permissions.AccessChannels | Permissions.SendMessages; if ((permissions & requiredPerms) != requiredPerms) return; - var embed = new DiscordEmbedBuilder().WithDescription($"[Jump to pinged message]({args.Message.JumpLink})"); - await args.Channel.SendMessageAsync($"Psst, **{msg.Member.DisplayName ?? msg.Member.Name}** (<@{msg.Message.Sender}>), you have been pinged by <@{args.User.Id}>.", embed: embed.Build()); - + if (!msg.System.PingsEnabled) { + // If the target system has disabled pings, tell the pinger and bail + var member = await args.Guild.GetMemberAsync(args.User.Id); + try + { + await member.SendMessageAsync($"{Emojis.Error} {msg.Member.DisplayName ?? msg.Member.Name}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:"); + await member.SendMessageAsync($"`<@{msg.Message.Sender}>`"); + } + catch (UnauthorizedException) { } + } + else + { + var embed = new DiscordEmbedBuilder().WithDescription($"[Jump to pinged message]({args.Message.JumpLink})"); + await args.Channel.SendMessageAsync($"Psst, **{msg.Member.DisplayName ?? msg.Member.Name}** (<@{msg.Message.Sender}>), you have been pinged by <@{args.User.Id}>.", embed: embed.Build()); + } + // Finally remove the original reaction (if we can) if (args.Channel.BotHasAllPermissions(Permissions.ManageMessages)) await args.Message.DeleteReactionAsync(args.Emoji, args.User); @@ -359,4 +372,4 @@ namespace PluralKit.Bot await _data.DeleteMessagesBulk(args.Messages.Select(m => m.Id).ToList()); } } -} \ No newline at end of file +} diff --git a/PluralKit.Core/Migrations/5.sql b/PluralKit.Core/Migrations/5.sql index 89bb2547..0dbaad2f 100644 --- a/PluralKit.Core/Migrations/5.sql +++ b/PluralKit.Core/Migrations/5.sql @@ -1,3 +1,3 @@ --- SCHEMA VERSION 4: 2020-02-14 +-- SCHEMA VERSION 5: 2020-02-14 alter table servers add column log_cleanup_enabled bool not null default false; update info set schema_version = 5; \ No newline at end of file diff --git a/PluralKit.Core/Migrations/6.sql b/PluralKit.Core/Migrations/6.sql new file mode 100755 index 00000000..d41c2af9 --- /dev/null +++ b/PluralKit.Core/Migrations/6.sql @@ -0,0 +1,3 @@ +-- SCHEMA VERSION 6: 2020-03-21 +alter table systems add column pings_enabled bool not null default true; +update info set schema_version = 6; \ No newline at end of file diff --git a/PluralKit.Core/Models/PKSystem.cs b/PluralKit.Core/Models/PKSystem.cs index 9cc09fd6..0dc6e66a 100644 --- a/PluralKit.Core/Models/PKSystem.cs +++ b/PluralKit.Core/Models/PKSystem.cs @@ -17,11 +17,12 @@ namespace PluralKit.Core { [JsonIgnore] public string Token { get; set; } [JsonProperty("created")] public Instant Created { get; set; } [JsonProperty("tz")] public string UiTz { get; set; } - public PrivacyLevel DescriptionPrivacy { get; set; } + [JsonProperty("ping")] public bool PingsEnabled { get; set; } + public PrivacyLevel DescriptionPrivacy { get; set; } public PrivacyLevel MemberListPrivacy { get; set; } public PrivacyLevel FrontPrivacy { get; set; } public PrivacyLevel FrontHistoryPrivacy { get; set; } [JsonIgnore] public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz); } -} \ No newline at end of file +} diff --git a/PluralKit.Core/Services/PostgresDataStore.cs b/PluralKit.Core/Services/PostgresDataStore.cs index 737b6581..e4d9b8ca 100644 --- a/PluralKit.Core/Services/PostgresDataStore.cs +++ b/PluralKit.Core/Services/PostgresDataStore.cs @@ -118,7 +118,7 @@ namespace PluralKit.Core { public async Task SaveSystem(PKSystem system) { using (var conn = await _conn.Obtain()) - await conn.ExecuteAsync("update systems set name = @Name, description = @Description, tag = @Tag, avatar_url = @AvatarUrl, token = @Token, ui_tz = @UiTz, description_privacy = @DescriptionPrivacy, member_list_privacy = @MemberListPrivacy, front_privacy = @FrontPrivacy, front_history_privacy = @FrontHistoryPrivacy where id = @Id", system); + await conn.ExecuteAsync("update systems set name = @Name, description = @Description, tag = @Tag, avatar_url = @AvatarUrl, token = @Token, ui_tz = @UiTz, description_privacy = @DescriptionPrivacy, member_list_privacy = @MemberListPrivacy, front_privacy = @FrontPrivacy, front_history_privacy = @FrontHistoryPrivacy, pings_enabled = @PingsEnabled where id = @Id", system); _logger.Information("Updated system {@System}", system); await _cache.InvalidateSystem(system); diff --git a/PluralKit.Core/Services/SchemaService.cs b/PluralKit.Core/Services/SchemaService.cs index 1c4c34fc..c2630ed2 100644 --- a/PluralKit.Core/Services/SchemaService.cs +++ b/PluralKit.Core/Services/SchemaService.cs @@ -11,7 +11,7 @@ using Serilog; namespace PluralKit.Core { public class SchemaService { - private const int TargetSchemaVersion = 5; + private const int TargetSchemaVersion = 6; private DbConnectionFactory _conn; private ILogger _logger;