mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 09:59:20 +00:00
Merge pull request #297 from jhqwqmc/dev-hotfix
fix(network): 修复启用客户端模组显示问题
This commit is contained in:
@@ -1,23 +1,12 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.data.HappyGhastData;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.BukkitNetworkManager;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bukkit.parser.location.LocationParser;
|
||||
import org.incendo.cloud.parser.standard.IntegerParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
|
||||
@@ -29,35 +18,9 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||
return builder
|
||||
.senderType(Player.class)
|
||||
.required("location", LocationParser.locationParser())
|
||||
.required("remove", IntegerParser.integerParser())
|
||||
.handler(context -> {
|
||||
Player player = context.sender();
|
||||
int removeEntityId = context.get("remove");
|
||||
if (removeEntityId >= 0) {
|
||||
try {
|
||||
Object packet = NetworkReflections.constructor$ClientboundRemoveEntitiesPacket.newInstance((Object) new int[]{removeEntityId});
|
||||
plugin().adapt(player).sendPacket(packet, true);
|
||||
player.sendMessage("发送成功");
|
||||
} catch (ReflectiveOperationException e) {
|
||||
player.sendMessage("发送失败");
|
||||
}
|
||||
return;
|
||||
}
|
||||
Location location = context.get("location");
|
||||
int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
List<Object> packets = new ArrayList<>();
|
||||
List<Object> cachedShulkerValues = new ArrayList<>();
|
||||
HappyGhastData.MobFlags.addEntityDataIfNotDefaultValue((byte) 0x01, cachedShulkerValues); // NO AI
|
||||
// HappyGhastData.SharedFlags.addEntityDataIfNotDefaultValue((byte) 0x20, cachedShulkerValues); // Invisible
|
||||
HappyGhastData.StaysStill.addEntityDataIfNotDefaultValue(true, cachedShulkerValues);
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityId, UUID.randomUUID(), location.x(), location.y(), location.z(), 0, location.getYaw(),
|
||||
MEntityTypes.HAPPY_GHAST, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, List.copyOf(cachedShulkerValues)));
|
||||
plugin().adapt(player).sendPackets(packets, true);
|
||||
player.sendMessage("发送成功 id: " + entityId);
|
||||
player.sendMessage("客户端模组状态: " + BukkitNetworkManager.instance().getUser(player).clientModEnabled());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import net.momirealms.craftengine.bukkit.plugin.network.handler.*;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.payload.DiscardedPayload;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.payload.NetWorkDataTypes;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.payload.Payload;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.payload.UnknownPayload;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
|
||||
@@ -105,7 +106,7 @@ public class PacketConsumers {
|
||||
byte yHeadRot = buf.readByte();
|
||||
int data = buf.readVarInt();
|
||||
// Falling blocks
|
||||
int remapped = remap(data);
|
||||
int remapped = user.clientModEnabled() ? remapMOD(data) : remap(data);
|
||||
if (remapped != data) {
|
||||
int xa = buf.readShort();
|
||||
int ya = buf.readShort();
|
||||
@@ -428,7 +429,7 @@ public class PacketConsumers {
|
||||
if (user.clientModEnabled() && !BlockStateUtils.isVanillaBlock(before)) {
|
||||
return;
|
||||
}
|
||||
int state = remap(before);
|
||||
int state = user.clientModEnabled() ? remapMOD(before) : remap(before);
|
||||
if (state == before) {
|
||||
return;
|
||||
}
|
||||
@@ -450,7 +451,7 @@ public class PacketConsumers {
|
||||
BlockPos blockPos = buf.readBlockPos();
|
||||
int state = buf.readInt();
|
||||
boolean global = buf.readBoolean();
|
||||
int newState = remap(state);
|
||||
int newState = user.clientModEnabled() ? remapMOD(state) : remap(state);
|
||||
if (newState == state) {
|
||||
return;
|
||||
}
|
||||
@@ -1006,7 +1007,7 @@ public class PacketConsumers {
|
||||
if (!CoreReflections.clazz$BlockParticleOption.isInstance(option)) return;
|
||||
Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option);
|
||||
int id = BlockStateUtils.blockStateToId(blockState);
|
||||
int remapped = remap(id);
|
||||
int remapped = user.clientModEnabled() ? remapMOD(id) : remap(id);
|
||||
if (remapped == id) return;
|
||||
Object type = FastNMS.INSTANCE.method$BlockParticleOption$getType(option);
|
||||
Object remappedOption = FastNMS.INSTANCE.constructor$BlockParticleOption(type, BlockStateUtils.idToBlockState(remapped));
|
||||
@@ -1046,7 +1047,7 @@ public class PacketConsumers {
|
||||
if (!CoreReflections.clazz$BlockParticleOption.isInstance(option)) return;
|
||||
Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option);
|
||||
int id = BlockStateUtils.blockStateToId(blockState);
|
||||
int remapped = remap(id);
|
||||
int remapped = user.clientModEnabled() ? remapMOD(id) : remap(id);
|
||||
if (remapped == id) return;
|
||||
Object type = FastNMS.INSTANCE.method$BlockParticleOption$getType(option);
|
||||
Object remappedOption = FastNMS.INSTANCE.constructor$BlockParticleOption(type, BlockStateUtils.idToBlockState(remapped));
|
||||
@@ -1086,7 +1087,7 @@ public class PacketConsumers {
|
||||
if (!CoreReflections.clazz$BlockParticleOption.isInstance(option)) return;
|
||||
Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option);
|
||||
int id = BlockStateUtils.blockStateToId(blockState);
|
||||
int remapped = remap(id);
|
||||
int remapped = user.clientModEnabled() ? remapMOD(id) : remap(id);
|
||||
if (remapped == id) return;
|
||||
Object type = FastNMS.INSTANCE.method$BlockParticleOption$getType(option);
|
||||
Object remappedOption = FastNMS.INSTANCE.constructor$BlockParticleOption(type, BlockStateUtils.idToBlockState(remapped));
|
||||
@@ -1884,34 +1885,38 @@ public class PacketConsumers {
|
||||
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> CUSTOM_PAYLOAD = (user, event, packet) -> {
|
||||
try {
|
||||
if (!VersionHelper.isOrAbove1_20_5()) return;
|
||||
if (!VersionHelper.isOrAbove1_20_2()) return;
|
||||
Object payload = NetworkReflections.methodHandle$ServerboundCustomPayloadPacket$payloadGetter.invokeExact(packet);
|
||||
Payload clientPayload;
|
||||
if (NetworkReflections.clazz$DiscardedPayload.isInstance(payload)) {
|
||||
Payload discardedPayload = DiscardedPayload.from(payload);
|
||||
if (discardedPayload == null || !discardedPayload.channel().equals(NetworkManager.MOD_CHANNEL_KEY))
|
||||
clientPayload = DiscardedPayload.from(payload);
|
||||
} else if (!VersionHelper.isOrAbove1_20_5() && NetworkReflections.clazz$UnknownPayload.isInstance(payload)) {
|
||||
clientPayload = UnknownPayload.from(payload);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (clientPayload == null || !clientPayload.channel().equals(NetworkManager.MOD_CHANNEL_KEY))
|
||||
return;
|
||||
FriendlyByteBuf buf = clientPayload.toBuffer();
|
||||
NetWorkDataTypes dataType = buf.readEnumConstant(NetWorkDataTypes.class);
|
||||
if (dataType == NetWorkDataTypes.CLIENT_CUSTOM_BLOCK) {
|
||||
int clientBlockRegistrySize = dataType.decode(buf);
|
||||
int serverBlockRegistrySize = RegistryUtils.currentBlockRegistrySize();
|
||||
if (clientBlockRegistrySize != serverBlockRegistrySize) {
|
||||
user.kick(Component.translatable(
|
||||
"disconnect.craftengine.block_registry_mismatch",
|
||||
TranslationArgument.numeric(clientBlockRegistrySize),
|
||||
TranslationArgument.numeric(serverBlockRegistrySize)
|
||||
));
|
||||
return;
|
||||
FriendlyByteBuf buf = discardedPayload.toBuffer();
|
||||
NetWorkDataTypes dataType = buf.readEnumConstant(NetWorkDataTypes.class);
|
||||
if (dataType == NetWorkDataTypes.CLIENT_CUSTOM_BLOCK) {
|
||||
int clientBlockRegistrySize = dataType.decode(buf);
|
||||
int serverBlockRegistrySize = RegistryUtils.currentBlockRegistrySize();
|
||||
if (clientBlockRegistrySize != serverBlockRegistrySize) {
|
||||
user.kick(Component.translatable(
|
||||
"disconnect.craftengine.block_registry_mismatch",
|
||||
TranslationArgument.numeric(clientBlockRegistrySize),
|
||||
TranslationArgument.numeric(serverBlockRegistrySize)
|
||||
));
|
||||
return;
|
||||
}
|
||||
user.setClientModState(true);
|
||||
} else if (dataType == NetWorkDataTypes.CANCEL_BLOCK_UPDATE) {
|
||||
if (!VersionHelper.isOrAbove1_20_2()) return;
|
||||
if (dataType.decode(buf)) {
|
||||
FriendlyByteBuf bufPayload = new FriendlyByteBuf(Unpooled.buffer());
|
||||
bufPayload.writeEnumConstant(dataType);
|
||||
dataType.encode(bufPayload, true);
|
||||
user.sendCustomPayload(NetworkManager.MOD_CHANNEL_KEY, bufPayload.array());
|
||||
}
|
||||
}
|
||||
user.setClientModState(true);
|
||||
} else if (dataType == NetWorkDataTypes.CANCEL_BLOCK_UPDATE) {
|
||||
if (dataType.decode(buf)) {
|
||||
FriendlyByteBuf bufPayload = new FriendlyByteBuf(Unpooled.buffer());
|
||||
bufPayload.writeEnumConstant(dataType);
|
||||
dataType.encode(bufPayload, true);
|
||||
user.sendCustomPayload(NetworkManager.MOD_CHANNEL_KEY, bufPayload.array());
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.network.payload;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public record UnknownPayload(Key channel, ByteBuf rawPayload) implements Payload{
|
||||
|
||||
public static UnknownPayload from(Object payload) {
|
||||
try {
|
||||
Object id = NetworkReflections.field$UnknownPayload$id.get(payload);
|
||||
ByteBuf data = (ByteBuf) NetworkReflections.field$UnknownPayload$data.get(payload);
|
||||
Key channel = KeyUtils.resourceLocationToKey(id);
|
||||
return new UnknownPayload(channel, data);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to create UnknownPayload", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FriendlyByteBuf toBuffer() {
|
||||
return new FriendlyByteBuf(rawPayload);
|
||||
}
|
||||
}
|
||||
@@ -1248,7 +1248,9 @@ public final class NetworkReflections {
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$ClientboundCustomPayloadPacket = requireNonNull(
|
||||
ReflectionUtils.getConstructor(clazz$ClientboundCustomPayloadPacket, 0)
|
||||
VersionHelper.isOrAbove1_20_2()
|
||||
? ReflectionUtils.getConstructor(clazz$ClientboundCustomPayloadPacket, clazz$CustomPacketPayload)
|
||||
: ReflectionUtils.getConstructor(clazz$ClientboundCustomPayloadPacket, CoreReflections.clazz$ResourceLocation, CoreReflections.clazz$FriendlyByteBuf)
|
||||
);
|
||||
|
||||
// 1.20.2+
|
||||
@@ -1621,4 +1623,27 @@ public final class NetworkReflections {
|
||||
throw new ReflectionInitException("Failed to initialize HashedStack$STREAM_CODEC", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 1.20.2~1.20.4
|
||||
public static final Class<?> clazz$UnknownPayload = MiscUtils.requireNonNullIf(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("network.protocol.common.ServerboundCustomPayloadPacket$UnknownPayload")
|
||||
),
|
||||
VersionHelper.isOrAbove1_20_2() && !VersionHelper.isOrAbove1_20_5()
|
||||
);
|
||||
|
||||
// 1.20.2~1.20.4
|
||||
public static final Field field$UnknownPayload$id = Optional.ofNullable(clazz$UnknownPayload)
|
||||
.map(it -> ReflectionUtils.getDeclaredField(it, CoreReflections.clazz$ResourceLocation, 0))
|
||||
.orElse(null);
|
||||
|
||||
// 1.20.2~1.20.4
|
||||
public static final Field field$UnknownPayload$data = Optional.ofNullable(clazz$UnknownPayload)
|
||||
.map(it -> ReflectionUtils.getDeclaredField(it, ByteBuf.class, 0))
|
||||
.orElse(null);
|
||||
|
||||
// 1.20.2~1.20.4
|
||||
public static final Constructor<?> constructor$UnknownPayload = Optional.ofNullable(clazz$UnknownPayload)
|
||||
.map(ReflectionUtils::getTheOnlyConstructor)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@@ -306,13 +306,20 @@ public class BukkitServerPlayer extends Player {
|
||||
public void sendCustomPayload(Key channel, byte[] data) {
|
||||
try {
|
||||
Object channelKey = KeyUtils.toResourceLocation(channel);
|
||||
Object dataPayload;
|
||||
if (DiscardedPayload.useNewMethod) {
|
||||
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelKey, data);
|
||||
Object responsePacket;
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
Object dataPayload;
|
||||
if (NetworkReflections.clazz$UnknownPayload != null) {
|
||||
dataPayload = NetworkReflections.constructor$UnknownPayload.newInstance(channelKey, Unpooled.wrappedBuffer(data));
|
||||
} else if (DiscardedPayload.useNewMethod) {
|
||||
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelKey, data);
|
||||
} else {
|
||||
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelKey, Unpooled.wrappedBuffer(data));
|
||||
}
|
||||
responsePacket = NetworkReflections.constructor$ClientboundCustomPayloadPacket.newInstance(dataPayload);
|
||||
} else {
|
||||
dataPayload = NetworkReflections.constructor$DiscardedPayload.newInstance(channelKey, Unpooled.wrappedBuffer(data));
|
||||
responsePacket = NetworkReflections.constructor$ClientboundCustomPayloadPacket.newInstance(channelKey, FastNMS.INSTANCE.constructor$FriendlyByteBuf(Unpooled.wrappedBuffer(data)));
|
||||
}
|
||||
Object responsePacket = NetworkReflections.constructor$ClientboundCustomPayloadPacket.newInstance(dataPayload);
|
||||
this.sendPacket(responsePacket, true);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to send custom payload to " + name(), e);
|
||||
|
||||
Reference in New Issue
Block a user