fix: use og server host for transfer
This commit is contained in:
8 files changed
+123
-6
No files matched your search
@@ -1,8 +1,8 @@
|
||||
§d§lSFCraft 已更新到 2.2.1。
|
||||
§d§lSFCraft 已更新到 2.3。
|
||||
§a主要改动:
|
||||
- 修复了非被斩首怪物掉落头颅的问题
|
||||
- 修复了 4K 图片无法下载到服务器中的问题。现在高分辨率图片会被降采样
|
||||
- 修复了鞘翅撞进地狱门需要有空隙的问题
|
||||
|
||||
具体信息请查阅我们的更新日志:
|
||||
§bhttps://sfclub.cc/~sfcraft/changelog/2026-08-08/
|
||||
§bhttps://sfclub.cc/~sfcraft/changelog/2026-08-24/
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.ib67.sfcraft.mixin.common;
|
||||
|
||||
import io.ib67.sfcraft.network.HandshakeAddress;
|
||||
import net.minecraft.network.Connection;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
/**
|
||||
* Connection 从握手一路存活到 play 阶段,拿来记玩家自报的进服地址。
|
||||
*/
|
||||
@Mixin(Connection.class)
|
||||
public class ConnectionMixin implements HandshakeAddress.Holder {
|
||||
@Unique
|
||||
private HandshakeAddress sfcraft$handshakeAddress;
|
||||
|
||||
@Override
|
||||
public @Nullable HandshakeAddress sfcraft$handshakeAddress() {
|
||||
return sfcraft$handshakeAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sfcraft$setHandshakeAddress(@Nullable HandshakeAddress address) {
|
||||
this.sfcraft$handshakeAddress = address;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package io.ib67.sfcraft.mixin.common.bridge;
|
||||
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(ServerCommonPacketListenerImpl.class)
|
||||
public interface ServerCommonNetworkHandlerBridge {
|
||||
@Accessor("connection")
|
||||
Connection sfcraft$getConnection();
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package io.ib67.sfcraft.mixin.server;
|
||||
|
||||
import io.ib67.sfcraft.SFCraft;
|
||||
import io.ib67.sfcraft.callback.SFCallbacks;
|
||||
import io.ib67.sfcraft.network.HandshakeAddress;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
|
||||
import net.minecraft.network.protocol.status.ServerStatus;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerHandshakePacketListenerImpl;
|
||||
@@ -11,7 +13,9 @@ import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ServerHandshakePacketListenerImpl.class)
|
||||
public abstract class ServerHandshakeNetworkHandlerMixin {
|
||||
@@ -19,6 +23,15 @@ public abstract class ServerHandshakeNetworkHandlerMixin {
|
||||
@Final
|
||||
private Connection connection;
|
||||
|
||||
/**
|
||||
* 记下玩家实际用来进服的地址,房间 transfer 时把他送回同一个入口。
|
||||
*/
|
||||
@Inject(method = "handleIntention", at = @At("HEAD"))
|
||||
private void sf$captureAddress(ClientIntentionPacket packet, CallbackInfo ci) {
|
||||
((HandshakeAddress.Holder) connection)
|
||||
.sfcraft$setHandshakeAddress(HandshakeAddress.sanitize(packet.hostName(), packet.port()));
|
||||
}
|
||||
|
||||
@Redirect(method = "handleIntention", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getStatus()Lnet/minecraft/network/protocol/status/ServerStatus;"))
|
||||
public ServerStatus getMetadata(MinecraftServer instance) {
|
||||
var result = SFCallbacks.MOTD.invoker().onMotd(instance,connection);
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.ib67.kiwi.tuple.Tuple2;
|
||||
import io.ib67.sfcraft.ServerModule;
|
||||
import io.ib67.sfcraft.config.SFConfig;
|
||||
import io.ib67.sfcraft.inject.MinecraftServerSupplier;
|
||||
import io.ib67.sfcraft.network.HandshakeAddress;
|
||||
import io.ib67.sfcraft.registry.RoomRegistry;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
@@ -20,7 +21,6 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.PacketSendListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.common.ClientboundStoreCookiePacket;
|
||||
import net.minecraft.network.protocol.common.ClientboundTransferPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
@@ -83,8 +83,9 @@ public class RoomModule extends ServerModule {
|
||||
return 0;
|
||||
}
|
||||
var networkHandler = player.connection;
|
||||
var transfer = HandshakeAddress.transferPacketFor(player, config);
|
||||
networkHandler.send(new ClientboundStoreCookiePacket(ROOM_COOKIE, EMPTY), PacketSendListener.thenRun(() -> {
|
||||
networkHandler.send(new ClientboundTransferPacket(config.domain, config.port));
|
||||
networkHandler.send(transfer);
|
||||
}));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.ib67.sfcraft.network;
|
||||
|
||||
import io.ib67.sfcraft.config.SFConfig;
|
||||
import io.ib67.sfcraft.mixin.common.bridge.ServerCommonNetworkHandlerBridge;
|
||||
import net.minecraft.network.protocol.common.ClientboundTransferPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* 玩家在握手包里自报的服务器地址,也就是他实际用来进服的那个地址。
|
||||
* 由 {@code ServerHandshakeNetworkHandlerMixin} 记到 {@link net.minecraft.network.Connection} 上,
|
||||
* transfer 时原样回显,让玩家重连回原本的入口而不是配置里写死的那个。
|
||||
*/
|
||||
public record HandshakeAddress(String host, int port) {
|
||||
/**
|
||||
* 代理(BungeeCord/Velocity legacy forwarding、FML)会把转发数据拼在 hostName 后面,以 '\0' 分隔。
|
||||
*/
|
||||
private static final char FORWARDING_SEPARATOR = '\0';
|
||||
|
||||
/**
|
||||
* 挂在 {@link net.minecraft.network.Connection} 上的握手地址,由 ConnectionMixin 实现。
|
||||
*/
|
||||
public interface Holder {
|
||||
@Nullable
|
||||
HandshakeAddress sfcraft$handshakeAddress();
|
||||
|
||||
void sfcraft$setHandshakeAddress(@Nullable HandshakeAddress address);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清洗握手包里的 hostName / port,不可用时返回 null。
|
||||
*/
|
||||
public static @Nullable HandshakeAddress sanitize(String hostName, int port) {
|
||||
if (hostName == null || port <= 0 || port > 65535) return null;
|
||||
var host = hostName;
|
||||
var separator = host.indexOf(FORWARDING_SEPARATOR);
|
||||
if (separator >= 0) host = host.substring(0, separator);
|
||||
// SRV 解析出来的 FQDN 可能带尾点
|
||||
while (host.endsWith(".")) host = host.substring(0, host.length() - 1);
|
||||
host = host.trim();
|
||||
return host.isEmpty() ? null : new HandshakeAddress(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读玩家当前连接上记的握手地址,拿不到返回 null。
|
||||
*/
|
||||
public static @Nullable HandshakeAddress of(ServerPlayer player) {
|
||||
var connection = ((ServerCommonNetworkHandlerBridge) player.connection).sfcraft$getConnection();
|
||||
return connection instanceof Holder holder ? holder.sfcraft$handshakeAddress() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优先把玩家送回他自己用的地址,拿不到才回退配置里的 domain / port。
|
||||
*/
|
||||
public static ClientboundTransferPacket transferPacketFor(ServerPlayer player, SFConfig fallback) {
|
||||
var address = of(player);
|
||||
return address == null
|
||||
? new ClientboundTransferPacket(fallback.domain, fallback.port)
|
||||
: new ClientboundTransferPacket(address.host(), address.port());
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,13 @@ import io.ib67.sfcraft.config.SFConfig;
|
||||
import io.ib67.sfcraft.inject.MinecraftServerSupplier;
|
||||
import io.ib67.sfcraft.module.RoomModule;
|
||||
import io.ib67.sfcraft.module.SignatureService;
|
||||
import io.ib67.sfcraft.network.HandshakeAddress;
|
||||
import io.ib67.sfcraft.registry.RoomRegistry;
|
||||
import io.ib67.sfcraft.subserver.Room;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.network.PacketSendListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.common.ClientboundStoreCookiePacket;
|
||||
import net.minecraft.network.protocol.common.ClientboundTransferPacket;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.CommonColors;
|
||||
@@ -44,6 +44,8 @@ public class RoomTeleporter {
|
||||
throw new IllegalStateException("world isn't exist");
|
||||
}
|
||||
var networkHandler = player.connection;
|
||||
// 趁连接还在 play 阶段先取好目标地址
|
||||
var transfer = HandshakeAddress.transferPacketFor(player, config);
|
||||
networkHandler.switchToConfig();
|
||||
var request = new RequestedRoom(room.getServerIdentifier(), name, finalUuid);
|
||||
var requestBuf = Unpooled.buffer();
|
||||
@@ -58,7 +60,7 @@ public class RoomTeleporter {
|
||||
)
|
||||
);
|
||||
networkHandler.send(new ClientboundStoreCookiePacket(ROOM_COOKIE, cookie), PacketSendListener.thenRun(() -> {
|
||||
networkHandler.send(new ClientboundTransferPacket(config.domain, config.port));
|
||||
networkHandler.send(transfer);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,13 @@
|
||||
"client": [
|
||||
],
|
||||
"server": [
|
||||
"common.ConnectionMixin",
|
||||
"common.EntityMixin",
|
||||
"common.MobEntityMixin",
|
||||
"common.PlayerEntityMixin",
|
||||
"common.bridge.EntityBridge",
|
||||
"common.bridge.ServerChunkManagerBridge",
|
||||
"common.bridge.ServerCommonNetworkHandlerBridge",
|
||||
"common.bridge.ServerPlayerBridge",
|
||||
"common.bridge.ServerWorldBridge",
|
||||
"common.fixes.EndermanEntityMixin",
|
||||
|
||||
Reference in new issue
Block a user