Add ability to replace legacy color codes - used by EssentialsX Signs when an error occurs (e.g., when you don't have enough to sell).

This commit is contained in:
Mathias Lystbæk 2024-03-10 02:11:55 +01:00
commit a43c19f748
6 changed files with 373 additions and 0 deletions

113
.gitignore vendored Normal file
View File

@ -0,0 +1,113 @@
# User-specific stuff
.idea/
*.iml
*.ipr
*.iws
# IntelliJ
out/
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml
# Common working directory
run/

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# Legacy Chat Fix
This is a simple plugin that aims to fix some of the issues with the legacy chat system in Minecraft. It is designed to be as lightweight as possible, and only fix the issues that are present in the legacy chat system.
Specifically, this plugin fixes the issue that EssentialsX Signs (sell signs in particular) would not be formatted correctly, leaving behind legacy formatting tags in the readable chat.
This plugin listens to system chat, looks for legacy chat formatting codes, and replaces them with the appropriate modern formatting codes, while cleaning up the chat message.

81
pom.xml Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.mathiasl</groupId>
<artifactId>LegacyChatFix</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>LegacyChatFix</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package eu.mathiasl.legacychatfix;
import com.comphenix.protocol.ProtocolLibrary;
import org.bukkit.plugin.java.JavaPlugin;
public final class LegacyChatFix extends JavaPlugin {
LegacyChatFixPacketAdapter adapter;
@Override
public void onEnable() {
// Plugin startup logic
adapter = new LegacyChatFixPacketAdapter(this);
ProtocolLibrary.getProtocolManager().addPacketListener(adapter);
}
@Override
public void onDisable() {
// Plugin shutdown logic
ProtocolLibrary.getProtocolManager().removePacketListener(adapter);
}
}

View File

@ -0,0 +1,143 @@
package eu.mathiasl.legacychatfix;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
public class LegacyChatFixPacketAdapter extends PacketAdapter {
/**
* Legacy color codes to replace.
* TODO: Add support for custom legacy color codes through
* the config file.
*/
private final HashMap<String, String> legacyColors = new HashMap<String, String>() {
{
put("\\<black>", "black");
put("\\<dark_blue>", "dark_blue");
put("\\<dark_green>", "dark_green");
put("\\<dark_aqua>", "dark_aqua");
put("\\<dark_red>", "dark_red");
put("\\<dark_purple>", "dark_purple");
put("\\<gold>", "gold");
put("\\<gray>", "gray");
put("\\<dark_gray>", "dark_gray");
put("\\<blue>", "blue");
put("\\<green>", "green");
put("\\<aqua>", "aqua");
put("\\<red>", "red");
put("\\<light_purple>", "light_purple");
put("\\<yellow>", "yellow");
put("\\<white>", "white");
put("\\<bold>", "bold");
put("\\<strikethrough>", "strikethrough");
put("\\<underline>", "underline");
put("\\<italic>", "italic");
put("\\<magic>", "obfuscated");
put("\\<secondary>", "gray");
}
};
/**
* Set the adapter to listen for packets being sent to the client from "system chat".
* @param plugin A reference to the plugin class responsible for the adapter.
*/
public LegacyChatFixPacketAdapter(Plugin plugin) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.SYSTEM_CHAT);
}
/**
* Listen for packets being sent to the client and replace legacy color codes.
*
* @param event The packet event being sent.
*/
@Override
public void onPacketSending(PacketEvent event) {
// Get the chat components from the packet
StructureModifier<WrappedChatComponent> chatComponents = event.getPacket().getChatComponents();
// If there are no chat components, return
if (chatComponents == null || chatComponents.size() == 0) return;
// Get the chat component
WrappedChatComponent chatComponent = chatComponents.read(0); // Get the chat component
// Convert the chat component to a JSON string
String message = chatComponent.getJson(); // Get the message
// Parse the message (to check if it's a chat component)
BaseComponent[] bungeeComponents;
try {
bungeeComponents = ComponentSerializer.parse(message); // Parse the message (to check if it's a chat component
} catch (Exception e) {
plugin.getLogger().warning("Failed to parse chat component: " + message);
return;
}
// If no bungee components are found after all, return
if (bungeeComponents.length == 0) return;
// Iterate through the bungee components and replace legacy color codes
for (BaseComponent component : bungeeComponents) {
// If the component is not a text component, continue
if (!(component instanceof TextComponent))
continue;
// Replace legacy color codes in the text component
TextComponent textComponent = (TextComponent) component;
replaceLegacyColor(textComponent, legacyColors);
// If the text component has extra components, replace legacy color codes in those as well
for (BaseComponent extra : textComponent.getExtra()) {
if (!(extra instanceof TextComponent))
continue;
TextComponent extraTextComponent = (TextComponent) extra;
replaceLegacyColor(extraTextComponent, legacyColors);
}
}
// Write the modified chat components back to the packet
chatComponents.write(0, WrappedChatComponent.fromJson(ComponentSerializer.toString(bungeeComponents)));
}
/**
* Replaces legacy color code formatting with modern color formatting in
* through the TextComponent and its extra components.
*
* @param textComponent The text component to replace the legacy color codes in.
* @param legacyColors The legacy color codes to replace.
*/
private void replaceLegacyColor(TextComponent textComponent, HashMap<String, String> legacyColors) {
// Get the text from the text component
String text = textComponent.getText();
// Iterate through the legacy color codes and replace them with modern color codes
for (String legacyColor : legacyColors.keySet()) {
// If the text does not contain the legacy color code, continue
if (!text.contains(legacyColor))
continue;
// Replace the legacy color code with an empty string
text = text.replace(legacyColor, "");
// Set the text component's text to the modified text
textComponent.setText(text);
// Set the text component's color to "RESET" initially
ChatColor chatColor = ChatColor.RESET;
try {
// Try to set the text component's color to the modern color code
chatColor = ChatColor.of(legacyColors.get(legacyColor));
} catch (IllegalArgumentException e) {
// If the modern color code is invalid, log a warning
this.getPlugin().getLogger().warning("Invalid color code: " + legacyColors.get(legacyColor));
}
// Set the text component's color to the modern color code
textComponent.setColor(chatColor);
}
}
}

View File

@ -0,0 +1,8 @@
name: LegacyChatFix
version: '${project.version}'
main: eu.mathiasl.legacychatfix.LegacyChatFix
api-version: '1.20'
author: 'Matho97'
description: 'Replaces legacy chat formatting with modern chat formatting.'
load: STARTUP