From 87fbbb96b080a7998df040a13530aa190d7d4fcd Mon Sep 17 00:00:00 2001 From: northperseids <109831425+northperseids@users.noreply.github.com> Date: Wed, 11 Feb 2026 23:05:36 -0500 Subject: [PATCH 1/4] Fix autoproxying in group DMs --- .gitignore | 3 +++ main.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 823f7d8..23f5737 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ usersbackup.txt # Distribution / packaging .Python +bin build/ develop-eggs/ dist/ @@ -20,6 +21,7 @@ eggs/ .eggs/ lib/ lib64/ +lib64 parts/ sdist/ var/ @@ -132,6 +134,7 @@ ENV/ env.bak/ venv.bak/ bot-env/ +pyvenv.cfg # Spyder project settings .spyderproject diff --git a/main.py b/main.py index 43fbfd4..4e56fe0 100644 --- a/main.py +++ b/main.py @@ -230,7 +230,7 @@ async def auto(message: Message): sid = message.channel.id else: sid = message.channel.server_id - autoproxy = next((x for x in user['auto'] if x['server'] == sid), None) + autoproxy = next((x for x in user['auto'] if x['server'] == sid), None) if arg == f"{prefix}auto": if autoproxy is None: user['auto'].append({'mode': AutoproxyMode.OFF.value, 'server':sid}) From 53e7e76a730563543c880fb1694525645fa1a672 Mon Sep 17 00:00:00 2001 From: northperseids <109831425+northperseids@users.noreply.github.com> Date: Thu, 12 Feb 2026 04:01:36 -0500 Subject: [PATCH 2/4] Scoped latch using per-server member ID key --- main.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index 4e56fe0..a7d2c26 100644 --- a/main.py +++ b/main.py @@ -508,6 +508,10 @@ async def send(message: Message): client = pluralkit.Client(token=user['token'], user_agent="ninty0808@gmail.com") proxier = None content = message.content + if type(message.channel) is not pyvolt.TextChannel: + sid = message.channel.id + else: + sid = message.channel.server_id try: for member in user['members']: @@ -527,7 +531,9 @@ async def send(message: Message): if pt(check): user['latch'] = True proxier = await client.get_member(member['id']) - user['members'].insert(0, user['members'].pop(user['members'].index(member))) + auto = next((x for x in user['auto'] if x['server'] == sid), None) + if auto is not None and auto['mode'] == 'latch': + auto['member'] = member['id'] if pt.prefix is not None: content = remove_prefix_ci(content, pre) if pt.suffix is not None: @@ -557,7 +563,9 @@ async def send(message: Message): if pt(check): user['latch'] = True proxier = await client.get_member(member['id']) - user['members'].insert(0, user['members'].pop(user['members'].index(member))) + auto = next((x for x in user['auto'] if x['server'] == sid), None) + if auto is not None and auto['mode'] == 'latch': + auto['member'] = member['id'] if pt.prefix is not None: content = remove_prefix_ci(emoji.emojize(content, language='alias'), pre) if pt.suffix is not None: @@ -565,10 +573,6 @@ async def send(message: Message): break if proxier is None: - if type(message.channel) is not pyvolt.TextChannel: - sid = message.channel.id - else: - sid = message.channel.server_id auto = next((x for x in user['auto'] if x['server'] == sid), None) if auto is None: return @@ -580,9 +584,8 @@ async def send(message: Message): proxier = member break case AutoproxyMode.LATCH.value: - for member in user['members']: - proxier = await client.get_member(member['id']) - break + if auto.get('member') is not None: + proxier = await client.get_member(auto['member']) except Unauthorized: if user['error']: From 5d589c8868810184b750ddf7d1f37c647928fbbe Mon Sep 17 00:00:00 2001 From: northperseids <109831425+northperseids@users.noreply.github.com> Date: Thu, 12 Feb 2026 04:18:54 -0500 Subject: [PATCH 3/4] Add double backslash autoproxy ignoring w newer scoped latch --- main.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index a7d2c26..b42e59b 100644 --- a/main.py +++ b/main.py @@ -501,17 +501,24 @@ async def send(message: Message): return if not user['proxy']: return + + if type(message.channel) is not pyvolt.TextChannel: + sid = message.channel.id + else: + sid = message.channel.server_id + if message.content.startswith("\\\\"): + user['latch'] = False + auto = next((x for x in user['auto'] if x['server'] == sid), None) + if auto is not None and auto['mode'] == 'latch': + auto['member'] = None + return if message.content.startswith("\\"): user['latch'] = False return client = pluralkit.Client(token=user['token'], user_agent="ninty0808@gmail.com") proxier = None content = message.content - if type(message.channel) is not pyvolt.TextChannel: - sid = message.channel.id - else: - sid = message.channel.server_id try: for member in user['members']: From 81b5e7d8c022fd5bcddf9d6ce944d5bf4d12fa19 Mon Sep 17 00:00:00 2001 From: northperseids <109831425+northperseids@users.noreply.github.com> Date: Thu, 12 Feb 2026 12:16:33 -0500 Subject: [PATCH 4/4] Update README and informational text about server-scoped latch --- README.md | 2 +- main.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6f964dd..454c73e 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Autoproxy settings work the same way on RevoltKit as they do [on PluralKit](http - `rk;auto latch` - Sets your system's autoproxy in this server to proxy the last manually proxied member. ##### RevoltKit's Latch Mode -Unlike PluralKit where the last member to proxy in a specific server will be used again when posting in the same server, RevoltKit's `latch` setting currently latches across all of Revolt and has no timeout. You will still need to turn it on in each server, however once the mode is set to `latch` the last proxied member for that mode is tracked across all servers. +~~Unlike PluralKit where the last member to proxy in a specific server will be used again when posting in the same server, RevoltKit's `latch` setting currently latches across all of Revolt and has no timeout.~~ RevoltKit's latch setting is similar to PluralKit's. You will need to turn it on in each server you want the latch to work in, and it will track per-server. #### Optional: Log Switches using RevoltKit When [authorized to do so](#Optional:Authorize-RevoltKit), RevoltKit can run all of the switch related commands that PluralKit can; [see more info on those here](https://pluralkit.me/commands/#switching-commands). Please note that while all the switch commands are supported, switch flags (such as the `-append` flag in the command `rk;sw edit -append [Name]`) are not supported yet. diff --git a/main.py b/main.py index b42e59b..3f4e24b 100644 --- a/main.py +++ b/main.py @@ -248,7 +248,7 @@ async def auto(message: Message): await message.channel.send(content="Will autoproxy with your front in this server.") case AutoproxyMode.LATCH.value: user['auto'].append({'mode': AutoproxyMode.LATCH.value, 'server': sid}) - await message.channel.send(content="Will autoproxy with latch in this server. (note: current latch is global)") + await message.channel.send(content="Will autoproxy with latch in this server.") case _: await message.channel.send(content=f"Incorrect argument, use {prefix}auto [off/front/latch]") @@ -429,7 +429,7 @@ async def on_ready(_) -> None: Command(name="switch delete", description=f"sw delete", run=switch_delete, shorthand=True) Command(name="switch", description=f"usage: {prefix}switch [name] | Log a new switch with the specified members (Requires Auth)\nusage: {prefix}switch move 1d 6h 3m | Move a switch to some time ago (Requires Auth)\nusage: {prefix}switch edit | Edit your current switch (Requires Auth)\nusage: {prefix}switch delete | Delete your current switch (Requires Auth)", run=switch) Command(name="case", description=f"usage: {prefix}case | Toggle your proxy's case sensitivity", run=case) - Command(name="autoproxy", description=f"usage: {prefix}auto [front/latch] | Set your autoproxy state per-server\n> Front mode will automatically use the first current fronter, while Latch mode will proxy as whoever proxied last *anywhere on Stoat*", run=auto) + Command(name="autoproxy", description=f"usage: {prefix}auto [front/latch] | Set your autoproxy state per-server\n> Front mode will automatically use the first current fronter, while Latch mode will proxy as whoever proxied last in that server", run=auto) Command(name="auto", description="ap shorthand", run=auto, shorthand=True) Command(name="ap", description="ap shorthand", run=auto, shorthand=True) Command(name="sw out", description=f"sw out", run=switch_out, shorthand=True)