mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
@@ -127,6 +127,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
|
||||
registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket);
|
||||
registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
|
||||
registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
|
||||
registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket());
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.bukkit.util.RayTraceResult;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
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) {
|
||||
//noinspection DuplicatedCode
|
||||
char[] chars = string.toCharArray();
|
||||
|
||||
@@ -5262,4 +5262,35 @@ public class Reflections {
|
||||
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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user