feat: customizable console chat format

This commit is contained in:
Chayapak 2025-03-21 10:39:46 +07:00
parent 37d7bbe2a7
commit 6f8fb1d3b6
Signed by: ChomeNS
SSH key fingerprint: SHA256:0YoxhdyXsgbc0nfeB2N6FYE60mxMU7DS4uCUMaw2mvA
5 changed files with 119 additions and 19 deletions
build-number.txt
src/main
java/me/chayapak1/chomens_bot
resources

View file

@ -1 +1 @@
2021
2024

View file

@ -32,6 +32,8 @@ public class Configuration {
public String ownerName = "chayapak"; // mabe mabe
public String consoleChatFormat = "{\"translate\":\"chat.type.text\",\"with\":[\"OWNER_NAME\",\"MESSAGE\"]}";
public ImposterFormatChecker imposterFormatChecker = new ImposterFormatChecker();
public OwnerAuthentication ownerAuthentication = new OwnerAuthentication();

View file

@ -131,7 +131,7 @@ public class Main {
}
// initialize plugins
console = new ConsolePlugin();
console = new ConsolePlugin(config);
LoggerPlugin.init();
if (config.database.enabled) database = new DatabasePlugin(config);
if (config.discord.enabled) discord = new DiscordPlugin(config);

View file

@ -1,27 +1,43 @@
package me.chayapak1.chomens_bot.plugins;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.Configuration;
import me.chayapak1.chomens_bot.Main;
import me.chayapak1.chomens_bot.command.Command;
import me.chayapak1.chomens_bot.command.ConsoleCommandContext;
import me.chayapak1.chomens_bot.util.ColorUtilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.SelectorComponent;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.renderer.TranslatableComponentRenderer;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.jetbrains.annotations.NotNull;
import org.jline.reader.*;
import java.util.List;
import java.util.Map;
public class ConsolePlugin implements Completer {
private static final ConsoleFormatRenderer RENDERER = new ConsoleFormatRenderer();
private static final LegacyComponentSerializer LEGACY = LegacyComponentSerializer.legacyAmpersand();
private final List<Bot> allBots;
public final LineReader reader;
public String consoleServer = "all";
private String prefix;
private final String prefix;
public ConsolePlugin () {
private final Component format;
public ConsolePlugin (Configuration config) {
this.allBots = Main.bots;
this.format = GsonComponentSerializer.gson().deserialize(config.consoleChatFormat);
this.prefix = config.consoleCommandPrefix;
this.reader = LineReaderBuilder
.builder()
.completer(this)
@ -29,11 +45,7 @@ public class ConsolePlugin implements Completer {
reader.option(LineReader.Option.DISABLE_EVENT_EXPANSION, true);
for (Bot bot : allBots) {
prefix = bot.config.consoleCommandPrefix;
bot.console = this;
}
for (Bot bot : allBots) bot.console = this;
final String prompt = "> ";
@ -56,7 +68,7 @@ public class ConsolePlugin implements Completer {
@Override
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
if (!line.line().startsWith(".")) return;
if (!line.line().startsWith(prefix)) return;
final String command = line.line().substring(prefix.length());
@ -93,14 +105,98 @@ public class ConsolePlugin implements Completer {
continue;
}
bot.chat.tellraw(
Component.translatable(
"[%s] %s %s",
Component.text(bot.username + " Console").color(NamedTextColor.GRAY),
Component.text(bot.config.ownerName).color(ColorUtilities.getColorByString(bot.config.colorPalette.ownerName)),
Component.text(line).color(NamedTextColor.GRAY)
).color(NamedTextColor.DARK_GRAY)
final Component stylizedMessage = LEGACY.deserialize(line);
final Component rendered = RENDERER.render(
format,
new ConsoleFormatContext(
bot.profile.getIdAsString(),
stylizedMessage,
Map.of(
"MESSAGE", line,
"USERNAME", bot.profile.getName(),
"OWNER_NAME", bot.config.ownerName
)
)
);
bot.chat.tellraw(rendered);
}
}
// Everything below is from https://code.chipmunk.land/ChomeNS/chipmunkmod/src/branch/1.21.4/src/main/java/land/chipmunk/chipmunkmod/modules/custom_chat
// Thank you, Amy!
private record ConsoleFormatContext (String uuid, Component message, Map<String, String> args) {}
private final static class ConsoleFormatRenderer extends TranslatableComponentRenderer<ConsoleFormatContext> {
@Override
protected @NotNull Component renderSelector (final @NotNull SelectorComponent component,
final @NotNull ConsoleFormatContext context) {
final String pattern = component.pattern();
if (pattern.equals("@s")) {
final SelectorComponent.Builder builder = Component.selector()
.pattern(context.uuid());
return this.mergeStyleAndOptionallyDeepRender(component, builder, context);
}
return super.renderSelector(component, context);
}
@Override
protected @NotNull Component renderText (final @NotNull TextComponent component,
final @NotNull ConsoleFormatContext context) {
final String content = component.content();
if (content.equals("MESSAGE")) {
return this.mergeMessage(component, context.message(), context);
}
final String arg = context.args().get(component.content());
if (arg != null) {
final TextComponent.Builder builder = Component.text()
.content(arg);
return this.mergeStyleAndOptionallyDeepRender(component, builder, context);
}
return super.renderText(component, context);
}
@SuppressWarnings("NonExtendableApiUsage") // Windows XP
@Override
protected <B extends ComponentBuilder<?, ?>> void mergeStyle (final Component component, final B builder,
final ConsoleFormatContext context) {
super.mergeStyle(component, builder, context);
// render clickEvent that may contain something like "MESSAGE"
// HoverEvent already handled by super
builder.clickEvent(this.mergeClickEvent(component.clickEvent(), context));
}
private Component mergeMessage (final Component root, final Component msg, final ConsoleFormatContext context) {
Component result = msg.applyFallbackStyle(root.style()); // applyFallbackStyle will apply everything that isn't content
final ClickEvent clickEvent = result.clickEvent();
if (clickEvent != null) {
result = result.clickEvent(mergeClickEvent(clickEvent, context));
}
final HoverEvent<?> hoverEvent = result.hoverEvent();
if (hoverEvent != null) {
result = result.hoverEvent(hoverEvent.withRenderedValue(this, context));
}
return result;
}
private ClickEvent mergeClickEvent (final ClickEvent clickEvent, final ConsoleFormatContext context) {
if (clickEvent == null) return null;
final String value = clickEvent.value();
final String arg = context.args().get(value);
if (arg == null) return clickEvent;
return ClickEvent.clickEvent(clickEvent.action(), arg);
}
}
}

View file

@ -69,6 +69,8 @@ colorPalette:
# you HAVE TO CHANGE THIS if you are hosting another instance of my bot.
ownerName: 'XxChange_mexX'
consoleChatFormat: '{"translate":"chat.type.text","with":["OWNER_NAME","MESSAGE"]}'
imposterFormatChecker:
enabled: false
key: ''