9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 23:19:15 +00:00

Merge pull request #55 from jhqwqmc/dev

feat(bukkit): 添加编辑书过滤
This commit is contained in:
XiaoMoMi
2025-03-23 23:44:23 +08:00
committed by GitHub
3 changed files with 80 additions and 0 deletions

View File

@@ -127,6 +127,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket); registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket);
registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket); registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket);
registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket); registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket);
registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket);
registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket());

View File

@@ -34,6 +34,8 @@ import org.bukkit.util.RayTraceResult;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -704,6 +706,52 @@ public class PacketConsumers {
} }
}; };
// we handle it on packet level to prevent it from being captured by plugins
@SuppressWarnings("unchecked")
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> EDIT_BOOK = (user, event, packet) -> {
try {
List<String> pages = (List<String>) Reflections.field$ServerboundEditBookPacket$pages.get(packet);
Optional<String> title = (Optional<String>) Reflections.field$ServerboundEditBookPacket$title.get(packet);
ImageManager manager = CraftEngine.instance().imageManager();
if (!manager.isDefaultFontInUse()) return;
AtomicBoolean hasChange = new AtomicBoolean(false);
List<String> newPages = new ArrayList<>(pages.size());
Optional<String> newTitle = title.map(t -> processTitle(t, manager, hasChange));
pages.forEach(page -> newPages.add(processPage(page, manager, hasChange)));
if (hasChange.get()) {
event.setCancelled(true);
Object newPacket = Reflections.constructor$ServerboundEditBookPacket.newInstance(
Reflections.field$ServerboundEditBookPacket$slot.get(packet),
newPages,
newTitle
);
user.receivePacket(newPacket);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundEditBookPacket", e);
}
};
private static String processTitle(String original, ImageManager manager, AtomicBoolean hasChange) {
AtomicReference<String> result = new AtomicReference<>(original);
runIfContainsIllegalCharacter(original, manager, modified -> {
result.set(modified);
hasChange.set(true);
});
return result.get();
}
private static String processPage(String original, ImageManager manager, AtomicBoolean hasChange) {
AtomicReference<String> result = new AtomicReference<>(original);
runIfContainsIllegalCharacter(original, manager, modified -> {
result.set(modified);
hasChange.set(true);
});
return result.get();
}
private static void runIfContainsIllegalCharacter(String string, ImageManager manager, Consumer<String> callback) { private static void runIfContainsIllegalCharacter(String string, ImageManager manager, Consumer<String> callback) {
//noinspection DuplicatedCode //noinspection DuplicatedCode
char[] chars = string.toCharArray(); char[] chars = string.toCharArray();

View File

@@ -5262,4 +5262,35 @@ public class Reflections {
AsyncChatDecorateEvent.class, void.class, clazz$AdventureComponent AsyncChatDecorateEvent.class, void.class, clazz$AdventureComponent
) )
); );
public static final Class<?> clazz$ServerboundEditBookPacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundEditBookPacket"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInBEdit")
)
);
public static final Field field$ServerboundEditBookPacket$slot = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ServerboundEditBookPacket, int.class, 0
)
);
public static final Field field$ServerboundEditBookPacket$pages = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ServerboundEditBookPacket, List.class, 0
)
);
public static final Field field$ServerboundEditBookPacket$title = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ServerboundEditBookPacket, Optional.class, 0
)
);
public static final Constructor<?> constructor$ServerboundEditBookPacket = requireNonNull(
ReflectionUtils.getConstructor(
clazz$ServerboundEditBookPacket, int.class, List.class, Optional.class
)
);
} }