9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-27 10:59:07 +00:00

Merge pull request #97 from Xiao-MoMi/dev

0.0.46
This commit is contained in:
XiaoMoMi
2025-04-09 02:09:04 +08:00
committed by GitHub
30 changed files with 725 additions and 466 deletions

View File

@@ -8,6 +8,7 @@ repositories {
maven("https://repo.infernalsuite.com/repository/maven-snapshots/") // slime world
maven("https://repo.momirealms.net/releases/")
maven("https://mvn.lumine.io/repository/maven-public/") // model engine
maven("https://nexus.phoenixdevt.fr/repository/maven-public/") // mmoitems
}
dependencies {
@@ -28,6 +29,9 @@ dependencies {
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.8")
// BetterModels
compileOnly("io.github.toxicity188:BetterModel:1.4.2")
// MMOItems
compileOnly("net.Indyuce:MMOItems-API:6.10-SNAPSHOT")
compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT")
}
java {

View File

@@ -0,0 +1,28 @@
package net.momirealms.craftengine.bukkit.compatibility.item;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.momirealms.craftengine.core.item.ExternalItemProvider;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import static java.util.Objects.requireNonNull;
public class MMOItemsProvider implements ExternalItemProvider<ItemStack> {
@Override
public String plugin() {
return "MMOItems";
}
@Override
public @Nullable ItemStack build(String id, ItemBuildContext context) {
String[] split = id.split(":", 2);
MMOItem mmoItem = MMOItems.plugin.getMMOItem(Type.get(split[0]), split[1].toUpperCase(Locale.ENGLISH));
return mmoItem == null ? new ItemStack(Material.AIR) : requireNonNull(mmoItem.newBuilder().build());
}
}

View File

@@ -160,9 +160,10 @@ image:
title: true
bossbar: true
container: true
# TODO: toast: true
# TODO: name: true
# TODO: team: true
team: true
scoreboard: true
entity-name: false
text-display: true
emoji: {}

View File

@@ -25,6 +25,7 @@ snake-yaml=${snake_yaml_version}
adventure-text-minimessage=${adventure_bundle_version}
adventure-text-serializer-gson=${adventure_bundle_version}
adventure-text-serializer-json=${adventure_bundle_version}
adventure-text-serializer-json-legacy-impl=${adventure_bundle_version}
netty-codec-http=${netty_version}
ahocorasick=${ahocorasick_version}
lz4=${lz4_version}

View File

@@ -114,6 +114,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
this.stateId2ImmutableBlockStates = new ImmutableBlockState[customBlockCount];
Arrays.fill(this.stateId2ImmutableBlockStates, EmptyBlock.INSTANCE.defaultState());
instance = this;
this.resetPacketConsumers();
}
public static BukkitBlockManager instance() {

View File

@@ -158,7 +158,7 @@ public class CropBlockBehavior extends BushBlockBehavior {
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags());
if (sendParticles) {
world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 12, 0.25, 0.25, 0.25);
world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 15, 0.25, 0.25, 0.25);
}
}

View File

@@ -120,7 +120,7 @@ public class SaplingBlockBehavior extends BushBlockBehavior {
int x = FastNMS.INSTANCE.field$Vec3i$x(blockPos);
int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos);
int z = FastNMS.INSTANCE.field$Vec3i$z(blockPos);
world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 12, 0.25, 0.25, 0.25);
world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 15, 0.25, 0.25, 0.25);
}
return success;
}

View File

@@ -217,6 +217,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
for (Entity entity : entities) {
if (entity instanceof ItemDisplay display) {
handleBaseEntityLoadEarly(display);
} else if (entity instanceof Shulker shulker) {
handleCollisionEntityLoadOnEntitiesLoad(shulker);
}
}
}
@@ -366,10 +368,19 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
}
public void handleCollisionEntityLoadOnEntitiesLoad(Shulker shulker) {
// remove the shulker if it's on chunk load stage
// faster
if (FastNMS.INSTANCE.method$CraftEntity$getHandle(shulker) instanceof CollisionEntity) {
shulker.remove();
return;
}
// not a collision entity
Byte flag = shulker.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE);
if (flag == null || flag != 1) {
return;
}
shulker.remove();
}
private AnchorType getAnchorType(Entity baseEntity, CustomFurniture furniture) {

View File

@@ -45,6 +45,8 @@ public class FurnitureEventListener implements Listener {
for (Entity entity : entities) {
if (entity instanceof ItemDisplay itemDisplay) {
this.manager.handleBaseEntityLoadEarly(itemDisplay);
} else if (entity instanceof Shulker shulker) {
this.manager.handleCollisionEntityLoadOnEntitiesLoad(shulker);
}
}
}

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.item;
import net.momirealms.craftengine.bukkit.compatibility.item.MMOItemsProvider;
import net.momirealms.craftengine.bukkit.compatibility.item.NeigeItemsProvider;
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
import net.momirealms.craftengine.bukkit.item.behavior.BoneMealItemBehavior;
@@ -89,6 +90,9 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
if (this.plugin.isPluginEnabled("NeigeItems")) {
registerExternalItemProvider(new NeigeItemsProvider());
}
if (this.plugin.isPluginEnabled("MMOItems")) {
registerExternalItemProvider(new MMOItemsProvider());
}
}
@Override

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
@@ -9,7 +8,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Shulker;
import org.bukkit.persistence.PersistentDataType;
import org.incendo.cloud.Command;
import java.util.Collection;

View File

@@ -8,7 +8,8 @@ import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.network.impl.*;
import net.momirealms.craftengine.bukkit.plugin.network.impl.PacketIds1_20;
import net.momirealms.craftengine.bukkit.plugin.network.impl.PacketIds1_20_5;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.plugin.CraftEngine;
@@ -117,14 +118,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
}
private PacketIds setupPacketIds() {
if (VersionHelper.isVersionNewerThan1_21()) {
return new PacketIds1_21();
} else if (VersionHelper.isVersionNewerThan1_20_5()) {
if (VersionHelper.isVersionNewerThan1_20_5()) {
return new PacketIds1_20_5();
} else if (VersionHelper.isVersionNewerThan1_20_3()) {
return new PacketIds1_20_3();
} else if (VersionHelper.isVersionNewerThan1_20_2()) {
return new PacketIds1_20_2();
} else {
return new PacketIds1_20();
}
@@ -141,7 +136,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.LOGIN, Reflections.clazz$ClientboundLoginPacket);
registerNMSPacketConsumer(PacketConsumers.RESPAWN, Reflections.clazz$ClientboundRespawnPacket);
registerNMSPacketConsumer(PacketConsumers.INTERACT_ENTITY, Reflections.clazz$ServerboundInteractPacket);
registerNMSPacketConsumer(PacketConsumers.REMOVE_ENTITY, Reflections.clazz$ClientboundRemoveEntitiesPacket);
registerNMSPacketConsumer(PacketConsumers.SYNC_ENTITY_POSITION, Reflections.clazz$ClientboundEntityPositionSyncPacket);
registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$Pos);
registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, Reflections.clazz$ServerboundPickItemFromEntityPacket);
@@ -150,7 +144,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket);
registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket);
registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, Reflections.clazz$ServerboundCustomPayloadPacket);
// registerNMSPacketConsumer(PacketConsumers.SET_ENTITY_DATA, Reflections.clazz$ClientboundSetEntityDataPacket);
registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket());
@@ -162,10 +155,11 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.BOSS_EVENT_1_20_3 : PacketConsumers.BOSS_EVENT_1_20, this.packetIds.clientboundBossEventPacket());
registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SYSTEM_CHAT_1_20_3 : PacketConsumers.SYSTEM_CHAT_1_20, this.packetIds.clientboundSystemChatPacket());
registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.TAB_LIST_1_20_3 : PacketConsumers.TAB_LIST_1_20, this.packetIds.clientboundTabListPacket());
// registerByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket());
registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.TEAM_1_20_3 : PacketConsumers.TEAM_1_20, this.packetIds.clientboundSetPlayerTeamPacket());
registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket());
registerByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket());
registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket());
// registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket());
// registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket());
}
public static BukkitNetworkManager instance() {

View File

@@ -31,7 +31,6 @@ import net.momirealms.craftengine.core.world.chunk.Palette;
import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
import net.momirealms.craftengine.core.world.chunk.packet.MCSection;
import net.momirealms.sparrow.nbt.Tag;
import net.momirealms.sparrow.nbt.serializer.NBTComponentSerializer;
import org.bukkit.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
@@ -242,6 +241,184 @@ public class PacketConsumers {
}
};
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> SOUND = (user, event, packet) -> {
try {
Object soundEvent = FastNMS.INSTANCE.field$ClientboundSoundPacket$soundEvent(packet);
Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(soundEvent).toString());
Key mapped = BukkitBlockManager.instance().replaceSoundIfExist(soundId);
if (mapped != null) {
event.setCancelled(true);
Object newId = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath(mapped.namespace(), mapped.value());
Object newSoundEvent = VersionHelper.isVersionNewerThan1_21_2() ?
Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$fixedRange.get(soundEvent)) :
Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$range.get(soundEvent), Reflections.field$SoundEvent$newSystem.get(soundEvent));
Object newSoundPacket = FastNMS.INSTANCE.fastConstructor$ClientboundSoundPacket(newSoundEvent, packet);
user.sendPacket(newSoundPacket, true);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSoundPacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> TEAM_1_20_3 = (user, event) -> {
if (!Config.interceptTeam()) return;
try {
FriendlyByteBuf buf = event.getBuffer();
String name = buf.readUtf();
byte method = buf.readByte();
if (method != 2 && method != 0) {
return;
}
Tag displayName = buf.readNbt(false);
if (displayName == null) return;
byte friendlyFlags = buf.readByte();
String nameTagVisibility = buf.readUtf(40);
String collisionRule = buf.readUtf(40);
int color = buf.readVarInt();
Tag prefix = buf.readNbt(false);
if (prefix == null) return;
Tag suffix = buf.readNbt(false);
if (suffix == null) return;
Map<String, String> tokens1 = CraftEngine.instance().imageManager().matchTags(displayName.getAsString());
Map<String, String> tokens2 = CraftEngine.instance().imageManager().matchTags(prefix.getAsString());
Map<String, String> tokens3 = CraftEngine.instance().imageManager().matchTags(suffix.getAsString());
if (tokens1.isEmpty() && tokens2.isEmpty() && tokens3.isEmpty()) return;
event.setChanged(true);
List<String> entities;
if (method == 0) {
entities = buf.readStringList();
} else {
entities = null;
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(name);
buf.writeByte(method);
if (!tokens1.isEmpty()) {
Component component = AdventureHelper.tagToComponent(displayName);
for (Map.Entry<String, String> token : tokens1.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(displayName, false);
}
buf.writeByte(friendlyFlags);
buf.writeUtf(nameTagVisibility);
buf.writeUtf(collisionRule);
buf.writeVarInt(color);
if (!tokens2.isEmpty()) {
Component component = AdventureHelper.tagToComponent(prefix);
for (Map.Entry<String, String> token : tokens2.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(prefix, false);
}
if (!tokens3.isEmpty()) {
Component component = AdventureHelper.tagToComponent(suffix);
for (Map.Entry<String, String> token : tokens3.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(suffix, false);
}
if (entities != null) {
buf.writeStringList(entities);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetPlayerTeamPacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> TEAM_1_20 = (user, event) -> {
if (!Config.interceptTeam()) return;
try {
FriendlyByteBuf buf = event.getBuffer();
String name = buf.readUtf();
byte method = buf.readByte();
if (method != 2 && method != 0) {
return;
}
String displayName = buf.readUtf();
byte friendlyFlags = buf.readByte();
String nameTagVisibility = buf.readUtf(40);
String collisionRule = buf.readUtf(40);
int color = buf.readVarInt();
String prefix = buf.readUtf();
String suffix = buf.readUtf();
Map<String, String> tokens1 = CraftEngine.instance().imageManager().matchTags(displayName);
Map<String, String> tokens2 = CraftEngine.instance().imageManager().matchTags(prefix);
Map<String, String> tokens3 = CraftEngine.instance().imageManager().matchTags(suffix);
if (tokens1.isEmpty() && tokens2.isEmpty() && tokens3.isEmpty()) return;
event.setChanged(true);
List<String> entities;
if (method == 0) {
entities = buf.readStringList();
} else {
entities = null;
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(name);
buf.writeByte(method);
if (!tokens1.isEmpty()) {
Component component = AdventureHelper.jsonToComponent(displayName);
for (Map.Entry<String, String> token : tokens1.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeUtf(AdventureHelper.componentToJson(component));
} else {
buf.writeUtf(displayName);
}
buf.writeByte(friendlyFlags);
buf.writeUtf(nameTagVisibility);
buf.writeUtf(collisionRule);
buf.writeVarInt(color);
if (!tokens2.isEmpty()) {
Component component = AdventureHelper.jsonToComponent(prefix);
for (Map.Entry<String, String> token : tokens2.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeUtf(AdventureHelper.componentToJson(component));
} else {
buf.writeUtf(prefix);
}
if (!tokens3.isEmpty()) {
Component component = AdventureHelper.jsonToComponent(suffix);
for (Map.Entry<String, String> token : tokens3.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeUtf(AdventureHelper.componentToJson(component));
} else {
buf.writeUtf(suffix);
}
if (entities != null) {
buf.writeStringList(entities);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetPlayerTeamPacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> BOSS_EVENT_1_20 = (user, event) -> {
if (!Config.interceptBossBar()) return;
try {
@@ -301,7 +478,7 @@ public class PacketConsumers {
if (nbt == null) return;
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString());
if (tokens.isEmpty()) return;
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
@@ -314,7 +491,7 @@ public class PacketConsumers {
buf.writeVarInt(event.packetID());
buf.writeUUID(uuid);
buf.writeVarInt(actionType);
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
buf.writeFloat(health);
buf.writeVarInt(color);
buf.writeVarInt(division);
@@ -325,7 +502,7 @@ public class PacketConsumers {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString());
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
@@ -333,23 +510,151 @@ public class PacketConsumers {
buf.writeVarInt(event.packetID());
buf.writeUUID(uuid);
buf.writeVarInt(actionType);
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundBossEventPacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SET_OBJECTIVE_1_20 = (user, event) -> {
if (!Config.interceptScoreboard()) return;
try {
FriendlyByteBuf buf = event.getBuffer();
String objective = buf.readUtf();
byte mode = buf.readByte();
if (mode != 0 && mode != 2) return;
String displayName = buf.readUtf();
int renderType = buf.readVarInt();
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(displayName);
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = AdventureHelper.jsonToComponent(displayName);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(objective);
buf.writeByte(mode);
buf.writeUtf(AdventureHelper.componentToJson(component));
buf.writeVarInt(renderType);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetObjectivePacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SET_OBJECTIVE_1_20_3 = (user, event) -> {
if (!Config.interceptScoreboard()) return;
try {
FriendlyByteBuf buf = event.getBuffer();
String objective = buf.readUtf();
byte mode = buf.readByte();
if (mode != 0 && mode != 2) return;
Tag displayName = buf.readNbt(false);
if (displayName == null) return;
int renderType = buf.readVarInt();
boolean optionalNumberFormat = buf.readBoolean();
if (optionalNumberFormat) {
int format = buf.readVarInt();
if (format == 0) {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString());
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = AdventureHelper.tagToComponent(displayName);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(objective);
buf.writeByte(mode);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
buf.writeVarInt(renderType);
buf.writeBoolean(true);
buf.writeVarInt(0);
} else if (format == 1) {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString());
if (tokens.isEmpty()) return;
Tag style = buf.readNbt(false);
event.setChanged(true);
Component component = AdventureHelper.tagToComponent(displayName);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(objective);
buf.writeByte(mode);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
buf.writeVarInt(renderType);
buf.writeBoolean(true);
buf.writeVarInt(1);
buf.writeNbt(style, false);
} else if (format == 2) {
Tag fixed = buf.readNbt(false);
if (fixed == null) return;
Map<String, String> tokens1 = CraftEngine.instance().imageManager().matchTags(displayName.getAsString());
Map<String, String> tokens2 = CraftEngine.instance().imageManager().matchTags(fixed.getAsString());
if (tokens1.isEmpty() && tokens2.isEmpty()) return;
event.setChanged(true);
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(objective);
buf.writeByte(mode);
if (!tokens1.isEmpty()) {
Component component = AdventureHelper.tagToComponent(displayName);
for (Map.Entry<String, String> token : tokens1.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(displayName, false);
}
buf.writeVarInt(renderType);
buf.writeBoolean(true);
buf.writeVarInt(2);
if (!tokens2.isEmpty()) {
Component component = AdventureHelper.tagToComponent(fixed);
for (Map.Entry<String, String> token : tokens2.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(fixed, false);
}
}
} else {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString());
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = AdventureHelper.tagToComponent(displayName);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeUtf(objective);
buf.writeByte(mode);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
buf.writeVarInt(renderType);
buf.writeBoolean(false);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetObjectivePacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SYSTEM_CHAT_1_20 = (user, event) -> {
if (!Config.interceptSystemChat()) return;
try {
FriendlyByteBuf buf = event.getBuffer();
String json = buf.readUtf();
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(json);
String jsonOrPlainString = buf.readUtf();
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(jsonOrPlainString);
if (tokens.isEmpty()) return;
boolean overlay = buf.readBoolean();
event.setChanged(true);
Component component = AdventureHelper.jsonToComponent(json);
Component component = AdventureHelper.jsonToComponent(jsonOrPlainString);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
@@ -372,13 +677,13 @@ public class PacketConsumers {
if (tokens.isEmpty()) return;
boolean overlay = buf.readBoolean();
event.setChanged(true);
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
buf.writeBoolean(overlay);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSystemChatPacket", e);
@@ -414,13 +719,13 @@ public class PacketConsumers {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString());
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetSubtitleTextPacket", e);
}
@@ -455,13 +760,13 @@ public class PacketConsumers {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString());
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetTitleTextPacket", e);
}
@@ -496,13 +801,13 @@ public class PacketConsumers {
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString());
if (tokens.isEmpty()) return;
event.setChanged(true);
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetActionBarTextPacket", e);
}
@@ -558,20 +863,20 @@ public class PacketConsumers {
buf.clear();
buf.writeVarInt(event.packetID());
if (!tokens1.isEmpty()) {
Component component = NBTComponentSerializer.nbt().deserialize(nbt1);
Component component = AdventureHelper.tagToComponent(nbt1);
for (Map.Entry<String, String> token : tokens1.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(nbt1, false);
}
if (!tokens2.isEmpty()) {
Component component = NBTComponentSerializer.nbt().deserialize(nbt2);
Component component = AdventureHelper.tagToComponent(nbt2);
for (Map.Entry<String, String> token : tokens2.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} else {
buf.writeNbt(nbt2, false);
}
@@ -614,7 +919,7 @@ public class PacketConsumers {
if (nbt == null) return;
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString());
if (tokens.isEmpty()) return;
Component component = NBTComponentSerializer.nbt().deserialize(nbt);
Component component = AdventureHelper.tagToComponent(nbt);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
@@ -622,7 +927,7 @@ public class PacketConsumers {
buf.writeVarInt(event.packetID());
buf.writeVarInt(containerId);
buf.writeVarInt(type);
buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false);
buf.writeNbt(AdventureHelper.componentToTag(component), false);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundOpenScreenPacket", e);
}
@@ -1039,6 +1344,8 @@ public class PacketConsumers {
}
} else if (type == Reflections.instance$EntityType$BLOCK_DISPLAY$registryId) {
user.entityView().put(id, Reflections.instance$EntityType$BLOCK_DISPLAY);
} else if (type == Reflections.instance$EntityType$TEXT_DISPLAY$registryId) {
user.entityView().put(id, Reflections.instance$EntityType$TEXT_DISPLAY);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundAddEntityPacket", e);
@@ -1095,17 +1402,27 @@ public class PacketConsumers {
}
};
// TODO USE bytebuffer
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> REMOVE_ENTITY = (user, event, packet) -> {
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> REMOVE_ENTITY = (user, event) -> {
try {
IntList intList = FastNMS.INSTANCE.field$ClientboundRemoveEntitiesPacket$entityIds(packet);
FriendlyByteBuf buf = event.getBuffer();
boolean isChange = false;
IntList intList = buf.readIntIdList();
for (int i = 0, size = intList.size(); i < size; i++) {
List<Integer> entities = user.furnitureView().remove(intList.getInt(i));
int entityId = intList.getInt(i);
user.entityView().remove(entityId);
List<Integer> entities = user.furnitureView().remove(entityId);
if (entities == null) continue;
for (int entityId : entities) {
intList.add(entityId);
for (int subEntityId : entities) {
isChange = true;
intList.add(subEntityId);
}
}
if (isChange) {
event.setChanged(true);
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeIntIdList(intList);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundRemoveEntitiesPacket", e);
}
@@ -1169,32 +1486,12 @@ public class PacketConsumers {
}
});
}
}, player.getWorld(), location.getBlockX() >> 4,location.getBlockZ() >> 4);
}, player.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundInteractPacket", e);
}
};
// TODO USE bytebuffer
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> SOUND = (user, event, packet) -> {
try {
Object soundEvent = FastNMS.INSTANCE.field$ClientboundSoundPacket$soundEvent(packet);
Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(soundEvent).toString());
Key mapped = BukkitBlockManager.instance().replaceSoundIfExist(soundId);
if (mapped != null) {
event.setCancelled(true);
Object newId = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath(mapped.namespace(), mapped.value());
Object newSoundEvent = VersionHelper.isVersionNewerThan1_21_2() ?
Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$fixedRange.get(soundEvent)) :
Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$range.get(soundEvent), Reflections.field$SoundEvent$newSystem.get(soundEvent));
Object newSoundPacket = FastNMS.INSTANCE.fastConstructor$ClientboundSoundPacket(newSoundEvent, packet);
user.sendPacket(newSoundPacket, true);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSoundPacket", e);
}
};
// we handle it on packet level to prevent it from being captured by plugins
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> RENAME_ITEM = (user, event, packet) -> {
try {
@@ -1387,90 +1684,117 @@ public class PacketConsumers {
}
};
// TODO 需要修复
// @SuppressWarnings("unchecked")
// public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SET_ENTITY_DATA = (user, event) -> {
// try {
// FriendlyByteBuf buf = event.getBuffer();
// int id = buf.readVarInt();
// Object entityType = user.entityView().get(id);
// if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) {
// Object registryFriendlyByteBuf = FastNMS.INSTANCE.constructor$RegistryFriendlyByteBuf(buf, Reflections.instance$registryAccess);
// boolean isChanged = false;
// List<Object> packedItems = (List<Object>) Reflections.method$ClientboundSetEntityDataPacket$unpack.invoke(null, registryFriendlyByteBuf);
// for (int i = 0; i < packedItems.size(); i++) {
// Object packedItem = packedItems.get(i);
// int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
// if (entityDataId != EntityDataUtils.BLOCK_STATE_DATA_ID) {
// continue;
// }
// Object blockState = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
// int stateId = BlockStateUtils.blockStateToId(blockState);
// int newStateId;
// if (!user.clientModEnabled()) {
// newStateId = remap(stateId);
// } else {
// newStateId = remapMOD(stateId);
// }
// Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
// packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(
// entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId)
// ));
// isChanged = true;
// break;
// }
// if (isChanged) {
// System.out.println("Changed");
// event.setChanged(true);
// buf.clear();
// buf.writeVarInt(event.packetID());
// Reflections.method$ClientboundSetEntityDataPacket$pack.invoke(null, packedItems, registryFriendlyByteBuf);
// }
// }
// } catch (Exception e) {
// CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e);
// }
// };
// 之前的旧东西经供参考需要改成使用bytebuffer的
// public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> SET_ENTITY_DATA = (user, event, packet) -> {
// try {
// int id = FastNMS.INSTANCE.field$ClientboundSetEntityDataPacket$id(packet);
// Object entityType = user.entityView().get(id);
// if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) {
// List<Object> packedItems = FastNMS.INSTANCE.field$ClientboundSetEntityDataPacket$packedItems(packet);
// for (int i = 0; i < packedItems.size(); i++) {
// Object packedItem = packedItems.get(i);
// int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
// if (entityDataId != EntityDataUtils.BLOCK_STATE_DATA_ID) {
// continue;
// }
// Object blockState = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
// int stateId = BlockStateUtils.blockStateToId(blockState);
// int newStateId;
// if (!user.clientModEnabled()) {
// newStateId = remap(stateId);
// } else {
// newStateId = remapMOD(stateId);
// }
// Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
// packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(
// entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId)
// ));
// break;
// }
// }
// } catch (Exception e) {
// CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e);
// }
// };
// public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> OPEN_SCREEN = (user, event, packet) -> {
// try {
//
// } catch (Exception e) {
// CraftEngine.instance().logger().warn("Failed to handle ClientboundOpenScreenPacket", e);
// }
// };
@SuppressWarnings("unchecked")
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SET_ENTITY_DATA = (user, event) -> {
try {
FriendlyByteBuf buf = event.getBuffer();
int id = buf.readVarInt();
Object entityType = user.entityView().get(id);
if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) {
boolean isChanged = false;
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
for (int i = 0; i < packedItems.size(); i++) {
Object packedItem = packedItems.get(i);
int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
if (entityDataId == EntityDataUtils.BLOCK_STATE_DATA_ID) {
Object blockState = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
int stateId = BlockStateUtils.blockStateToId(blockState);
int newStateId;
if (!user.clientModEnabled()) {
newStateId = remap(stateId);
} else {
newStateId = remapMOD(stateId);
}
Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(
entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId)
));
isChanged = true;
} else if (Config.interceptEntityName() && entityDataId == EntityDataUtils.CUSTOM_NAME_DATA_ID) {
Optional<Object> optionalTextComponent = (Optional<Object>) FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
if (optionalTextComponent.isPresent()) {
Object textComponent = optionalTextComponent.get();
String json = ComponentUtils.minecraftToJson(textComponent);
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(json);
if (!tokens.isEmpty()) {
Component component = AdventureHelper.jsonToComponent(json);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(
entityDataId, serializer, Optional.of(ComponentUtils.adventureToMinecraft(component))
));
isChanged = true;
}
}
}
}
if (isChanged) {
event.setChanged(true);
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeVarInt(id);
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
}
} else if (Config.interceptEntityName()) {
boolean isChanged = false;
List<Object> packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf);
if (entityType == Reflections.instance$EntityType$TEXT_DISPLAY) {
for (int i = 0; i < packedItems.size(); i++) {
Object packedItem = packedItems.get(i);
int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
if (entityDataId == EntityDataUtils.TEXT_DATA_ID) {
Object textComponent = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
if (textComponent == Reflections.instance$Component$empty) break;
String json = ComponentUtils.minecraftToJson(textComponent);
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(json);
if (!tokens.isEmpty()) {
Component component = AdventureHelper.jsonToComponent(json);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, ComponentUtils.adventureToMinecraft(component)));
isChanged = true;
break;
}
}
}
} else {
for (int i = 0; i < packedItems.size(); i++) {
Object packedItem = packedItems.get(i);
int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
if (entityDataId == EntityDataUtils.CUSTOM_NAME_DATA_ID) {
Optional<Object> optionalTextComponent = (Optional<Object>) FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
if (optionalTextComponent.isPresent()) {
Object textComponent = optionalTextComponent.get();
String json = ComponentUtils.minecraftToJson(textComponent);
Map<String, String> tokens = CraftEngine.instance().imageManager().matchTags(json);
if (!tokens.isEmpty()) {
Component component = AdventureHelper.jsonToComponent(json);
for (Map.Entry<String, String> token : tokens.entrySet()) {
component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue())));
}
Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem);
packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, Optional.of(ComponentUtils.adventureToMinecraft(component))));
isChanged = true;
break;
}
}
}
}
}
if (isChanged) {
event.setChanged(true);
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeVarInt(id);
FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf);
}
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e);
}
};
}

View File

@@ -31,4 +31,8 @@ public interface PacketIds {
int clientboundSystemChatPacket();
int clientboundTabListPacket();
int clientboundSetPlayerTeamPacket();
int clientboundSetObjectivePacket();
}

View File

@@ -1,26 +1,35 @@
package net.momirealms.craftengine.bukkit.plugin.network.impl;
import com.google.gson.JsonElement;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.VersionHelper;
import java.util.HashMap;
import java.util.Map;
public class PacketIdFinder {
private static final Map<String, Map<String, Integer>> gamePacketIds = new HashMap<>();
private static final Map<String, Map<String, Integer>> gamePacketIdsByName = new HashMap<>();
private static final Map<String, Map<Class<?>, Integer>> gamePacketIdsByClazz = new HashMap<>();
static {
try {
Object packetReport = Reflections.constructor$PacketReport.newInstance((Object) null);
JsonElement jsonElement = (JsonElement) Reflections.method$PacketReport$serializePackets.invoke(packetReport);
var play = jsonElement.getAsJsonObject().get("play");
for (var entry : play.getAsJsonObject().entrySet()) {
Map<String, Integer> ids = new HashMap<>();
gamePacketIds.put(entry.getKey(), ids);
for (var entry2 : entry.getValue().getAsJsonObject().entrySet()) {
ids.put(entry2.getKey(), entry2.getValue().getAsJsonObject().get("protocol_id").getAsInt());
if (VersionHelper.isVersionNewerThan1_21()) {
Object packetReport = Reflections.constructor$PacketReport.newInstance((Object) null);
JsonElement jsonElement = (JsonElement) Reflections.method$PacketReport$serializePackets.invoke(packetReport);
var play = jsonElement.getAsJsonObject().get("play");
for (var entry : play.getAsJsonObject().entrySet()) {
Map<String, Integer> ids = new HashMap<>();
gamePacketIdsByName.put(entry.getKey(), ids);
for (var entry2 : entry.getValue().getAsJsonObject().entrySet()) {
ids.put(entry2.getKey(), entry2.getValue().getAsJsonObject().get("protocol_id").getAsInt());
}
}
} else if (VersionHelper.isVersionNewerThan1_20_5()) {
gamePacketIdsByName.putAll(FastNMS.INSTANCE.method$getGamePacketIdsByName());
} else {
gamePacketIdsByClazz.putAll(FastNMS.INSTANCE.method$getGamePacketIdsByClazz());
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to get packets", e);
@@ -28,6 +37,10 @@ public class PacketIdFinder {
}
public static int clientboundByName(String packetName) {
return gamePacketIds.get("clientbound").getOrDefault(packetName, -1);
return gamePacketIdsByName.get("clientbound").getOrDefault(packetName, -1);
}
public static int clientboundByClazz(Class<?> clazz) {
return gamePacketIdsByClazz.get("clientbound").getOrDefault(clazz, -1);
}
}

View File

@@ -1,81 +1,92 @@
package net.momirealms.craftengine.bukkit.plugin.network.impl;
import net.momirealms.craftengine.bukkit.plugin.network.PacketIds;
import net.momirealms.craftengine.bukkit.util.Reflections;
public class PacketIds1_20 implements PacketIds {
@Override
public int clientboundBlockUpdatePacket() {
return 10;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundBlockUpdatePacket);
}
@Override
public int clientboundSectionBlocksUpdatePacket() {
return 67;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSectionBlocksUpdatePacket);
}
@Override
public int clientboundLevelParticlesPacket() {
return 38;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundLevelParticlesPacket);
}
@Override
public int clientboundLevelEventPacket() {
return 37;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundLevelEventPacket);
}
@Override
public int clientboundAddEntityPacket() {
return 1;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundAddEntityPacket);
}
@Override
public int clientboundOpenScreenPacket() {
return 48;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundOpenScreenPacket);
}
@Override
public int clientboundSoundPacket() {
return 98;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSoundPacket);
}
@Override
public int clientboundRemoveEntitiesPacket() {
return 62;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundRemoveEntitiesPacket);
}
@Override
public int clientboundSetEntityDataPacket() {
return 82;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetEntityDataPacket);
}
@Override
public int clientboundSetTitleTextPacket() {
return 95;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetTitleTextPacket);
}
@Override
public int clientboundSetSubtitleTextPacket() {
return 93;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetSubtitleTextPacket);
}
@Override
public int clientboundSetActionBarTextPacket() {
return 70;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetActionBarTextPacket);
}
@Override
public int clientboundBossEventPacket() {
return 11;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundBossEventPacket);
}
@Override
public int clientboundSystemChatPacket() {
return 100;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSystemChatPacket);
}
@Override
public int clientboundTabListPacket() {
return 101;
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundTabListPacket);
}
@Override
public int clientboundSetPlayerTeamPacket() {
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetPlayerTeamPacket);
}
@Override
public int clientboundSetObjectivePacket() {
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetObjectivePacket);
}
}

View File

@@ -1,81 +0,0 @@
package net.momirealms.craftengine.bukkit.plugin.network.impl;
import net.momirealms.craftengine.bukkit.plugin.network.PacketIds;
public class PacketIds1_20_2 implements PacketIds {
@Override
public int clientboundBlockUpdatePacket() {
return 9;
}
@Override
public int clientboundSectionBlocksUpdatePacket() {
return 69;
}
@Override
public int clientboundLevelParticlesPacket() {
return 39;
}
@Override
public int clientboundLevelEventPacket() {
return 38;
}
@Override
public int clientboundAddEntityPacket() {
return 1;
}
@Override
public int clientboundOpenScreenPacket() {
return 49;
}
@Override
public int clientboundSoundPacket() {
return 100;
}
@Override
public int clientboundRemoveEntitiesPacket() {
return 64;
}
@Override
public int clientboundSetEntityDataPacket() {
return 84;
}
@Override
public int clientboundSetTitleTextPacket() {
return 97;
}
@Override
public int clientboundSetSubtitleTextPacket() {
return 95;
}
@Override
public int clientboundSetActionBarTextPacket() {
return 72;
}
@Override
public int clientboundBossEventPacket() {
return 10;
}
@Override
public int clientboundSystemChatPacket() {
return 103;
}
@Override
public int clientboundTabListPacket() {
return 104;
}
}

View File

@@ -1,81 +0,0 @@
package net.momirealms.craftengine.bukkit.plugin.network.impl;
import net.momirealms.craftengine.bukkit.plugin.network.PacketIds;
public class PacketIds1_20_3 implements PacketIds {
@Override
public int clientboundBlockUpdatePacket() {
return 9;
}
@Override
public int clientboundSectionBlocksUpdatePacket() {
return 71;
}
@Override
public int clientboundLevelParticlesPacket() {
return 39;
}
@Override
public int clientboundLevelEventPacket() {
return 38;
}
@Override
public int clientboundAddEntityPacket() {
return 1;
}
@Override
public int clientboundOpenScreenPacket() {
return 49;
}
@Override
public int clientboundSoundPacket() {
return 102;
}
@Override
public int clientboundRemoveEntitiesPacket() {
return 64;
}
@Override
public int clientboundSetEntityDataPacket() {
return 86;
}
@Override
public int clientboundSetTitleTextPacket() {
return 99;
}
@Override
public int clientboundSetSubtitleTextPacket() {
return 97;
}
@Override
public int clientboundSetActionBarTextPacket() {
return 74;
}
@Override
public int clientboundBossEventPacket() {
return 10;
}
@Override
public int clientboundSystemChatPacket() {
return 105;
}
@Override
public int clientboundTabListPacket() {
return 106;
}
}

