Skip to content

Added Ceasar cypher encryption/decryption to BetterChat module - #6554

Open
Adog64 wants to merge 3 commits into
MeteorDevelopment:masterfrom
Adog64:better-chat-ceasar-cypher
Open

Added Ceasar cypher encryption/decryption to BetterChat module#6554
Adog64 wants to merge 3 commits into
MeteorDevelopment:masterfrom
Adog64:better-chat-ceasar-cypher

Conversation

@Adog64

@Adog64 Adog64 commented Aug 4, 2026

Copy link
Copy Markdown

Type of change

  • Bug fix
  • New feature

Description

Added a simple Ceasar cipher to encrypt and decrypt chat messages. The feature has been added to the BetterChat module. Along with the toggle to enable/disable encryption, there is also an option to set the encryption offset (see Ceasar Cipher on Wikipedia). To avoid weird unicode issues, the cipher only operates on the ASCII characters in the range [32, 126], which includes basically all the characters on an American QWERTY keyboard.

Motivation

With the recent crackdowns on chat regulation on Minecraft servers from Microsoft, certain servers have implemented a chat filter. Chat filters are stupid (both in terms of player freedom and algorithmic complexity). Therefore even a simple cipher like a Ceasar cipher can get around them. I have no doubt that this is a permanent solution, but if this gets patched, I have a few more tricks up my sleeve.

How Has This Been Tested?

Currently, I'm just running ./gradlew runClient and opening a world to LAN for my vanilla client to join. Messages in chat are rendered correctly on the modded instance and show up as garbage in the vanilla instance. Importantly, echoing the same garbage on the vanilla instance, gets decoded on the modded side to produce the original message.

So far I've tested with all the typable characters on my keyboard and checked that unicode characters are unaffected. I've also done testing at different offset amounts (min, max, and in between).

image image

Checklist:

  • My code follows the style guidelines of this project.
  • I have added comments to my code in more complex areas.
  • I have tested the code in both development and production environments.

@Adog64

Adog64 commented Aug 4, 2026

Copy link
Copy Markdown
Author

This is my first PR here, and I'm wondering what you mean by testing code in a production environment. Is that building a jar and using a mod loader or is there some CI/CD task runner that is used or something else? Thank you in advance!

Also, is there any additional housekeeping work that I should do (create and link an issue, write unit tests, etc.)?

@Adog64
Adog64 marked this pull request as ready for review August 4, 2026 07:38
@crosby-moe

Copy link
Copy Markdown
Collaborator

This is my first PR here, and I'm wondering what you mean by testing code in a production environment. Is that building a jar and using a mod loader or is there some CI/CD task runner that is used or something else? Thank you in advance!

testing in a production environment just involves using an actual minecraft launcher rather than fabric loom's runClient task

.build()
);

private final Setting<Integer> cypherOffset = sgFilter.add(new IntSetting.Builder()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private final Setting<Integer> cypherOffset = sgFilter.add(new IntSetting.Builder()
private final Setting<Integer> cypherOffset = sgGeneral.add(new IntSetting.Builder()

Comment thread src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java Outdated
Comment thread src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java Outdated
Comment on lines +578 to +579
StringBuilder modString = new StringBuilder();
int msgStart = message.indexOf("> ") + 2;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
StringBuilder modString = new StringBuilder();
int msgStart = message.indexOf("> ") + 2;
int msgStart = message.indexOf("> ") + 2;
StringBuilder modString = new StringBuilder(msgLen - (msgStart + 2));

needs double check, i mathed in my head

Comment on lines +283 to +285
// Always decrypt messages regardless of whether we are encrypting them
String decryptedMessage = applyDecryption(message.getString());
message = Component.empty().append(decryptedMessage);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure whether always decrypting is the behaviour we want, but regardless the message should only be replaced if the text actually contained a caesar cipher encoded message so that:

  1. we dont allocate a redundant Component
  2. we dont override the styling information held in message unless we actually replace the text it contains

private String applyDecryption(String message) {
int msgLen = message.length();
StringBuilder modString = new StringBuilder();
int msgStart = message.indexOf("> ") + 2;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code incorrectly assumes all incoming chat messages will be decodable, which isn't true (ex. system messages)
specifically, message.indexOf("> ") may return -1 and cause the second character of the message to be read as the cipher's offset which will result in gibberish

additionally, this function should never cause an exception to be thrown otherwise players would be able to remotely crash our users, so please double check everything

Adog64 and others added 2 commits August 4, 2026 17:52
Co-authored-by: Crosby <32882447+crosby-moe@users.noreply.github.com>
Co-authored-by: Crosby <32882447+crosby-moe@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants