diff --git a/build.gradle b/build.gradle index 6a77558..663edfe 100644 --- a/build.gradle +++ b/build.gradle @@ -3,8 +3,8 @@ plugins { id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +sourceCompatibility = JavaVersion.VERSION_21 +targetCompatibility = JavaVersion.VERSION_21 archivesBaseName = project.archives_base_name version = project.mod_version @@ -45,6 +45,7 @@ dependencies { // carpet modImplementation "carpet:fabric-carpet:${project.carpet_core_version}" + // modImplementation(files("./lib/fabric-carpet-1.20-1.4.112+v230608.jar")) // Fabric Permission API include(modImplementation('me.lucko:fabric-permissions-api:0.2-SNAPSHOT')) @@ -67,8 +68,8 @@ processResources { } tasks.withType(JavaCompile).configureEach { - // Minecraft 1.18 (1.18-pre2) upwards uses Java 17. - it.options.release = 17 + // Minecraft 1.21 and upwards uses Java 21. + it.options.release = 21 } java { diff --git a/gradle.properties b/gradle.properties index 2ee6508..30d0d02 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,16 +3,16 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/develop - minecraft_version=1.20.1 - yarn_mappings=1.20.1+build.2 - loader_version=0.14.21 + minecraft_version=1.21 + yarn_mappings=1.21+build.1 + loader_version=0.15.11 # Mod Properties - mod_version = 0.7.1 + mod_version = 0.11.0 maven_group = com.github.zly2006 archives_base_name = carpet-sls-addition # Dependencies - fabric_version=0.83.1+1.20.1 - carpet_core_version=1.20-1.4.112+v230608 + fabric_version=0.100.1+1.21 + carpet_core_version=1.21-1.4.147+v240613 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661..17655d0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/lib/fabric-carpet-1.20-1.4.112+v230608.jar b/lib/fabric-carpet-1.20-1.4.112+v230608.jar new file mode 100644 index 0000000..0479541 Binary files /dev/null and b/lib/fabric-carpet-1.20-1.4.112+v230608.jar differ diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java b/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java index 8129e3e..2297b50 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java @@ -17,15 +17,9 @@ public class SLSCarpetSettings { @Rule(categories = {CARPET_ID, RuleCategory.OPTIMIZATION}) public static int skipTicksForJoblessVillager = 0; - @Rule(categories = {CARPET_ID, RuleCategory.OPTIMIZATION}, options = {"-1", "24", "50"}) - public static int maxVillagersInABlock = -1; - @Rule(categories = {CARPET_ID, RuleCategory.CREATIVE}) public static boolean creativeNoInfinitePickup = false; - @Rule(categories = {CARPET_ID}) - public static boolean autoUrl = false; - @Rule(categories = {CARPET_ID, RuleCategory.OPTIMIZATION}) public static boolean noBatSpawning = false; @@ -38,6 +32,9 @@ public class SLSCarpetSettings { @Rule(categories = {CARPET_ID, RuleCategory.FEATURE}) public static boolean canUseSitCommand = false; + @Rule(categories = {CARPET_ID, RuleCategory.FEATURE}) + public static boolean fakePlayersNotOccupiedSleepQuota = false; + @Rule(categories = {CARPET_ID, RuleCategory.CREATIVE}) public static int maxUpdateQueueSize = -1; @@ -59,6 +56,9 @@ public class SLSCarpetSettings { @Rule(categories = {CARPET_ID, PCA, RuleCategory.FEATURE}) public static boolean playerSit = false; + @Rule(categories = {CARPET_ID, RuleCategory.FEATURE}) + public static boolean endermanCanPickUpMushroom = true; + @Rule(categories = {CARPET_ID, RuleCategory.CREATIVE}) public static boolean oldRedstoneConnectionLogic = false; 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 5b21dae..035d01b 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/command/BotCommand.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/command/BotCommand.java @@ -23,6 +23,7 @@ import net.minecraft.command.argument.Vec3ArgumentType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; import net.minecraft.registry.RegistryKey; +import net.minecraft.server.Main; import net.minecraft.server.MinecraftServer; import net.minecraft.server.PlayerManager; import net.minecraft.server.command.ServerCommandSource; @@ -42,6 +43,8 @@ import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import static net.minecraft.command.CommandSource.suggestMatching; @@ -49,6 +52,7 @@ import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; public class BotCommand { + public static final ArrayBlockingQueue playerQueue = new ArrayBlockingQueue<>(128); public static void register(CommandDispatcher dispatcher) { LiteralArgumentBuilder command = literal("bot") @@ -263,7 +267,7 @@ public class BotCommand { source.getWorld().getRegistryKey() ); - String playerName = "bot_" + StringArgumentType.getString(context, "player"); + String playerName = StringArgumentType.getString(context, "player"); if (playerName.length() > maxNameLength(source.getServer())) { Messenger.m(source, "rb Player name: " + playerName + " is too long"); @@ -275,14 +279,25 @@ public class BotCommand { Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world"); return 0; } - ServerPlayerEntity player = EntityPlayerMPFake.createFake(playerName, source.getServer(), pos, facing.y, facing.x, dimType, GameMode.SURVIVAL, false); - if (player == null) + boolean success = EntityPlayerMPFake.createFake(playerName, source.getServer(), pos, facing.y, facing.x, dimType, GameMode.SURVIVAL, false); + + if (!success) { Messenger.m(source, "rb Player " + playerName + " doesn't exist and cannot spawn in online mode. " + "Turn the server offline to spawn non-existing players"); return 0; } else { + ServerPlayerEntity player; + try { + player = playerQueue.poll(500, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + return 1; + } + + if (player == null) return 1; + ((PlayerAccess) player).setDisplayName(Text.empty().append(Text.literal("[%s] ".formatted(source.getName())).setStyle(Style.EMPTY.withColor(Formatting.AQUA))).append(Text.literal(playerName).setStyle(Style.EMPTY))); ServerMain.server.getPlayerManager().broadcast(Text.empty() .append(Text.literal("假人").setStyle(Style.EMPTY.withColor(Formatting.GREEN))) diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinFakePlayer.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinFakePlayer.java index a1b8bb6..8e8d99f 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinFakePlayer.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/carpet/MixinFakePlayer.java @@ -2,15 +2,20 @@ package com.github.zly2006.carpetslsaddition.mixin.carpet; import carpet.patches.EntityPlayerMPFake; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; +import com.github.zly2006.carpetslsaddition.command.BotCommand; import com.mojang.authlib.GameProfile; import net.minecraft.util.UserCache; import net.minecraft.util.Uuids; +import net.minecraft.util.math.Vec3d; 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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.TimeUnit; @Mixin(value = EntityPlayerMPFake.class) public class MixinFakePlayer { @@ -22,4 +27,12 @@ public class MixinFakePlayer { } return instance.findByName(name); } + + @Inject(method = "lambda$createFake$1", at = @At("TAIL")) + private static void onAcceptFakePlayer(EntityPlayerMPFake instance, Vec3d pos, double yaw, double pitch, CallbackInfo ci) { + try { + BotCommand.playerQueue.offer(instance, 500, TimeUnit.MILLISECONDS); + } + catch (InterruptedException ignored) {} + } } 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 new file mode 100644 index 0000000..ee1d32b --- /dev/null +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/entity/MixinEndermanGoal.java @@ -0,0 +1,28 @@ +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 org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(EndermanEntity.PickUpBlockGoal.class) +public class + + + +MixinEndermanGoal { + @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;isIn(Lnet/minecraft/registry/tag/TagKey;)Z")) + public boolean isHoldable(BlockState blockState, TagKey tagKey) { + if (!SLSCarpetSettings.endermanCanPickUpMushroom) { + return blockState.isIn(tagKey) && !(blockState.getBlock() instanceof MushroomPlantBlock); + } + else { + return blockState.isIn(tagKey); + } + } +} diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/protocol/pcaSyncProtocol/block/MixinBeehiveBlockEntity.java b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/protocol/pcaSyncProtocol/block/MixinBeehiveBlockEntity.java index df5e41f..eeb4035 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/mixin/protocol/pcaSyncProtocol/block/MixinBeehiveBlockEntity.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/protocol/pcaSyncProtocol/block/MixinBeehiveBlockEntity.java @@ -30,8 +30,11 @@ public abstract class MixinBeehiveBlockEntity extends BlockEntity { @Inject(method = "tickBees", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;remove()V", shift = At.Shift.AFTER)) private static void postTickBees(World world, BlockPos pos, BlockState state, List bees, BlockPos flowerPos, CallbackInfo ci) { - if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(Objects.requireNonNull(world.getBlockEntity(pos)))) { - ServerMain.LOGGER.debug("update BeehiveBlockEntity: {}", pos); + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity != null) { + if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(blockEntity)) { + ServerMain.LOGGER.debug("update BeehiveBlockEntity: {}", pos); + } } } 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 new file mode 100644 index 0000000..8cf6fb2 --- /dev/null +++ b/src/main/java/com/github/zly2006/carpetslsaddition/mixin/world/MixinSleepManager.java @@ -0,0 +1,23 @@ +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 org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(SleepManager.class) +public class MixinSleepManager { + + @Redirect(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;isSpectator()Z")) + private boolean isNormalPlayer(ServerPlayerEntity serverPlayerEntity) { + if (SLSCarpetSettings.fakePlayersNotOccupiedSleepQuota) { + return serverPlayerEntity.isSpectator() || serverPlayerEntity instanceof EntityPlayerMPFake; + } + else { + return serverPlayerEntity.isSpectator(); + } + } +} diff --git a/src/main/resources/assets/slsaddition/lang/en_us.json b/src/main/resources/assets/slsaddition/lang/en_us.json index 131e155..7e14c38 100644 --- a/src/main/resources/assets/slsaddition/lang/en_us.json +++ b/src/main/resources/assets/slsaddition/lang/en_us.json @@ -6,9 +6,7 @@ "carpet.rule.obtainableReinforcedDeepSlate.name": "Obtainable reinforced deep slate", "carpet.rule.skipTicksForJoblessVillager.name": "Skip ticks for jobless villager", - "carpet.rule.maxVillagersInABlock.name": "Max villagers in a block", "carpet.rule.creativeNoInfinitePickup.name": "Creative mode cannot infinite pickup", - "carpet.rule.autoUrl.name": "Auto add click event for url", "carpet.rule.noBatSpawning.name": "No bat spawning", "carpet.rule.offlineFakePlayers.name": "Use offline mode for fake players", "carpet.rule.pcaSyncProtocol.name": "Enable PCA Sync Protocol", @@ -22,12 +20,13 @@ "carpet.rule.maxUpdateQueueSize.name": "Maximum allowed capacity of update queue", "carpet.rule.oldRedstoneConnectionLogic.name": "Restore the previous redstone wire connection logic", "carpet.rule.optimizedOnDragonRespawn.name": "Optimize the dragon respawn", + "carpet.rule.enableCCESuppressor.name": "Enable CCE suppressor.", + "carpet.rule.fakePlayersNotOccupiedSleepQuota.name": "Fake players do not occupy sleep quotas.", + "carpet.rule.endermanCanPickUpMushroom.name": "Enderman can pick up mushroom", "carpet.rule.obtainableReinforcedDeepSlate.desc": "When an anvil falls on 64 dropped deepslates, they will be turned in a reinforced deepslate instead of disappearing.", "carpet.rule.skipTicksForJoblessVillager.desc": "For jobless/nitwit villagers, after performing a set number of tick operations, skip the 1 tick operation.", - "carpet.rule.maxVillagersInABlock.desc": "The maximum number of villagers that can be in a block, set to -1 to disable.", "carpet.rule.creativeNoInfinitePickup.desc": "If my inventory is full, don't pick up items in creative mode.", - "carpet.rule.autoUrl.desc": "Automatically add click event to URLs in chat.", "carpet.rule.noBatSpawning.desc": "Prevents bats from spawning.", "carpet.rule.offlineFakePlayers.desc": "Using offline uuid and skin so that fake players wont cause extra network traffic.", "carpet.rule.pcaSyncProtocol.desc": "Using PCA protocol to support sync entity and blockEntity from server", @@ -41,8 +40,10 @@ "carpet.rule.maxUpdateQueueSize.desc": "Set the maximum allowed length of the update queue", "carpet.rule.oldRedstoneConnectionLogic.desc": "Restore the interaction logic between the Redstone wire and the trap door to the performance of versions 1.19 and earlier", "carpet.rule.optimizedOnDragonRespawn.desc": "Optimize the dragon respawn process", + "carpet.rule.enableCCESuppressor.desc": "Make CCE suppressors from 1.20.1 and earlier versions available again.", + "carpet.rule.fakePlayersNotOccupiedSleepQuota.desc": "Make the fake player generated by Carpet no longer occupy sleep quotas", + "carpet.rule.endermanCanPickUpMushroom.desc": "Enderman can pick up the mushroom plant if enabled", - "carpet.rule.autoUrl.extra.0": "The URL sent by players to be directly clicked and redirected by other players", "carpet.rule.skipTicksForJoblessVillager.extra.0": "Set to 0 to maintain the vanilla behavior", "carpet.rule.skipTicksForJoblessVillager.extra.1": "Set to a number greater than 0, the value will be +1 based on the setting", "carpet.rule.skipTicksForJoblessVillager.extra.2": "To prevents villagers from getting completely stuck when set to 1", diff --git a/src/main/resources/assets/slsaddition/lang/zh_cn.json b/src/main/resources/assets/slsaddition/lang/zh_cn.json index 4f03195..5a4dd65 100644 --- a/src/main/resources/assets/slsaddition/lang/zh_cn.json +++ b/src/main/resources/assets/slsaddition/lang/zh_cn.json @@ -6,9 +6,7 @@ "carpet.rule.obtainableReinforcedDeepSlate.name": "强化深板岩可获取", "carpet.rule.skipTicksForJoblessVillager.name": "无业村民跳刻", - "carpet.rule.maxVillagersInABlock.name": "单格最大村民数", "carpet.rule.creativeNoInfinitePickup.name": "创造模式满背包无法拾取", - "carpet.rule.autoUrl.name": "更便捷的URL", "carpet.rule.noBatSpawning.name": "禁止蝙蝠生成", "carpet.rule.offlineFakePlayers.name": "假人离线模式", "carpet.rule.pcaSyncProtocol.name": "启动兼容PCA的同步协议", @@ -22,12 +20,13 @@ "carpet.rule.maxUpdateQueueSize.name": "最大更新队列容量", "carpet.rule.oldRedstoneConnectionLogic.name": "恢复红石线连接逻辑", "carpet.rule.optimizedOnDragonRespawn.name": "龙战优化", + "carpet.rule.enableCCESuppressor.name": "恢复CCE抑制器", + "carpet.rule.fakePlayersNotOccupiedSleepQuota.name": "假人不占用睡眠名额", + "carpet.rule.endermanCanPickUpMushroom.name": "末影人可拿起蘑菇", - "carpet.rule.maxVillagersInABlock.desc": "每个方块中最大村民数量,设置-1为无限制", "carpet.rule.obtainableReinforcedDeepSlate.desc": "当铁砧在64个深板岩的掉落物上时,可以获得强化深板岩", "carpet.rule.skipTicksForJoblessVillager.desc": "对于无业/傻子村民,执行设定数量的tick运算后,跳过1tick的运算", "carpet.rule.creativeNoInfinitePickup.desc": "创造模式下,玩家不能无限制地拾取物品", - "carpet.rule.autoUrl.desc": "自动识别URL并为其添加点击事件", "carpet.rule.noBatSpawning.desc": "禁止任何区域蝙蝠生成", "carpet.rule.offlineFakePlayers.desc": "由Carpet生成的假玩家,将使用离线皮肤和UUID", "carpet.rule.pcaSyncProtocol.desc": "借助PCA同步协议,支持同步 BlockEntity 和 Entity 到客户端", @@ -41,8 +40,10 @@ "carpet.rule.maxUpdateQueueSize.desc": "设定最大允许的更新队列长度", "carpet.rule.oldRedstoneConnectionLogic.desc": "使活板门上的红石线与其他红石线连接的逻辑恢复到1.19及之前版本的表现", "carpet.rule.optimizedOnDragonRespawn.desc": "对重生末影龙的过程进行优化", + "carpet.rule.enableCCESuppressor.desc": "让1.20.1及更早的CCE抑制器变得再次可用", + "carpet.rule.fakePlayersNotOccupiedSleepQuota.desc": "让假人不再占用睡眠名额,这样即使假人不睡觉也能跳过夜晚", + "carpet.rule.endermanCanPickUpMushroom.desc": "如果该选项打开,则末影人可以捡起地上的蘑菇", - "carpet.rule.autoUrl.extra.0": "使玩家发出的URL可以被其他玩家直接点击跳转", "carpet.rule.skipTicksForJoblessVillager.extra.0": "设置为0则保持原版行为", "carpet.rule.skipTicksForJoblessVillager.extra.1": "设置为大于0的数,将在设置的基础上将该值+1", "carpet.rule.skipTicksForJoblessVillager.extra.2": "以此避免在设置为1的时候,村民完全卡死", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 04f580b..215689a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -6,7 +6,8 @@ "name": "Carpet SLS Addition", "description": "", "authors": [ - "zly2006" + "zly2006", + "Disy920" ], "contact": { }, @@ -25,7 +26,7 @@ ], "depends": { - "fabricloader": ">=0.13", + "fabricloader": ">=0.15.1", "fabric-api": "*", "minecraft": ">=1.20", "java": ">=17", diff --git a/src/main/resources/slsa.accesswidener b/src/main/resources/slsa.accesswidener index f049378..b567afa 100644 --- a/src/main/resources/slsa.accesswidener +++ b/src/main/resources/slsa.accesswidener @@ -1,2 +1,3 @@ accessWidener v1 named accessible class net/minecraft/world/block/ChainRestrictedNeighborUpdater$Entry +accessible class net/minecraft/entity/mob/EndermanEntity$PickUpBlockGoal \ No newline at end of file diff --git a/src/main/resources/slsaddition.mixins.json b/src/main/resources/slsaddition.mixins.json index 3b86f01..a225cd3 100644 --- a/src/main/resources/slsaddition.mixins.json +++ b/src/main/resources/slsaddition.mixins.json @@ -16,6 +16,7 @@ "carpet.MixinSettingsManager", "entity.MixinArmorStandEntity", "entity.MixinEnderDragonFight", + "entity.MixinEndermanGoal", "entity.MixinFallingBlockEntity", "entity.MixinItemEntity", "entity.MixinPlayerEntity", @@ -41,6 +42,7 @@ "screen.MixinSlot", "server.MixinMinecraftServer", "server.MixinPlayerManager", + "world.MixinSleepManager", "world.MixinSpawnHelper", "world.MixinWorld" ],