View File

@@ -6,76 +6,86 @@ public class PacketIds1_20_5 implements PacketIds {
@Override
public int clientboundBlockUpdatePacket() {
return 9;
return PacketIdFinder.clientboundByName("minecraft:block_update");
}
@Override
public int clientboundSectionBlocksUpdatePacket() {
return 73;
return PacketIdFinder.clientboundByName("minecraft:section_blocks_update");
}
@Override
public int clientboundLevelParticlesPacket() {
return 41;
return PacketIdFinder.clientboundByName("minecraft:level_particles");
}
@Override
public int clientboundLevelEventPacket() {
return 40;
return PacketIdFinder.clientboundByName("minecraft:level_event");
}
@Override
public int clientboundAddEntityPacket() {
return 1;
return PacketIdFinder.clientboundByName("minecraft:add_entity");
}
@Override
public int clientboundOpenScreenPacket() {
return 51;
return PacketIdFinder.clientboundByName("minecraft:open_screen");
}
@Override
public int clientboundSoundPacket() {
return 104;
return PacketIdFinder.clientboundByName("minecraft:sound");
}
@Override
public int clientboundRemoveEntitiesPacket() {
return 66;
return PacketIdFinder.clientboundByName("minecraft:remove_entities");
}
@Override
public int clientboundSetEntityDataPacket() {
return 88;
return PacketIdFinder.clientboundByName("minecraft:set_entity_data");
}
@Override
public int clientboundSetTitleTextPacket() {
return 101;
return PacketIdFinder.clientboundByName("minecraft:set_title_text");
}
@Override
public int clientboundSetSubtitleTextPacket() {
return 99;
return PacketIdFinder.clientboundByName("minecraft:set_subtitle_text");
}
@Override
public int clientboundSetActionBarTextPacket() {
return 76;
return PacketIdFinder.clientboundByName("minecraft:set_action_bar_text");
}
@Override
public int clientboundBossEventPacket() {
return 10;
return PacketIdFinder.clientboundByName("minecraft:boss_event");
}
@Override
public int clientboundSystemChatPacket() {
return 108;
return PacketIdFinder.clientboundByName("minecraft:system_chat");
}
@Override
public int clientboundTabListPacket() {
return 109;
return PacketIdFinder.clientboundByName("minecraft:tab_list");
}
@Override
public int clientboundSetPlayerTeamPacket() {
return PacketIdFinder.clientboundByName("minecraft:set_player_team");
}
@Override
public int clientboundSetObjectivePacket() {
return PacketIdFinder.clientboundByName("minecraft:set_objective");
}
}

View File

@@ -1,81 +0,0 @@
package net.momirealms.craftengine.bukkit.plugin.network.impl;
import net.momirealms.craftengine.bukkit.plugin.network.PacketIds;
public class PacketIds1_21 implements PacketIds {
@Override
public int clientboundBlockUpdatePacket() {
return PacketIdFinder.clientboundByName("minecraft:block_update");
}
@Override
public int clientboundSectionBlocksUpdatePacket() {
return PacketIdFinder.clientboundByName("minecraft:section_blocks_update");
}
@Override
public int clientboundLevelParticlesPacket() {
return PacketIdFinder.clientboundByName("minecraft:level_particles");
}
@Override
public int clientboundLevelEventPacket() {
return PacketIdFinder.clientboundByName("minecraft:level_event");
}
@Override
public int clientboundAddEntityPacket() {
return PacketIdFinder.clientboundByName("minecraft:add_entity");
}
@Override
public int clientboundOpenScreenPacket() {
return PacketIdFinder.clientboundByName("minecraft:open_screen");
}
@Override
public int clientboundSoundPacket() {
return PacketIdFinder.clientboundByName("minecraft:sound");
}
@Override
public int clientboundRemoveEntitiesPacket() {
return PacketIdFinder.clientboundByName("minecraft:remove_entities");
}
@Override
public int clientboundSetEntityDataPacket() {
return PacketIdFinder.clientboundByName("minecraft:set_entity_data");
}
@Override
public int clientboundSetTitleTextPacket() {
return PacketIdFinder.clientboundByName("minecraft:set_title_text");
}
@Override
public int clientboundSetSubtitleTextPacket() {
return PacketIdFinder.clientboundByName("minecraft:set_subtitle_text");
}
@Override
public int clientboundSetActionBarTextPacket() {
return PacketIdFinder.clientboundByName("minecraft:set_action_bar_text");
}
@Override
public int clientboundBossEventPacket() {
return PacketIdFinder.clientboundByName("minecraft:boss_event");
}
@Override
public int clientboundSystemChatPacket() {
return PacketIdFinder.clientboundByName("minecraft:system_chat");
}
@Override
public int clientboundTabListPacket() {
return PacketIdFinder.clientboundByName("minecraft:tab_list");
}
}

