Port some more commands, mostly for embeds

This commit is contained in:
Ske 2020-12-25 12:56:46 +01:00
parent 9d919d687b
commit 2e0c30eb5d
13 changed files with 140 additions and 135 deletions

View File

@ -17,6 +17,7 @@ namespace Myriad.Rest.Ratelimit
private DateTimeOffset _nextReset; private DateTimeOffset _nextReset;
private bool _resetTimeValid; private bool _resetTimeValid;
private bool _hasReceivedRemaining;
public Bucket(ILogger logger, string key, ulong major, int limit) public Bucket(ILogger logger, string key, ulong major, int limit)
{ {
@ -77,8 +78,8 @@ namespace Myriad.Rest.Ratelimit
var headerNextReset = DateTimeOffset.UtcNow + headers.ResetAfter.Value; // todo: server time var headerNextReset = DateTimeOffset.UtcNow + headers.ResetAfter.Value; // todo: server time
if (headerNextReset > _nextReset) if (headerNextReset > _nextReset)
{ {
_logger.Debug("{BucketKey}/{BucketMajor}: Received reset time {NextReset} from server (after: {NextResetAfter})", _logger.Debug("{BucketKey}/{BucketMajor}: Received reset time {NextReset} from server (after: {NextResetAfter}, new remaining: {Remaining})",
Key, Major, headerNextReset, headers.ResetAfter.Value); Key, Major, headerNextReset, headers.ResetAfter.Value, headers.Remaining);
_nextReset = headerNextReset; _nextReset = headerNextReset;
_resetTimeValid = true; _resetTimeValid = true;
@ -87,6 +88,12 @@ namespace Myriad.Rest.Ratelimit
if (headers.Limit != null) if (headers.Limit != null)
Limit = headers.Limit.Value; Limit = headers.Limit.Value;
if (headers.Remaining != null && !_hasReceivedRemaining)
{
_hasReceivedRemaining = true;
Remaining = headers.Remaining.Value;
}
} }
finally finally
{ {

View File

@ -44,6 +44,7 @@ namespace Myriad.Rest.Ratelimit
if (!_knownKeyLimits.TryGetValue(key, out var knownLimit)) if (!_knownKeyLimits.TryGetValue(key, out var knownLimit))
return null; return null;
_logger.Debug("Creating new bucket {BucketKey}/{BucketMajor} with limit {KnownLimit}", key, major, knownLimit);
return _buckets.GetOrAdd((key, major), return _buckets.GetOrAdd((key, major),
k => new Bucket(_logger, k.Item1, k.Item2, knownLimit)); k => new Bucket(_logger, k.Item1, k.Item2, knownLimit));
} }

View File

@ -45,7 +45,7 @@ namespace PluralKit.Bot
} }
// If we have an attachment, use that // If we have an attachment, use that
if (ctx.Message.Attachments.FirstOrDefault() is {} attachment) if (ctx.MessageNew.Attachments.FirstOrDefault() is {} attachment)
{ {
var url = TryRewriteCdnUrl(attachment.ProxyUrl); var url = TryRewriteCdnUrl(attachment.ProxyUrl);
return new ParsedImage {Url = url, Source = AvatarSource.Attachment}; return new ParsedImage {Url = url, Source = AvatarSource.Attachment};

View File

@ -6,8 +6,6 @@ using System.Threading.Tasks;
using Dapper; using Dapper;
using DSharpPlus.Entities;
using Humanizer; using Humanizer;
using Myriad.Builders; using Myriad.Builders;
@ -56,12 +54,12 @@ namespace PluralKit.Bot
var newGroup = await _repo.CreateGroup(conn, ctx.System.Id, groupName); var newGroup = await _repo.CreateGroup(conn, ctx.System.Id, groupName);
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithDescription($"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:") .Description($"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:")
.AddField("View the group card", $"> pk;group **{newGroup.Reference()}**") .Field(new("View the group card", $"> pk;group **{newGroup.Reference()}**"))
.AddField("Add members to the group", $"> pk;group **{newGroup.Reference()}** add **MemberName**\n> pk;group **{newGroup.Reference()}** add **Member1** **Member2** **Member3** (and so on...)") .Field(new("Add members to the group", $"> pk;group **{newGroup.Reference()}** add **MemberName**\n> pk;group **{newGroup.Reference()}** add **Member1** **Member2** **Member3** (and so on...)"))
.AddField("Set the description", $"> pk;group **{newGroup.Reference()}** description **This is my new group, and here is the description!**") .Field(new("Set the description", $"> pk;group **{newGroup.Reference()}** description **This is my new group, and here is the description!**"))
.AddField("Set the group icon", $"> pk;group **{newGroup.Reference()}** icon\n*(with an image attached)*"); .Field(new("Set the group icon", $"> pk;group **{newGroup.Reference()}** icon\n*(with an image attached)*"));
await ctx.Reply($"{Emojis.Success} Group created!", eb.Build()); await ctx.Reply($"{Emojis.Success} Group created!", eb.Build());
} }
@ -103,12 +101,12 @@ namespace PluralKit.Bot
else if (!ctx.HasNext()) else if (!ctx.HasNext())
{ {
// No perms check, display name isn't covered by member privacy // No perms check, display name isn't covered by member privacy
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.AddField("Name", target.Name) .Field(new("Name", target.Name))
.AddField("Display Name", target.DisplayName ?? "*(none)*"); .Field(new("Display Name", target.DisplayName ?? "*(none)*"));
if (ctx.System?.Id == target.System) if (ctx.System?.Id == target.System)
eb.WithDescription($"To change display name, type `pk;group {target.Reference()} displayname <display name>`.\nTo clear it, type `pk;group {target.Reference()} displayname -clear`."); eb.Description($"To change display name, type `pk;group {target.Reference()} displayname <display name>`.\nTo clear it, type `pk;group {target.Reference()} displayname -clear`.");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
} }
@ -145,11 +143,11 @@ namespace PluralKit.Bot
else if (ctx.MatchFlag("r", "raw")) else if (ctx.MatchFlag("r", "raw"))
await ctx.Reply($"```\n{target.Description}\n```"); await ctx.Reply($"```\n{target.Description}\n```");
else else
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle("Group description") .Title("Group description")
.WithDescription(target.Description) .Description(target.Description)
.AddField("\u200B", $"To print the description with formatting, type `pk;group {target.Reference()} description -raw`." .Field(new("\u200B", $"To print the description with formatting, type `pk;group {target.Reference()} description -raw`."
+ (ctx.System?.Id == target.System ? $" To clear it, type `pk;group {target.Reference()} description -clear`." : "")) + (ctx.System?.Id == target.System ? $" To clear it, type `pk;group {target.Reference()} description -clear`." : "")))
.Build()); .Build());
} }
else else
@ -204,13 +202,13 @@ namespace PluralKit.Bot
{ {
if ((target.Icon?.Trim() ?? "").Length > 0) if ((target.Icon?.Trim() ?? "").Length > 0)
{ {
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithTitle("Group icon") .Title("Group icon")
.WithImageUrl(target.Icon); .Image(new(target.Icon));
if (target.System == ctx.System?.Id) if (target.System == ctx.System?.Id)
{ {
eb.WithDescription($"To clear, use `pk;group {target.Reference()} icon -clear`."); eb.Description($"To clear, use `pk;group {target.Reference()} icon -clear`.");
} }
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
@ -359,13 +357,13 @@ namespace PluralKit.Bot
// Display privacy settings // Display privacy settings
if (!ctx.HasNext() && newValueFromCommand == null) if (!ctx.HasNext() && newValueFromCommand == null)
{ {
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle($"Current privacy settings for {target.Name}") .Title($"Current privacy settings for {target.Name}")
.AddField("Description", target.DescriptionPrivacy.Explanation()) .Field(new("Description", target.DescriptionPrivacy.Explanation()) )
.AddField("Icon", target.IconPrivacy.Explanation()) .Field(new("Icon", target.IconPrivacy.Explanation()))
.AddField("Member list", target.ListPrivacy.Explanation()) .Field(new("Member list", target.ListPrivacy.Explanation()))
.AddField("Visibility", target.Visibility.Explanation()) .Field(new("Visibility", target.Visibility.Explanation()))
.WithDescription($"To edit privacy settings, use the command:\n> pk;group **{target.Reference()}** privacy **<subject>** **<level>**\n\n- `subject` is one of `description`, `icon`, `members`, `visibility`, or `all`\n- `level` is either `public` or `private`.") .Description($"To edit privacy settings, use the command:\n> pk;group **{target.Reference()}** privacy **<subject>** **<level>**\n\n- `subject` is one of `description`, `icon`, `members`, `visibility`, or `all`\n- `level` is either `public` or `private`.")
.Build()); .Build());
return; return;
} }

View File

@ -1,6 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using DSharpPlus.Entities; using Myriad.Builders;
using PluralKit.Core; using PluralKit.Core;
@ -10,17 +10,17 @@ namespace PluralKit.Bot
{ {
public async Task HelpRoot(Context ctx) public async Task HelpRoot(Context ctx)
{ {
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle("PluralKit") .Title("PluralKit")
.WithDescription("PluralKit is a bot designed for plural communities on Discord. It allows you to register systems, maintain system information, set up message proxying, log switches, and more.") .Description("PluralKit is a bot designed for plural communities on Discord. It allows you to register systems, maintain system information, set up message proxying, log switches, and more.")
.AddField("What is this for? What are systems?", "This bot detects messages with certain tags associated with a profile, then replaces that message under a \"pseudo-account\" of that profile using webhooks. This is useful for multiple people sharing one body (aka \"systems\"), people who wish to roleplay as different characters without having several accounts, or anyone else who may want to post messages as a different person from the same account.") .Field(new("What is this for? What are systems?", "This bot detects messages with certain tags associated with a profile, then replaces that message under a \"pseudo-account\" of that profile using webhooks. This is useful for multiple people sharing one body (aka \"systems\"), people who wish to roleplay as different characters without having several accounts, or anyone else who may want to post messages as a different person from the same account."))
.AddField("Why are people's names saying [BOT] next to them?", "These people are not actually bots, this is just a Discord limitation. See [the documentation](https://pluralkit.me/guide#proxying) for an in-depth explanation.") .Field(new("Why are people's names saying [BOT] next to them?", "These people are not actually bots, this is just a Discord limitation. See [the documentation](https://pluralkit.me/guide#proxying) for an in-depth explanation."))
.AddField("How do I get started?", "To get started using PluralKit, try running the following commands (of course replacing the relevant names with your own):\n**1**. `pk;system new` - Create a system (if you haven't already)\n**2**. `pk;member add John` - Add a new member to your system\n**3**. `pk;member John proxy [text]` - Set up [square brackets] as proxy tags\n**4**. You're done! You can now type [a message in brackets] and it'll be proxied appropriately.\n**5**. Optionally, you may set an avatar from the URL of an image with `pk;member John avatar [link to image]`, or from a file by typing `pk;member John avatar` and sending the message with an attached image.\n\nSee [the Getting Started guide](https://pluralkit.me/start) for more information.") .Field(new("How do I get started?", "To get started using PluralKit, try running the following commands (of course replacing the relevant names with your own):\n**1**. `pk;system new` - Create a system (if you haven't already)\n**2**. `pk;member add John` - Add a new member to your system\n**3**. `pk;member John proxy [text]` - Set up [square brackets] as proxy tags\n**4**. You're done! You can now type [a message in brackets] and it'll be proxied appropriately.\n**5**. Optionally, you may set an avatar from the URL of an image with `pk;member John avatar [link to image]`, or from a file by typing `pk;member John avatar` and sending the message with an attached image.\n\nSee [the Getting Started guide](https://pluralkit.me/start) for more information."))
.AddField("Useful tips", $"React with {Emojis.Error} on a proxied message to delete it (only if you sent it!)\nReact with {Emojis.RedQuestion} on a proxied message to look up information about it (like who sent it)\nReact with {Emojis.Bell} on a proxied message to \"ping\" the sender\nType **`pk;invite`** to get a link to invite this bot to your own server!") .Field(new("Useful tips", $"React with {Emojis.Error} on a proxied message to delete it (only if you sent it!)\nReact with {Emojis.RedQuestion} on a proxied message to look up information about it (like who sent it)\nReact with {Emojis.Bell} on a proxied message to \"ping\" the sender\nType **`pk;invite`** to get a link to invite this bot to your own server!"))
.AddField("More information", "For a full list of commands, see [the command list](https://pluralkit.me/commands).\nFor a more in-depth explanation of message proxying, see [the documentation](https://pluralkit.me/guide#proxying).\nIf you're an existing user of Tupperbox, type `pk;import` and attach a Tupperbox export file (from `tul!export`) to import your data from there.") .Field(new("More information", "For a full list of commands, see [the command list](https://pluralkit.me/commands).\nFor a more in-depth explanation of message proxying, see [the documentation](https://pluralkit.me/guide#proxying).\nIf you're an existing user of Tupperbox, type `pk;import` and attach a Tupperbox export file (from `tul!export`) to import your data from there."))
.AddField("Support server", "We also have a Discord server for support, discussion, suggestions, announcements, etc: https://discord.gg/PczBt78") .Field(new("Support server", "We also have a Discord server for support, discussion, suggestions, announcements, etc: https://discord.gg/PczBt78"))
.WithFooter($"By @Ske#6201 | Myriad by @Layl#8888 | GitHub: https://github.com/xSke/PluralKit/ | Website: https://pluralkit.me/") .Footer(new($"By @Ske#6201 | Myriad by @Layl#8888 | GitHub: https://github.com/xSke/PluralKit/ | Website: https://pluralkit.me/"))
.WithColor(DiscordUtils.Blue) .Color((uint?) DiscordUtils.Blue.Value)
.Build()); .Build());
} }

View File

@ -5,9 +5,9 @@ using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Myriad.Rest.Exceptions;
using Newtonsoft.Json; using Newtonsoft.Json;
using DSharpPlus.Exceptions;
using DSharpPlus.Entities;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -18,7 +18,7 @@ namespace PluralKit.Bot
public class ImportExport public class ImportExport
{ {
private readonly DataFileService _dataFiles; private readonly DataFileService _dataFiles;
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings private readonly JsonSerializerSettings _settings = new()
{ {
// Otherwise it'll mess up/reformat the ISO strings for ???some??? reason >.> // Otherwise it'll mess up/reformat the ISO strings for ???some??? reason >.>
DateParseHandling = DateParseHandling.None DateParseHandling = DateParseHandling.None
@ -145,8 +145,9 @@ namespace PluralKit.Bot
await dm.SendMessageAsync($"<{msg.Attachments[0].Url}>"); await dm.SendMessageAsync($"<{msg.Attachments[0].Url}>");
// If the original message wasn't posted in DMs, send a public reminder // If the original message wasn't posted in DMs, send a public reminder
if (!(ctx.Channel is DiscordDmChannel)) // TODO: DMs
await ctx.Reply($"{Emojis.Success} Check your DMs!"); // if (!(ctx.Channel is DiscordDmChannel))
// await ctx.Reply($"{Emojis.Success} Check your DMs!");
} }
catch (UnauthorizedException) catch (UnauthorizedException)
{ {

View File

@ -7,6 +7,8 @@ using Dapper;
using DSharpPlus.Entities; using DSharpPlus.Entities;
using Myriad.Builders;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PluralKit.Core; using PluralKit.Core;
@ -89,11 +91,11 @@ namespace PluralKit.Bot
var data = JObject.Parse(await resp.Content.ReadAsStringAsync()); var data = JObject.Parse(await resp.Content.ReadAsStringAsync());
var scream = data["soulscream"]!.Value<string>(); var scream = data["soulscream"]!.Value<string>();
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithColor(DiscordColor.Red) .Color((uint?) DiscordColor.Red.Value)
.WithTitle(name) .Title(name)
.WithUrl($"https://onomancer.sibr.dev/reflect?name={encoded}") .Url($"https://onomancer.sibr.dev/reflect?name={encoded}")
.WithDescription($"*{scream}*"); .Description($"*{scream}*");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
} }
} }

View File

@ -2,8 +2,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using DSharpPlus.Entities;
using Myriad.Builders; using Myriad.Builders;
using PluralKit.Core; using PluralKit.Core;
@ -60,11 +58,11 @@ namespace PluralKit.Bot
var field = location == AvatarLocation.Server ? $"server avatar (for {ctx.GuildNew.Name})" : "avatar"; var field = location == AvatarLocation.Server ? $"server avatar (for {ctx.GuildNew.Name})" : "avatar";
var cmd = location == AvatarLocation.Server ? "serveravatar" : "avatar"; var cmd = location == AvatarLocation.Server ? "serveravatar" : "avatar";
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithTitle($"{target.NameFor(ctx)}'s {field}") .Title($"{target.NameFor(ctx)}'s {field}")
.WithImageUrl(currentValue); .Image(new(currentValue));
if (target.System == ctx.System?.Id) if (target.System == ctx.System?.Id)
eb.WithDescription($"To clear, use `pk;member {target.Reference()} {cmd} clear`."); eb.Description($"To clear, use `pk;member {target.Reference()} {cmd} clear`.");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
} }

View File

@ -2,7 +2,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System; using System;
using DSharpPlus.Entities; using Myriad.Builders;
using NodaTime; using NodaTime;
@ -75,11 +75,11 @@ namespace PluralKit.Bot
else if (ctx.MatchFlag("r", "raw")) else if (ctx.MatchFlag("r", "raw"))
await ctx.Reply($"```\n{target.Description}\n```"); await ctx.Reply($"```\n{target.Description}\n```");
else else
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle("Member description") .Title("Member description")
.WithDescription(target.Description) .Description(target.Description)
.AddField("\u200B", $"To print the description with formatting, type `pk;member {target.Reference()} description -raw`." .Field(new("\u200B", $"To print the description with formatting, type `pk;member {target.Reference()} description -raw`."
+ (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} description -clear`." : "")) + (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} description -clear`." : "")))
.Build()); .Build());
} }
else else
@ -158,11 +158,11 @@ namespace PluralKit.Bot
else else
await ctx.Reply("This member does not have a color set."); await ctx.Reply("This member does not have a color set.");
else else
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle("Member color") .Title("Member color")
.WithColor(target.Color.ToDiscordColor().Value) .Color((uint?) target.Color.ToDiscordColor()!.Value.Value)
.WithThumbnail($"https://fakeimg.pl/256x256/{target.Color}/?text=%20") .Thumbnail(new($"https://fakeimg.pl/256x256/{target.Color}/?text=%20"))
.WithDescription($"This member's color is **#{target.Color}**." .Description($"This member's color is **#{target.Color}**."
+ (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} color -clear`." : "")) + (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} color -clear`." : ""))
.Build()); .Build());
} }
@ -176,10 +176,10 @@ namespace PluralKit.Bot
var patch = new MemberPatch {Color = Partial<string>.Present(color.ToLowerInvariant())}; var patch = new MemberPatch {Color = Partial<string>.Present(color.ToLowerInvariant())};
await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch));
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle($"{Emojis.Success} Member color changed.") .Title($"{Emojis.Success} Member color changed.")
.WithColor(color.ToDiscordColor().Value) .Color((uint?) color.ToDiscordColor()!.Value.Value)
.WithThumbnail($"https://fakeimg.pl/256x256/{color}/?text=%20") .Thumbnail(new($"https://fakeimg.pl/256x256/{color}/?text=%20"))
.Build()); .Build());
} }
} }
@ -221,7 +221,7 @@ namespace PluralKit.Bot
} }
} }
private async Task<DiscordEmbedBuilder> CreateMemberNameInfoEmbed(Context ctx, PKMember target) private async Task<EmbedBuilder> CreateMemberNameInfoEmbed(Context ctx, PKMember target)
{ {
var lcx = ctx.LookupContextFor(target); var lcx = ctx.LookupContextFor(target);
@ -229,28 +229,29 @@ namespace PluralKit.Bot
if (ctx.GuildNew != null) if (ctx.GuildNew != null)
memberGuildConfig = await _db.Execute(c => _repo.GetMemberGuild(c, ctx.GuildNew.Id, target.Id)); memberGuildConfig = await _db.Execute(c => _repo.GetMemberGuild(c, ctx.GuildNew.Id, target.Id));
var eb = new DiscordEmbedBuilder().WithTitle($"Member names") var eb = new EmbedBuilder()
.WithFooter($"Member ID: {target.Hid} | Active name in bold. Server name overrides display name, which overrides base name."); .Title($"Member names")
.Footer(new($"Member ID: {target.Hid} | Active name in bold. Server name overrides display name, which overrides base name."));
if (target.DisplayName == null && memberGuildConfig?.DisplayName == null) if (target.DisplayName == null && memberGuildConfig?.DisplayName == null)
eb.AddField("Name", $"**{target.NameFor(ctx)}**"); eb.Field(new("Name", $"**{target.NameFor(ctx)}**"));
else else
eb.AddField("Name", target.NameFor(ctx)); eb.Field(new("Name", target.NameFor(ctx)));
if (target.NamePrivacy.CanAccess(lcx)) if (target.NamePrivacy.CanAccess(lcx))
{ {
if (target.DisplayName != null && memberGuildConfig?.DisplayName == null) if (target.DisplayName != null && memberGuildConfig?.DisplayName == null)
eb.AddField("Display Name", $"**{target.DisplayName}**"); eb.Field(new("Display Name", $"**{target.DisplayName}**"));
else else
eb.AddField("Display Name", target.DisplayName ?? "*(none)*"); eb.Field(new("Display Name", target.DisplayName ?? "*(none)*"));
} }
if (ctx.GuildNew != null) if (ctx.GuildNew != null)
{ {
if (memberGuildConfig?.DisplayName != null) if (memberGuildConfig?.DisplayName != null)
eb.AddField($"Server Name (in {ctx.GuildNew.Name})", $"**{memberGuildConfig.DisplayName}**"); eb.Field(new($"Server Name (in {ctx.GuildNew.Name})", $"**{memberGuildConfig.DisplayName}**"));
else else
eb.AddField($"Server Name (in {ctx.GuildNew.Name})", memberGuildConfig?.DisplayName ?? "*(none)*"); eb.Field(new($"Server Name (in {ctx.GuildNew.Name})", memberGuildConfig?.DisplayName ?? "*(none)*"));
} }
return eb; return eb;
@ -285,7 +286,7 @@ namespace PluralKit.Bot
// No perms check, display name isn't covered by member privacy // No perms check, display name isn't covered by member privacy
var eb = await CreateMemberNameInfoEmbed(ctx, target); var eb = await CreateMemberNameInfoEmbed(ctx, target);
if (ctx.System?.Id == target.System) if (ctx.System?.Id == target.System)
eb.WithDescription($"To change display name, type `pk;member {target.Reference()} displayname <display name>`.\nTo clear it, type `pk;member {target.Reference()} displayname -clear`."); eb.Description($"To change display name, type `pk;member {target.Reference()} displayname <display name>`.\nTo clear it, type `pk;member {target.Reference()} displayname -clear`.");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
} }
else else
@ -322,7 +323,7 @@ namespace PluralKit.Bot
// No perms check, server name isn't covered by member privacy // No perms check, server name isn't covered by member privacy
var eb = await CreateMemberNameInfoEmbed(ctx, target); var eb = await CreateMemberNameInfoEmbed(ctx, target);
if (ctx.System?.Id == target.System) if (ctx.System?.Id == target.System)
eb.WithDescription($"To change server name, type `pk;member {target.Reference()} servername <server name>`.\nTo clear it, type `pk;member {target.Reference()} servername -clear`."); eb.Description($"To change server name, type `pk;member {target.Reference()} servername <server name>`.\nTo clear it, type `pk;member {target.Reference()} servername -clear`.");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
} }
else else
@ -398,16 +399,16 @@ namespace PluralKit.Bot
// Display privacy settings // Display privacy settings
if (!ctx.HasNext() && newValueFromCommand == null) if (!ctx.HasNext() && newValueFromCommand == null)
{ {
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle($"Current privacy settings for {target.NameFor(ctx)}") .Title($"Current privacy settings for {target.NameFor(ctx)}")
.AddField("Name (replaces name with display name if member has one)",target.NamePrivacy.Explanation()) .Field(new("Name (replaces name with display name if member has one)",target.NamePrivacy.Explanation()))
.AddField("Description", target.DescriptionPrivacy.Explanation()) .Field(new("Description", target.DescriptionPrivacy.Explanation()))
.AddField("Avatar", target.AvatarPrivacy.Explanation()) .Field(new("Avatar", target.AvatarPrivacy.Explanation()))
.AddField("Birthday", target.BirthdayPrivacy.Explanation()) .Field(new("Birthday", target.BirthdayPrivacy.Explanation()))
.AddField("Pronouns", target.PronounPrivacy.Explanation()) .Field(new("Pronouns", target.PronounPrivacy.Explanation()))
.AddField("Meta (message count, last front, last message)",target.MetadataPrivacy.Explanation()) .Field(new("Meta (message count, last front, last message)",target.MetadataPrivacy.Explanation()))
.AddField("Visibility", target.MemberVisibility.Explanation()) .Field(new("Visibility", target.MemberVisibility.Explanation()))
.WithDescription("To edit privacy settings, use the command:\n`pk;member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `avatar`, `birthday`, `pronouns`, `created`, `messages`, `visibility`, or `all`\n- `level` is either `public` or `private`.") .Description("To edit privacy settings, use the command:\n`pk;member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `avatar`, `birthday`, `pronouns`, `created`, `messages`, `visibility`, or `all`\n- `level` is either `public` or `private`.")
.Build()); .Build());
return; return;
} }

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using DSharpPlus.Entities; using Myriad.Builders;
using PluralKit.Core; using PluralKit.Core;
@ -84,7 +84,7 @@ namespace PluralKit.Bot
msg += $"\nTo remove this member from one or more groups, use `pk;m {target.Reference()} group remove <group> [group 2] [group 3...]`"; msg += $"\nTo remove this member from one or more groups, use `pk;m {target.Reference()} group remove <group> [group 2] [group 3...]`";
} }
await ctx.Reply(msg, embed: (new DiscordEmbedBuilder().WithTitle($"{target.Name}'s groups").WithDescription(description)).Build()); await ctx.Reply(msg, (new EmbedBuilder().Title($"{target.Name}'s groups").Description(description)).Build());
} }
} }
} }

View File

@ -3,17 +3,13 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using DSharpPlus; using Myriad.Builders;
using DSharpPlus.Entities;
using Myriad.Cache; using Myriad.Cache;
using Myriad.Extensions; using Myriad.Extensions;
using Myriad.Types; using Myriad.Types;
using PluralKit.Core; using PluralKit.Core;
using Permissions = DSharpPlus.Permissions;
namespace PluralKit.Bot namespace PluralKit.Bot
{ {
public class ServerConfig public class ServerConfig
@ -183,15 +179,15 @@ namespace PluralKit.Bot
newValue = false; newValue = false;
else else
{ {
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithTitle("Log cleanup settings") .Title("Log cleanup settings")
.AddField("Supported bots", botList); .Field(new("Supported bots", botList));
var guildCfg = await _db.Execute(c => _repo.GetGuild(c, ctx.GuildNew.Id)); var guildCfg = await _db.Execute(c => _repo.GetGuild(c, ctx.GuildNew.Id));
if (guildCfg.LogCleanupEnabled) if (guildCfg.LogCleanupEnabled)
eb.WithDescription("Log cleanup is currently **on** for this server. To disable it, type `pk;logclean off`."); eb.Description("Log cleanup is currently **on** for this server. To disable it, type `pk;logclean off`.");
else else
eb.WithDescription("Log cleanup is currently **off** for this server. To enable it, type `pk;logclean on`."); eb.Description("Log cleanup is currently **off** for this server. To enable it, type `pk;logclean on`.");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
return; return;
} }

View File

@ -2,8 +2,6 @@ using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using DSharpPlus.Entities;
using Myriad.Builders; using Myriad.Builders;
using NodaTime; using NodaTime;
@ -77,10 +75,10 @@ namespace PluralKit.Bot
else if (ctx.MatchFlag("r", "raw")) else if (ctx.MatchFlag("r", "raw"))
await ctx.Reply($"```\n{ctx.System.Description}\n```"); await ctx.Reply($"```\n{ctx.System.Description}\n```");
else else
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new EmbedBuilder()
.WithTitle("System description") .Title("System description")
.WithDescription(ctx.System.Description) .Description(ctx.System.Description)
.WithFooter("To print the description with formatting, type `pk;s description -raw`. To clear it, type `pk;s description -clear`. To change it, type `pk;s description <new description>`.") .Footer(new("To print the description with formatting, type `pk;s description -raw`. To clear it, type `pk;s description -clear`. To change it, type `pk;s description <new description>`."))
.Build()); .Build());
} }
else else
@ -160,10 +158,10 @@ namespace PluralKit.Bot
{ {
if ((ctx.System.AvatarUrl?.Trim() ?? "").Length > 0) if ((ctx.System.AvatarUrl?.Trim() ?? "").Length > 0)
{ {
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithTitle("System icon") .Title("System icon")
.WithImageUrl(ctx.System.AvatarUrl) .Image(new(ctx.System.AvatarUrl))
.WithDescription("To clear, use `pk;system icon clear`."); .Description("To clear, use `pk;system icon clear`.");
await ctx.Reply(embed: eb.Build()); await ctx.Reply(embed: eb.Build());
} }
else else
@ -257,14 +255,14 @@ namespace PluralKit.Bot
Task PrintEmbed() Task PrintEmbed()
{ {
var eb = new DiscordEmbedBuilder() var eb = new EmbedBuilder()
.WithTitle("Current privacy settings for your system") .Title("Current privacy settings for your system")
.AddField("Description", ctx.System.DescriptionPrivacy.Explanation()) .Field(new("Description", ctx.System.DescriptionPrivacy.Explanation()))
.AddField("Member list", ctx.System.MemberListPrivacy.Explanation()) .Field(new("Member list", ctx.System.MemberListPrivacy.Explanation()))
.AddField("Group list", ctx.System.GroupListPrivacy.Explanation()) .Field(new("Group list", ctx.System.GroupListPrivacy.Explanation()))
.AddField("Current fronter(s)", ctx.System.FrontPrivacy.Explanation()) .Field(new("Current fronter(s)", ctx.System.FrontPrivacy.Explanation()))
.AddField("Front/switch history", ctx.System.FrontHistoryPrivacy.Explanation()) .Field(new("Front/switch history", ctx.System.FrontHistoryPrivacy.Explanation()))
.WithDescription("To edit privacy settings, use the command:\n`pk;system privacy <subject> <level>`\n\n- `subject` is one of `description`, `list`, `front`, `fronthistory`, `groups`, or `all` \n- `level` is either `public` or `private`."); .Description("To edit privacy settings, use the command:\n`pk;system privacy <subject> <level>`\n\n- `subject` is one of `description`, `list`, `front`, `fronthistory`, `groups`, or `all` \n- `level` is either `public` or `private`.");
return ctx.Reply(embed: eb.Build()); return ctx.Reply(embed: eb.Build());
} }

View File

@ -1,7 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using DSharpPlus.Entities; using Myriad.Rest.Exceptions;
using DSharpPlus.Exceptions;
using PluralKit.Core; using PluralKit.Core;
@ -33,14 +32,16 @@ namespace PluralKit.Bot
await dm.SendMessageFixedAsync(token); await dm.SendMessageFixedAsync(token);
// If we're not already in a DM, reply with a reminder to check // If we're not already in a DM, reply with a reminder to check
if (!(ctx.Channel is DiscordDmChannel)) // TODO: DMs
await ctx.Reply($"{Emojis.Success} Check your DMs!"); // if (!(ctx.Channel is DiscordDmChannel))
// await ctx.Reply($"{Emojis.Success} Check your DMs!");
} }
catch (UnauthorizedException) catch (UnauthorizedException)
{ {
// Can't check for permission errors beforehand, so have to handle here :/ // Can't check for permission errors beforehand, so have to handle here :/
if (!(ctx.Channel is DiscordDmChannel)) // TODO: DMs
await ctx.Reply($"{Emojis.Error} Could not send token in DMs. Are your DMs closed?"); // if (!(ctx.Channel is DiscordDmChannel))
// await ctx.Reply($"{Emojis.Error} Could not send token in DMs. Are your DMs closed?");
} }
} }
@ -74,14 +75,16 @@ namespace PluralKit.Bot
await dm.SendMessageFixedAsync(token); await dm.SendMessageFixedAsync(token);
// If we're not already in a DM, reply with a reminder to check // If we're not already in a DM, reply with a reminder to check
if (!(ctx.Channel is DiscordDmChannel)) // TODO: DMs
await ctx.Reply($"{Emojis.Success} Check your DMs!"); // if (!(ctx.Channel is DiscordDmChannel))
// await ctx.Reply($"{Emojis.Success} Check your DMs!");
} }
catch (UnauthorizedException) catch (UnauthorizedException)
{ {
// Can't check for permission errors beforehand, so have to handle here :/ // Can't check for permission errors beforehand, so have to handle here :/
if (!(ctx.Channel is DiscordDmChannel)) // TODO: DMs
await ctx.Reply($"{Emojis.Error} Could not send token in DMs. Are your DMs closed?"); // if (!(ctx.Channel is DiscordDmChannel))
// await ctx.Reply($"{Emojis.Error} Could not send token in DMs. Are your DMs closed?");
} }
} }
} }