fix(room): skin is rendered incorrectly.

This commit is contained in:
iceBear67 committed 2024-09-01 23:41:04 +08:00
1 parent b3e5f2753e
commit d66918fe78
7 files changed
+74 -24

No files matched your search

@@ -1,6 +1,7 @@
package io.ib67.sfcraft.mixin.server.subserver; package io.ib67.sfcraft.mixin.server.subserver;
import io.ib67.sfcraft.SFCraft; import io.ib67.sfcraft.SFCraft;
import io.ib67.sfcraft.module.RoomModule;
import io.ib67.sfcraft.registry.RoomRegistry; import io.ib67.sfcraft.registry.RoomRegistry;
import io.ib67.sfcraft.util.Helper; import io.ib67.sfcraft.util.Helper;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@@ -21,7 +22,7 @@ public abstract class EntityMixin {
@Inject(at = @At("HEAD"), method = "teleportTo", cancellable = true) @Inject(at = @At("HEAD"), method = "teleportTo", cancellable = true)
private void sf$redirectTeleport(TeleportTarget teleportTarget, CallbackInfoReturnable<Entity> cir) { private void sf$redirectTeleport(TeleportTarget teleportTarget, CallbackInfoReturnable<Entity> cir) {
if (Helper.isVirtual(this.getUuid())) { if (RoomModule.isVirtual(this.getUuid())) {
cir.setReturnValue((Entity) (Object) this); cir.setReturnValue((Entity) (Object) this);
} }
} }
@@ -0,0 +1,41 @@
package io.ib67.sfcraft.mixin.server.subserver;
import com.mojang.authlib.GameProfile;
import io.ib67.sfcraft.SFCraft;
import io.ib67.sfcraft.module.RoomModule;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.UUID;
@Mixin(PlayerListS2CPacket.Entry.class)
public class PlayerListS2CPacket$EntryMixin {
@Unique
private static final byte[] lock = new byte[0];
@Unique
private static volatile RoomModule module;
@Unique
private static RoomModule getModule() {
if (module == null) {
synchronized (lock) {
if (module == null) {
module = SFCraft.getInjector().getInstance(RoomModule.class);
}
}
}
return module;
}
@Redirect(method = "<init>(Lnet/minecraft/server/network/ServerPlayerEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;getGameProfile()Lcom/mojang/authlib/GameProfile;"))
private static GameProfile sf$redirectGameProfileForRoom(ServerPlayerEntity instance) {
if (!RoomModule.isVirtual(instance.getUuid())) {
return instance.getGameProfile();
}
return getModule().devirtualize(instance.getUuid());
}
}
@@ -1,6 +1,7 @@
package io.ib67.sfcraft.mixin.server.subserver; package io.ib67.sfcraft.mixin.server.subserver;
import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixer;
import io.ib67.sfcraft.module.RoomModule;
import io.ib67.sfcraft.util.Helper; import io.ib67.sfcraft.util.Helper;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.WorldSavePath; import net.minecraft.util.WorldSavePath;
@@ -33,7 +34,7 @@ public class PlayerSaveHandlerMixin {
@Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/world/PlayerSaveHandler;playerDataDir:Ljava/io/File;"), method = "savePlayerData") @Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/world/PlayerSaveHandler;playerDataDir:Ljava/io/File;"), method = "savePlayerData")
private File sf$getPlayerDataFolder(PlayerSaveHandler instance, PlayerEntity entity) { private File sf$getPlayerDataFolder(PlayerSaveHandler instance, PlayerEntity entity) {
if (Helper.isVirtual(entity.getUuid())) { if (RoomModule.isVirtual(entity.getUuid())) {
return virtualPlayerFolder; return virtualPlayerFolder;
} else { } else {
return this.playerDataDir; return this.playerDataDir;
@@ -42,7 +43,7 @@ public class PlayerSaveHandlerMixin {
@Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/world/PlayerSaveHandler;playerDataDir:Ljava/io/File;"), method = "loadPlayerData(Lnet/minecraft/entity/player/PlayerEntity;Ljava/lang/String;)Ljava/util/Optional;") @Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/world/PlayerSaveHandler;playerDataDir:Ljava/io/File;"), method = "loadPlayerData(Lnet/minecraft/entity/player/PlayerEntity;Ljava/lang/String;)Ljava/util/Optional;")
private File sf$saveGetPlayerFolder(PlayerSaveHandler instance, PlayerEntity player) { private File sf$saveGetPlayerFolder(PlayerSaveHandler instance, PlayerEntity player) {
if (Helper.isVirtual(player.getUuid())) { if (RoomModule.isVirtual(player.getUuid())) {
return virtualPlayerFolder; return virtualPlayerFolder;
} else { } else {
return this.playerDataDir; return this.playerDataDir;
@@ -10,7 +10,6 @@ import io.ib67.sfcraft.config.SFConfig;
import io.ib67.sfcraft.inject.MinecraftServerSupplier; import io.ib67.sfcraft.inject.MinecraftServerSupplier;
import io.ib67.sfcraft.room.RequestedRoom; import io.ib67.sfcraft.room.RequestedRoom;
import io.ib67.sfcraft.registry.RoomRegistry; import io.ib67.sfcraft.registry.RoomRegistry;
import io.ib67.sfcraft.util.Helper;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@@ -24,7 +23,6 @@ import net.minecraft.network.packet.s2c.common.StoreCookieS2CPacket;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.world.ChunkTicket;
import net.minecraft.server.world.ChunkTicketType; import net.minecraft.server.world.ChunkTicketType;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@@ -40,10 +38,11 @@ import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key; import java.security.Key;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.concurrent.ConcurrentHashMap;
import static io.ib67.sfcraft.room.RoomTeleporter.ROOM_COOKIE; import static io.ib67.sfcraft.room.RoomTeleporter.ROOM_COOKIE;
import static io.ib67.sfcraft.util.SFConsts.COMMAND_RECO; import static io.ib67.sfcraft.util.SFConsts.COMMAND_RECO;
@@ -59,6 +58,7 @@ public class RoomModule extends ServerModule {
private SFConfig config; private SFConfig config;
private Key key; private Key key;
private final List<Pair<RegistryKey<World>, BlockPos>> pregenQueue = new ArrayList<>(); private final List<Pair<RegistryKey<World>, BlockPos>> pregenQueue = new ArrayList<>();
private final Map<UUID, GameProfile> uuidMapper = new ConcurrentHashMap<>();
@Override @Override
public void onInitialize() { public void onInitialize() {
@@ -70,11 +70,11 @@ public class RoomModule extends ServerModule {
public void onEnable() { public void onEnable() {
for (Pair<RegistryKey<World>, BlockPos> registryKeyBlockPosPair : pregenQueue) { for (Pair<RegistryKey<World>, BlockPos> registryKeyBlockPosPair : pregenQueue) {
var world = serverSupplier.get().getWorld(registryKeyBlockPosPair.getLeft()); var world = serverSupplier.get().getWorld(registryKeyBlockPosPair.getLeft());
if(world == null){ if (world == null) {
log.warn("Cannot find world "+registryKeyBlockPosPair.getLeft()); log.warn("Cannot find world " + registryKeyBlockPosPair.getLeft());
continue; continue;
} }
world.getChunkManager().addTicket(ChunkTicketType.START,new ChunkPos(registryKeyBlockPosPair.getRight()),64, Unit.INSTANCE); world.getChunkManager().addTicket(ChunkTicketType.START, new ChunkPos(registryKeyBlockPosPair.getRight()), 64, Unit.INSTANCE);
} }
} }
@@ -88,7 +88,7 @@ public class RoomModule extends ServerModule {
private int onCleanReconnect(CommandContext<ServerCommandSource> serverCommandSourceCommandContext) { private int onCleanReconnect(CommandContext<ServerCommandSource> serverCommandSourceCommandContext) {
var player = serverCommandSourceCommandContext.getSource().getPlayer(); var player = serverCommandSourceCommandContext.getSource().getPlayer();
if (!Helper.isVirtual(player.getUuid())) { if (!isVirtual(player.getUuid())) {
player.sendMessage(Text.literal("你不在任何 \"房间\" 内。")); player.sendMessage(Text.literal("你不在任何 \"房间\" 内。"));
return 0; return 0;
} }
@@ -161,4 +161,19 @@ public class RoomModule extends ServerModule {
public void enqueuePregen(RegistryKey<World> world, BlockPos spawnPos) { public void enqueuePregen(RegistryKey<World> world, BlockPos spawnPos) {
pregenQueue.add(new Pair<>(world, spawnPos)); pregenQueue.add(new Pair<>(world, spawnPos));
} }
public UUID generateIdForRoom(GameProfile issuer, String name, Identifier room) {
var uuid = UUID.nameUUIDFromBytes((name + "@" + room.toString()).getBytes(StandardCharsets.UTF_8));
var result = new UUID(uuid.getMostSignificantBits(), 0);
if (issuer != null) uuidMapper.put(result, issuer);
return result;
}
public static boolean isVirtual(UUID uuid) {
return uuid.getLeastSignificantBits() == 0;
}
public GameProfile devirtualize(UUID virtual) {
return uuidMapper.get(virtual);
}
} }
@@ -28,13 +28,13 @@ public class RoomTeleporter {
public static final Identifier ROOM_COOKIE = Identifier.of("sfcraft", "room"); public static final Identifier ROOM_COOKIE = Identifier.of("sfcraft", "room");
public void teleportTo(Room room, ServerPlayerEntity player) { public void teleportTo(Room room, ServerPlayerEntity player) {
if (Helper.isVirtual(player.getUuid())) { if (roomModule.isVirtual(player.getUuid())) {
player.sendMessage(Text.literal("您已经在某个房间里了").withColor(Colors.LIGHT_RED)); player.sendMessage(Text.literal("您已经在某个房间里了").withColor(Colors.LIGHT_RED));
return; return;
} }
var finalUuid = Helper.generateIdForRoom(player.getName().getLiteralString(), room.getServerIdentifier()); var finalUuid = roomModule.generateIdForRoom(player.getGameProfile(), player.getName().getLiteralString(), room.getServerIdentifier());
var sess = room.getPlayerManager().createSessionFor(finalUuid); var sess = room.getPlayerManager().createSessionFor(finalUuid);
if(player.getServer().getWorld(sess.getSpawnPosition().dimension()) == null){ if (player.getServer().getWorld(sess.getSpawnPosition().dimension()) == null) {
throw new IllegalStateException("world isn't exist"); throw new IllegalStateException("world isn't exist");
} }
var networkHandler = player.networkHandler; var networkHandler = player.networkHandler;
@@ -117,13 +117,4 @@ public class Helper {
} }
return q[0] + "." + q[1] + ".*.*"; return q[0] + "." + q[1] + ".*.*";
} }
public static UUID generateIdForRoom(String name, Identifier room) {
var uuid = UUID.nameUUIDFromBytes((name + "@" + room.toString()).getBytes(StandardCharsets.UTF_8));
return new UUID(uuid.getMostSignificantBits(), 0);
}
public static boolean isVirtual(UUID uuid) {
return uuid.getLeastSignificantBits() == 0;
}
} }
+2 -1
View File
@@ -31,7 +31,8 @@
"server.subserver.EntityMixin", "server.subserver.EntityMixin",
"server.subserver.PlayerManagerMixin", "server.subserver.PlayerManagerMixin",
"server.subserver.PlayerSaveHandlerMixin", "server.subserver.PlayerSaveHandlerMixin",
"server.subserver.ServerPlayerEntityMixin" "server.subserver.ServerPlayerEntityMixin",
"server.subserver.PlayerListS2CPacket$EntryMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1