View File

@@ -12,6 +12,8 @@ public class EntityDataUtils {
private static final int LEFT_ALIGNMENT = 0x08; // 8
private static final int RIGHT_ALIGNMENT = 0x10; // 16
public static final int BLOCK_STATE_DATA_ID = VersionHelper.isVersionNewerThan1_20_2() ? 23 : 22;
public static final int TEXT_DATA_ID = VersionHelper.isVersionNewerThan1_20_2() ? 23 : 22;
public static final int CUSTOM_NAME_DATA_ID = 2;
public static byte encodeTextDisplayMask(boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackground, int alignment) {
int bitMask = 0;

View File

@@ -3335,8 +3335,8 @@ public class Reflections {
instance$ItemStack$EMPTY = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ItemStack, clazz$ItemStack, 0
).get(null)
);
)
).get(null);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
@@ -6270,27 +6270,42 @@ public class Reflections {
);
public static final int instance$EntityType$BLOCK_DISPLAY$registryId;
public static final int instance$EntityType$TEXT_DISPLAY$registryId;
public static final int instance$EntityType$FALLING_BLOCK$registryId;
static {
try {
instance$EntityType$BLOCK_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$BLOCK_DISPLAY);
instance$EntityType$TEXT_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$TEXT_DISPLAY);
instance$EntityType$FALLING_BLOCK$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$FALLING_BLOCK);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 先注释后面再说
// public static final Method method$ClientboundSetEntityDataPacket$pack = requireNonNull(
// ReflectionUtils.getDeclaredMethod(
// clazz$ClientboundSetEntityDataPacket, void.class, List.class, clazz$RegistryFriendlyByteBuf
// )
// );
//
// public static final Method method$ClientboundSetEntityDataPacket$unpack = requireNonNull(
// ReflectionUtils.getDeclaredMethod(
// clazz$ClientboundSetEntityDataPacket, List.class, clazz$RegistryFriendlyByteBuf
// )
// );
public static final Class<?> clazz$ClientboundSetTitleTextPacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetTitleTextPacket")
)
);
public static final Class<?> clazz$ClientboundSetSubtitleTextPacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetSubtitleTextPacket")
)
);
public static final Class<?> clazz$ClientboundTabListPacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundTabListPacket"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutPlayerListHeaderFooter")
)
);
public static final Class<?> clazz$ClientboundSetObjectivePacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetObjectivePacket"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardObjective")
)
);
}

View File

@@ -25,6 +25,7 @@ dependencies {
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}") {
exclude("com.google.code.gson", "gson")
}
compileOnly("net.kyori:adventure-text-serializer-json-legacy-impl:${rootProject.properties["adventure_bundle_version"]}")
// Command
compileOnly("org.incendo:cloud-core:${rootProject.properties["cloud_core_version"]}")
compileOnly("org.incendo:cloud-minecraft-extras:${rootProject.properties["cloud_minecraft_extras_version"]}")
@@ -46,7 +47,6 @@ dependencies {
compileOnly("org.lz4:lz4-java:${rootProject.properties["lz4_version"]}")
// Commons IO
compileOnly("commons-io:commons-io:${rootProject.properties["commons_io_version"]}")
compileOnly("commons-io:commons-io:${rootProject.properties["commons_io_version"]}")
// Data Fixer Upper
compileOnly("com.mojang:datafixerupper:${rootProject.properties["datafixerupper_version"]}")
// Aho-Corasick java implementation

View File

@@ -395,14 +395,14 @@ public abstract class AbstractPackManager implements PackManager {
for (Pack pack : loadedPacks()) {
Pair<List<Path>, List<Path>> files = FileUtils.getConfigsDeeply(pack.configurationFolder());
for (Path path : files.left()) {
Yaml yaml = new Yaml(new StringKeyConstructor(new LoaderOptions()));
try (InputStreamReader inputStream = new InputStreamReader(new FileInputStream(path.toFile()), StandardCharsets.UTF_8)) {
Yaml yaml = new Yaml(new StringKeyConstructor(new LoaderOptions()));
Map<String, Object> data = yaml.load(inputStream);
if (data == null) continue;
for (Map.Entry<String, Object> entry : data.entrySet()) {
processConfigEntry(entry, path, pack);
}
} catch (IOException e) {
} catch (Exception e) {
this.plugin.logger().warn(path, "Error loading config file", e);
}
}
@@ -413,7 +413,7 @@ public abstract class AbstractPackManager implements PackManager {
for (Map.Entry<String, Object> entry : data.entrySet()) {
processConfigEntry(entry, path, pack);
}
} catch (IOException e) {
} catch (Exception e) {
this.plugin.logger().warn(path, "Error loading config file", e);
}
}

View File

@@ -142,12 +142,16 @@ public abstract class CraftEngine implements Plugin {
if (reloadRecipe) {
this.recipeManager.reload();
}
// now we load resources
this.packManager.loadResources(reloadRecipe);
// handle some special client lang for instance block_name
this.translationManager.delayedLoad();
try {
// now we load resources
this.packManager.loadResources(reloadRecipe);
} catch (Exception e) {
this.logger().warn("Failed to load resources folder", e);
}
// init suggestions and packet mapper
this.blockManager.delayedLoad();
// handle some special client lang for instance block_name
this.translationManager.delayedLoad();
// init suggestions
this.furnitureManager.delayedLoad();
// sort the categories
@@ -278,7 +282,7 @@ public abstract class CraftEngine implements Plugin {
Dependencies.SNAKE_YAML,
Dependencies.BOOSTED_YAML,
Dependencies.MINIMESSAGE,
Dependencies.TEXT_SERIALIZER_GSON,
Dependencies.TEXT_SERIALIZER_GSON, Dependencies.TEXT_SERIALIZER_GSON_LEGACY,
Dependencies.TEXT_SERIALIZER_JSON,
Dependencies.AHO_CORASICK,
Dependencies.LZ4

View File

@@ -128,6 +128,10 @@ public class Config {
protected boolean image$intercept_packets$title;
protected boolean image$intercept_packets$bossbar;
protected boolean image$intercept_packets$container;
protected boolean image$intercept_packets$team;
protected boolean image$intercept_packets$scoreboard;
protected boolean image$intercept_packets$entity_name;
protected boolean image$intercept_packets$text_display;
public Config(CraftEngine plugin) {
this.plugin = plugin;
@@ -290,6 +294,10 @@ public class Config {
image$intercept_packets$title = config.getBoolean("image.intercept-packets.title", true);
image$intercept_packets$bossbar = config.getBoolean("image.intercept-packets.bossbar", true);
image$intercept_packets$container = config.getBoolean("image.intercept-packets.container", true);
image$intercept_packets$team = config.getBoolean("image.intercept-packets.team", true);
image$intercept_packets$scoreboard = config.getBoolean("image.intercept-packets.scoreboard", true);
image$intercept_packets$entity_name = config.getBoolean("image.intercept-packets.entity-name", true);
image$intercept_packets$text_display = config.getBoolean("image.intercept-packets.text-display", true);
Class<?> modClazz = ReflectionUtils.getClazz(CraftEngine.MOD_CLASS);
if (modClazz != null) {
@@ -614,6 +622,22 @@ public class Config {
return instance.image$intercept_packets$container;
}
public static boolean interceptTeam() {
return instance.image$intercept_packets$team;
}
public static boolean interceptEntityName() {
return instance.image$intercept_packets$entity_name;
}
public static boolean interceptScoreboard() {
return instance.image$intercept_packets$scoreboard;
}
public static boolean interceptTextDisplay() {
return instance.image$intercept_packets$text_display;
}
public YamlDocument loadOrCreateYamlData(String fileName) {
File file = new File(this.plugin.dataFolderFile(), fileName);
if (!file.exists()) {

View File

@@ -200,6 +200,13 @@ public class Dependencies {
"adventure-text-serializer-gson",
List.of(Relocation.of("adventure", "net{}kyori{}adventure"))
);
public static final Dependency TEXT_SERIALIZER_GSON_LEGACY = new Dependency(
"adventure-text-serializer-json-legacy-impl",
"net{}kyori",
"adventure-text-serializer-json-legacy-impl",
"adventure-text-serializer-json-legacy-impl",
List.of(Relocation.of("adventure", "net{}kyori{}adventure"))
);
public static final Dependency TEXT_SERIALIZER_JSON = new Dependency(
"adventure-text-serializer-json",
"net{}kyori",

View File

@@ -7,6 +7,10 @@ import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.json.JSONOptions;
import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer;
import net.momirealms.sparrow.nbt.Tag;
import net.momirealms.sparrow.nbt.serializer.NBTComponentSerializer;
/**
* Helper class for handling Adventure components and related functionalities.
@@ -16,11 +20,18 @@ public class AdventureHelper {
private final MiniMessage miniMessage;
private final MiniMessage miniMessageStrict;
private final GsonComponentSerializer gsonComponentSerializer;
private final NBTComponentSerializer nbtComponentSerializer;
private AdventureHelper() {
this.miniMessage = MiniMessage.builder().build();
this.miniMessageStrict = MiniMessage.builder().strict(true).build();
this.gsonComponentSerializer = GsonComponentSerializer.builder().build();
GsonComponentSerializer.Builder builder = GsonComponentSerializer.builder();
if (!VersionHelper.isVersionNewerThan1_20_5()) {
builder.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get());
builder.editOptions((b) -> b.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, false));
}
this.gsonComponentSerializer = builder.build();
this.nbtComponentSerializer = NBTComponentSerializer.builder().build();
}
private static class SingletonHolder {
@@ -54,6 +65,15 @@ public class AdventureHelper {
return getInstance().gsonComponentSerializer;
}
/**
* Retrieves the NBTComponentSerializer instance.
*
* @return the NBTComponentSerializer instance
*/
public static NBTComponentSerializer getNBT() {
return getInstance().nbtComponentSerializer;
}
/**
* Sends a message to an audience.
*
@@ -134,6 +154,14 @@ public class AdventureHelper {
return getGson().serializeToTree(component);
}
public static Tag componentToTag(Component component) {
return getNBT().serialize(component);
}
public static Component tagToComponent(Tag tag) {
return getNBT().deserialize(tag);
}
/**
* Checks if a character is a legacy color code.
*

View File

@@ -48,6 +48,22 @@ public class FriendlyByteBuf extends ByteBuf {
return BlockPos.of(buf.readLong());
}
public List<String> readStringList() {
int i = this.readVarInt();
List<String> list = new ArrayList<>(i);
for (int j = 0; j < i; ++j) {
list.add(readUtf());
}
return list;
}
public void writeStringList(List<String> list) {
writeVarInt(list.size());
for (String s : list) {
writeUtf(s);
}
}
public FriendlyByteBuf writeBlockPos(BlockPos pos) {
this.writeLong(pos.asLong());
return this;

View File

@@ -21,7 +21,7 @@ gson_version=2.11.0
asm_version=9.8
asm_commons_version=9.8
jar_relocator_version=1.7
adventure_bundle_version=4.19.0
adventure_bundle_version=4.20.0
adventure_platform_version=4.3.4
cloud_core_version=2.0.0
cloud_services_version=2.0.0
@@ -40,7 +40,7 @@ lz4_version=1.8.0
geantyref_version=1.3.16
zstd_version=1.5.7-2
commons_io_version=2.18.0
sparrow_nbt_version=0.5
sparrow_nbt_version=0.6.1
sparrow_util_version=0.37
fastutil_version=8.5.15
netty_version=4.1.119.Final
@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3
snake_yaml_version=2.4
anti_grief_version=0.13
nms_helper_version=0.45
nms_helper_version=0.47
# Ignite Dependencies
mixinextras_version=0.4.1
mixin_version=0.15.2+mixin.0.8.7