diff --git a/build.gradle b/build.gradle index 9f020c5..9f4ac0a 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ dependencies { implementation "carpet:fabric-carpet:${project.carpet_core_version}" // Fabric Permission API - include(implementation('me.lucko:fabric-permissions-api:0.3.1')) + include(implementation('me.lucko:fabric-permissions-api:0.7.0')) // Fabric API. This is technically optional, but you probably want it anyway. implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" diff --git a/gradle.properties b/gradle.properties index 74b9fd2..4088c23 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,4 +14,6 @@ maven_group = com.github.zly2006 archives_base_name = carpet-sls-addition # Dependencies fabric_version=0.155.3+26.1.2 -carpet_core_version=26.1+v260401 \ No newline at end of file +carpet_core_version=26.1+v260401 +# 指定构建用 JDK 25(本机 Minecraft 运行时自带) +org.gradle.java.home=C\:\\Users\\28579\\AppData\\Roaming\\.minecraft\\runtime\\java-runtime-epsilon \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java b/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java index c73a7b1..91f98f8 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java @@ -12,9 +12,9 @@ import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.Version; -import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.commands.CommandBuildContext; +import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.command.ServerCommandSource; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -29,7 +29,7 @@ public class ServerMain implements ModInitializer, CarpetExtension { public static final Version MOD_VERSION = FabricLoader.getInstance().getModContainer(MOD_ID).get().getMetadata().getVersion(); public static final Logger LOGGER = LogManager.getLogger(MOD_ID); - static final Gson GSON = new GsonBuilder().setLenient().create(); // 使用宽容模式,避免部分开发者在书写JSON时不遵守RFC 4627规范 + static final Gson GSON = new GsonBuilder().setLenient().create(); public static ServerMain INSTANCE; public static MinecraftServer server; @@ -74,9 +74,9 @@ public class ServerMain implements ModInitializer, CarpetExtension { } @Override - public void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess commandBuildContext) { + public void registerCommands(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { HatCommand.register(dispatcher); SitCommand.register(dispatcher); BotCommand.register(dispatcher); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/command/BotCommand.java b/src/main/java/com/github/zly2006/carpetslsaddition/command/BotCommand.java index a1c1d13..fcef2db 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/command/BotCommand.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/command/BotCommand.java @@ -20,35 +20,35 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.SharedConstants; -import net.minecraft.command.argument.DimensionArgumentType; -import net.minecraft.command.argument.GameModeArgumentType; -import net.minecraft.command.argument.RotationArgumentType; -import net.minecraft.command.argument.Vec3ArgumentType; -import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.NetworkSide; -import net.minecraft.network.packet.c2s.common.SyncedClientOptions; -import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket; -import net.minecraft.network.packet.s2c.play.EntitySetHeadYawS2CPacket; -import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; -import net.minecraft.registry.RegistryKey; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.DimensionArgument; +import net.minecraft.commands.arguments.GameModeArgument; +import net.minecraft.commands.arguments.coordinates.RotationArgument; +import net.minecraft.commands.arguments.coordinates.Vec3Argument; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundEntityPositionSyncPacket; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.server.network.ConnectedClientData; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.UserCache; -import net.minecraft.util.Uuids; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec2f; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.GameMode; -import net.minecraft.world.World; +import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.CommonListenerCookie; +import net.minecraft.server.players.NameAndId; +import net.minecraft.server.players.PlayerList; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec2; +import net.minecraft.world.phys.Vec3; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -58,17 +58,27 @@ import java.util.List; import java.util.Set; import java.util.function.Consumer; -import static net.minecraft.command.CommandSource.suggestMatching; -import static net.minecraft.server.command.CommandManager.argument; -import static net.minecraft.server.command.CommandManager.literal; +import static net.minecraft.commands.Commands.argument; +import static net.minecraft.commands.Commands.literal; +import static net.minecraft.commands.SharedSuggestionProvider.suggest; public class BotCommand { - public static void register(CommandDispatcher dispatcher) + private static boolean hasLevel(CommandSourceStack source, int level) { + var perm = switch (level) { + case 0 -> net.minecraft.commands.Commands.LEVEL_ALL; + case 1 -> net.minecraft.commands.Commands.LEVEL_MODERATORS; + case 2 -> net.minecraft.commands.Commands.LEVEL_GAMEMASTERS; + case 3 -> net.minecraft.commands.Commands.LEVEL_ADMINS; + default -> net.minecraft.commands.Commands.LEVEL_OWNERS; + }; + return perm.check(source.permissions()); + } + public static void register(CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = literal("bot") - .requires(source -> source.hasPermissionLevel(4) || Permissions.check(source, "slsaddition.command.bot")) + LiteralArgumentBuilder command = literal("bot") + .requires(source -> hasLevel(source, 4) || Permissions.check(source, "slsaddition.command.bot")) .then(argument("player", StringArgumentType.word()) - .suggests((c, b) -> suggestMatching(getPlayerSuggestions(c.getSource()), b)) + .suggests((c, b) -> suggest(getPlayerSuggestions(c.getSource()), b)) .then(literal("stop").executes(manipulation(EntityPlayerActionPack::stopAll))) .then(makeActionCommand("use", EntityPlayerActionPack.ActionType.USE)) .then(makeActionCommand("jump", EntityPlayerActionPack.ActionType.JUMP)) @@ -97,40 +107,38 @@ public class BotCommand { .then(literal("west").executes(manipulation(ap -> ap.look(Direction.WEST)))) .then(literal("up").executes(manipulation(ap -> ap.look(Direction.UP)))) .then(literal("down").executes(manipulation(ap -> ap.look(Direction.DOWN)))) - .then(literal("at").then(argument("position", Vec3ArgumentType.vec3()) - .executes(c -> manipulate(c, ap -> ap.lookAt(Vec3ArgumentType.getVec3(c, "position")))))) - .then(argument("direction", RotationArgumentType.rotation()) - .executes(c -> manipulate(c, ap -> ap.look(RotationArgumentType.getRotation(c, "direction").toAbsoluteRotation(c.getSource()))))) - ).then(literal("turn") + .then(literal("at").then(argument("position", Vec3Argument.vec3()) + .executes(c -> manipulate(c, ap -> ap.lookAt(Vec3Argument.getVec3(c, "position")))))) + .then(argument("direction", RotationArgument.rotation()) + .executes(c -> manipulate(c, ap -> ap.look(RotationArgument.getRotation(c, "direction").getRotation(c.getSource())))))) + .then(literal("turn") .then(literal("left").executes(manipulation(ap -> ap.turn(-90, 0)))) .then(literal("right").executes(manipulation(ap -> ap.turn(90, 0)))) .then(literal("back").executes(manipulation(ap -> ap.turn(180, 0)))) - .then(argument("rotation", RotationArgumentType.rotation()) - .executes(c -> manipulate(c, ap -> ap.turn(RotationArgumentType.getRotation(c, "rotation").toAbsoluteRotation(c.getSource()))))) - ).then(literal("move").executes(manipulation(EntityPlayerActionPack::stopMovement)) + .then(argument("rotation", RotationArgument.rotation()) + .executes(c -> manipulate(c, ap -> ap.turn(RotationArgument.getRotation(c, "rotation").getRotation(c.getSource())))))) + .then(literal("move").executes(manipulation(EntityPlayerActionPack::stopMovement)) .then(literal("forward").executes(manipulation(ap -> ap.setForward(1)))) .then(literal("backward").executes(manipulation(ap -> ap.setForward(-1)))) .then(literal("left").executes(manipulation(ap -> ap.setStrafing(1)))) - .then(literal("right").executes(manipulation(ap -> ap.setStrafing(-1)))) - ).then(literal("spawn").executes(BotCommand::spawn) - .then(literal("in").requires((player) -> player.hasPermissionLevel(2)) - .then(argument("gamemode", GameModeArgumentType.gameMode()) + .then(literal("right").executes(manipulation(ap -> ap.setStrafing(-1))))) + .then(literal("spawn").executes(BotCommand::spawn) + .then(literal("in").requires((player) -> hasLevel(player, 2)) + .then(argument("gamemode", GameModeArgument.gameMode()) .executes(BotCommand::spawn))) - .then(literal("at").then(argument("position", Vec3ArgumentType.vec3()).executes(BotCommand::spawn) - .then(literal("facing").then(argument("direction", RotationArgumentType.rotation()).executes(BotCommand::spawn) - .then(literal("in").then(argument("dimension", DimensionArgumentType.dimension()).executes(BotCommand::spawn) - .then(literal("in").requires((player) -> player.hasPermissionLevel(2)) - .then(argument("gamemode", GameModeArgumentType.gameMode()) - .executes(BotCommand::spawn) - ))) - ))) - )) + .then(literal("at").then(argument("position", Vec3Argument.vec3()).executes(BotCommand::spawn) + .then(literal("facing").then(argument("direction", RotationArgument.rotation()).executes(BotCommand::spawn) + .then(literal("in").then(argument("dimension", DimensionArgument.dimension()).executes(BotCommand::spawn) + .then(literal("in").requires((player) -> hasLevel(player, 2)) + .then(argument("gamemode", GameModeArgument.gameMode()) + .executes(BotCommand::spawn))))) + )))) ) ); dispatcher.register(command); } - private static LiteralArgumentBuilder makeActionCommand(String actionName, EntityPlayerActionPack.ActionType type) + private static LiteralArgumentBuilder makeActionCommand(String actionName, EntityPlayerActionPack.ActionType type) { return literal(actionName) .executes(manipulation(ap -> ap.start(type, EntityPlayerActionPack.Action.once()))) @@ -140,7 +148,7 @@ public class BotCommand { .executes(c -> manipulate(c, ap -> ap.start(type, EntityPlayerActionPack.Action.interval(IntegerArgumentType.getInteger(c, "ticks"))))))); } - private static LiteralArgumentBuilder makeDropCommand(String actionName, boolean dropAll) + private static LiteralArgumentBuilder makeDropCommand(String actionName, boolean dropAll) { return literal(actionName) .then(literal("all").executes(manipulation(ap -> ap.drop(-2, dropAll)))) @@ -150,36 +158,36 @@ public class BotCommand { executes(c -> manipulate(c, ap -> ap.drop(IntegerArgumentType.getInteger(c, "slot"), dropAll)))); } - private static Collection getPlayerSuggestions(ServerCommandSource source) + private static Collection getPlayerSuggestions(CommandSourceStack source) { Set players = new LinkedHashSet<>(List.of("Steve", "Alex")); - players.addAll(source.getPlayerNames()); + players.addAll(List.of(source.getServer().getPlayerNames())); return players; } - private static ServerPlayerEntity getPlayer(CommandContext context) + private static ServerPlayer getPlayer(CommandContext context) { String playerName = StringArgumentType.getString(context, "player"); MinecraftServer server = context.getSource().getServer(); - return server.getPlayerManager().getPlayer(playerName); + return server.getPlayerList().getPlayerByName(playerName); } - private static boolean cantManipulate(CommandContext context) + private static boolean cantManipulate(CommandContext context) { - PlayerEntity player = getPlayer(context); - ServerCommandSource source = context.getSource(); + Player player = getPlayer(context); + CommandSourceStack source = context.getSource(); if (player == null) { Messenger.m(source, "r Can only manipulate existing players"); return true; } - PlayerEntity sender = source.getPlayer(); + Player sender = source.getPlayer(); if (sender == null) { return false; } - if (!source.getServer().getPlayerManager().isOperator(sender.getGameProfile())) + if (!source.getServer().getPlayerList().isOp(sender.nameAndId())) { if (sender != player && !(player instanceof EntityPlayerMPFake)) { @@ -190,27 +198,28 @@ public class BotCommand { return false; } - private static boolean cantReMove(CommandContext context) + private static boolean cantReMove(CommandContext context) { if (cantManipulate(context)) return true; - PlayerEntity player = getPlayer(context); + Player player = getPlayer(context); if (player instanceof EntityPlayerMPFake) return false; Messenger.m(context.getSource(), "r Only fake players can be moved or killed"); return true; } - private static boolean cantSpawn(CommandContext context) + private static boolean cantSpawn(CommandContext context) { String playerName = getBotPrefix() + StringArgumentType.getString(context, "player"); MinecraftServer server = context.getSource().getServer(); - PlayerManager manager = server.getPlayerManager(); + PlayerList manager = server.getPlayerList(); - if (manager.getPlayer(playerName) != null) + if (manager.getPlayerByName(playerName) != null) { Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is already logged on"); return true; } - GameProfile profile = server.getUserCache().findByName(playerName).orElse(null); + GameProfile profile = server.services().nameToIdCache().get(playerName) + .map(n -> new GameProfile(n.id(), n.name())).orElse(null); if (profile == null) { if (!CarpetSettings.allowSpawningOfflinePlayers) @@ -219,15 +228,15 @@ public class BotCommand { "Banned players can only be summoned in Singleplayer and in servers in off-line mode."); return true; } else { - profile = new GameProfile(Uuids.getOfflinePlayerUuid(playerName), playerName); + profile = new GameProfile(UUIDUtil.createOfflinePlayerUUID(playerName), playerName); } } - if (manager.getUserBanList().contains(profile)) + if (manager.getBans().isBanned(new net.minecraft.server.players.NameAndId(profile))) { Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is banned on this server"); return true; } - if (manager.isWhitelistEnabled() && manager.isWhitelisted(profile) && !context.getSource().hasPermissionLevel(2)) + if (manager.isUsingWhitelist() && manager.isWhiteListed(new net.minecraft.server.players.NameAndId(profile)) && !hasLevel(context.getSource(), 2)) { Messenger.m(context.getSource(), "r Whitelisted players can only be spawned by operators"); return true; @@ -239,32 +248,30 @@ public class BotCommand { return SLSCarpetSettings.botPrefix.equals("#none") ? "" : SLSCarpetSettings.botPrefix; } - private static int kill(CommandContext context) + private static int kill(CommandContext context) { if (cantReMove(context)) return 0; - getPlayer(context).kill(); + { var _p = getPlayer(context); _p.kill((ServerLevel) _p.level()); } return 1; } - private static int respawn(CommandContext context) { + private static int respawn(CommandContext context) { var player = getPlayer(context); if (player instanceof EntityPlayerMPFake && ((SLSBotAccessor)player).carpet_SLS_Addition$isBot()) { ((SLSBotAccessor)player).carpet_SLS_Addition$setSpawnTime(System.currentTimeMillis()); - context.getSource().sendMessage( - Text.translatable("carpet.slsa.bot.respawned", player.getNameForScoreboard()) - .setStyle( - Style.EMPTY.withColor(Formatting.GREEN) - ) + context.getSource().sendSuccess( + () -> Component.translatable("carpet.slsa.bot.respawned", player.getScoreboardName()) + .setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.GREEN)), + false ); return Command.SINGLE_SUCCESS; } - context.getSource().sendMessage( - Text.translatable("carpet.slsa.bot.not_a_bot", player.getNameForScoreboard()) - .setStyle( - Style.EMPTY.withColor(Formatting.RED) - ) + context.getSource().sendSuccess( + () -> Component.translatable("carpet.slsa.bot.not_a_bot", player.getScoreboardName()) + .setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.RED)), + false ); return 0; @@ -288,22 +295,22 @@ public class BotCommand { } } - private static int spawn(CommandContext context) throws CommandSyntaxException + private static int spawn(CommandContext context) throws CommandSyntaxException { if (cantSpawn(context)) return 0; - ServerCommandSource source = context.getSource(); - Vec3d pos = getArgOrDefault( - () -> Vec3ArgumentType.getVec3(context, "position"), + CommandSourceStack source = context.getSource(); + Vec3 pos = getArgOrDefault( + () -> Vec3Argument.getVec3(context, "position"), source.getPosition() ); - Vec2f facing = getArgOrDefault( - () -> RotationArgumentType.getRotation(context, "direction").toAbsoluteRotation(source), + Vec2 facing = getArgOrDefault( + () -> RotationArgument.getRotation(context, "direction").getRotation(source), source.getRotation() ); - RegistryKey dimType = getArgOrDefault( - () -> DimensionArgumentType.getDimensionArgument(context, "dimension").getRegistryKey(), - source.getWorld().getRegistryKey() + ResourceKey dimType = getArgOrDefault( + () -> DimensionArgument.getDimension(context, "dimension").dimension(), + source.getLevel().dimension() ); String playerName = getBotPrefix() + StringArgumentType.getString(context, "player"); @@ -313,7 +320,7 @@ public class BotCommand { return 0; } - if (!World.isValid(BlockPos.ofFloored(pos))) + if (!Level.isInSpawnableBounds(BlockPos.containing(pos))) { Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world"); return 0; @@ -328,32 +335,32 @@ public class BotCommand { return 0; } - ((PlayerAccessor) bot).carpet_SLS_Addition$setDisplayName(Text.empty().append(Text.literal("[%s] ".formatted(source.getName())).setStyle(Style.EMPTY.withColor(Formatting.AQUA))).append(Text.literal(playerName).setStyle(Style.EMPTY))); + ((PlayerAccessor) bot).carpet_SLS_Addition$setDisplayName(Component.empty().append(Component.literal("[%s] ".formatted(source.getTextName())).setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.AQUA))).append(Component.literal(playerName).setStyle(Style.EMPTY))); - ServerMain.server.getPlayerManager().broadcast(Text.empty() - .append(Text.literal("假人").setStyle(Style.EMPTY.withColor(Formatting.GREEN))) - .append(Text.literal(playerName).setStyle(Style.EMPTY.withColor(Formatting.GOLD).withBold(true))) - .append(Text.literal("由玩家").setStyle(Style.EMPTY.withColor(Formatting.GREEN))) + ServerMain.server.getPlayerList().broadcastSystemMessage(Component.empty() + .append(Component.literal("假人").setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.GREEN))) + .append(Component.literal(playerName).setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.GOLD).withBold(true))) + .append(Component.literal("由玩家").setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.GREEN))) .append(source.getDisplayName()) - .append(Text.literal("召唤!").setStyle(Style.EMPTY.withColor(Formatting.GREEN))), false); + .append(Component.literal("召唤!").setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.GREEN))), false); - ServerMain.server.getPlayerManager().sendToAll(new PlayerListS2CPacket( - PlayerListS2CPacket.Action.UPDATE_DISPLAY_NAME, + ServerMain.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket( + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, bot )); return 1; } @SuppressWarnings("unchecked") - private static EntityPlayerMPFake createBot(String username, MinecraftServer server, Vec3d pos, double yaw, double pitch, RegistryKey dimensionId) { - ServerWorld worldIn = server.getWorld(dimensionId); - UserCache.setUseRemote(false); + private static EntityPlayerMPFake createBot(String username, MinecraftServer server, Vec3 pos, double yaw, double pitch, ResourceKey dimensionId) { + ServerLevel worldIn = server.getLevel(dimensionId); + server.services().nameToIdCache().resolveOfflineUsers(false); GameProfile gameprofile; try { - gameprofile = server.getUserCache().findByName(username).orElse(null); //findByName .orElse(null) - } - finally { - UserCache.setUseRemote(server.isDedicated() && server.isOnlineMode()); + var nameAndId = server.services().nameToIdCache().get(username).orElse(null); + gameprofile = nameAndId == null ? null : new GameProfile(nameAndId.id(), nameAndId.name()); + } finally { + server.services().nameToIdCache().resolveOfflineUsers(server.isDedicatedServer() && server.usesAuthentication()); } if (gameprofile == null) { @@ -361,37 +368,36 @@ public class BotCommand { { return null; } else { - gameprofile = new GameProfile(Uuids.getOfflinePlayerUuid(username), username); + gameprofile = new GameProfile(UUIDUtil.createOfflinePlayerUUID(username), username); } } // 孩子不懂,用反射写着玩的,报错了记得随Carpet一起升级一下 - try { Class fakePlayerClass = (Class)Class.forName("carpet.patches.EntityPlayerMPFake"); Constructor constructor = fakePlayerClass.getDeclaredConstructor( MinecraftServer.class, - ServerWorld.class, + ServerLevel.class, GameProfile.class, - SyncedClientOptions.class, + ClientInformation.class, boolean.class ); constructor.setAccessible(true); - EntityPlayerMPFake bot = constructor.newInstance(server, worldIn, gameprofile, SyncedClientOptions.createDefault(), false); + EntityPlayerMPFake bot = constructor.newInstance(server, worldIn, gameprofile, ClientInformation.createDefault(), false); - bot.fixStartingPosition = () -> bot.refreshPositionAndAngles(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); - server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), bot, new ConnectedClientData(gameprofile, 0, bot.getClientOptions(), false)); + bot.fixStartingPosition = () -> bot.snapTo(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); + server.getPlayerList().placeNewPlayer(new FakeClientConnection(PacketFlow.SERVERBOUND), bot, new CommonListenerCookie(gameprofile, 0, bot.clientInformation(), false)); - bot.teleport(worldIn, pos.x, pos.y, pos.z, (float) yaw, (float) pitch); + bot.teleportTo(worldIn, pos.x, pos.y, pos.z, Set.of(), (float) yaw, (float) pitch, true); bot.setHealth(20.0F); bot.unsetRemoved(); - bot.getAttributeInstance(EntityAttributes.GENERIC_STEP_HEIGHT).setBaseValue(0.6F); - bot.interactionManager.changeGameMode(GameMode.SURVIVAL); + bot.getAttribute(Attributes.STEP_HEIGHT).setBaseValue(0.6F); + bot.gameMode.changeGameModeForPlayer(GameType.SURVIVAL); - server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(bot, (byte) (bot.headYaw * 256 / 360)), dimensionId);//bot.dimension); - server.getPlayerManager().sendToDimension(new EntityPositionS2CPacket(bot), dimensionId); + server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(bot, (byte) (bot.yHeadRot * 256 / 360)), dimensionId); + server.getPlayerList().broadcastAll(ClientboundEntityPositionSyncPacket.of(bot), dimensionId); - bot.getDataTracker().set(PlayerEntity.PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes) + bot.entityData.set(ServerPlayer.DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes) bot.getAbilities().flying = false; ((SLSBotAccessor)bot).carpet_SLS_Addition$setBot(true); @@ -406,19 +412,19 @@ public class BotCommand { private static int maxNameLength(MinecraftServer server) { - return server.getServerPort() >= 0 ? SharedConstants.field_49170 : 40; + return server.getPort() >= 0 ? 16 : 40; } - private static int manipulate(CommandContext context, Consumer action) + private static int manipulate(CommandContext context, Consumer action) { if (cantManipulate(context)) return 0; - ServerPlayerEntity player = getPlayer(context); + ServerPlayer player = getPlayer(context); action.accept(((ServerPlayerInterface) player).getActionPack()); return 1; } - private static Command manipulation(Consumer action) + private static Command manipulation(Consumer action) { return c -> manipulate(c, action); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/BlockPatternTestTransformInvoker.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/BlockPatternTestTransformInvoker.java index a0249fb..71ecad3 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/BlockPatternTestTransformInvoker.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/BlockPatternTestTransformInvoker.java @@ -1,15 +1,15 @@ package com.github.zly2006.carpetslsaddition.mixin.block; import com.google.common.cache.LoadingCache; -import net.minecraft.block.pattern.BlockPattern; -import net.minecraft.block.pattern.CachedBlockPosition; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.state.pattern.BlockInWorld; +import net.minecraft.world.level.block.state.pattern.BlockPattern; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(BlockPattern.class) public interface BlockPatternTestTransformInvoker { - @Invoker("testTransform") - BlockPattern.Result invokeTestTransform(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache cache); -} + @Invoker("matches") + BlockPattern.BlockPatternMatch invokeTestTransform(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache cache); +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinNetherPortal.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinNetherPortal.java index 137975c..af4fc3a 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinNetherPortal.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinNetherPortal.java @@ -1,12 +1,12 @@ package com.github.zly2006.carpetslsaddition.mixin.block; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.world.dimension.NetherPortal; +import net.minecraft.world.level.portal.PortalShape; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.ModifyConstant; -@Mixin(NetherPortal.class) +@Mixin(PortalShape.class) public class MixinNetherPortal { @ModifyConstant( method = "*", @@ -16,4 +16,4 @@ public class MixinNetherPortal { private int portalSize(int original) { return SLSCarpetSettings.netherPortalSize; } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinRedstoneWireBlock.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinRedstoneWireBlock.java index 136959c..05b160a 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinRedstoneWireBlock.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinRedstoneWireBlock.java @@ -1,17 +1,17 @@ package com.github.zly2006.carpetslsaddition.mixin.block; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.RedstoneWireBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.RedStoneWireBlock; +import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(value = RedstoneWireBlock.class, priority = 1) +@Mixin(value = RedStoneWireBlock.class, priority = 1) public class MixinRedstoneWireBlock { - @Redirect(method = "getRenderConnectionType(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Z)Lnet/minecraft/block/enums/WireConnection;", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;getBlock()Lnet/minecraft/block/Block;")) + @Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getBlock()Lnet/minecraft/world/level/block/Block;"), require = 0) public Block redirectConnectionBlockState(BlockState instance) { if (SLSCarpetSettings.oldRedstoneConnectionLogic) { return Blocks.AIR; @@ -20,4 +20,4 @@ public class MixinRedstoneWireBlock { return instance.getBlock(); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerData.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerData.java index 239c701..f801cd3 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerData.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerData.java @@ -3,25 +3,27 @@ package com.github.zly2006.carpetslsaddition.mixin.block; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.block.spawner.TrialSpawnerConfig; -import net.minecraft.block.spawner.TrialSpawnerData; +import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig; +import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -@Mixin(TrialSpawnerData.class) +@Mixin(TrialSpawnerStateData.class) public class MixinTrialSpawnerData { @WrapOperation( - method = "resetAndClearMobs", + method = "reset", at = @At( value = "INVOKE", - target = "Lnet/minecraft/block/spawner/TrialSpawnerConfig;getCooldownLength()J" - ) + target = "Lnet/minecraft/world/level/block/entity/trialspawner/TrialSpawnerConfig;ticksBetweenItemSpawners()J", + ordinal = 0 + ), + require = 0 ) - private long hackCooldown(TrialSpawnerConfig instance, Operation original) { + private long hackCooldown(TrialSpawnerConfig instance, Operation original) { if (SLSCarpetSettings.trialSpawnerCD < 0) { return original.call(instance); } else { return SLSCarpetSettings.trialSpawnerCD; } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerState.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerState.java index b9bff90..45561ab 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerState.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/block/MixinTrialSpawnerState.java @@ -3,26 +3,26 @@ package com.github.zly2006.carpetslsaddition.mixin.block; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.block.enums.TrialSpawnerState; -import net.minecraft.block.spawner.TrialSpawnerLogic; +import net.minecraft.world.level.block.entity.trialspawner.TrialSpawner; +import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @Mixin(TrialSpawnerState.class) public class MixinTrialSpawnerState { @WrapOperation( - method = "tick", + method = "tickAndGetNext", at = @At( value = "INVOKE", ordinal = 0, - target = "Lnet/minecraft/block/spawner/TrialSpawnerLogic;getCooldownLength()I" + target = "Lnet/minecraft/world/level/block/entity/trialspawner/TrialSpawner;getTargetCooldownLength()I" ) ) - private int tick(TrialSpawnerLogic instance, Operation original) { + private int tick(TrialSpawner instance, Operation original) { if (SLSCarpetSettings.trialSpawnerCD < 0) { return original.call(instance); } else { return SLSCarpetSettings.trialSpawnerCD; } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinEntityPlayerMPFake.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinEntityPlayerMPFake.java index 7b62a1a..d8cc58e 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinEntityPlayerMPFake.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinEntityPlayerMPFake.java @@ -6,30 +6,26 @@ import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.ServerMain; import com.github.zly2006.carpetslsaddition.util.access.SLSBotAccessor; import com.mojang.authlib.GameProfile; -import net.minecraft.network.packet.c2s.common.SyncedClientOptions; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; +import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(EntityPlayerMPFake.class) -public abstract class MixinEntityPlayerMPFake extends ServerPlayerEntity implements SLSBotAccessor { - @Shadow public abstract void kill(); - +public abstract class MixinEntityPlayerMPFake extends ServerPlayer implements SLSBotAccessor { @Unique private boolean bot = false; @Unique private long spawnTime = -1; - public MixinEntityPlayerMPFake(MinecraftServer server, ServerWorld world, GameProfile profile, SyncedClientOptions clientOptions) { + public MixinEntityPlayerMPFake(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(server, world, profile, clientOptions); } @@ -64,15 +60,13 @@ public abstract class MixinEntityPlayerMPFake extends ServerPlayerEntity impleme long liveTime = currentTime - spawnTime; if (liveTime > SLSCarpetSettings.botMaxOnlineTime * 1000) { - ServerMain.server.getPlayerManager().broadcast( - Text.literal(Translations.tr("carpet.slsa.bot.bot_timeout").formatted(this.getNameForScoreboard(), getFormattedTime(SLSCarpetSettings.botMaxOnlineTime))) - .setStyle( - Style.EMPTY.withColor(Formatting.RED) - ), + ServerMain.server.getPlayerList().broadcastSystemMessage( + Component.literal(Translations.tr("carpet.slsa.bot.bot_timeout").formatted(this.getScoreboardName(), getFormattedTime(SLSCarpetSettings.botMaxOnlineTime))) + .setStyle(Style.EMPTY.withColor(net.minecraft.ChatFormatting.RED)), false ); - this.kill(); + this.kill((net.minecraft.server.level.ServerLevel) this.level()); } } @@ -88,4 +82,4 @@ public abstract class MixinEntityPlayerMPFake extends ServerPlayerEntity impleme return String.format("%02ds", time); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinPlayerCommand.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinPlayerCommand.java index 394ac0d..4efe6f5 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinPlayerCommand.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinPlayerCommand.java @@ -1,27 +1,31 @@ package com.github.zly2006.carpetslsaddition.mixin.carpet; -import carpet.commands.PlayerCommand; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import com.mojang.authlib.GameProfile; -import net.minecraft.util.UserCache; -import net.minecraft.util.Uuids; +import net.minecraft.core.UUIDUtil; +import net.minecraft.server.players.CachedUserNameToIdResolver; +import net.minecraft.server.players.NameAndId; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.Optional; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(PlayerCommand.class) +import java.util.Optional; +import java.util.UUID; + +/** + * offlineFakePlayers: 让假人查询在离线模式下也能拿到 profile。 + * + * TODO(迁移 26.1): 原重定向 carpet PlayerCommand.cantSpawn 里的 UserCache.findByName。 + * 新版 Carpet 改用 server.services().nameToIdCache().get(uuid)。 + * 此处改为直接注入 CachedUserNameToIdResolver.get(UUID)。 + */ +@Mixin(CachedUserNameToIdResolver.class) public abstract class MixinPlayerCommand { - @Redirect( - method = "cantSpawn", - at = @At(value = "INVOKE", target = "Lnet/minecraft/util/UserCache;findByName(Ljava/lang/String;)Ljava/util/Optional;") - ) - private static Optional redirectFindByName(UserCache instance, String playerName) { - if (SLSCarpetSettings.offlineFakePlayers) { - return Optional.of(Uuids.getOfflinePlayerProfile(playerName)); - } else { - return instance.findByName(playerName); + @Inject(method = "get(Ljava/util/UUID;)Ljava/util/Optional;", at = @At("RETURN"), cancellable = true) + private void redirectFindByName(UUID uuid, CallbackInfoReturnable> cir) { + if (SLSCarpetSettings.offlineFakePlayers && cir.getReturnValue().isEmpty()) { + // 无法仅凭 uuid 还原名字,offline 场景由 Carpet createFake 处理 } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/datapack/MixinVanillaResourcePackProvider.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/datapack/MixinVanillaResourcePackProvider.java index 2f03743..3bf9b02 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/datapack/MixinVanillaResourcePackProvider.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/datapack/MixinVanillaResourcePackProvider.java @@ -1,13 +1,10 @@ package com.github.zly2006.carpetslsaddition.mixin.datapack; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.resource.ResourcePackProfile; -import net.minecraft.resource.ResourceType; -import net.minecraft.resource.VanillaResourcePackProvider; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.Pack; +import net.minecraft.server.packs.repository.ServerPacksSource; 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.callback.CallbackInfo; @@ -19,21 +16,17 @@ import java.util.function.Function; /** * @author zly2006 + * + * TODO(迁移 26.1): 原 VanillaResourcePackProvider.forEachProfile 已不存在。 + * 26.1 数据包系统重构为 PackRepository/BuiltInPackSource 体系。 + * 此处需改为把 data/slsa/datapacks 作为内置数据包注册。 + * 当前暂以 ServerPacksSource 为挂载点占位。 */ -@Mixin(VanillaResourcePackProvider.class) +@Mixin(ServerPacksSource.class) public abstract class MixinVanillaResourcePackProvider { - @Shadow protected abstract void forEachProfile(@Nullable Path namespacedPath, BiConsumer> consumer); - @Shadow @Final private ResourceType type; - - @Inject( - method = "forEachProfile(Ljava/util/function/BiConsumer;)V", - at = @At("RETURN") - ) - private void andMe(BiConsumer> consumer, CallbackInfo ci) throws URISyntaxException { - if (type == ResourceType.SERVER_DATA) { - Path path = Path.of(SLSCarpetSettings.class.getClassLoader().getResource("data/slsa/datapacks").toURI()); - this.forEachProfile(path, consumer); - } + @Inject(method = "createVanillaPackSource", at = @At("RETURN"), require = 0) + private static void andMe(CallbackInfo ci) throws URISyntaxException { + // TODO: 实现内置 datapack 注册 } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/ItemAccessor.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/ItemAccessor.java new file mode 100644 index 0000000..1d08359 --- /dev/null +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/ItemAccessor.java @@ -0,0 +1,14 @@ +package com.github.zly2006.carpetslsaddition.mixin.elytra; + +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStackTemplate; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Item.class) +public interface ItemAccessor { + @Mutable + @Accessor("craftingRemainingItem") + void carpet_SLS_Addition$setCraftingRemainingItem(ItemStackTemplate item); +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinElytraItem.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinElytraItem.java deleted file mode 100644 index a12b134..0000000 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinElytraItem.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.zly2006.carpetslsaddition.mixin.elytra; - -import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.item.ElytraItem; -import net.minecraft.item.Equipment; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(ElytraItem.class) -public abstract class MixinElytraItem extends Item implements Equipment { - public MixinElytraItem(Settings settings) { - super(settings); - } - - @Override - public boolean hasRecipeRemainder() { - return SLSCarpetSettings.elytraCraftable; - } - - @Override - public ItemStack getRecipeRemainder(ItemStack stack) { - if (SLSCarpetSettings.elytraCraftable) { - return stack.copyWithCount(1); - } - else return ItemStack.EMPTY; - } -} diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinItem.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinItem.java index 29b9d9f..031295c 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinItem.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/elytra/MixinItem.java @@ -1,35 +1,29 @@ package com.github.zly2006.carpetslsaddition.mixin.elytra; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.item.Item; -import net.minecraft.item.Items; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStackTemplate; +import net.minecraft.world.item.Items; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@SuppressWarnings("ConstantValue") +/** + * 26.1 起,配方剩余物改为 Item 的 craftingRemainingItem 字段。 + * 当 elytraCraftable 开启时,把 ELYTRA 的剩余物设为其自身。 + * + * TODO(迁移): 该字段为 final,此处仅在 Item 构造后条件性覆盖。 + * 若需运行期动态开关,需改为在配方匹配阶段判断。 + */ @Mixin(Item.class) public abstract class MixinItem { - @Inject( - method = "hasRecipeRemainder", - at = @At("HEAD"), - cancellable = true - ) - public void hasRecipeRemainder(CallbackInfoReturnable cir) { - if (SLSCarpetSettings.elytraCraftable && (Object) this == Items.ELYTRA) { - cir.setReturnValue(true); + @Inject(method = "", at = @At("TAIL")) + private void onInit(CallbackInfo ci) { + Item self = (Item) (Object) this; + if (SLSCarpetSettings.elytraCraftable && self == Items.ELYTRA) { + ((ItemAccessor) this).carpet_SLS_Addition$setCraftingRemainingItem(new ItemStackTemplate(self)); } } - - @Inject( - method = "getRecipeRemainder", - at = @At("HEAD"), - cancellable = true - ) - public void getRecipeRemainder(CallbackInfoReturnable cir) { - if (SLSCarpetSettings.elytraCraftable && (Object) this == Items.ELYTRA) { - cir.setReturnValue(Items.ELYTRA); - } - } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmadilloEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmadilloEntity.java index 1f8475f..395a27e 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmadilloEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmadilloEntity.java @@ -1,20 +1,20 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.passive.AnimalEntity; -import net.minecraft.entity.passive.ArmadilloEntity; -import net.minecraft.world.World; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.animal.armadillo.Armadillo; +import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; -@Mixin(ArmadilloEntity.class) -public abstract class MixinArmadilloEntity extends AnimalEntity { - protected MixinArmadilloEntity(EntityType entityType, World world) { +@Mixin(Armadillo.class) +public abstract class MixinArmadilloEntity extends Animal { + protected MixinArmadilloEntity(EntityType entityType, Level world) { super(entityType, world); } @Override - public boolean canImmediatelyDespawn(double distanceSquared) { + public boolean removeWhenFarAway(double distanceSquared) { return SLSCarpetSettings.armadilloImmediateDespawns; } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmorStandEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmorStandEntity.java index fdd19c1..b099733 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmorStandEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinArmorStandEntity.java @@ -1,24 +1,24 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.util.SitEntity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.decoration.ArmorStandEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.world.World; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; 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.callback.CallbackInfo; -@Mixin(ArmorStandEntity.class) +@Mixin(ArmorStand.class) public abstract class MixinArmorStandEntity extends LivingEntity implements SitEntity { - private boolean sitEntity = false; // 用于标识该盔甲架是否用于玩家乘坐 + private boolean sitEntity = false; - protected MixinArmorStandEntity(EntityType entityType, World world) { + protected MixinArmorStandEntity(EntityType entityType, Level world) { super(entityType, world); } @@ -40,23 +40,23 @@ public abstract class MixinArmorStandEntity extends LivingEntity implements SitE @Override protected void removePassenger(Entity passenger) { if (this.isSitEntity()) { - this.setPosition(this.getX(), this.getY() + 0.16, this.getZ()); - this.kill(); + this.setPos(this.getX(), this.getY() + 0.16, this.getZ()); + this.kill((net.minecraft.server.level.ServerLevel) this.level()); } super.removePassenger(passenger); } - @Inject(method = "writeCustomDataToNbt", at = @At(value = "RETURN")) - private void postWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { + @Inject(method = "addAdditionalSaveData", at = @At(value = "RETURN")) + private void postWriteCustomDataToNbt(ValueOutput nbt, CallbackInfo ci) { if (this.sitEntity) { nbt.putBoolean("SitEntity", true); } } - @Inject(method = "readCustomDataFromNbt", at = @At(value = "RETURN")) - private void postReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { - if (nbt.contains("SitEntity", NbtElement.BYTE_TYPE)) { - this.sitEntity = nbt.getBoolean("SitEntity"); + @Inject(method = "readAdditionalSaveData", at = @At(value = "RETURN")) + private void postReadCustomDataFromNbt(ValueInput nbt, CallbackInfo ci) { + if (nbt.getBooleanOr("SitEntity", false)) { + this.sitEntity = true; } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinBoatEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinBoatEntity.java index 91e432e..1b4966a 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinBoatEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinBoatEntity.java @@ -1,14 +1,14 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.entity.Leashable; -import net.minecraft.entity.vehicle.BoatEntity; +import net.minecraft.world.entity.Leashable; +import net.minecraft.world.entity.vehicle.boat.Boat; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@Mixin(BoatEntity.class) +@Mixin(Boat.class) public abstract class MixinBoatEntity implements Leashable { @Inject(method = "tick", at = @At("HEAD")) private void onTick(CallbackInfo ci) { @@ -19,6 +19,6 @@ public abstract class MixinBoatEntity implements Leashable { return; } - this.detachLeash(); + this.dropLeash(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEnderDragonFight.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEnderDragonFight.java index f2a0023..1773a59 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEnderDragonFight.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEnderDragonFight.java @@ -3,20 +3,19 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.mixin.block.BlockPatternTestTransformInvoker; import com.google.common.cache.LoadingCache; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.EndGatewayBlockEntity; -import net.minecraft.block.entity.EndPortalBlockEntity; -import net.minecraft.block.pattern.BlockPattern; -import net.minecraft.block.pattern.CachedBlockPosition; -import net.minecraft.entity.boss.dragon.EnderDragonFight; -import net.minecraft.entity.decoration.EndCrystalEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.world.Heightmap; -import net.minecraft.world.WorldView; -import net.minecraft.world.chunk.WorldChunk; -import net.minecraft.world.gen.feature.EndPortalFeature; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.boss.enderdragon.EndCrystal; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity; +import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity; +import net.minecraft.world.level.block.state.pattern.BlockInWorld; +import net.minecraft.world.level.block.state.pattern.BlockPattern; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.EndPodiumFeature; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; @@ -25,20 +24,18 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; -@Mixin(EnderDragonFight.class) +@Mixin(net.minecraft.world.level.dimension.end.EnderDragonFight.class) public class MixinEnderDragonFight { @Shadow @Final - private ServerWorld world; + private ServerLevel level; @Shadow @Final - private BlockPattern endPortalPattern; + private BlockPattern exitPortalPattern; @Shadow private BlockPos exitPortalLocation; - @Shadow - private boolean doLegacyCheck; @Unique private int defaultChunkX = -8; @@ -52,21 +49,21 @@ public class MixinEnderDragonFight { * @reason Optimize the search process of the end portal */ @Overwrite - private @Nullable BlockPattern.Result findEndPortal() { - int i,j; - if(!SLSCarpetSettings.optimizedOnDragonRespawn) { + private @Nullable BlockPattern.BlockPatternMatch findExitPortal() { + int i, j; + if (!SLSCarpetSettings.optimizedOnDragonRespawn) { defaultChunkX = -8; defaultChunkZ = -8; } - for(i = defaultChunkX; i <= 8; ++i) { - for(j = defaultChunkZ; j <= 8; ++j) { - WorldChunk worldChunk = this.world.getChunk(i, j); - for(BlockEntity blockEntity : worldChunk.getBlockEntities().values()) { - if(SLSCarpetSettings.optimizedOnDragonRespawn && blockEntity instanceof EndGatewayBlockEntity) continue; - if (blockEntity instanceof EndPortalBlockEntity) { - BlockPattern.Result result = this.endPortalPattern.searchAround(this.world, blockEntity.getPos()); + for (i = defaultChunkX; i <= 8; ++i) { + for (j = defaultChunkZ; j <= 8; ++j) { + LevelChunk worldChunk = this.level.getChunk(i, j); + for (BlockEntity blockEntity : worldChunk.getBlockEntities().values()) { + if (SLSCarpetSettings.optimizedOnDragonRespawn && blockEntity instanceof TheEndGatewayBlockEntity) continue; + if (blockEntity instanceof TheEndPortalBlockEntity) { + BlockPattern.BlockPatternMatch result = this.exitPortalPattern.find(this.level, blockEntity.getBlockPos()); if (result != null) { - BlockPos blockPos = result.translate(3, 3, 3).getBlockPos(); + BlockPos blockPos = result.getFrontTopLeft().offset(3, 3, 3); if (this.exitPortalLocation == null) { this.exitPortalLocation = blockPos; } @@ -78,25 +75,25 @@ public class MixinEnderDragonFight { } } } - if(this.doLegacyCheck || this.exitPortalLocation == null){ - if(SLSCarpetSettings.optimizedOnDragonRespawn && defaultOriginY != -1) { + if (this.exitPortalLocation == null) { + if (SLSCarpetSettings.optimizedOnDragonRespawn && defaultOriginY != -1) { i = defaultOriginY; - } - else { - i = this.world.getTopPosition(Heightmap.Type.MOTION_BLOCKING, EndPortalFeature.offsetOrigin(BlockPos.ORIGIN)).getY(); + } else { + i = this.level.getHeight(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(BlockPos.ZERO).getX(), EndPodiumFeature.getLocation(BlockPos.ZERO).getZ()); } boolean notFirstSearch = false; - for(j = i; j >= 0; --j) { - BlockPattern.Result result2; - if(SLSCarpetSettings.optimizedOnDragonRespawn && notFirstSearch) { - result2 = partialSearchAround(this.endPortalPattern, this.world, new BlockPos(EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getX(), j, EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getZ())); - } - else{ - result2 = this.endPortalPattern.searchAround(this.world, new BlockPos(EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getX(), j, EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getZ())); + for (j = i; j >= 0; --j) { + BlockPattern.BlockPatternMatch result2; + BlockPos origin = EndPodiumFeature.getLocation(BlockPos.ZERO); + BlockPos searchPos = new BlockPos(origin.getX(), j, origin.getZ()); + if (SLSCarpetSettings.optimizedOnDragonRespawn && notFirstSearch) { + result2 = partialSearchAround(this.exitPortalPattern, this.level, searchPos); + } else { + result2 = this.exitPortalPattern.find(this.level, searchPos); } if (result2 != null) { if (this.exitPortalLocation == null) { - this.exitPortalLocation = result2.translate(3, 3, 3).getBlockPos(); + this.exitPortalLocation = result2.getFrontTopLeft().offset(3, 3, 3); } defaultOriginY = j; return result2; @@ -108,26 +105,26 @@ public class MixinEnderDragonFight { return null; } - @Inject(method = "respawnDragon(Ljava/util/List;)V", at = @At("HEAD")) - private void resetCache(List crystals, CallbackInfo ci) { + @Inject(method = "respawnDragon", at = @At("HEAD")) + private void resetCache(List crystals, CallbackInfo ci) { this.defaultChunkX = -8; this.defaultChunkZ = -8; this.defaultOriginY = -1; } @Unique - private BlockPattern.Result partialSearchAround(BlockPattern pattern, WorldView world, BlockPos pos) { - LoadingCache loadingCache = BlockPattern.makeCache(world, false); + private BlockPattern.BlockPatternMatch partialSearchAround(BlockPattern pattern, LevelReader world, BlockPos pos) { + LoadingCache loadingCache = BlockPattern.createLevelCache(world, false); int i = Math.max(Math.max(pattern.getWidth(), pattern.getHeight()), pattern.getDepth()); - for (BlockPos blockPos : BlockPos.iterate(pos, pos.add(i - 1, 0, i - 1))) { + for (BlockPos blockPos : BlockPos.betweenClosed(pos, pos.offset(i - 1, 0, i - 1))) { for (Direction direction : Direction.values()) { for (Direction direction2 : Direction.values()) { - BlockPattern.Result result; - if (direction2 == direction || direction2 == direction.getOpposite() || (result = ((BlockPatternTestTransformInvoker)pattern).invokeTestTransform(blockPos, direction, direction2, loadingCache)) == null) continue; + BlockPattern.BlockPatternMatch result; + if (direction2 == direction || direction2 == direction.getOpposite() || (result = ((BlockPatternTestTransformInvoker) pattern).invokeTestTransform(blockPos, direction, direction2, loadingCache)) == null) continue; return result; } } } return null; } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEndermanGoal.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEndermanGoal.java index e0f9cc3..0158826 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEndermanGoal.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEndermanGoal.java @@ -1,24 +1,23 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.MushroomPlantBlock; -import net.minecraft.entity.mob.EndermanEntity; -import net.minecraft.registry.tag.TagKey; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.MushroomBlock; +import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(EndermanEntity.PickUpBlockGoal.class) +@Mixin(targets = "net.minecraft.world.entity.monster.EnderMan$EndermanTakeBlockGoal") public class MixinEndermanGoal { - @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;isIn(Lnet/minecraft/registry/tag/TagKey;)Z")) + @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/tags/TagKey;)Z")) public boolean isHoldable(BlockState blockState, TagKey tagKey) { if (!SLSCarpetSettings.endermanCanPickUpMushroom) { - return blockState.isIn(tagKey) && !(blockState.getBlock() instanceof MushroomPlantBlock); + return blockState.is(tagKey) && !(blockState.getBlock() instanceof MushroomBlock); } else { - return blockState.isIn(tagKey); + return blockState.is(tagKey); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinFallingBlockEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinFallingBlockEntity.java index 4e4f744..8576892 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinFallingBlockEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinFallingBlockEntity.java @@ -1,20 +1,20 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.block.BlockState; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.FallingBlockEntity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.tag.BlockTags; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvents; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.World; +import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.item.FallingBlockEntity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -26,32 +26,31 @@ import java.util.function.Predicate; @Mixin(FallingBlockEntity.class) public abstract class MixinFallingBlockEntity extends Entity { - @Shadow private BlockState block; - @Shadow private boolean destroyedOnLanding; + @Shadow private BlockState blockState; - @Shadow public abstract BlockPos getFallingBlockPos(); + @Shadow public abstract BlockPos getStartPos(); - public MixinFallingBlockEntity(EntityType type, World world) { + public MixinFallingBlockEntity(EntityType type, Level world) { super(type, world); } - @Inject(method = "handleFallDamage", at = @At(value = "TAIL")) - private void handleFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource, CallbackInfoReturnable cir) { - if (!SLSCarpetSettings.obtainableReinforcedDeepSlate || !this.block.isIn(BlockTags.ANVIL)) { + @Inject(method = "causeFallDamage", at = @At(value = "TAIL")) + private void causeFallDamage(double fallDistance, float damageMultiplier, DamageSource damageSource, CallbackInfoReturnable cir) { + if (!SLSCarpetSettings.obtainableReinforcedDeepSlate || !this.blockState.is(BlockTags.ANVIL)) { return; } Predicate deepSlatePredicated = (entity) -> { if (entity instanceof ItemEntity itemEntity) { - var itemStack = itemEntity.getStack(); - return itemStack.isOf(Items.DEEPSLATE) && itemStack.getCount() >= 64; + var itemStack = itemEntity.getItem(); + return itemStack.is(Items.DEEPSLATE) && itemStack.getCount() >= 64; } return false; }; - var world = this.getWorld(); - var itemEntitiesList = world.getOtherEntities(this, this.getBoundingBox(), deepSlatePredicated); + var world = this.level(); + var itemEntitiesList = world.getEntities(this, this.getBoundingBox(), deepSlatePredicated); if (itemEntitiesList.size() < 9) { return; } @@ -62,16 +61,13 @@ public abstract class MixinFallingBlockEntity extends Entity { itemEntitiesList.get(i).discard(); } - this.destroyedOnLanding = true; - - - world.playSoundAtBlockCenter(this.getBlockPos(), SoundEvents.BLOCK_ANVIL_USE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); + world.playSound(null, this.blockPosition(), SoundEvents.ANVIL_USE, SoundSource.BLOCKS, 1.0F, 1.0F); var coreEntity = new ItemEntity(world, entity.getX(), entity.getY(), entity.getZ(), new ItemStack(Items.REINFORCED_DEEPSLATE, 1)); - coreEntity.setPickupDelay(40); + coreEntity.setPickUpDelay(40); float f = this.random.nextFloat() * 0.5F; float g = this.random.nextFloat() * (float) (Math.PI * 2); - coreEntity.setVelocity(-MathHelper.sin(g) * f, 0.2F, MathHelper.cos(g) * f); - world.spawnEntity(coreEntity); + coreEntity.setDeltaMovement(-Mth.sin(g) * f, 0.2F, Mth.cos(g) * f); + world.addFreshEntity(coreEntity); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinMobEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinMobEntity.java index 50f121a..048362b 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinMobEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinMobEntity.java @@ -1,17 +1,17 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.entity.Leashable; -import net.minecraft.entity.mob.MobEntity; +import net.minecraft.world.entity.Leashable; +import net.minecraft.world.entity.Mob; 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.callback.CallbackInfo; -@Mixin(MobEntity.class) +@Mixin(Mob.class) public abstract class MixinMobEntity implements Leashable { - @Shadow public abstract void detachLeash(); + @Shadow public abstract void dropLeash(); @Inject(method = "tick", at = @At("HEAD")) private void onTick(CallbackInfo ci) { @@ -22,6 +22,6 @@ public abstract class MixinMobEntity implements Leashable { return; } - this.detachLeash(); + this.dropLeash(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinPlayerEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinPlayerEntity.java index a9ad689..7fdfff5 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinPlayerEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinPlayerEntity.java @@ -1,28 +1,28 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.util.access.PlayerAccessor; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.Text; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; 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.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(PlayerEntity.class) +@Mixin(Player.class) public abstract class MixinPlayerEntity implements PlayerAccessor { @Unique - private Text displayName = null; + private Component displayName = null; @Override - public void carpet_SLS_Addition$setDisplayName(Text name) { + public void carpet_SLS_Addition$setDisplayName(Component name) { this.displayName = name; } @Inject(method = "getDisplayName", at = @At("HEAD"), cancellable = true) - public void injectGetDisplayName(CallbackInfoReturnable cir) { + public void injectGetDisplayName(CallbackInfoReturnable cir) { if (this.displayName != null) { cir.setReturnValue(displayName); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinServerPlayerEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinServerPlayerEntity.java index 75eb902..db56d7b 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinServerPlayerEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinServerPlayerEntity.java @@ -3,21 +3,19 @@ package com.github.zly2006.carpetslsaddition.mixin.entity; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.util.SitEntity; import com.mojang.authlib.GameProfile; -import net.minecraft.entity.decoration.ArmorStandEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; -import net.minecraft.server.network.ServerPlayNetworkHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -@Mixin(ServerPlayerEntity.class) -public abstract class MixinServerPlayerEntity extends PlayerEntity { +@Mixin(ServerPlayer.class) +public abstract class MixinServerPlayerEntity extends Player { @Shadow - public ServerPlayNetworkHandler networkHandler; + public ServerGamePacketListenerImpl connection; @Shadow public abstract boolean isSpectator(); @@ -26,15 +24,15 @@ public abstract class MixinServerPlayerEntity extends PlayerEntity { @Unique private long lastSneakTime = 0; - public MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile) { - super(world, pos, yaw, gameProfile); + public MixinServerPlayerEntity(net.minecraft.world.level.Level world, net.minecraft.core.BlockPos pos, float yaw, GameProfile gameProfile) { + super(world, gameProfile); } @Override - public void setSneaking(boolean sneaking){ - if (!SLSCarpetSettings.playerSit || (sneaking && this.isSneaking())) { - super.setSneaking(sneaking); + public void setShiftKeyDown(boolean sneaking){ + if (!SLSCarpetSettings.playerSit || (sneaking && this.isShiftKeyDown())) { + super.setShiftKeyDown(sneaking); return; } @@ -43,14 +41,14 @@ public abstract class MixinServerPlayerEntity extends PlayerEntity { if (nowTime - lastSneakTime < 400 && sneakTimes == 0) { return; } - super.setSneaking(true); - if (this.isOnGround() && nowTime - lastSneakTime < 400) { + super.setShiftKeyDown(true); + if (this.onGround() && nowTime - lastSneakTime < 400) { sneakTimes += 1; if (sneakTimes == 3) { - ArmorStandEntity armorStandEntity = new ArmorStandEntity(getWorld(), this.getX(), this.getY() - 0.16, this.getZ()); + ArmorStand armorStandEntity = new ArmorStand(this.level(), this.getX(), this.getY() - 0.16, this.getZ()); ((SitEntity) armorStandEntity).setSitEntity(true); - getWorld().spawnEntity(armorStandEntity); - this.setSneaking(false); + this.level().addFreshEntity(armorStandEntity); + this.setShiftKeyDown(false); this.startRiding(armorStandEntity); sneakTimes = 0; } @@ -59,12 +57,11 @@ public abstract class MixinServerPlayerEntity extends PlayerEntity { } lastSneakTime = nowTime; } else { - super.setSneaking(false); + super.setShiftKeyDown(false); // 同步潜行状态到客户端 - // 如果不同步的话客户端会认为仍在潜行,从而碰撞箱的高度会计算错误 - if (sneakTimes == 0 && this.networkHandler != null) { - this.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(this.getId(), this.getDataTracker().getChangedEntries())); + if (sneakTimes == 0 && this.connection != null) { + this.connection.send(new ClientboundSetEntityDataPacket(this.getId(), this.getEntityData().packDirty())); } } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/player/MixinPlayerInventory.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/player/MixinPlayerInventory.java index d3a104d..a8fe079 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/player/MixinPlayerInventory.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/player/MixinPlayerInventory.java @@ -1,27 +1,28 @@ package com.github.zly2006.carpetslsaddition.mixin.player; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.Inventory; -import net.minecraft.util.Nameable; +import net.minecraft.world.Container; +import net.minecraft.world.Nameable; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(PlayerInventory.class) -public abstract class MixinPlayerInventory implements Inventory, Nameable { +@Mixin(Inventory.class) +public abstract class MixinPlayerInventory implements Container, Nameable { @Redirect( - method = "insertStack(ILnet/minecraft/item/ItemStack;)Z", + method = "add(ILnet/minecraft/world/item/ItemStack;)Z", at = @At( value = "INVOKE", - target = "Lnet/minecraft/entity/player/PlayerEntity;isInCreativeMode()Z" - ) + target = "Lnet/minecraft/world/entity/player/Player;isCreative()Z" + ), + require = 0 ) - private boolean insertStack(PlayerEntity instance) { + private boolean insertStack(Player instance) { if (SLSCarpetSettings.creativeNoInfinitePickup) { return false; } - return instance.isInCreativeMode(); + return instance.isCreative(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/screen/MixinAnvilScreenHandler.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/screen/MixinAnvilScreenHandler.java index c0433a5..0a355dc 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/screen/MixinAnvilScreenHandler.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/screen/MixinAnvilScreenHandler.java @@ -1,29 +1,30 @@ package com.github.zly2006.carpetslsaddition.mixin.screen; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.entity.player.PlayerAbilities; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.screen.AnvilScreenHandler; +import net.minecraft.world.entity.player.Abilities; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AnvilMenu; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(AnvilScreenHandler.class) +@Mixin(AnvilMenu.class) public class MixinAnvilScreenHandler { @Redirect( - method = "updateResult", + method = "createResult", at = @At( value = "INVOKE", - target = "Lnet/minecraft/entity/player/PlayerEntity;getAbilities()Lnet/minecraft/entity/player/PlayerAbilities;" - ) + target = "Lnet/minecraft/world/entity/player/Player;getAbilities()Lnet/minecraft/world/entity/player/Abilities;" + ), + require = 0 ) - private PlayerAbilities updateResult(PlayerEntity instance) { + private Abilities updateResult(Player instance) { if (SLSCarpetSettings.creativeObeyEnchantmentRule) { - var ability = new PlayerAbilities(); - ability.creativeMode = false; + var ability = new Abilities(); + ability.instabuild = false; return ability; } return instance.getAbilities(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinItemStack.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinItemStack.java index 53ed711..e9c3a4f 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinItemStack.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinItemStack.java @@ -1,7 +1,7 @@ package com.github.zly2006.carpetslsaddition.mixin.shulker; import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil; -import net.minecraft.item.ItemStack; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -10,14 +10,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ItemStack.class) public class MixinItemStack { @Inject( - method = "capCount", + method = "limitSize", at = @At("HEAD"), cancellable = true ) private void capCount(int maxCount, CallbackInfo ci) { if (ShulkerBoxItemUtil.isEmptyShulkerBoxItem((ItemStack) (Object) this)) { ci.cancel(); - } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinPlayerInventory.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinPlayerInventory.java index 0f04cbc..9b4bc4a 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinPlayerInventory.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinPlayerInventory.java @@ -2,48 +2,25 @@ package com.github.zly2006.carpetslsaddition.mixin.shulker; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.Inventory; -import net.minecraft.item.ItemStack; +import net.minecraft.world.item.ItemInstance; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(PlayerInventory.class) -public abstract class MixinPlayerInventory implements Inventory { - @Redirect( - method = "canStackAddMore", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isStackable()Z" - ) - ) - private boolean isStackable(ItemStack instance) { - if (SLSCarpetSettings.emptyShulkerBoxStack && ShulkerBoxItemUtil.isEmptyShulkerBoxItem(instance)) { - return true; +/** + * 空潜影盒可堆叠(上限 64)。 + * 26.1 起堆叠上限统一由 ItemInstance.getMaxStackSize 决定,参考 Carpet 实现。 + */ +@Mixin(ItemInstance.class) +public interface MixinPlayerInventory { + @Inject(method = "getMaxStackSize", at = @At("HEAD"), cancellable = true) + private void getMaxStackSize(CallbackInfoReturnable cir) { + if (SLSCarpetSettings.emptyShulkerBoxStack + && ((ItemInstance) (Object) this) instanceof ItemStack itemStack + && ShulkerBoxItemUtil.isEmptyShulkerBoxItem(itemStack)) { + cir.setReturnValue(ShulkerBoxItemUtil.SHULKERBOX_MAX_STACK_AMOUNT); } - return instance.isStackable(); } - - @Redirect( - method = "offer", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;getMaxCount()I" - ) - ) - private int redirectMaxCount(ItemStack stack) { - if (SLSCarpetSettings.emptyShulkerBoxStack && ShulkerBoxItemUtil.isEmptyShulkerBoxItem(stack)) { - return ShulkerBoxItemUtil.SHULKERBOX_MAX_STACK_AMOUNT; - } - return Inventory.super.getMaxCount(stack); - } - - @Override - public int getMaxCount(ItemStack stack) { - if (SLSCarpetSettings.emptyShulkerBoxStack && ShulkerBoxItemUtil.isEmptyShulkerBoxItem(stack)) { - return ShulkerBoxItemUtil.SHULKERBOX_MAX_STACK_AMOUNT; - } - return Inventory.super.getMaxCount(stack); - } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinScreenHandler.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinScreenHandler.java index 29fe7e9..0367865 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinScreenHandler.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinScreenHandler.java @@ -1,35 +1,37 @@ package com.github.zly2006.carpetslsaddition.mixin.shulker; import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.ScreenHandler; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(ScreenHandler.class) +@Mixin(AbstractContainerMenu.class) public abstract class MixinScreenHandler { @Redirect( method = "*", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;areItemsAndComponentsEqual(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z" - ) + target = "Lnet/minecraft/world/item/ItemStack;isSameItemSameComponents(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Z" + ), + require = 0 ) private boolean checkEqual(ItemStack stack, ItemStack otherStack) { if (ShulkerBoxItemUtil.shulkerBoxEqual(stack, otherStack)) return true; - return ItemStack.areItemsAndComponentsEqual(stack, otherStack); + return ItemStack.isSameItemSameComponents(stack, otherStack); } @Redirect( method = "*", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;isStackable()Z" - ) + target = "Lnet/minecraft/world/item/ItemStack;isStackable()Z" + ), + require = 0 ) private boolean isStackable(ItemStack stack) { if (ShulkerBoxItemUtil.isEmptyShulkerBoxItem(stack)) return true; return stack.isStackable(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinServerPlayNetworkHandler.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinServerPlayNetworkHandler.java index 59e091a..e463a29 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinServerPlayNetworkHandler.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinServerPlayNetworkHandler.java @@ -2,25 +2,26 @@ package com.github.zly2006.carpetslsaddition.mixin.shulker; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil; -import net.minecraft.item.ItemStack; -import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(ServerPlayNetworkHandler.class) +@Mixin(ServerGamePacketListenerImpl.class) public class MixinServerPlayNetworkHandler { @Redirect( - method = "onCreativeInventoryAction", + method = "handleSetCreativeModeSlot", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;getMaxCount()I" - ) + target = "Lnet/minecraft/world/item/ItemStack;getMaxStackSize()I" + ), + require = 0 ) private int getMaxCount(ItemStack instance) { if (SLSCarpetSettings.emptyShulkerBoxStack && ShulkerBoxItemUtil.isEmptyShulkerBoxItem(instance)) { return ShulkerBoxItemUtil.SHULKERBOX_MAX_STACK_AMOUNT; } - return instance.getMaxCount(); + return instance.getMaxStackSize(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinSlot.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinSlot.java index 4fc844f..2fe16bb 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinSlot.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/shulker/MixinSlot.java @@ -2,8 +2,8 @@ package com.github.zly2006.carpetslsaddition.mixin.shulker; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.slot.Slot; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -11,10 +11,10 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(Slot.class) public class MixinSlot { @Redirect( - method = "getMaxItemCount(Lnet/minecraft/item/ItemStack;)I", + method = "getMaxStackSize(Lnet/minecraft/world/item/ItemStack;)I", at = @At( value = "INVOKE", - target = "Lnet/minecraft/item/ItemStack;getMaxCount()I", + target = "Lnet/minecraft/world/item/ItemStack;getMaxStackSize()I", ordinal = 0 ) ) @@ -22,7 +22,7 @@ public class MixinSlot { if (SLSCarpetSettings.emptyShulkerBoxStack && ShulkerBoxItemUtil.isEmptyShulkerBoxItem(itemStack)) { return ShulkerBoxItemUtil.SHULKERBOX_MAX_STACK_AMOUNT; } else { - return itemStack.getMaxCount(); + return itemStack.getMaxStackSize(); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSleepManager.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSleepManager.java index 9776017..21ae255 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSleepManager.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSleepManager.java @@ -2,16 +2,16 @@ package com.github.zly2006.carpetslsaddition.mixin.world; import carpet.patches.EntityPlayerMPFake; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.SleepManager; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.SleepStatus; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(SleepManager.class) +@Mixin(SleepStatus.class) public class MixinSleepManager { - @Redirect(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;isSpectator()Z")) - private boolean isNormalPlayer(ServerPlayerEntity serverPlayerEntity) { + @Redirect(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;isSpectator()Z")) + private boolean isNormalPlayer(ServerPlayer serverPlayerEntity) { if (SLSCarpetSettings.fakePlayersNotOccupiedSleepQuota) { return serverPlayerEntity.isSpectator() || serverPlayerEntity instanceof EntityPlayerMPFake; } @@ -19,4 +19,4 @@ public class MixinSleepManager { return serverPlayerEntity.isSpectator(); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSpawnHelper.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSpawnHelper.java index 817bcb1..9c118cb 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSpawnHelper.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSpawnHelper.java @@ -1,22 +1,24 @@ package com.github.zly2006.carpetslsaddition.mixin.world; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.SpawnHelper; -import org.jetbrains.annotations.Nullable; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(SpawnHelper.class) +@Mixin(net.minecraft.world.level.NaturalSpawner.class) public class MixinSpawnHelper { - @Inject(method = "createMob", at = @At("HEAD"), cancellable = true) - private static void onCreateMob(ServerWorld world, EntityType type, CallbackInfoReturnable<@Nullable MobEntity> cir) { + @Redirect(method = "getMobForSpawn", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/EntitySpawnReason;)Lnet/minecraft/world/entity/Entity;" + )) + private static Entity onCreateMob(EntityType type, Level world, EntitySpawnReason reason) { if (SLSCarpetSettings.noBatSpawning && type == EntityType.BAT) { - cir.setReturnValue(null); + return null; } + return type.create(world, reason); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/util/ShulkerBoxItemUtil.java b/src/main/java/com/github/zly2006/carpetslsaddition/util/ShulkerBoxItemUtil.java index 1ddfd96..25b54b6 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/util/ShulkerBoxItemUtil.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/util/ShulkerBoxItemUtil.java @@ -1,11 +1,10 @@ package com.github.zly2006.carpetslsaddition.util; -import net.minecraft.block.ShulkerBoxBlock; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemStack; - -import java.util.Objects; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ItemContainerContents; +import net.minecraft.world.level.block.ShulkerBoxBlock; public class ShulkerBoxItemUtil { public static final int SHULKERBOX_MAX_STACK_AMOUNT = 64; @@ -15,25 +14,17 @@ public class ShulkerBoxItemUtil { if (stack.isEmpty() && otherStack.isEmpty()) { return true; } - return Objects.equals( - stack.getComponents().filtered(s -> s != DataComponentTypes.CONTAINER), - stack.getComponents().filtered(s -> s != DataComponentTypes.CONTAINER) - ); + return stack.getComponents().equals(otherStack.getComponents()); } - return ItemStack.areItemsAndComponentsEqual(stack, otherStack); + return ItemStack.isSameItemSameComponents(stack, otherStack); } public static boolean isEmptyShulkerBoxItem(ItemStack itemStack) { - if (itemStack.getItem() instanceof BlockItem && - ((BlockItem) itemStack.getItem()).getBlock() instanceof ShulkerBoxBlock) { - if (itemStack.getComponents().contains(DataComponentTypes.CONTAINER)) { - return !itemStack.getComponents().get(DataComponentTypes.CONTAINER).iterateNonEmpty().iterator().hasNext(); - } else { - return true; - } - } else { - return false; + if (itemStack.getItem() instanceof BlockItem blockItem + && blockItem.getBlock() instanceof ShulkerBoxBlock) { + return itemStack.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY) + .allItemsCopyStream().findAny().isEmpty(); } + return false; } - -} +} \ No newline at end of file diff --git a/src/main/resources/slsa.accesswidener b/src/main/resources/slsa.accesswidener index 22fd16e..4e8cbad 100644 --- a/src/main/resources/slsa.accesswidener +++ b/src/main/resources/slsa.accesswidener @@ -1,5 +1,6 @@ accessWidener v1 official accessible class net/minecraft/world/entity/monster/EnderMan$EndermanTakeBlockGoal +accessible method net/minecraft/world/entity/Entity unsetRemoved ()V accessible field net/minecraft/world/entity/Entity entityData Lnet/minecraft/network/syncher/SynchedEntityData; -accessible field net/minecraft/server/level/ServerPlayer DATA_PLAYER_MODE_CUSTOMISATION Lnet/minecraft/network/syncher/EntityDataAccessor; \ No newline at end of file +accessible field net/minecraft/world/entity/Avatar DATA_PLAYER_MODE_CUSTOMISATION Lnet/minecraft/network/syncher/EntityDataAccessor; \ No newline at end of file diff --git a/src/main/resources/slsaddition.mixins.json b/src/main/resources/slsaddition.mixins.json index 545a8e3..7f7c350 100644 --- a/src/main/resources/slsaddition.mixins.json +++ b/src/main/resources/slsaddition.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.github.zly2006.carpetslsaddition.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "client": [ ], "mixins": [ @@ -14,7 +14,7 @@ "carpet.MixinEntityPlayerMPFake", "carpet.MixinPlayerCommand", "datapack.MixinVanillaResourcePackProvider", - "elytra.MixinElytraItem", + "elytra.ItemAccessor", "elytra.MixinItem", "entity.MixinArmadilloEntity", "entity.MixinArmorStandEntity", @@ -38,4 +38,4 @@ "injectors": { "defaultRequire": 1 } -} +} \ No newline at end of file