mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
fix message edit commands, parse DM message links for ids
This commit is contained in:
parent
134855f8f8
commit
a307dd37c4
6 changed files with 74 additions and 47 deletions
|
|
@ -282,7 +282,8 @@ public partial class CommandTree
|
||||||
Commands.MessageInfo(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), flags.delete, flags.author)),
|
Commands.MessageInfo(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), flags.delete, flags.author)),
|
||||||
Commands.MessageAuthor(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), false, true)),
|
Commands.MessageAuthor(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), false, true)),
|
||||||
Commands.MessageDelete(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), true, false)),
|
Commands.MessageDelete(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), true, false)),
|
||||||
Commands.MessageEdit(var param, var flags) => ctx.Execute<ProxiedMessage>(MessageEdit, m => m.EditMessage(ctx, param.target.MessageId, param.new_content, flags.regex, flags.mutate_space, flags.append, flags.prepend, flags.clear_embeds, flags.clear_attachments)),
|
Commands.MessageEditSpecified(var param, var flags) => ctx.Execute<ProxiedMessage>(MessageEdit, m => m.EditMessage(ctx, param.target.MessageId, param.new_content, flags.regex, flags.mutate_space, flags.append, flags.prepend, flags.clear_embeds, flags.clear_attachments)),
|
||||||
|
Commands.MessageEdit(var param, var flags) => ctx.Execute<ProxiedMessage>(MessageEdit, m => m.EditMessage(ctx, null, param.new_content, flags.regex, flags.mutate_space, flags.append, flags.prepend, flags.clear_embeds, flags.clear_attachments)),
|
||||||
Commands.MessageReproxySpecified(var param, _) => ctx.Execute<ProxiedMessage>(MessageReproxy, m => m.ReproxyMessage(ctx, param.msg.MessageId, param.member)),
|
Commands.MessageReproxySpecified(var param, _) => ctx.Execute<ProxiedMessage>(MessageReproxy, m => m.ReproxyMessage(ctx, param.msg.MessageId, param.member)),
|
||||||
Commands.MessageReproxy(var param, _) => ctx.Execute<ProxiedMessage>(MessageReproxy, m => m.ReproxyMessage(ctx, null, param.member)),
|
Commands.MessageReproxy(var param, _) => ctx.Execute<ProxiedMessage>(MessageReproxy, m => m.ReproxyMessage(ctx, null, param.member)),
|
||||||
Commands.Import(var param, var flags) => ctx.Execute<ImportExport>(Import, m => m.Import(ctx, param.url, flags.yes)),
|
Commands.Import(var param, var flags) => ctx.Execute<ImportExport>(Import, m => m.Import(ctx, param.url, flags.yes)),
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,24 @@ namespace PluralKit.Bot;
|
||||||
// corresponds to the ffi Paramater type, but with stricter types (also avoiding exposing ffi types!)
|
// corresponds to the ffi Paramater type, but with stricter types (also avoiding exposing ffi types!)
|
||||||
public abstract record Parameter()
|
public abstract record Parameter()
|
||||||
{
|
{
|
||||||
public record MemberRef(PKMember member): Parameter;
|
public record MemberRef(PKMember member) : Parameter;
|
||||||
public record MemberRefs(List<PKMember> members): Parameter;
|
public record MemberRefs(List<PKMember> members) : Parameter;
|
||||||
public record GroupRef(PKGroup group): Parameter;
|
public record GroupRef(PKGroup group) : Parameter;
|
||||||
public record GroupRefs(List<PKGroup> groups): Parameter;
|
public record GroupRefs(List<PKGroup> groups) : Parameter;
|
||||||
public record SystemRef(PKSystem system): Parameter;
|
public record SystemRef(PKSystem system) : Parameter;
|
||||||
public record UserRef(User user): Parameter;
|
public record UserRef(User user) : Parameter;
|
||||||
public record MessageRef(Message.Reference message): Parameter;
|
public record MessageRef(Message.Reference message) : Parameter;
|
||||||
public record ChannelRef(Channel channel): Parameter;
|
public record ChannelRef(Channel channel) : Parameter;
|
||||||
public record GuildRef(Guild guild): Parameter;
|
public record GuildRef(Guild guild) : Parameter;
|
||||||
public record MemberPrivacyTarget(MemberPrivacySubject target): Parameter;
|
public record MemberPrivacyTarget(MemberPrivacySubject target) : Parameter;
|
||||||
public record GroupPrivacyTarget(GroupPrivacySubject target): Parameter;
|
public record GroupPrivacyTarget(GroupPrivacySubject target) : Parameter;
|
||||||
public record SystemPrivacyTarget(SystemPrivacySubject target): Parameter;
|
public record SystemPrivacyTarget(SystemPrivacySubject target) : Parameter;
|
||||||
public record PrivacyLevel(Core.PrivacyLevel level): Parameter;
|
public record PrivacyLevel(Core.PrivacyLevel level) : Parameter;
|
||||||
public record Toggle(bool value): Parameter;
|
public record Toggle(bool value) : Parameter;
|
||||||
public record Opaque(string value): Parameter;
|
public record Opaque(string value) : Parameter;
|
||||||
public record Number(int value): Parameter;
|
public record Number(int value) : Parameter;
|
||||||
public record Avatar(ParsedImage avatar): Parameter;
|
public record Avatar(ParsedImage avatar) : Parameter;
|
||||||
public record ProxySwitchAction(SystemConfig.ProxySwitchAction action): Parameter;
|
public record ProxySwitchAction(SystemConfig.ProxySwitchAction action) : Parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Parameters
|
public class Parameters
|
||||||
|
|
@ -48,6 +48,10 @@ public class Parameters
|
||||||
_cb = command.@commandRef;
|
_cb = command.@commandRef;
|
||||||
_flags = command.@flags;
|
_flags = command.@flags;
|
||||||
_params = command.@params;
|
_params = command.@params;
|
||||||
|
foreach (var param in _params)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{param.Key}: {param.Value}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
||||||
let delete = ("delete", ["del", "d"]);
|
let delete = ("delete", ["del", "d"]);
|
||||||
let reproxy = ("reproxy", ["rp", "crimes", "crime"]);
|
let reproxy = ("reproxy", ["rp", "crimes", "crime"]);
|
||||||
|
|
||||||
let edit = tokens!(("edit", ["e"]), ("new_content", OpaqueStringRemainder));
|
let edit = ("edit", ["e"]);
|
||||||
let apply_edit = |cmd: Command| {
|
let apply_edit = |cmd: Command| {
|
||||||
cmd.flag(("append", ["a"]))
|
cmd.flag(("append", ["a"]))
|
||||||
.flag(("prepend", ["p"]))
|
.flag(("prepend", ["p"]))
|
||||||
|
|
@ -25,8 +25,9 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
||||||
.help("Shows information about a proxied message"),
|
.help("Shows information about a proxied message"),
|
||||||
command!(message, author => "message_author").help("Shows the author of a proxied message"),
|
command!(message, author => "message_author").help("Shows the author of a proxied message"),
|
||||||
command!(message, delete => "message_delete").help("Deletes a proxied message"),
|
command!(message, delete => "message_delete").help("Deletes a proxied message"),
|
||||||
apply_edit(command!(message, edit => "message_edit")),
|
apply_edit(command!(message, edit, ("new_content", OpaqueStringRemainder) => "message_edit_specified")),
|
||||||
apply_edit(command!(edit => "message_edit")),
|
apply_edit(command!(edit, Skip(MessageRef), ("new_content", OpaqueStringRemainder) => "message_edit_specified")),
|
||||||
|
apply_edit(command!(edit, ("new_content", OpaqueStringRemainder) => "message_edit")),
|
||||||
command!(reproxy, ("member", MemberRef) => "message_reproxy")
|
command!(reproxy, ("member", MemberRef) => "message_reproxy")
|
||||||
.help("Reproxies a message with a different member"),
|
.help("Reproxies a message with a different member"),
|
||||||
command!(reproxy, ("msg", MessageRef), ("member", MemberRef) => "message_reproxy_specified")
|
command!(reproxy, ("msg", MessageRef), ("member", MemberRef) => "message_reproxy_specified")
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,13 @@ pub fn parse_command(
|
||||||
let mut matched_tokens: Vec<(Tree, (Token, TokenMatchResult, usize))> = Vec::new();
|
let mut matched_tokens: Vec<(Tree, (Token, TokenMatchResult, usize))> = Vec::new();
|
||||||
let mut filtered_tokens: Vec<Token> = Vec::new();
|
let mut filtered_tokens: Vec<Token> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
println!(
|
// println!(
|
||||||
"possible: {:?}",
|
// "possible: {:?}",
|
||||||
local_tree
|
// local_tree
|
||||||
.possible_tokens()
|
// .possible_tokens()
|
||||||
.filter(|t| filtered_tokens.contains(t))
|
// .filter(|t| filtered_tokens.contains(t))
|
||||||
.collect::<Vec<_>>()
|
// .collect::<Vec<_>>()
|
||||||
);
|
// );
|
||||||
let next = next_token(
|
let next = next_token(
|
||||||
local_tree
|
local_tree
|
||||||
.possible_tokens()
|
.possible_tokens()
|
||||||
|
|
@ -64,7 +64,7 @@ pub fn parse_command(
|
||||||
&input,
|
&input,
|
||||||
current_pos,
|
current_pos,
|
||||||
);
|
);
|
||||||
println!("next: {:?}", next);
|
// println!("next: {:?}", next);
|
||||||
match &next {
|
match &next {
|
||||||
Some((found_token, result, new_pos)) => {
|
Some((found_token, result, new_pos)) => {
|
||||||
match &result {
|
match &result {
|
||||||
|
|
|
||||||
|
|
@ -135,32 +135,41 @@ impl Parameter {
|
||||||
return Ok(ParameterValue::MessageRef(None, None, message_id));
|
return Ok(ParameterValue::MessageRef(None, None, message_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
static RE: std::sync::LazyLock<regex::Regex> = std::sync::LazyLock::new(|| {
|
static SERVER_RE: std::sync::LazyLock<regex::Regex> = std::sync::LazyLock::new(
|
||||||
|
|| {
|
||||||
|
regex::Regex::new(
|
||||||
|
r"https://(?:\w+\.)?discord(?:app)?\.com/channels/(?P<guild>\d+)/(?P<channel>\d+)/(?P<message>\d+)",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
static DM_RE: std::sync::LazyLock<regex::Regex> = std::sync::LazyLock::new(|| {
|
||||||
regex::Regex::new(
|
regex::Regex::new(
|
||||||
r"https://(?:\w+\.)?discord(?:app)?\.com/channels/(\d+)/(\d+)/(\d+)",
|
r"https://(?:\w+\.)?discord(?:app)?\.com/channels/@me/(?P<channel>\d+)/(?P<message>\d+)",
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(captures) = RE.captures(input) {
|
if let Some(captures) = SERVER_RE.captures(input) {
|
||||||
let guild_id = captures
|
let guild_id = captures.parse_id("guild")?;
|
||||||
.get(1)
|
let channel_id = captures.parse_id("channel")?;
|
||||||
.and_then(|m| m.as_str().parse::<u64>().ok())
|
let message_id = captures.parse_id("message")?;
|
||||||
.ok_or_else(|| SmolStr::new("invalid guild ID in message link"))?;
|
|
||||||
let channel_id = captures
|
|
||||||
.get(2)
|
|
||||||
.and_then(|m| m.as_str().parse::<u64>().ok())
|
|
||||||
.ok_or_else(|| SmolStr::new("invalid channel ID in message link"))?;
|
|
||||||
let message_id = captures
|
|
||||||
.get(3)
|
|
||||||
.and_then(|m| m.as_str().parse::<u64>().ok())
|
|
||||||
.ok_or_else(|| SmolStr::new("invalid message ID in message link"))?;
|
|
||||||
|
|
||||||
Ok(ParameterValue::MessageRef(
|
Ok(ParameterValue::MessageRef(
|
||||||
Some(guild_id),
|
Some(guild_id),
|
||||||
Some(channel_id),
|
Some(channel_id),
|
||||||
message_id,
|
message_id,
|
||||||
))
|
))
|
||||||
|
} else if let Some(captures) = DM_RE.captures(input) {
|
||||||
|
let channel_id = captures.parse_id("channel")?;
|
||||||
|
let message_id = captures.parse_id("message")?;
|
||||||
|
|
||||||
|
Ok(ParameterValue::MessageRef(
|
||||||
|
None,
|
||||||
|
Some(channel_id),
|
||||||
|
message_id,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Err(SmolStr::new("invalid message reference"))
|
Err(SmolStr::new("invalid message reference"))
|
||||||
}
|
}
|
||||||
|
|
@ -560,3 +569,15 @@ impl FromStr for ProxySwitchAction {
|
||||||
.ok_or_else(|| SmolStr::new("invalid proxy switch action, must be new/add/off"))
|
.ok_or_else(|| SmolStr::new("invalid proxy switch action, must be new/add/off"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait ParseMessageLink {
|
||||||
|
fn parse_id(&self, name: &str) -> Result<u64, SmolStr>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParseMessageLink for regex::Captures<'_> {
|
||||||
|
fn parse_id(&self, name: &str) -> Result<u64, SmolStr> {
|
||||||
|
self.name(name)
|
||||||
|
.and_then(|m| m.as_str().parse::<u64>().ok())
|
||||||
|
.ok_or_else(|| SmolStr::new(format!("invalid {} in message link", name)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
extract_fn_name = get_param_param_ty(param.kind()),
|
extract_fn_name = get_param_param_ty(param.kind()),
|
||||||
throw_null = param
|
throw_null = param
|
||||||
.is_optional()
|
.is_optional()
|
||||||
.then_some("")
|
.then(String::new)
|
||||||
.unwrap_or(" ?? throw new PKError(\"this is a bug\")"),
|
.unwrap_or(format!(" ?? throw new PKError(\"parameter {} not found but was required, this is a bug in the command parser, for command: {}!\")", param.name(), command.cb)),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
let mut command_flags_init = String::new();
|
let mut command_flags_init = String::new();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue