feat: initial 1.21.5 with adventure still not being updated
This commit is contained in:
parent
ac9c26bcd0
commit
db56afd319
11 changed files with 159 additions and 24 deletions
build.gradle
src/main
java/me/chayapak1/chomens_bot
Configuration.java
data/bossbar
plugins
BossbarManagerPlugin.javaChatPlugin.javaCorePlugin.javaPositionPlugin.javaScreensharePlugin.javaSelfCarePlugin.java
util
resources
|
@ -41,7 +41,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.geysermc.mcprotocollib:protocol:1.21.4-SNAPSHOT'
|
||||
implementation 'org.geysermc.mcprotocollib:protocol:1.21.5-SNAPSHOT'
|
||||
implementation 'net.kyori:adventure-text-serializer-legacy:4.19.0'
|
||||
implementation 'com.google.code.gson:gson:2.12.1'
|
||||
implementation 'com.google.guava:guava:33.4.0-jre'
|
||||
|
|
|
@ -76,7 +76,7 @@ public class Configuration {
|
|||
}
|
||||
|
||||
public static class Core {
|
||||
public String customName = "{\"text\":\"@\"}";
|
||||
public String customName = "{text:'@'}";
|
||||
}
|
||||
|
||||
public static class Position {
|
||||
|
@ -172,6 +172,7 @@ public class Configuration {
|
|||
public boolean useCore = true;
|
||||
public boolean useCorePlaceBlock = false;
|
||||
public boolean useChat = false;
|
||||
public boolean useSNBTComponents = true;
|
||||
public boolean coreCommandSpy = true;
|
||||
public boolean resolveSRV = true;
|
||||
public int reconnectDelay = 2000;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package me.chayapak1.chomens_bot.data.bossbar;
|
||||
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import me.chayapak1.chomens_bot.util.SNBTUtilities;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.BossBarColor;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.BossBarDivision;
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class BotBossBar extends BossBar {
|
|||
|
||||
this.title = title;
|
||||
|
||||
final String serialized = GsonComponentSerializer.gson().serialize(title);
|
||||
final String serialized = SNBTUtilities.fromComponent(bot, title);
|
||||
|
||||
bot.core.run("minecraft:bossbar set " + id + " name " + serialized);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import me.chayapak1.chomens_bot.data.bossbar.BotBossBar;
|
|||
import me.chayapak1.chomens_bot.data.listener.Listener;
|
||||
import me.chayapak1.chomens_bot.data.player.PlayerEntry;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import me.chayapak1.chomens_bot.util.SNBTUtilities;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
|
@ -196,7 +196,7 @@ public class BossbarManagerPlugin implements Listener {
|
|||
|
||||
final Component title = bossBar.secret;
|
||||
|
||||
final String stringTitle = GsonComponentSerializer.gson().serialize(title);
|
||||
final String stringTitle = SNBTUtilities.fromComponent(bot, title);
|
||||
|
||||
bot.core.run("minecraft:bossbar add " + name + " " + stringTitle);
|
||||
|
||||
|
|
|
@ -9,16 +9,12 @@ import me.chayapak1.chomens_bot.data.chat.ChatParser;
|
|||
import me.chayapak1.chomens_bot.data.chat.PlayerMessage;
|
||||
import me.chayapak1.chomens_bot.data.listener.Listener;
|
||||
import me.chayapak1.chomens_bot.data.player.PlayerEntry;
|
||||
import me.chayapak1.chomens_bot.util.ComponentUtilities;
|
||||
import me.chayapak1.chomens_bot.util.IllegalCharactersUtilities;
|
||||
import me.chayapak1.chomens_bot.util.StringUtilities;
|
||||
import me.chayapak1.chomens_bot.util.UUIDUtilities;
|
||||
import me.chayapak1.chomens_bot.util.*;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import net.kyori.adventure.text.renderer.TranslatableComponentRenderer;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
|
@ -300,7 +296,8 @@ public class ChatPlugin implements Listener {
|
|||
0L,
|
||||
null,
|
||||
0,
|
||||
new BitSet()
|
||||
new BitSet(),
|
||||
0
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -359,7 +356,7 @@ public class ChatPlugin implements Listener {
|
|||
final String stringified = ComponentUtilities.stringifySectionSign(component).replace("§", "&");
|
||||
send(stringified);
|
||||
} else {
|
||||
bot.core.run("minecraft:tellraw " + targets + " " + GsonComponentSerializer.gson().serialize(component));
|
||||
bot.core.run("minecraft:tellraw " + targets + " " + SNBTUtilities.fromComponent(bot, component));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,7 +366,7 @@ public class ChatPlugin implements Listener {
|
|||
|
||||
public void actionBar (final Component component, final String targets) {
|
||||
if (bot.options.useChat) return;
|
||||
bot.core.run("minecraft:title " + targets + " actionbar " + GsonComponentSerializer.gson().serialize(component));
|
||||
bot.core.run("minecraft:title " + targets + " actionbar " + SNBTUtilities.fromComponent(bot, component));
|
||||
}
|
||||
|
||||
public void actionBar (final Component component, final UUID uuid) { actionBar(component, UUIDUtilities.selector(uuid)); }
|
||||
|
|
|
@ -541,11 +541,7 @@ public class CorePlugin implements Listener {
|
|||
|
||||
useChat
|
||||
? ""
|
||||
: "{CustomName:'" +
|
||||
bot.config.core.customName
|
||||
.replace("\\", "\\\\")
|
||||
.replace("'", "\\'") +
|
||||
"'}"
|
||||
: "{CustomName:" + bot.config.core.customName + "}"
|
||||
);
|
||||
|
||||
if (useChat) bot.chat.sendCommandInstantly(command);
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.geysermc.mcprotocollib.network.packet.Packet;
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.*;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundAcceptTeleportationPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package me.chayapak1.chomens_bot.plugins;
|
||||
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import me.chayapak1.chomens_bot.util.SNBTUtilities;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
|
||||
import java.awt.*;
|
||||
|
@ -141,7 +141,7 @@ public class ScreensharePlugin {
|
|||
}
|
||||
|
||||
for (int i = 0; i < names.size(); i++) {
|
||||
bot.core.run("minecraft:data merge entity @e[tag=" + tags.get(i) + ",limit=1] {text:'" + GsonComponentSerializer.gson().serialize(names.get(i)) + "'}");
|
||||
bot.core.run("minecraft:data merge entity @e[tag=" + tags.get(i) + ",limit=1] {text:" + SNBTUtilities.fromComponent(bot, names.get(i)) + "}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -159,12 +159,12 @@ public class SelfCarePlugin implements Listener {
|
|||
final GameEvent notification = packet.getNotification();
|
||||
final GameEventValue value = packet.getValue();
|
||||
|
||||
if (notification == GameEvent.ENTER_CREDITS && bot.config.selfCare.endCredits) {
|
||||
if (notification == GameEvent.WIN_GAME && bot.config.selfCare.endCredits) {
|
||||
bot.session.send(new ServerboundClientCommandPacket(ClientCommand.RESPAWN));
|
||||
return;
|
||||
}
|
||||
|
||||
if (notification == GameEvent.CHANGE_GAMEMODE) gamemode = (GameMode) value;
|
||||
if (notification == GameEvent.CHANGE_GAME_MODE) gamemode = (GameMode) value;
|
||||
}
|
||||
|
||||
private void packetReceived (final ClientboundEntityEventPacket packet) {
|
||||
|
|
140
src/main/java/me/chayapak1/chomens_bot/util/SNBTUtilities.java
Normal file
140
src/main/java/me/chayapak1/chomens_bot/util/SNBTUtilities.java
Normal file
|
@ -0,0 +1,140 @@
|
|||
package me.chayapak1.chomens_bot.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
// for 1.21.5 SNBT components, not sure how performant this is
|
||||
// since i'm not good at writing performant code, but this should
|
||||
// reduce the size of the result being sent to the server by quite a bit
|
||||
public class SNBTUtilities {
|
||||
private static final String QUOTE = "'";
|
||||
|
||||
private static final String COMMA = ",";
|
||||
|
||||
private static final String BEGIN_OBJECT = "{";
|
||||
private static final String COLON = ":";
|
||||
private static final String END_OBJECT = "}";
|
||||
|
||||
private static final String BEGIN_ARRAY = "[";
|
||||
private static final String END_ARRAY = "]";
|
||||
|
||||
public static String fromComponent (final Bot bot, final Component component) {
|
||||
if (!bot.options.useSNBTComponents) return GsonComponentSerializer.gson().serialize(component);
|
||||
|
||||
final JsonElement json = GsonComponentSerializer.gson().serializeToTree(component);
|
||||
|
||||
return fromJson(json);
|
||||
}
|
||||
|
||||
// RIPPED from https://minecraft.wiki/w/NBT_format#Conversion_from_JSON
|
||||
public static String fromJson (final JsonElement json) {
|
||||
if (json.isJsonPrimitive()) {
|
||||
final JsonPrimitive primitive = json.getAsJsonPrimitive();
|
||||
|
||||
if (primitive.isString()) return
|
||||
// don't wrap the string with quotes when not needed
|
||||
// like {abc:def} instead of {abc:'def'}
|
||||
needQuotes(primitive.getAsString())
|
||||
? QUOTE + escapeString(primitive.getAsString()) + QUOTE
|
||||
: primitive.getAsString();
|
||||
else if (primitive.isBoolean()) return primitive.getAsBoolean() ? "1b" : "0b";
|
||||
else if (primitive.isNumber()) return String.valueOf(primitive.getAsNumber());
|
||||
} else if (json.isJsonArray()) {
|
||||
final StringBuilder stringBuilder = new StringBuilder(BEGIN_ARRAY);
|
||||
|
||||
boolean notEmpty = false;
|
||||
|
||||
for (final JsonElement element : json.getAsJsonArray()) {
|
||||
notEmpty = true;
|
||||
stringBuilder.append(fromJson(element));
|
||||
stringBuilder.append(COMMA);
|
||||
}
|
||||
|
||||
if (notEmpty) stringBuilder.deleteCharAt(stringBuilder.length() - 1); // removes comma
|
||||
|
||||
stringBuilder.append(END_ARRAY);
|
||||
|
||||
return stringBuilder.toString();
|
||||
} else if (json.isJsonObject()) {
|
||||
final StringBuilder stringBuilder = new StringBuilder(BEGIN_OBJECT);
|
||||
|
||||
boolean notEmpty = false;
|
||||
|
||||
for (final Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||
notEmpty = true;
|
||||
|
||||
// FIXME: only works in 1.21.5 adventure, at the time of writing this,
|
||||
// the 1.21.5 PR is still not merged yet, so i am doing
|
||||
// a lazy fix for the hover event `contents` being replaced with
|
||||
// `value` and the hoverEvent and clickEvent being snake case,
|
||||
// so some things work
|
||||
|
||||
if (entry.getKey().equals("contents")) {
|
||||
stringBuilder.append("value");
|
||||
|
||||
// no click_event replacement yet
|
||||
|
||||
} else {
|
||||
stringBuilder.append(convertCamelCaseToSnake(entry.getKey()));
|
||||
}
|
||||
stringBuilder.append(COLON);
|
||||
stringBuilder.append(fromJson(entry.getValue()));
|
||||
stringBuilder.append(COMMA);
|
||||
}
|
||||
|
||||
if (notEmpty) stringBuilder.deleteCharAt(stringBuilder.length() - 1); // removes comma
|
||||
|
||||
stringBuilder.append(END_OBJECT);
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
return QUOTE + QUOTE;
|
||||
}
|
||||
|
||||
private static String escapeString (final String string) {
|
||||
return string
|
||||
.replace("\\", "\\\\")
|
||||
.replace("'", "\\'")
|
||||
.replace("\n", "\\n")
|
||||
.replace("\r", "\\r")
|
||||
.replace("\t", "\\t")
|
||||
.replace("\b", "\\b")
|
||||
.replace("\f", "\\f");
|
||||
}
|
||||
|
||||
// should this be in StringUtilities?
|
||||
public static boolean needQuotes (final String string) {
|
||||
if (string.isBlank()) return true;
|
||||
for (int i = 0; i < string.length(); i++) {
|
||||
final char c = string.charAt(i);
|
||||
// even though we can do like `abc123.among.us__69` without quotes
|
||||
// i am too lazy to implement that
|
||||
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://www.baeldung.com/java-camel-snake-case-conversion
|
||||
// 3. Manual Approach
|
||||
// FIXME: this is optional after adventure 1.21.5, remove this afterward
|
||||
// it's why this is here instead of in StringUtilities
|
||||
public static String convertCamelCaseToSnake (final String input) {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
for (final char c : input.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
result.append("_").append(Character.toLowerCase(c));
|
||||
} else {
|
||||
result.append(c);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
|
@ -141,6 +141,7 @@ bots:
|
|||
# useCore - if enabled it just sends the command using chat instead of using core. recommended to enable useChat too when this is disabled
|
||||
# useCorePlaceBlock - uses the place block core instead of the main core. only used if useCore is enabled
|
||||
# useChat - when the bot tellraws it will chat instead of using the core to run tellraw
|
||||
# useSNBTComponents - if the server is >=1.21.5, it's pretty likely that you can enable this since 1.21.5 supports SNBT components
|
||||
# coreCommandSpy - set to true if server supports enabling player's commandspy through command block, defaults to true
|
||||
# resolveSRV - whether to resolve SRV records on the server. the notchian minecraft doesn't resolve them
|
||||
# essentialsMessages - the messages in essentials that the bot uses for self care (no example is intentional)
|
||||
|
@ -160,6 +161,7 @@ bots:
|
|||
# useCore: true
|
||||
# useCorePlaceBlock: false
|
||||
# useChat: false
|
||||
# useSNBTComponents: true
|
||||
# coreCommandSpy: true
|
||||
# resolveSRV: true
|
||||
# reconnectDelay: 2000
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue