9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-24 09:29:33 +00:00
This commit is contained in:
XiaoMoMi
2025-09-03 05:16:22 +08:00
9 changed files with 82 additions and 7 deletions

View File

@@ -45,6 +45,7 @@ public class BukkitPackManager extends AbstractPackManager implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) {
if (Config.sendPackOnJoin() && !VersionHelper.isOrAbove1_20_2()) {
Player player = BukkitAdaptors.adapt(event.getPlayer());
if (player == null) return;
this.sendResourcePack(player);
}
}

View File

@@ -204,7 +204,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, NetworkReflections.clazz$ServerboundRenameItemPacket);
registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, NetworkReflections.clazz$ServerboundSignUpdatePacket);
registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, NetworkReflections.clazz$ServerboundEditBookPacket);
registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, NetworkReflections.clazz$ServerboundCustomPayloadPacket);
registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD_1_20_2, VersionHelper.isOrAbove1_20_2() ? NetworkReflections.clazz$ServerboundCustomPayloadPacket : null);
registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_RESPONSE, NetworkReflections.clazz$ServerboundResourcePackPacket);
registerNMSPacketConsumer(PacketConsumers.ENTITY_EVENT, NetworkReflections.clazz$ClientboundEntityEventPacket);
registerNMSPacketConsumer(PacketConsumers.MOVE_POS_AND_ROTATE_ENTITY, NetworkReflections.clazz$ClientboundMoveEntityPacket$PosRot);
@@ -247,6 +247,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerC2SByteBufPacketConsumer(PacketConsumers.SET_CREATIVE_MODE_SLOT, this.packetIds.serverboundSetCreativeModeSlotPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_20, VersionHelper.isOrAbove1_21_5() ? -1 : this.packetIds.serverboundContainerClickPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.INTERACT_ENTITY, this.packetIds.serverboundInteractPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD_1_20, VersionHelper.isOrAbove1_20_2() ? -1 : this.packetIds.serverboundCustomPayloadPacket());
}
@EventHandler(priority = EventPriority.LOWEST)

View File

