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;
import io.ib67.sfcraft.SFCraft;
import io.ib67.sfcraft.module.RoomModule;
import io.ib67.sfcraft.registry.RoomRegistry;
import io.ib67.sfcraft.util.Helper;
import net.minecraft.entity.Entity;
@@ -21,7 +22,7 @@ public abstract class EntityMixin {
@Inject(at = @At("HEAD"), method = "teleportTo", cancellable = true)
private void sf$redirectTeleport(TeleportTarget teleportTarget, CallbackInfoReturnable<Entity> cir) {
if (Helper.isVirtual(this.getUuid())) {
if (RoomModule.isVirtual(this.getUuid())) {
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;
import com.mojang.datafixers.DataFixer;
import io.ib67.sfcraft.module.RoomModule;
import io.ib67.sfcraft.util.Helper;
import net.minecraft.entity.player.PlayerEntity;
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")
private File sf$getPlayerDataFolder(PlayerSaveHandler instance, PlayerEntity entity) {
if (Helper.isVirtual(entity.getUuid())) {
if (RoomModule.isVirtual(entity.getUuid())) {
return virtualPlayerFolder;
} else {
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;")
private File sf$saveGetPlayerFolder(PlayerSaveHandler instance, PlayerEntity player) {
if (Helper.isVirtual(player.getUuid())) {
if (RoomModule.isVirtual(player.getUuid())) {
return virtualPlayerFolder;
} else {
return this.playerDataDir;
@@ -10,7 +10,6 @@ import io.ib67.sfcraft.config.SFConfig;
import io.ib67.sfcraft.inject.MinecraftServerSupplier;
import io.ib67.sfcraft.room.RequestedRoom;
import io.ib67.sfcraft.registry.RoomRegistry;
import io.ib67.sfcraft.util.Helper;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.SneakyThrows;
@@ -24,7 +23,6 @@ import net.minecraft.network.packet.s2c.common.StoreCookieS2CPacket;
import net.minecraft.registry.RegistryKey;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.world.ChunkTicket;
import net.minecraft.server.world.ChunkTicketType;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
@@ -40,10 +38,11 @@ import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static io.ib67.sfcraft.room.RoomTeleporter.ROOM_COOKIE;
import static io.ib67.sfcraft.util.SFConsts.COMMAND_RECO;
@@ -59,6 +58,7 @@ public class RoomModule extends ServerModule {
private SFConfig config;
private Key key;
private final List<Pair<RegistryKey<World>, BlockPos>> pregenQueue = new ArrayList<>();
private final Map<UUID, GameProfile> uuidMapper = new ConcurrentHashMap<>();
@Override
public void onInitialize() {
@@ -70,11 +70,11 @@ public class RoomModule extends ServerModule {
public void onEnable() {
for (Pair<RegistryKey<World>, BlockPos> registryKeyBlockPosPair : pregenQueue) {
var world = serverSupplier.get().getWorld(registryKeyBlockPosPair.getLeft());
if(world == null){
log.warn("Cannot find world "+registryKeyBlockPosPair.getLeft());
if (world == null) {
log.warn("Cannot find world " + registryKeyBlockPosPair.getLeft());
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) {
var player = serverCommandSourceCommandContext.getSource().getPlayer();
if (!Helper.isVirtual(player.getUuid())) {
if (!isVirtual(player.getUuid())) {
player.sendMessage(Text.literal("你不在任何 \"房间\" 内。"));
return 0;
}
@@ -161,4 +161,19 @@ public class RoomModule extends ServerModule {
public void enqueuePregen(RegistryKey<World> world, BlockPos 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 void teleportTo(Room room, ServerPlayerEntity player) {
if (Helper.isVirtual(player.getUuid())) {
if (roomModule.isVirtual(player.getUuid())) {
player.sendMessage(Text.literal("您已经在某个房间里了").withColor(Colors.LIGHT_RED));
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);
if(player.getServer().getWorld(sess.getSpawnPosition().dimension()) == null){
if (player.getServer().getWorld(sess.getSpawnPosition().dimension()) == null) {
throw new IllegalStateException("world isn't exist");
}
var networkHandler = player.networkHandler;
@@ -117,13 +117,4 @@ public class Helper {
}
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.PlayerManagerMixin",
"server.subserver.PlayerSaveHandlerMixin",
"server.subserver.ServerPlayerEntityMixin"
"server.subserver.ServerPlayerEntityMixin",
"server.subserver.PlayerListS2CPacket$EntryMixin"
],
"injectors": {
"defaultRequire": 1