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

初步实现连接状态切换

This commit is contained in:
jhqwqmc
2025-12-11 01:23:06 +08:00
parent a096e3078b
commit aa9bde99af
40 changed files with 779 additions and 377 deletions

View File

@@ -4,8 +4,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.momirealms.craftengine.core.entity.furniture.ExternalModel;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.Context;
import java.util.UUID;
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
public interface CompatibilityManager {
@@ -37,7 +36,7 @@ public interface CompatibilityManager {
String parse(Player player1, Player player2, String text);
int getPlayerProtocolVersion(UUID uuid);
int getViaVersionProtocolVersion(NetWorkUser user);
void executeMMSkill(String skill, float power, Player player);

View File

@@ -1,45 +0,0 @@
package net.momirealms.craftengine.core.plugin.network;
import net.momirealms.craftengine.core.util.Cancellable;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public class ByteBufPacketEvent implements Cancellable {
private boolean cancelled;
private final FriendlyByteBuf buf;
private boolean changed;
private final int packetID;
private final int preIndex;
public ByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex) {
this.buf = buf;
this.packetID = packetID;
this.preIndex = preIndex;
}
public int packetID() {
return this.packetID;
}
public FriendlyByteBuf getBuffer() {
this.buf.readerIndex(this.preIndex);
return this.buf;
}
public void setChanged(boolean dirty) {
this.changed = dirty;
}
public boolean changed() {
return this.changed;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@@ -2,6 +2,8 @@ package net.momirealms.craftengine.core.plugin.network;
import it.unimi.dsi.fastutil.ints.IntList;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.network.event.ByteBufPacketEvent;
import net.momirealms.craftengine.core.plugin.network.event.NMSPacketEvent;
public interface EntityPacketHandler {

View File

@@ -100,4 +100,14 @@ public interface NetWorkUser {
IntIdentityList clientBlockList();
void setClientBlockList(IntIdentityList integers);
ProtocolVersion protocolVersion();
void setProtocolVersion(ProtocolVersion protocolVersion);
void setConnectionState(ConnectionState connectionState);
void setDecoderState(ConnectionState decoderState);
void setEncoderState(ConnectionState encoderState);
}

View File

@@ -1,6 +1,6 @@
package net.momirealms.craftengine.core.plugin.network;
public enum PacketFlow {
SERVERBOUND,
CLIENTBOUND;
SERVERBOUND, // c2s
CLIENTBOUND; // s2c
}

View File

@@ -1,33 +1,42 @@
package net.momirealms.craftengine.core.plugin.network;
public enum ProtocolVersion {
UNKNOWN(-1, "Unknown"),
V1_20(763, "1.20"),
V1_20_1(763, "1.20.1"),
V1_20_2(764, "1.20.2"),
V1_20_3(765, "1.20.3"),
V1_20_4(765, "1.20.4"),
V1_20_5(766, "1.20.5"),
V1_20_6(766, "1.20.6"),
V1_21(767, "1.21"),
V1_21_1(767, "1.21.1"),
V1_21_2(768, "1.21.2"),
V1_21_3(768, "1.21.3"),
V1_21_4(769, "1.21.4"),
V1_21_5(770, "1.21.5"),
V1_21_6(771, "1.21.6"),
V1_21_7(772, "1.21.7"),
V1_21_8(772, "1.21.8"),
V1_21_9(773, "1.21.9"),
V1_21_10(773, "1.21.10"),
V1_21_11(774, "1.21.11");
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Map;
public final class ProtocolVersion {
public static final ProtocolVersion UNKNOWN = new ProtocolVersion(-1, "Unknown");
public static final ProtocolVersion V1_20 = new ProtocolVersion(763, "1.20");
public static final ProtocolVersion V1_20_1 = new ProtocolVersion(763, "1.20.1");
public static final ProtocolVersion V1_20_2 = new ProtocolVersion(764, "1.20.2");
public static final ProtocolVersion V1_20_3 = new ProtocolVersion(765, "1.20.3");
public static final ProtocolVersion V1_20_4 = new ProtocolVersion(765, "1.20.4");
public static final ProtocolVersion V1_20_5 = new ProtocolVersion(766, "1.20.5");
public static final ProtocolVersion V1_20_6 = new ProtocolVersion(766, "1.20.6");
public static final ProtocolVersion V1_21 = new ProtocolVersion(767, "1.21");
public static final ProtocolVersion V1_21_1 = new ProtocolVersion(767, "1.21.1");
public static final ProtocolVersion V1_21_2 = new ProtocolVersion(768, "1.21.2");
public static final ProtocolVersion V1_21_3 = new ProtocolVersion(768, "1.21.3");
public static final ProtocolVersion V1_21_4 = new ProtocolVersion(769, "1.21.4");
public static final ProtocolVersion V1_21_5 = new ProtocolVersion(770, "1.21.5");
public static final ProtocolVersion V1_21_6 = new ProtocolVersion(771, "1.21.6");
public static final ProtocolVersion V1_21_7 = new ProtocolVersion(772, "1.21.7");
public static final ProtocolVersion V1_21_8 = new ProtocolVersion(772, "1.21.8");
public static final ProtocolVersion V1_21_9 = new ProtocolVersion(773, "1.21.9");
public static final ProtocolVersion V1_21_10 = new ProtocolVersion(773, "1.21.10");
public static final ProtocolVersion V1_21_11 = new ProtocolVersion(774, "1.21.11");
private static final Map<Integer, ProtocolVersion> BY_ID = new Int2ObjectOpenHashMap<>();
private static final Map<String, ProtocolVersion> BY_NAME = new Object2ObjectOpenHashMap<>();
private final int id;
private final String name;
ProtocolVersion(int id, String name) {
private ProtocolVersion(int id, String name) {
this.id = id;
this.name = name;
BY_ID.put(id, this);
BY_NAME.put(name, this);
}
public int getId() {
@@ -43,20 +52,18 @@ public enum ProtocolVersion {
}
public static ProtocolVersion getByName(String name) {
for (ProtocolVersion version : values()) {
if (version.getName().equals(name)) {
return version;
}
}
return UNKNOWN;
return BY_NAME.getOrDefault(name, UNKNOWN);
}
public static ProtocolVersion getById(int id) {
for (ProtocolVersion version : values()) {
if (version.getId() == id) {
return version;
}
}
return UNKNOWN;
return BY_ID.getOrDefault(id, UNKNOWN);
}
@Override
public String toString() {
return "ProtocolVersion{" +
"id=" + id +
", name=" + name +
'}';
}
}

View File

@@ -0,0 +1,69 @@
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.PacketFlow;
import net.momirealms.craftengine.core.util.Cancellable;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public abstract class ByteBufPacketEvent implements Cancellable {
private boolean cancelled;
private final FriendlyByteBuf buf;
private boolean changed;
private final int packetID;
private final int preIndex;
private final ConnectionState state;
private final PacketFlow direction;
protected ByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex, ConnectionState state, PacketFlow direction) {
this.buf = buf;
this.packetID = packetID;
this.preIndex = preIndex;
this.state = state;
this.direction = direction;
}
public int packetID() {
return this.packetID;
}
public FriendlyByteBuf getBuffer() {
this.buf.readerIndex(this.preIndex);
return this.buf;
}
public void setChanged(boolean dirty) {
this.changed = dirty;
}
public boolean changed() {
return this.changed;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public ConnectionState state() {
return state;
}
public PacketFlow direction() {
return direction;
}
public static ByteBufPacketEvent create(int packetID, FriendlyByteBuf buf, int preIndex, ConnectionState state, PacketFlow direction) {
return switch (state) {
case HANDSHAKING -> new HandshakingByteBufPacketEvent(packetID, buf, preIndex, direction);
case STATUS -> new StatusByteBufPacketEvent(packetID, buf, preIndex, direction);
case LOGIN -> new LoginByteBufPacketEvent(packetID, buf, preIndex, direction);
case PLAY -> new PlayByteBufPacketEvent(packetID, buf, preIndex, direction);
case CONFIGURATION -> new ConfigurationByteBufPacketEvent(packetID, buf, preIndex, direction);
};
}
}

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.PacketFlow;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public class ConfigurationByteBufPacketEvent extends ByteBufPacketEvent {
public ConfigurationByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex, PacketFlow direction) {
super(packetID, buf, preIndex, ConnectionState.CONFIGURATION, direction);
}
}

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.PacketFlow;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public class HandshakingByteBufPacketEvent extends ByteBufPacketEvent {
public HandshakingByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex, PacketFlow direction) {
super(packetID, buf, preIndex, ConnectionState.HANDSHAKING, direction);
}
}

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.PacketFlow;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public class LoginByteBufPacketEvent extends ByteBufPacketEvent {
public LoginByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex, PacketFlow direction) {
super(packetID, buf, preIndex, ConnectionState.LOGIN, direction);
}
}

View File

@@ -1,4 +1,4 @@
package net.momirealms.craftengine.core.plugin.network;
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.util.Cancellable;
import org.jetbrains.annotations.NotNull;

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.PacketFlow;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public class PlayByteBufPacketEvent extends ByteBufPacketEvent {
public PlayByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex, PacketFlow direction) {
super(packetID, buf, preIndex, ConnectionState.PLAY, direction);
}
}

View File

@@ -0,0 +1,12 @@
package net.momirealms.craftengine.core.plugin.network.event;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.PacketFlow;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
public class StatusByteBufPacketEvent extends ByteBufPacketEvent {
public StatusByteBufPacketEvent(int packetID, FriendlyByteBuf buf, int preIndex, PacketFlow direction) {
super(packetID, buf, preIndex, ConnectionState.STATUS, direction);
}
}

View File

@@ -13,15 +13,28 @@ import java.util.Arrays;
import java.util.List;
public class ReflectionUtils {
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
public static final Unsafe UNSAFE;
public static final MethodHandles.Lookup LOOKUP;
private static final MethodHandle methodHandle$MethodHandleNatives$refKindIsSetter;
private static final MethodHandle methodHandle$constructor$MemberName;
private static final MethodHandle methodHandle$MemberName$getReferenceKind;
private static final MethodHandle methodHandle$MethodHandles$Lookup$getDirectField;
static {
try {
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
UNSAFE = (Unsafe) unsafeField.get(null);
Field implLookup = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
@SuppressWarnings("deprecation") Object base = UNSAFE.staticFieldBase(implLookup);
@SuppressWarnings("deprecation") long offset = UNSAFE.staticFieldOffset(implLookup);
LOOKUP = (MethodHandles.Lookup) UNSAFE.getObject(base, offset); // 获取神权lookup
Class<?> clazz$MethodHandleNatives = Class.forName("java.lang.invoke.MethodHandleNatives");
Class<?> clazz$MemberName = Class.forName("java.lang.invoke.MemberName");
methodHandle$MethodHandleNatives$refKindIsSetter = LOOKUP.unreflect(clazz$MethodHandleNatives.getDeclaredMethod("refKindIsSetter", byte.class));
methodHandle$constructor$MemberName = LOOKUP.unreflectConstructor(clazz$MemberName.getDeclaredConstructor(Field.class, boolean.class));
methodHandle$MemberName$getReferenceKind = LOOKUP.unreflect(clazz$MemberName.getDeclaredMethod("getReferenceKind"));
methodHandle$MethodHandles$Lookup$getDirectField = LOOKUP.unreflect(MethodHandles.Lookup.class.getDeclaredMethod("getDirectField", byte.class, Class.class, clazz$MemberName));
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
@@ -510,12 +523,19 @@ public class ReflectionUtils {
}
}
public static MethodHandle unreflectSetter(Field field) throws IllegalAccessException {
@Nullable
public static MethodHandle unreflectSetter(Field field) {
try {
return LOOKUP.unreflectSetter(field);
} catch (IllegalAccessException e) {
field.setAccessible(true);
return LOOKUP.unreflectSetter(field);
try { // 绕过final限制获取方法句柄
Object memberName = methodHandle$constructor$MemberName.invoke(field, true);
Object refKind = methodHandle$MemberName$getReferenceKind.invoke(memberName);
methodHandle$MethodHandleNatives$refKindIsSetter.invoke(refKind);
return (MethodHandle) methodHandle$MethodHandles$Lookup$getDirectField.invoke(LOOKUP, refKind, field.getDeclaringClass(), memberName);
} catch (Throwable ex) {
return null;
}
}
}