@@ -1923,12 +1923,12 @@ public class PacketConsumers {
return hasIllegal ? Pair.of(true, new String(newCodepoints, 0, newCodepoints.length)) : Pair.of(false, original);
}
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> CUSTOM_PAYLOAD = (user, event, packet) -> {
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> CUSTOM_PAYLOAD_1_20_2 = (user, event, packet) -> {
try {
if (!VersionHelper.isOrAbove1_20_2()) return;
Object payload = NetworkReflections.methodHandle$ServerboundCustomPayloadPacket$payloadGetter.invokeExact(packet);
Payload clientPayload;
if (NetworkReflections.clazz$DiscardedPayload.isInstance(payload)) {
if (VersionHelper.isOrAbove1_20_5() && NetworkReflections.clazz$DiscardedPayload.isInstance(payload)) {
clientPayload = DiscardedPayload.from(payload);
} else if (!VersionHelper.isOrAbove1_20_5() && NetworkReflections.clazz$ServerboundCustomPayloadPacket$UnknownPayload.isInstance(payload)) {
clientPayload = UnknownPayload.from(payload);
@@ -1942,6 +1942,18 @@ public class PacketConsumers {
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> CUSTOM_PAYLOAD_1_20 = (user, event) -> {
try {
if (VersionHelper.isOrAbove1_20_2()) return;
FriendlyByteBuf byteBuf = event.getBuffer();
Key key = byteBuf.readKey();
if (!key.equals(NetworkManager.MOD_CHANNEL_KEY)) return;
PayloadHelper.handleReceiver(new UnknownPayload(key, byteBuf.readBytes(byteBuf.readableBytes())), user);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ServerboundCustomPayloadPacket", e);
}
};
@SuppressWarnings("unchecked")
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> SET_ENTITY_DATA = (user, event) -> {
try {

View File

@@ -69,4 +69,6 @@ public interface PacketIds {
int clientboundUpdateRecipesPacket();
int clientboundForgetLevelChunkPacket();
int serverboundCustomPayloadPacket();
}

View File

@@ -174,4 +174,9 @@ public class PacketIds1_20 implements PacketIds {
public int clientboundForgetLevelChunkPacket() {
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundForgetLevelChunkPacket);
}
@Override
public int serverboundCustomPayloadPacket() {
return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ServerboundCustomPayloadPacket);
}
}

View File

@@ -173,4 +173,9 @@ public class PacketIds1_20_5 implements PacketIds {
public int clientboundForgetLevelChunkPacket() {
return PacketIdFinder.clientboundByName("minecraft:forget_level_chunk");
}
@Override
public int serverboundCustomPayloadPacket() {
return PacketIdFinder.serverboundByName("custom_payload");
}
}

View File

@@ -1,17 +1,21 @@
package net.momirealms.craftengine.bukkit.plugin.network.payload.protocol;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslationArgument;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.paper.PaperReflections;
import net.momirealms.craftengine.bukkit.util.RegistryUtils;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.network.ModPacket;
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
import net.momirealms.craftengine.core.plugin.network.codec.NetworkCodec;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.IntIdentityList;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceKey;
import net.momirealms.craftengine.core.util.*;
import org.bukkit.entity.Player;
public record ClientCustomBlockPacket(int size) implements ModPacket {
public static final ResourceKey<NetworkCodec<FriendlyByteBuf, ? extends ModPacket>> TYPE = ResourceKey.create(
@@ -37,6 +41,7 @@ public record ClientCustomBlockPacket(int size) implements ModPacket {
@Override
public void handle(NetWorkUser user) {
if (user.clientModEnabled()) return; // 防止滥用
int serverBlockRegistrySize = RegistryUtils.currentBlockRegistrySize();
if (this.size != serverBlockRegistrySize) {
user.kick(Component.translatable(
@@ -48,6 +53,25 @@ public record ClientCustomBlockPacket(int size) implements ModPacket {
}
user.setClientModState(true);
user.setClientBlockList(new IntIdentityList(this.size));
if (!VersionHelper.isOrAbove1_20_2()) {
// 因为旧版本没有配置阶段需要重新发送区块
try {
Object chunkLoader = PaperReflections.field$ServerPlayer$chunkLoader.get(user.serverPlayer());
LongOpenHashSet sentChunks = (LongOpenHashSet) PaperReflections.field$RegionizedPlayerChunkLoader$PlayerChunkLoaderData$sentChunks.get(chunkLoader);
Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(((Player) user.platformPlayer()).getWorld());
Object lightEngine = CoreReflections.method$BlockAndTintGetter$getLightEngine.invoke(serverLevel);
Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel);
for (long chunkPos : sentChunks) {
int chunkX = (int) chunkPos;
int chunkZ = (int) (chunkPos >> 32);
Object levelChunk = FastNMS.INSTANCE.method$ServerChunkCache$getChunk(chunkSource, chunkX, chunkZ, false);
Object packet = NetworkReflections.constructor$ClientboundLevelChunkWithLightPacket.newInstance(levelChunk, lightEngine, null, null);
user.sendPacket(packet, true);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to refresh chunk for player " + user.name(), e);
}
}
}
}

View File

@@ -8,6 +8,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
import net.momirealms.craftengine.bukkit.plugin.reflection.paper.PaperReflections;
import net.momirealms.craftengine.bukkit.util.BukkitReflectionUtils;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ReflectionUtils;
@@ -4177,4 +4178,8 @@ public final class CoreReflections {
"world.level.storage.loot.entries.LootPoolEntryType"
)
);
public static final Method method$BlockAndTintGetter$getLightEngine = requireNonNull(
ReflectionUtils.getDeclaredMethod(clazz$BlockAndTintGetter, clazz$LevelLightEngine)
);
}

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin.reflection.paper;
import com.google.gson.Gson;
import io.papermc.paper.event.player.AsyncChatDecorateEvent;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.core.util.ReflectionUtils;
@@ -97,4 +98,23 @@ public final class PaperReflections {
public static final Method method$BookMeta$page = requireNonNull(
ReflectionUtils.getMethod(CraftBukkitReflections.clazz$BookMeta, void.class, int.class, clazz$AdventureComponent)
);
public static final Class<?> clazz$RegionizedPlayerChunkLoader$PlayerChunkLoaderData = requireNonNull(
ReflectionUtils.getClazz(
"ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader$PlayerChunkLoaderData",
"io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader$PlayerChunkLoaderData"
)
);
public static final Field field$ServerPlayer$chunkLoader = requireNonNull(
ReflectionUtils.getDeclaredField(
CoreReflections.clazz$ServerPlayer, PaperReflections.clazz$RegionizedPlayerChunkLoader$PlayerChunkLoaderData, 0
)
);
public static final Field field$RegionizedPlayerChunkLoader$PlayerChunkLoaderData$sentChunks = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$RegionizedPlayerChunkLoader$PlayerChunkLoaderData, LongOpenHashSet.class, 0
)
);
}