mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
feat: implement system proxy commands
This commit is contained in:
parent
047bdd870d
commit
cb0a9eaf9f
11 changed files with 93 additions and 29 deletions
|
|
@ -96,6 +96,10 @@ public partial class CommandTree
|
|||
Commands.SystemClearBanner(var param, var flags) => ctx.Execute<SystemEdit>(SystemBannerImage, m => m.ClearBannerImage(ctx, ctx.System, flags.yes)),
|
||||
Commands.SystemChangeBanner(var param, _) => ctx.Execute<SystemEdit>(SystemBannerImage, m => m.ChangeBannerImage(ctx, ctx.System, param.banner)),
|
||||
Commands.SystemDelete(_, var flags) => ctx.Execute<SystemEdit>(SystemDelete, m => m.Delete(ctx, ctx.System, flags.no_export)),
|
||||
Commands.SystemShowProxyCurrent(_, _) => ctx.Execute<SystemEdit>(SystemProxy, m => m.ShowSystemProxy(ctx, ctx.Guild)),
|
||||
Commands.SystemShowProxy(var param, _) => ctx.Execute<SystemEdit>(SystemProxy, m => m.ShowSystemProxy(ctx, param.target)),
|
||||
Commands.SystemToggleProxyCurrent(var param, _) => ctx.Execute<SystemEdit>(SystemProxy, m => m.ToggleSystemProxy(ctx, ctx.Guild, param.toggle)),
|
||||
Commands.SystemToggleProxy(var param, _) => ctx.Execute<SystemEdit>(SystemProxy, m => m.ToggleSystemProxy(ctx, param.target, param.toggle)),
|
||||
_ =>
|
||||
// this should only ever occur when deving if commands are not implemented...
|
||||
ctx.Reply(
|
||||
|
|
@ -167,8 +171,6 @@ public partial class CommandTree
|
|||
if (ctx.Match("proxy"))
|
||||
if (ctx.Match("debug"))
|
||||
return ctx.Execute<Checks>(ProxyCheck, m => m.MessageProxyCheck(ctx));
|
||||
else
|
||||
return ctx.Execute<SystemEdit>(SystemProxy, m => m.SystemProxy(ctx));
|
||||
if (ctx.Match("invite")) return ctx.Execute<Misc>(Invite, m => m.Invite(ctx));
|
||||
if (ctx.Match("mn")) return ctx.Execute<Fun>(null, m => m.Mn(ctx));
|
||||
if (ctx.Match("fire")) return ctx.Execute<Fun>(null, m => m.Fire(ctx));
|
||||
|
|
@ -295,8 +297,6 @@ public partial class CommandTree
|
|||
// todo: these aren't deprecated but also shouldn't be here
|
||||
else if (ctx.Match("webhook", "hook"))
|
||||
await ctx.Execute<Api>(null, m => m.SystemWebhook(ctx));
|
||||
else if (ctx.Match("proxy"))
|
||||
await ctx.Execute<SystemEdit>(SystemProxy, m => m.SystemProxy(ctx));
|
||||
|
||||
// finally, parse commands that *can* take a system target
|
||||
else
|
||||
|
|
|
|||
|
|
@ -213,6 +213,14 @@ public static class ContextEntityArgumentsExt
|
|||
return channel;
|
||||
}
|
||||
|
||||
public static async Task<Guild> ParseGuild(this Context ctx, string input)
|
||||
{
|
||||
if (!ulong.TryParse(input, out var id))
|
||||
return null;
|
||||
|
||||
return await ctx.Rest.GetGuildOrNull(id);
|
||||
}
|
||||
|
||||
public static async Task<Guild> MatchGuild(this Context ctx)
|
||||
{
|
||||
if (!ulong.TryParse(ctx.PeekArgument(), out var id))
|
||||
|
|
|
|||
|
|
@ -59,4 +59,12 @@ public static class ContextParametersExt
|
|||
param => (param as Parameter.Avatar)?.avatar
|
||||
);
|
||||
}
|
||||
|
||||
public static async Task<Myriad.Types.Guild?> ParamResolveGuild(this Context ctx, string param_name)
|
||||
{
|
||||
return await ctx.Parameters.ResolveParameter(
|
||||
ctx, param_name,
|
||||
param => (param as Parameter.GuildRef)?.guild
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ public abstract record Parameter()
|
|||
{
|
||||
public record MemberRef(PKMember member): Parameter;
|
||||
public record SystemRef(PKSystem system): Parameter;
|
||||
public record GuildRef(Guild guild): Parameter;
|
||||
public record MemberPrivacyTarget(MemberPrivacySubject target): Parameter;
|
||||
public record PrivacyLevel(string level): Parameter;
|
||||
public record Toggle(bool value): Parameter;
|
||||
|
|
@ -83,6 +84,8 @@ public class Parameters
|
|||
return new Parameter.Opaque(opaque.raw);
|
||||
case uniffi.commands.Parameter.Avatar avatar:
|
||||
return new Parameter.Avatar(await ctx.GetUserPfp(avatar.avatar) ?? ctx.ParseImage(avatar.avatar));
|
||||
case uniffi.commands.Parameter.GuildRef guildRef:
|
||||
return new Parameter.GuildRef(await ctx.ParseGuild(guildRef.guild) ?? throw new PKError($"Guild {guildRef.guild} not found"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -830,11 +830,32 @@ public class SystemEdit
|
|||
await ctx.Repository.DeleteSystem(target.Id);
|
||||
}
|
||||
|
||||
public async Task SystemProxy(Context ctx)
|
||||
public async Task ToggleSystemProxy(Context ctx, Guild guildArg, bool newValue)
|
||||
{
|
||||
ctx.CheckSystem();
|
||||
|
||||
var guild = await ctx.MatchGuild() ?? ctx.Guild ??
|
||||
var guild = guildArg ??
|
||||
throw new PKError("You must run this command in a server or pass a server ID.");
|
||||
|
||||
string serverText;
|
||||
if (guild.Id == ctx.Guild?.Id)
|
||||
serverText = $"this server ({guild.Name.EscapeMarkdown()})";
|
||||
else
|
||||
serverText = $"the server {guild.Name.EscapeMarkdown()}";
|
||||
|
||||
await ctx.Repository.UpdateSystemGuild(ctx.System.Id, guild.Id, new SystemGuildPatch { ProxyEnabled = newValue });
|
||||
|
||||
if (newValue)
|
||||
await ctx.Reply($"Message proxying in {serverText} is now **enabled** for your system.");
|
||||
else
|
||||
await ctx.Reply($"Message proxying in {serverText} is now **disabled** for your system.");
|
||||
}
|
||||
|
||||
public async Task ShowSystemProxy(Context ctx, Guild guildArg)
|
||||
{
|
||||
ctx.CheckSystem();
|
||||
|
||||
var guild = guildArg ??
|
||||
throw new PKError("You must run this command in a server or pass a server ID.");
|
||||
|
||||
var gs = await ctx.Repository.GetSystemGuild(guild.Id, ctx.System.Id);
|
||||
|
|
@ -845,25 +866,12 @@ public class SystemEdit
|
|||
else
|
||||
serverText = $"the server {guild.Name.EscapeMarkdown()}";
|
||||
|
||||
if (!ctx.HasNext())
|
||||
{
|
||||
if (gs.ProxyEnabled)
|
||||
await ctx.Reply(
|
||||
$"Proxying in {serverText} is currently **enabled** for your system. To disable it, type `{ctx.DefaultPrefix}system proxy off`.");
|
||||
else
|
||||
await ctx.Reply(
|
||||
$"Proxying in {serverText} is currently **disabled** for your system. To enable it, type `{ctx.DefaultPrefix}system proxy on`.");
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = ctx.MatchToggle();
|
||||
|
||||
await ctx.Repository.UpdateSystemGuild(ctx.System.Id, guild.Id, new SystemGuildPatch { ProxyEnabled = newValue });
|
||||
|
||||
if (newValue)
|
||||
await ctx.Reply($"Message proxying in {serverText} is now **enabled** for your system.");
|
||||
if (gs.ProxyEnabled)
|
||||
await ctx.Reply(
|
||||
$"Proxying in {serverText} is currently **enabled** for your system. To disable it, type `{ctx.DefaultPrefix}system proxy off`.");
|
||||
else
|
||||
await ctx.Reply($"Message proxying in {serverText} is now **disabled** for your system.");
|
||||
await ctx.Reply(
|
||||
$"Proxying in {serverText} is currently **disabled** for your system. To enable it, type `{ctx.DefaultPrefix}system proxy on`.");
|
||||
}
|
||||
|
||||
public async Task SystemPrivacy(Context ctx, PKSystem target)
|
||||
|
|
|
|||
|
|
@ -200,6 +200,16 @@ pub fn edit() -> impl Iterator<Item = Command> {
|
|||
.help("Deletes the system"),
|
||||
);
|
||||
|
||||
let system_proxy = tokens!(system, "proxy");
|
||||
let system_proxy_cmd = [
|
||||
command!(system_proxy => "system_show_proxy_current").help("Shows your system's proxy setting for the guild you are in"),
|
||||
command!(system_proxy, Toggle => "system_toggle_proxy_current")
|
||||
.help("Toggle your system's proxy for the guild you are in"),
|
||||
command!(system_proxy, GuildRef => "system_show_proxy").help("Shows your system's proxy setting for a guild"),
|
||||
command!(system_proxy, GuildRef, Toggle => "system_toggle_proxy")
|
||||
.help("Toggle your system's proxy for a guild"),
|
||||
].into_iter();
|
||||
|
||||
system_new_cmd
|
||||
.chain(system_name_self_cmd)
|
||||
.chain(system_server_name_self_cmd)
|
||||
|
|
@ -212,6 +222,7 @@ pub fn edit() -> impl Iterator<Item = Command> {
|
|||
.chain(system_server_avatar_self_cmd)
|
||||
.chain(system_banner_self_cmd)
|
||||
.chain(system_delete)
|
||||
.chain(system_proxy_cmd)
|
||||
.chain(system_name_cmd)
|
||||
.chain(system_server_name_cmd)
|
||||
.chain(system_description_cmd)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ pub enum ParameterValue {
|
|||
OpaqueString(String),
|
||||
MemberRef(String),
|
||||
SystemRef(String),
|
||||
GuildRef(String),
|
||||
MemberPrivacyTarget(String),
|
||||
PrivacyLevel(String),
|
||||
Toggle(bool),
|
||||
|
|
@ -42,6 +43,7 @@ impl Display for Parameter {
|
|||
}
|
||||
ParameterKind::MemberRef => write!(f, "<target member>"),
|
||||
ParameterKind::SystemRef => write!(f, "<target system>"),
|
||||
ParameterKind::GuildRef => write!(f, "<target guild>"),
|
||||
ParameterKind::MemberPrivacyTarget => write!(f, "<privacy target>"),
|
||||
ParameterKind::PrivacyLevel => write!(f, "[privacy level]"),
|
||||
ParameterKind::Toggle => write!(f, "on/off"),
|
||||
|
|
@ -74,6 +76,7 @@ pub enum ParameterKind {
|
|||
OpaqueStringRemainder,
|
||||
MemberRef,
|
||||
SystemRef,
|
||||
GuildRef,
|
||||
MemberPrivacyTarget,
|
||||
PrivacyLevel,
|
||||
Toggle,
|
||||
|
|
@ -87,6 +90,7 @@ impl ParameterKind {
|
|||
ParameterKind::OpaqueStringRemainder => "string",
|
||||
ParameterKind::MemberRef => "target",
|
||||
ParameterKind::SystemRef => "target",
|
||||
ParameterKind::GuildRef => "target",
|
||||
ParameterKind::MemberPrivacyTarget => "member_privacy_target",
|
||||
ParameterKind::PrivacyLevel => "privacy_level",
|
||||
ParameterKind::Toggle => "toggle",
|
||||
|
|
@ -114,8 +118,13 @@ impl ParameterKind {
|
|||
Toggle::from_str(input).map(|t| ParameterValue::Toggle(t.into()))
|
||||
}
|
||||
ParameterKind::Avatar => Ok(ParameterValue::Avatar(input.into())),
|
||||
ParameterKind::GuildRef => Ok(ParameterValue::GuildRef(input.into())),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn skip_if_cant_match(&self) -> bool {
|
||||
matches!(self, ParameterKind::Toggle)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum MemberPrivacyTargetKind {
|
||||
|
|
|
|||
|
|
@ -67,9 +67,15 @@ impl Token {
|
|||
name: param.name().into(),
|
||||
value: matched,
|
||||
},
|
||||
Err(err) => TokenMatchResult::ParameterMatchError {
|
||||
input: input.into(),
|
||||
msg: err,
|
||||
Err(err) => {
|
||||
if param.kind().skip_if_cant_match() {
|
||||
return None;
|
||||
} else {
|
||||
TokenMatchResult::ParameterMatchError {
|
||||
input: input.into(),
|
||||
msg: err,
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
// don't add a _ match here!
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use std::{env, fmt::Write, fs, path::PathBuf, str::FromStr};
|
||||
|
||||
use command_parser::{
|
||||
command, parameter::{Parameter, ParameterKind}, token::Token
|
||||
parameter::{Parameter, ParameterKind},
|
||||
token::Token,
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
@ -16,6 +17,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
writeln!(&mut glue, "#nullable enable\n")?;
|
||||
writeln!(&mut glue, "using PluralKit.Core;\n")?;
|
||||
writeln!(&mut glue, "using Myriad.Types;")?;
|
||||
writeln!(&mut glue, "namespace PluralKit.Bot;\n")?;
|
||||
|
||||
let mut record_fields = String::new();
|
||||
|
|
@ -114,7 +116,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
}
|
||||
let mut command_reply_format = String::new();
|
||||
if command.flags.iter().any(|flag| flag.get_name() == "plaintext") {
|
||||
if command
|
||||
.flags
|
||||
.iter()
|
||||
.any(|flag| flag.get_name() == "plaintext")
|
||||
{
|
||||
writeln!(
|
||||
&mut command_reply_format,
|
||||
r#"if (plaintext) return ReplyFormat.Plaintext;"#,
|
||||
|
|
@ -166,6 +172,7 @@ fn get_param_ty(kind: ParameterKind) -> &'static str {
|
|||
ParameterKind::PrivacyLevel => "string",
|
||||
ParameterKind::Toggle => "bool",
|
||||
ParameterKind::Avatar => "ParsedImage",
|
||||
ParameterKind::GuildRef => "Guild",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,6 +185,7 @@ fn get_param_param_ty(kind: ParameterKind) -> &'static str {
|
|||
ParameterKind::PrivacyLevel => "PrivacyLevel",
|
||||
ParameterKind::Toggle => "Toggle",
|
||||
ParameterKind::Avatar => "Avatar",
|
||||
ParameterKind::GuildRef => "Guild",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ interface CommandResult {
|
|||
interface Parameter {
|
||||
MemberRef(string member);
|
||||
SystemRef(string system);
|
||||
GuildRef(string guild);
|
||||
MemberPrivacyTarget(string target);
|
||||
PrivacyLevel(string level);
|
||||
OpaqueString(string raw);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ pub enum CommandResult {
|
|||
pub enum Parameter {
|
||||
MemberRef { member: String },
|
||||
SystemRef { system: String },
|
||||
GuildRef { guild: String },
|
||||
MemberPrivacyTarget { target: String },
|
||||
PrivacyLevel { level: String },
|
||||
OpaqueString { raw: String },
|
||||
|
|
@ -41,6 +42,7 @@ impl From<ParameterValue> for Parameter {
|
|||
ParameterValue::OpaqueString(raw) => Self::OpaqueString { raw },
|
||||
ParameterValue::Toggle(toggle) => Self::Toggle { toggle },
|
||||
ParameterValue::Avatar(avatar) => Self::Avatar { avatar },
|
||||
ParameterValue::GuildRef(guild) => Self::GuildRef { guild },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue