Merge branch 'main' into feature/groups
This commit is contained in:
@@ -201,7 +201,7 @@ namespace PluralKit.Bot
|
||||
await ctx.Execute<System>(SystemInfo, m => m.Query(ctx, ctx.System));
|
||||
|
||||
// First, we match own-system-only commands (ie. no target system parameter)
|
||||
else if (ctx.Match("new", "create", "make", "add", "register", "init"))
|
||||
else if (ctx.Match("new", "create", "make", "add", "register", "init", "n"))
|
||||
await ctx.Execute<System>(SystemNew, m => m.New(ctx));
|
||||
else if (ctx.Match("name", "rename", "changename"))
|
||||
await ctx.Execute<SystemEdit>(SystemRename, m => m.Name(ctx));
|
||||
|
@@ -40,7 +40,8 @@ namespace PluralKit.Bot
|
||||
if (ctx.MatchFlag("by-last-fronted", "by-last-front", "by-last-switch", "blf", "bls")) p.SortProperty = SortProperty.LastSwitch;
|
||||
if (ctx.MatchFlag("by-last-message", "blm", "blp")) p.SortProperty = SortProperty.LastMessage;
|
||||
if (ctx.MatchFlag("by-birthday", "by-birthdate", "bbd")) p.SortProperty = SortProperty.Birthdate;
|
||||
|
||||
if (ctx.MatchFlag("random")) p.SortProperty = SortProperty.Random;
|
||||
|
||||
// Sort reverse?
|
||||
if (ctx.MatchFlag("r", "rev", "reverse"))
|
||||
p.Reverse = true;
|
||||
@@ -136,7 +137,7 @@ namespace PluralKit.Bot
|
||||
profile.Append($"\n**Birthdate**: {m.BirthdayString}");
|
||||
|
||||
if (m.ProxyTags.Count > 0)
|
||||
profile.Append($"\n**Proxy tags:** {m.ProxyTagsString()}");
|
||||
profile.Append($"\n**Proxy tags**: {m.ProxyTagsString()}");
|
||||
|
||||
if (opts.IncludeMessageCount && m.MessageCountFor(lookupCtx) is {} count && count > 0)
|
||||
profile.Append($"\n**Message count:** {count}");
|
||||
@@ -161,4 +162,4 @@ namespace PluralKit.Bot
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,8 @@ namespace PluralKit.Bot
|
||||
public string CreateFilterString()
|
||||
{
|
||||
var str = new StringBuilder();
|
||||
str.Append("Sorting by ");
|
||||
str.Append("Sorting ");
|
||||
if (SortProperty != SortProperty.Random) str.Append("by ");
|
||||
str.Append(SortProperty switch
|
||||
{
|
||||
SortProperty.Name => "member name",
|
||||
@@ -40,6 +41,7 @@ namespace PluralKit.Bot
|
||||
SortProperty.LastSwitch => "last switch",
|
||||
SortProperty.MessageCount => "message count",
|
||||
SortProperty.Birthdate => "birthday",
|
||||
SortProperty.Random => "randomly",
|
||||
_ => new ArgumentOutOfRangeException($"Couldn't find readable string for sort property {SortProperty}")
|
||||
});
|
||||
|
||||
@@ -77,6 +79,8 @@ namespace PluralKit.Bot
|
||||
IComparer<T> ReverseMaybe<T>(IComparer<T> c) =>
|
||||
opts.Reverse ? Comparer<T>.Create((a, b) => c.Compare(b, a)) : c;
|
||||
|
||||
var randGen = new global::System.Random();
|
||||
|
||||
var culture = StringComparer.InvariantCultureIgnoreCase;
|
||||
return (opts.SortProperty switch
|
||||
{
|
||||
@@ -98,6 +102,8 @@ namespace PluralKit.Bot
|
||||
SortProperty.LastSwitch => input
|
||||
.OrderByDescending(m => m.LastSwitchTime.HasValue)
|
||||
.ThenByDescending(m => m.LastSwitchTime, ReverseMaybe(Comparer<Instant?>.Default)),
|
||||
SortProperty.Random => input
|
||||
.OrderBy(m => randGen.Next()),
|
||||
_ => throw new ArgumentOutOfRangeException($"Unknown sort property {opts.SortProperty}")
|
||||
})
|
||||
// Lastly, add a by-name fallback order for collisions (generally hits w/ lots of null values)
|
||||
@@ -114,7 +120,8 @@ namespace PluralKit.Bot
|
||||
CreationDate,
|
||||
LastSwitch,
|
||||
LastMessage,
|
||||
Birthdate
|
||||
Birthdate,
|
||||
Random
|
||||
}
|
||||
|
||||
public enum ListType
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using PluralKit.Core;
|
||||
|
||||
@@ -61,7 +62,11 @@ namespace PluralKit.Bot
|
||||
//Maybe move this somewhere else in the file structure since it doesn't need to get created at every command
|
||||
|
||||
// TODO: don't buffer these, find something else to do ig
|
||||
var members = await _data.GetSystemMembers(ctx.System).Where(m => m.MemberVisibility == PrivacyLevel.Public).ToListAsync();
|
||||
|
||||
List<PKMember> members;
|
||||
if (ctx.MatchFlag("all", "a")) members = await _data.GetSystemMembers(ctx.System).ToListAsync();
|
||||
else members = await _data.GetSystemMembers(ctx.System).Where(m => m.MemberVisibility == PrivacyLevel.Public).ToListAsync();
|
||||
|
||||
if (members == null || !members.Any())
|
||||
throw Errors.NoMembersError;
|
||||
var randInt = randGen.Next(members.Count);
|
||||
|
@@ -36,8 +36,8 @@ namespace PluralKit.Bot
|
||||
|
||||
// Warn if there's already a member by this name
|
||||
var existingMember = await _data.GetMemberByName(ctx.System, newName);
|
||||
if (existingMember != null)
|
||||
if (existingMember.Id != target.Id) {
|
||||
if (existingMember != null && existingMember.Id != target.Id)
|
||||
{
|
||||
var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (`{existingMember.Hid}`). Do you want to rename this member to that name too?";
|
||||
if (!await ctx.PromptYesNo(msg)) throw new PKError("Member renaming cancelled.");
|
||||
}
|
||||
@@ -187,7 +187,7 @@ namespace PluralKit.Bot
|
||||
await ctx.Reply(embed: new DiscordEmbedBuilder()
|
||||
.WithTitle($"{Emojis.Success} Member color changed.")
|
||||
.WithColor(color.ToDiscordColor().Value)
|
||||
.WithThumbnail($"https://fakeimg.pl/256x256/{target.Color}/?text=%20")
|
||||
.WithThumbnail($"https://fakeimg.pl/256x256/{color}/?text=%20")
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
|
@@ -94,27 +94,23 @@ namespace PluralKit.Bot {
|
||||
public async Task PermCheckGuild(Context ctx)
|
||||
{
|
||||
DiscordGuild guild;
|
||||
DiscordMember senderGuildUser = null;
|
||||
|
||||
if (ctx.Guild != null && !ctx.HasNext())
|
||||
{
|
||||
guild = ctx.Guild;
|
||||
senderGuildUser = (DiscordMember)ctx.Author;
|
||||
}
|
||||
else
|
||||
{
|
||||
var guildIdStr = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a server ID or run this command as .");
|
||||
var guildIdStr = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a server ID or run this command in a server.");
|
||||
if (!ulong.TryParse(guildIdStr, out var guildId))
|
||||
throw new PKSyntaxError($"Could not parse `{guildIdStr}` as an ID.");
|
||||
|
||||
// TODO: will this call break for sharding if you try to request a guild on a different bot instance?
|
||||
guild = await ctx.Rest.GetGuild(guildId);
|
||||
if (guild == null)
|
||||
throw Errors.GuildNotFound(guildId);
|
||||
guild = ctx.Client.GetGuild(guildId);
|
||||
if (guild != null) senderGuildUser = await guild.GetMember(ctx.Author.Id);
|
||||
if (guild == null || senderGuildUser == null) throw Errors.GuildNotFound(guildId);
|
||||
}
|
||||
|
||||
// Ensure people can't query guilds they're not in + get their own permissions (for view access checking)
|
||||
var senderGuildUser = await guild.GetMember(ctx.Author.Id);
|
||||
if (senderGuildUser == null)
|
||||
throw new PKError("You must be a member of the guild you are querying.");
|
||||
|
||||
var requiredPermissions = new []
|
||||
{
|
||||
|
@@ -25,9 +25,11 @@ namespace PluralKit.Bot
|
||||
ctx.CheckGuildContext().CheckAuthorPermission(Permissions.ManageGuild, "Manage Server");
|
||||
|
||||
DiscordChannel channel = null;
|
||||
if (ctx.HasNext())
|
||||
channel = await ctx.MatchChannel() ?? throw new PKSyntaxError("You must pass a #channel to set.");
|
||||
if (channel != null && channel.GuildId != ctx.Guild.Id) throw new PKError("That channel is not in this server!");
|
||||
if (!ctx.HasNext())
|
||||
throw new PKSyntaxError("You must pass a #channel to set.");
|
||||
var channelString = ctx.PeekArgument();
|
||||
channel = await ctx.MatchChannel();
|
||||
if (channel == null || channel.GuildId != ctx.Guild.Id) throw Errors.ChannelNotFound(channelString);
|
||||
|
||||
var patch = new GuildPatch {LogChannel = channel?.Id};
|
||||
await _db.Execute(conn => conn.UpsertGuild(ctx.Guild.Id, patch));
|
||||
@@ -48,8 +50,9 @@ namespace PluralKit.Bot
|
||||
else if (!ctx.HasNext()) throw new PKSyntaxError("You must pass one or more #channels.");
|
||||
else while (ctx.HasNext())
|
||||
{
|
||||
var channel = await ctx.MatchChannel() ?? throw new PKSyntaxError($"Channel \"{ctx.PopArgument()}\" not found.");
|
||||
if (channel.GuildId != ctx.Guild.Id) throw new PKError($"Channel {ctx.Guild.Id} is not in this server.");
|
||||
var channelString = ctx.PeekArgument();
|
||||
var channel = await ctx.MatchChannel();
|
||||
if (channel == null || channel.GuildId != ctx.Guild.Id) throw Errors.ChannelNotFound(channelString);
|
||||
affectedChannels.Add(channel);
|
||||
}
|
||||
|
||||
@@ -127,8 +130,9 @@ namespace PluralKit.Bot
|
||||
else if (!ctx.HasNext()) throw new PKSyntaxError("You must pass one or more #channels.");
|
||||
else while (ctx.HasNext())
|
||||
{
|
||||
var channel = await ctx.MatchChannel() ?? throw new PKSyntaxError($"Channel \"{ctx.PopArgument()}\" not found.");
|
||||
if (channel.GuildId != ctx.Guild.Id) throw new PKError($"Channel {ctx.Guild.Id} is not in this server.");
|
||||
var channelString = ctx.PeekArgument();
|
||||
var channel = await ctx.MatchChannel();
|
||||
if (channel == null || channel.GuildId != ctx.Guild.Id) throw Errors.ChannelNotFound(channelString);
|
||||
affectedChannels.Add(channel);
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,11 @@ namespace PluralKit.Bot
|
||||
{
|
||||
ctx.CheckNoSystem();
|
||||
|
||||
var system = await _data.CreateSystem(ctx.RemainderOrNull());
|
||||
var systemName = ctx.RemainderOrNull();
|
||||
if (systemName != null && systemName.Length > Limits.MaxSystemNameLength)
|
||||
throw Errors.SystemNameTooLongError(systemName.Length);
|
||||
|
||||
var system = await _data.CreateSystem(systemName);
|
||||
await _data.AddAccount(system, ctx.Author.Id);
|
||||
await ctx.Reply($"{Emojis.Success} Your system has been created. Type `pk;system` to view it, and type `pk;system help` for more information about commands you can use now. Now that you have that set up, check out the getting started guide on setting up members and proxies: <https://pluralkit.me/start>");
|
||||
}
|
||||
|
Reference in New Issue
Block a user