feat: 拴绳修复与bot在线时长限制

This commit is contained in:
Disy authored and zly2006 committed 2024-07-11 12:14:03 +08:00
1 parent abb25c0d48
commit 57d2058a6b
18 files changed
+236 -16

No files matched your search

@@ -36,6 +36,10 @@ public class SLSCarpetSettings {
@Rule(categories = {SLSA}, strict = false, options = {"#none"}) @Rule(categories = {SLSA}, strict = false, options = {"#none"})
public static String botPrefix = "#none"; public static String botPrefix = "#none";
/** Carpet SLS Addition original **/
@Rule(categories = {SLSA})
public static long botMaxOnlineTime = -1;
/** Carpet SLS Addition original **/ /** Carpet SLS Addition original **/
@Rule(categories = {SLSA, RuleCategory.FEATURE}) @Rule(categories = {SLSA, RuleCategory.FEATURE})
public static boolean creativeObeyEnchantmentRule = false; public static boolean creativeObeyEnchantmentRule = false;
@@ -75,4 +79,8 @@ public class SLSCarpetSettings {
/** Carpet SLS Addition original **/ /** Carpet SLS Addition original **/
@Rule(categories = {SLSA, RuleCategory.FEATURE}) @Rule(categories = {SLSA, RuleCategory.FEATURE})
public static boolean elytraCraftable = false; public static boolean elytraCraftable = false;
/** Carpet SLS Addition original **/
@Rule(categories = {SLSA, RuleCategory.FEATURE})
public static boolean spectatorCannotUseLeash = false;
} }
@@ -5,7 +5,6 @@ import carpet.CarpetServer;
import com.github.zly2006.carpetslsaddition.command.BotCommand; import com.github.zly2006.carpetslsaddition.command.BotCommand;
import com.github.zly2006.carpetslsaddition.command.HatCommand; import com.github.zly2006.carpetslsaddition.command.HatCommand;
import com.github.zly2006.carpetslsaddition.command.SitCommand; import com.github.zly2006.carpetslsaddition.command.SitCommand;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import com.github.zly2006.carpetslsaddition.util.access.SettingsManagerAccessor; import com.github.zly2006.carpetslsaddition.util.access.SettingsManagerAccessor;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.Gson; import com.google.gson.Gson;
@@ -49,7 +48,7 @@ public class ServerMain implements ModInitializer, CarpetExtension {
public void onServerLoaded(MinecraftServer server) { public void onServerLoaded(MinecraftServer server) {
ServerMain.server = server; ServerMain.server = server;
CarpetServer.settingsManager.parseSettingsClass(SLSCarpetSettings.class); CarpetServer.settingsManager.parseSettingsClass(SLSCarpetSettings.class);
((SettingsManagerAccessor) CarpetServer.settingsManager).loadSettings(); ((SettingsManagerAccessor) CarpetServer.settingsManager).carpet_SLS_Addition$loadSettings();
} }
@Override @Override
@@ -8,7 +8,8 @@ import carpet.patches.FakeClientConnection;
import carpet.utils.Messenger; import carpet.utils.Messenger;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain; import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess; import com.github.zly2006.carpetslsaddition.util.access.PlayerAccessor;
import com.github.zly2006.carpetslsaddition.util.access.SLSBotAccessor;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.Command; import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
@@ -81,6 +82,7 @@ public class BotCommand {
.then(argument("slot", IntegerArgumentType.integer(1, 9)) .then(argument("slot", IntegerArgumentType.integer(1, 9))
.executes(c -> manipulate(c, ap -> ap.setSlot(IntegerArgumentType.getInteger(c, "slot")))))) .executes(c -> manipulate(c, ap -> ap.setSlot(IntegerArgumentType.getInteger(c, "slot"))))))
.then(literal("kill").executes(BotCommand::kill)) .then(literal("kill").executes(BotCommand::kill))
.then(literal("respawn")).executes(BotCommand::respawn)
.then(literal("mount").executes(manipulation(ap -> ap.mount(true))) .then(literal("mount").executes(manipulation(ap -> ap.mount(true)))
.then(literal("anything").executes(manipulation(ap -> ap.mount(false))))) .then(literal("anything").executes(manipulation(ap -> ap.mount(false)))))
.then(literal("dismount").executes(manipulation(EntityPlayerActionPack::dismount))) .then(literal("dismount").executes(manipulation(EntityPlayerActionPack::dismount)))
@@ -244,6 +246,30 @@ public class BotCommand {
return 1; return 1;
} }
private static int respawn(CommandContext<ServerCommandSource> context) {
var player = getPlayer(context);
if (((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)
)
);
return Command.SINGLE_SUCCESS;
}
context.getSource().sendMessage(
Text.translatable("carpet.slsa.bot.not_a_bot", player.getNameForScoreboard())
.setStyle(
Style.EMPTY.withColor(Formatting.RED)
)
);
return 0;
}
@FunctionalInterface @FunctionalInterface
interface SupplierWithCSE<T> interface SupplierWithCSE<T>
{ {
@@ -302,7 +328,7 @@ public class BotCommand {
return 0; return 0;
} }
((PlayerAccess) 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(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() ServerMain.server.getPlayerManager().broadcast(Text.empty()
.append(Text.literal("假人").setStyle(Style.EMPTY.withColor(Formatting.GREEN))) .append(Text.literal("假人").setStyle(Style.EMPTY.withColor(Formatting.GREEN)))
@@ -368,6 +394,9 @@ public class BotCommand {
bot.getDataTracker().set(PlayerEntity.PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes) bot.getDataTracker().set(PlayerEntity.PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes)
bot.getAbilities().flying = false; bot.getAbilities().flying = false;
((SLSBotAccessor)bot).carpet_SLS_Addition$setBot(true);
((SLSBotAccessor)bot).carpet_SLS_Addition$setSpawnTime(System.currentTimeMillis());
return bot; return bot;
} }
catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
@@ -0,0 +1,90 @@
package com.github.zly2006.carpetslsaddition.mixin.carpet;
import carpet.patches.EntityPlayerMPFake;
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.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 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();
@Unique
private boolean bot = false;
@Unique
private long spawnTime = -1;
public MixinEntityPlayerMPFake(MinecraftServer server, ServerWorld world, GameProfile profile, SyncedClientOptions clientOptions) {
super(server, world, profile, clientOptions);
}
@Override
public boolean carpet_SLS_Addition$isBot() {
return bot;
}
@Override
public void carpet_SLS_Addition$setBot(boolean isBot) {
this.bot = isBot;
}
@Override
public long carpet_SLS_Addition$getSpawnTime() {
if (spawnTime == -1) spawnTime = System.currentTimeMillis();
return spawnTime;
}
@Override
public void carpet_SLS_Addition$setSpawnTime(long spawnTime) {
this.spawnTime = spawnTime;
}
@Inject(method = "tick", at = @At("HEAD"))
public void onTick(CallbackInfo ci) {
if (!this.bot || SLSCarpetSettings.botMaxOnlineTime < 0) {
return;
}
long currentTime = System.currentTimeMillis();
long liveTime = currentTime - spawnTime;
if (liveTime > SLSCarpetSettings.botMaxOnlineTime * 1000) {
ServerMain.server.getPlayerManager().broadcast(
Text.translatable("carpet.slsa.bot.bot_timeout", this.getNameForScoreboard(), getFormattedTime(SLSCarpetSettings.botMaxOnlineTime))
.setStyle(
Style.EMPTY.withColor(Formatting.RED)
),
false
);
this.kill();
}
}
@Unique
private static String getFormattedTime(long time) {
if (time > 120 * 60) {
return String.format("%02dh%02dm%02ds", time / 3600, (time % 3600) / 60, time % 60);
}
else if (time > 120) {
return String.format("%02dm%02ds", time / 60, time % 60);
}
else {
return String.format("%02ds", time);
}
}
}
@@ -20,7 +20,7 @@ public abstract class MixinSettingsManager implements SettingsManagerAccessor {
@Shadow protected abstract void loadConfigurationFromConf(); @Shadow protected abstract void loadConfigurationFromConf();
@Override @Override
public void loadSettings() { public void carpet_SLS_Addition$loadSettings() {
this.loadConfigurationFromConf(); this.loadConfigurationFromConf();
} }
@@ -0,0 +1,24 @@
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 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)
public abstract class MixinBoatEntity implements Leashable {
@Inject(method = "tick", at = @At("HEAD"))
private void onTick(CallbackInfo ci) {
if (!SLSCarpetSettings.spectatorCannotUseLeash ||
this.getLeashHolder() == null ||
!this.getLeashHolder().isSpectator()
) {
return;
}
this.detachLeash();
}
}
@@ -0,0 +1,27 @@
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 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)
public abstract class MixinMobEntity implements Leashable {
@Shadow public abstract void detachLeash();
@Inject(method = "tick", at = @At("HEAD"))
private void onTick(CallbackInfo ci) {
if (!SLSCarpetSettings.spectatorCannotUseLeash ||
this.getLeashHolder() == null ||
!this.getLeashHolder().isSpectator()
) {
return;
}
this.detachLeash();
}
}
@@ -1,6 +1,6 @@
package com.github.zly2006.carpetslsaddition.mixin.entity; package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess; import com.github.zly2006.carpetslsaddition.util.access.PlayerAccessor;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntity.class) @Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity implements PlayerAccess { public abstract class MixinPlayerEntity implements PlayerAccessor {
@Unique @Unique
private Text displayName = null; private Text displayName = null;
@@ -3,8 +3,11 @@ package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings; import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.util.SitEntity; import com.github.zly2006.carpetslsaddition.util.SitEntity;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.entity.Entity;
import net.minecraft.entity.Leashable;
import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.LeadItem;
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
@@ -12,12 +15,23 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; 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;
import java.util.List;
@Mixin(ServerPlayerEntity.class) @Mixin(ServerPlayerEntity.class)
public abstract class MixinServerPlayerEntity extends PlayerEntity { public abstract class MixinServerPlayerEntity extends PlayerEntity {
@Shadow @Shadow
public ServerPlayNetworkHandler networkHandler; public ServerPlayNetworkHandler networkHandler;
@Shadow public abstract boolean isSpectator();
@Unique
private int sneakTimes = 0; private int sneakTimes = 0;
@Unique
private long lastSneakTime = 0; private long lastSneakTime = 0;
public MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile) { public MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile) {
@@ -1,6 +1,6 @@
package com.github.zly2006.carpetslsaddition.mixin.server; package com.github.zly2006.carpetslsaddition.mixin.server;
import com.github.zly2006.carpetslsaddition.util.access.ServerAccess; import com.github.zly2006.carpetslsaddition.util.access.ServerAccessor;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.server.dedicated.MinecraftDedicatedServer; import net.minecraft.server.dedicated.MinecraftDedicatedServer;
@@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
@Environment(EnvType.SERVER) @Environment(EnvType.SERVER)
@Mixin(MinecraftDedicatedServer.class) @Mixin(MinecraftDedicatedServer.class)
public class MixinMinecraftDedicatedServer implements ServerAccess { public class MixinMinecraftDedicatedServer implements ServerAccessor {
@Shadow @Shadow
@Final @Final
@@ -3,7 +3,7 @@ package com.github.zly2006.carpetslsaddition.mixin.world;
import com.github.zly2006.carpetslsaddition.ServerMain; import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.block.RewriteChainRestrictedNeighborUpdater; import com.github.zly2006.carpetslsaddition.block.RewriteChainRestrictedNeighborUpdater;
import com.github.zly2006.carpetslsaddition.util.NeighborUpdaterChanger; import com.github.zly2006.carpetslsaddition.util.NeighborUpdaterChanger;
import com.github.zly2006.carpetslsaddition.util.access.ServerAccess; import com.github.zly2006.carpetslsaddition.util.access.ServerAccessor;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.world.World; import net.minecraft.world.World;
@@ -27,7 +27,7 @@ public abstract class MixinWorld implements NeighborUpdaterChanger {
int maxDepth; int maxDepth;
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) { if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) {
maxDepth = ((ServerAccess) ServerMain.server).getPropertiesLoader().getPropertiesHandler().maxChainedNeighborUpdates; maxDepth = ((ServerAccessor) ServerMain.server).getPropertiesLoader().getPropertiesHandler().maxChainedNeighborUpdates;
} }
else { else {
maxDepth = 1000000; maxDepth = 1000000;
@@ -2,6 +2,6 @@ package com.github.zly2006.carpetslsaddition.util.access;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public interface PlayerAccess { public interface PlayerAccessor {
void carpet_SLS_Addition$setDisplayName(Text name); void carpet_SLS_Addition$setDisplayName(Text name);
} }
@@ -0,0 +1,8 @@
package com.github.zly2006.carpetslsaddition.util.access;
public interface SLSBotAccessor {
boolean carpet_SLS_Addition$isBot();
void carpet_SLS_Addition$setBot(boolean isBot);
long carpet_SLS_Addition$getSpawnTime();
void carpet_SLS_Addition$setSpawnTime(long spawnTime);
}
@@ -2,6 +2,6 @@ package com.github.zly2006.carpetslsaddition.util.access;
import net.minecraft.server.dedicated.ServerPropertiesLoader; import net.minecraft.server.dedicated.ServerPropertiesLoader;
public interface ServerAccess { public interface ServerAccessor {
ServerPropertiesLoader getPropertiesLoader(); ServerPropertiesLoader getPropertiesLoader();
} }
@@ -1,5 +1,5 @@
package com.github.zly2006.carpetslsaddition.util.access; package com.github.zly2006.carpetslsaddition.util.access;
public interface SettingsManagerAccessor { public interface SettingsManagerAccessor {
void loadSettings(); void carpet_SLS_Addition$loadSettings();
} }
@@ -23,6 +23,8 @@
"carpet.rule.fakePlayersNotOccupiedSleepQuota.name": "Fake players do not occupy sleep quotas.", "carpet.rule.fakePlayersNotOccupiedSleepQuota.name": "Fake players do not occupy sleep quotas.",
"carpet.rule.endermanCanPickUpMushroom.name": "Enderman can pick up mushroom", "carpet.rule.endermanCanPickUpMushroom.name": "Enderman can pick up mushroom",
"carpet.rule.printStackTraceOnVillagerSpawn.name": "Print the stack trace when a villager spawns", "carpet.rule.printStackTraceOnVillagerSpawn.name": "Print the stack trace when a villager spawns",
"carpet.rule.botMaxOnlineTime.name": "The maximum living time of the bot",
"carpet.rule.spectatorCannotUseLeash.name": "Spectators cannot use the leash",
"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.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.skipTicksForJoblessVillager.desc": "For jobless/nitwit villagers, after performing a set number of tick operations, skip the 1 tick operation.",
@@ -43,6 +45,9 @@
"carpet.rule.fakePlayersNotOccupiedSleepQuota.desc": "Make the fake player generated by Carpet no longer occupy sleep quotas", "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.endermanCanPickUpMushroom.desc": "Enderman can pick up the mushroom plant if enabled",
"carpet.rule.printStackTraceOnVillagerSpawn.desc": "Print the report to the server console when a villager spawns", "carpet.rule.printStackTraceOnVillagerSpawn.desc": "Print the report to the server console when a villager spawns",
"carpet.rule.elytraCraftable.desc": "Make elytra craftable for Minecraft 1.20.6+ (eltra wont disappear when crafting)",
"carpet.rule.botMaxOnlineTime.desc": "Set the maximum living time of the bot which create by carpet sls addition.",
"carpet.rule.spectatorCannotUseLeash.desc": "If a player is a spectator, they cannot use the leash.",
"carpet.rule.skipTicksForJoblessVillager.extra.0": "Set to 0 to maintain the vanilla behavior", "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.1": "Set to a number greater than 0, the value will be +1 based on the setting",
@@ -51,5 +56,9 @@
"carpet.rule.maxUpdateQueueSize.extra.1": "Otherwise, when the number of single updates exceeds the set value, an OutOfMemoryError will be thrown to generate update suppression", "carpet.rule.maxUpdateQueueSize.extra.1": "Otherwise, when the number of single updates exceeds the set value, an OutOfMemoryError will be thrown to generate update suppression",
"carpet.rule.emptyShulkerBoxStack.extra.0": "Empty shulker boxes can stack in a player's inventory or hand", "carpet.rule.emptyShulkerBoxStack.extra.0": "Empty shulker boxes can stack in a player's inventory or hand",
"carpet.rule.emptyShulkerBoxStack.extra.1": "Empty shulker boxes will not stack in other inventories, such as chests or hoppers", "carpet.rule.emptyShulkerBoxStack.extra.1": "Empty shulker boxes will not stack in other inventories, such as chests or hoppers",
"carpet.rule.elytraCraftable.desc": "Make elytra craftable for Minecraft 1.20.6+ (eltra wont disappear when crafting)" "carpet.rule.botMaxOnlineTime.extra.0": "The value in seconds. Set to -1 to disable this limit",
"carpet.slsa.bot.bot_timeout": "The bot %s has exceeded the maximum online time of %s, and has been disconnected now.",
"carpet.slsa.bot.respawned": "The bot %s's online time has been reset.",
"carpet.slsa.bot.not_a_bot": "The player %s is not created by carpet sls addition, so you can't reset the online time."
} }
@@ -23,6 +23,8 @@
"carpet.rule.fakePlayersNotOccupiedSleepQuota.name": "假人不占用睡眠名额", "carpet.rule.fakePlayersNotOccupiedSleepQuota.name": "假人不占用睡眠名额",
"carpet.rule.endermanCanPickUpMushroom.name": "末影人可拿起蘑菇", "carpet.rule.endermanCanPickUpMushroom.name": "末影人可拿起蘑菇",
"carpet.rule.printStackTraceOnVillagerSpawn.name": "打印村民生成报告", "carpet.rule.printStackTraceOnVillagerSpawn.name": "打印村民生成报告",
"carpet.rule.botMaxOnlineTime.name": "Bot最大存活时间",
"carpet.rule.spectatorCannotUseLeash.name": "观察者模式禁用拴绳",
"carpet.rule.obtainableReinforcedDeepSlate.desc": "当铁砧在64个深板岩的掉落物上时,可以获得强化深板岩", "carpet.rule.obtainableReinforcedDeepSlate.desc": "当铁砧在64个深板岩的掉落物上时,可以获得强化深板岩",
"carpet.rule.skipTicksForJoblessVillager.desc": "对于无业/傻子村民,执行设定数量的tick运算后,跳过1tick的运算", "carpet.rule.skipTicksForJoblessVillager.desc": "对于无业/傻子村民,执行设定数量的tick运算后,跳过1tick的运算",
@@ -43,6 +45,9 @@
"carpet.rule.fakePlayersNotOccupiedSleepQuota.desc": "让假人不再占用睡眠名额,这样即使假人不睡觉也能跳过夜晚", "carpet.rule.fakePlayersNotOccupiedSleepQuota.desc": "让假人不再占用睡眠名额,这样即使假人不睡觉也能跳过夜晚",
"carpet.rule.endermanCanPickUpMushroom.desc": "如果该选项打开,则末影人可以捡起地上的蘑菇", "carpet.rule.endermanCanPickUpMushroom.desc": "如果该选项打开,则末影人可以捡起地上的蘑菇",
"carpet.rule.printStackTraceOnVillagerSpawn.desc": "当有村民生成时,将会生成一份包含调用栈的报告,显示在控制端中", "carpet.rule.printStackTraceOnVillagerSpawn.desc": "当有村民生成时,将会生成一份包含调用栈的报告,显示在控制端中",
"carpet.rule.elytraCraftable.desc": "使鞘翅在 1.20.6+ 可合成 (合成时不会消失)",
"carpet.rule.botMaxOnlineTime.desc": "设置由Carpet SLS Addition生成的Bot的最大存活时间",
"carpet.rule.spectatorCannotUseLeash.desc": "若启用,则观察者模式的玩家不再能使用拴绳,已经拴住动物的拴绳也会自动失效",
"carpet.rule.skipTicksForJoblessVillager.extra.0": "设置为0则保持原版行为", "carpet.rule.skipTicksForJoblessVillager.extra.0": "设置为0则保持原版行为",
"carpet.rule.skipTicksForJoblessVillager.extra.1": "设置为大于0的数,将在设置的基础上将该值+1", "carpet.rule.skipTicksForJoblessVillager.extra.1": "设置为大于0的数,将在设置的基础上将该值+1",
@@ -51,5 +56,9 @@
"carpet.rule.maxUpdateQueueSize.extra.1": "否则,在单次更新数量超过设定最大容量后,服务器将抛出OutOfMemoryError,以达到快速更新抑制的效果", "carpet.rule.maxUpdateQueueSize.extra.1": "否则,在单次更新数量超过设定最大容量后,服务器将抛出OutOfMemoryError,以达到快速更新抑制的效果",
"carpet.rule.emptyShulkerBoxStack.extra.0": "空潜影盒可以在玩家的背包进行自动堆叠,同时玩家可以手动堆叠空潜影盒", "carpet.rule.emptyShulkerBoxStack.extra.0": "空潜影盒可以在玩家的背包进行自动堆叠,同时玩家可以手动堆叠空潜影盒",
"carpet.rule.emptyShulkerBoxStack.extra.1": "但是空潜影盒无法在容器中自动堆叠,比如箱子,漏斗", "carpet.rule.emptyShulkerBoxStack.extra.1": "但是空潜影盒无法在容器中自动堆叠,比如箱子,漏斗",
"carpet.rule.elytraCraftable.desc": "使鞘翅在 1.20.6+ 可合成 (合成时不会消失)" "carpet.rule.botMaxOnlineTime.extra.0": "单位为秒,设置为-1则不启用限制",
"carpet.slsa.bot.bot_timeout": "假人%s在线时间已超出服务器设定的最大在线时长%s,已被自动踢出",
"carpet.slsa.bot.respawned": "假人%s的在线时长已重置!",
"carpet.slsa.bot.not_a_bot": "假人%s不是由Carpet SLS Addition生成的,所以你不能重置它的在线时间!"
} }
@@ -11,16 +11,19 @@
"mixins": [ "mixins": [
"block.BlockPatternTestTransformInvoker", "block.BlockPatternTestTransformInvoker",
"block.MixinRedstoneWireBlock", "block.MixinRedstoneWireBlock",
"carpet.MixinEntityPlayerMPFake",
"carpet.MixinSettingsManager", "carpet.MixinSettingsManager",
"datapack.MixinVanillaResourcePackProvider", "datapack.MixinVanillaResourcePackProvider",
"elytra.MixinElytraItem", "elytra.MixinElytraItem",
"elytra.MixinItem", "elytra.MixinItem",
"elytra.MixinRecipe", "elytra.MixinRecipe",
"entity.MixinArmorStandEntity", "entity.MixinArmorStandEntity",
"entity.MixinBoatEntity",
"entity.MixinEnderDragonFight", "entity.MixinEnderDragonFight",
"entity.MixinEndermanGoal", "entity.MixinEndermanGoal",
"entity.MixinFallingBlockEntity", "entity.MixinFallingBlockEntity",
"entity.MixinItemEntity", "entity.MixinItemEntity",
"entity.MixinMobEntity",
"entity.MixinPlayerEntity", "entity.MixinPlayerEntity",
"entity.MixinServerPlayerEntity", "entity.MixinServerPlayerEntity",
"entity.MixinVillagerEntity", "entity.MixinVillagerEntity",