feat: 调整了bot的实现方式
This commit is contained in:
1 parent
07596c15c7
commit
2063933634
10 files changed
+80
-76
No files matched your search
+2
-2
@@ -41,14 +41,14 @@ dependencies {
|
|||||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
// luck perm
|
// luck perm
|
||||||
modRuntimeOnly "maven.modrinth:luckperms:v5.4.83-fabric"
|
modRuntimeOnly "maven.modrinth:luckperms:v5.4.133-fabric"
|
||||||
|
|
||||||
// carpet
|
// carpet
|
||||||
modImplementation "carpet:fabric-carpet:${project.carpet_core_version}"
|
modImplementation "carpet:fabric-carpet:${project.carpet_core_version}"
|
||||||
// modImplementation(files("./lib/fabric-carpet-1.20-1.4.112+v230608.jar"))
|
// modImplementation(files("./lib/fabric-carpet-1.20-1.4.112+v230608.jar"))
|
||||||
|
|
||||||
// Fabric Permission API
|
// Fabric Permission API
|
||||||
include(modImplementation('me.lucko:fabric-permissions-api:0.2-SNAPSHOT'))
|
include(modImplementation('me.lucko:fabric-permissions-api:0.3.1'))
|
||||||
include(modImplementation('com.github.Fallen-Breath:conditional-mixin:v0.4.0'))
|
include(modImplementation('com.github.Fallen-Breath:conditional-mixin:v0.4.0'))
|
||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ public class SLSCarpetSettings {
|
|||||||
@Rule(categories = {CARPET_ID, RuleCategory.OPTIMIZATION})
|
@Rule(categories = {CARPET_ID, RuleCategory.OPTIMIZATION})
|
||||||
public static boolean noBatSpawning = false;
|
public static boolean noBatSpawning = false;
|
||||||
|
|
||||||
@Rule(categories = {CARPET_ID, RuleCategory.FEATURE})
|
|
||||||
public static boolean offlineFakePlayers = false;
|
|
||||||
|
|
||||||
@Rule(categories = {CARPET_ID, RuleCategory.FEATURE})
|
@Rule(categories = {CARPET_ID, RuleCategory.FEATURE})
|
||||||
public static boolean canUseHatCommand = false;
|
public static boolean canUseHatCommand = false;
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import carpet.CarpetSettings;
|
|||||||
import carpet.fakes.ServerPlayerInterface;
|
import carpet.fakes.ServerPlayerInterface;
|
||||||
import carpet.helpers.EntityPlayerActionPack;
|
import carpet.helpers.EntityPlayerActionPack;
|
||||||
import carpet.patches.EntityPlayerMPFake;
|
import carpet.patches.EntityPlayerMPFake;
|
||||||
|
import carpet.patches.FakeClientConnection;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess;
|
|
||||||
import com.github.zly2006.carpetslsaddition.ServerMain;
|
import com.github.zly2006.carpetslsaddition.ServerMain;
|
||||||
|
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess;
|
||||||
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;
|
||||||
@@ -20,17 +21,24 @@ import net.minecraft.command.argument.DimensionArgumentType;
|
|||||||
import net.minecraft.command.argument.GameModeArgumentType;
|
import net.minecraft.command.argument.GameModeArgumentType;
|
||||||
import net.minecraft.command.argument.RotationArgumentType;
|
import net.minecraft.command.argument.RotationArgumentType;
|
||||||
import net.minecraft.command.argument.Vec3ArgumentType;
|
import net.minecraft.command.argument.Vec3ArgumentType;
|
||||||
|
import net.minecraft.entity.attribute.EntityAttributes;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
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.network.packet.s2c.play.PlayerListS2CPacket;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.server.Main;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.PlayerManager;
|
import net.minecraft.server.PlayerManager;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.server.network.ConnectedClientData;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.text.Style;
|
import net.minecraft.text.Style;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
|
import net.minecraft.util.UserCache;
|
||||||
import net.minecraft.util.Uuids;
|
import net.minecraft.util.Uuids;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
@@ -39,12 +47,12 @@ import net.minecraft.util.math.Vec3d;
|
|||||||
import net.minecraft.world.GameMode;
|
import net.minecraft.world.GameMode;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static net.minecraft.command.CommandSource.suggestMatching;
|
import static net.minecraft.command.CommandSource.suggestMatching;
|
||||||
@@ -52,7 +60,6 @@ import static net.minecraft.server.command.CommandManager.argument;
|
|||||||
import static net.minecraft.server.command.CommandManager.literal;
|
import static net.minecraft.server.command.CommandManager.literal;
|
||||||
|
|
||||||
public class BotCommand {
|
public class BotCommand {
|
||||||
public static final ArrayBlockingQueue<ServerPlayerEntity> playerQueue = new ArrayBlockingQueue<>(128);
|
|
||||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher)
|
public static void register(CommandDispatcher<ServerCommandSource> dispatcher)
|
||||||
{
|
{
|
||||||
LiteralArgumentBuilder<ServerCommandSource> command = literal("bot")
|
LiteralArgumentBuilder<ServerCommandSource> command = literal("bot")
|
||||||
@@ -279,26 +286,18 @@ public class BotCommand {
|
|||||||
Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world");
|
Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
boolean success = EntityPlayerMPFake.createFake(playerName, source.getServer(), pos, facing.y, facing.x, dimType, GameMode.SURVIVAL, false);
|
|
||||||
|
|
||||||
if (!success)
|
EntityPlayerMPFake bot = createBot(playerName, source.getServer(), pos, facing.y, facing.x, dimType);
|
||||||
|
|
||||||
|
if (bot == null)
|
||||||
{
|
{
|
||||||
Messenger.m(source, "rb Player " + playerName + " doesn't exist and cannot spawn in online mode. " +
|
Messenger.m(source, "rb Player " + playerName + " doesn't exist and cannot spawn in online mode. " +
|
||||||
"Turn the server offline to spawn non-existing players");
|
"Turn the server offline to spawn non-existing players");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ServerPlayerEntity player;
|
|
||||||
try {
|
|
||||||
player = playerQueue.poll(500, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player == null) return 1;
|
((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)));
|
||||||
|
|
||||||
((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()
|
ServerMain.server.getPlayerManager().broadcast(Text.empty()
|
||||||
.append(Text.literal("假人").setStyle(Style.EMPTY.withColor(Formatting.GREEN)))
|
.append(Text.literal("假人").setStyle(Style.EMPTY.withColor(Formatting.GREEN)))
|
||||||
.append(Text.literal(playerName).setStyle(Style.EMPTY.withColor(Formatting.GOLD).withBold(true)))
|
.append(Text.literal(playerName).setStyle(Style.EMPTY.withColor(Formatting.GOLD).withBold(true)))
|
||||||
@@ -308,12 +307,68 @@ public class BotCommand {
|
|||||||
|
|
||||||
ServerMain.server.getPlayerManager().sendToAll(new PlayerListS2CPacket(
|
ServerMain.server.getPlayerManager().sendToAll(new PlayerListS2CPacket(
|
||||||
PlayerListS2CPacket.Action.UPDATE_DISPLAY_NAME,
|
PlayerListS2CPacket.Action.UPDATE_DISPLAY_NAME,
|
||||||
player
|
bot
|
||||||
));
|
));
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static EntityPlayerMPFake createBot(String username, MinecraftServer server, Vec3d pos, double yaw, double pitch, RegistryKey<World> dimensionId) {
|
||||||
|
ServerWorld worldIn = server.getWorld(dimensionId);
|
||||||
|
UserCache.setUseRemote(false);
|
||||||
|
GameProfile gameprofile;
|
||||||
|
try {
|
||||||
|
gameprofile = server.getUserCache().findByName(username).orElse(null); //findByName .orElse(null)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
UserCache.setUseRemote(server.isDedicated() && server.isOnlineMode());
|
||||||
|
}
|
||||||
|
if (gameprofile == null)
|
||||||
|
{
|
||||||
|
if (!CarpetSettings.allowSpawningOfflinePlayers)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
gameprofile = new GameProfile(Uuids.getOfflinePlayerUuid(username), username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 孩子不懂,用反射写着玩的,报错了记得随Carpet一起升级一下
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class<EntityPlayerMPFake> fakePlayerClass = (Class<EntityPlayerMPFake>)Class.forName("carpet.patches.EntityPlayerMPFake");
|
||||||
|
Constructor<EntityPlayerMPFake> constructor = fakePlayerClass.getDeclaredConstructor(
|
||||||
|
MinecraftServer.class,
|
||||||
|
ServerWorld.class,
|
||||||
|
GameProfile.class,
|
||||||
|
SyncedClientOptions.class,
|
||||||
|
boolean.class
|
||||||
|
);
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
EntityPlayerMPFake bot = constructor.newInstance(server, worldIn, gameprofile, SyncedClientOptions.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.teleport(worldIn, pos.x, pos.y, pos.z, (float) yaw, (float) pitch);
|
||||||
|
bot.setHealth(20.0F);
|
||||||
|
bot.unsetRemoved();
|
||||||
|
bot.getAttributeInstance(EntityAttributes.GENERIC_STEP_HEIGHT).setBaseValue(0.6F);
|
||||||
|
bot.interactionManager.changeGameMode(GameMode.SURVIVAL);
|
||||||
|
|
||||||
|
server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(bot, (byte) (bot.headYaw * 256 / 360)), dimensionId);//bot.dimension);
|
||||||
|
server.getPlayerManager().sendToDimension(new EntityPositionS2CPacket(bot), dimensionId);
|
||||||
|
|
||||||
|
bot.getDataTracker().set(PlayerEntity.PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes)
|
||||||
|
bot.getAbilities().flying = false;
|
||||||
|
|
||||||
|
return bot;
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException("An error has occurred when trying spawn a new bot with reflection", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static int maxNameLength(MinecraftServer server)
|
private static int maxNameLength(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return 40;
|
return 40;
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
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 {
|
|
||||||
@Redirect(method = "createFake", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/UserCache;findByName(Ljava/lang/String;)Ljava/util/Optional;"))
|
|
||||||
private static Optional<GameProfile> onCreate(UserCache instance, String name) {
|
|
||||||
if (SLSCarpetSettings.offlineFakePlayers) {
|
|
||||||
UUID uuid = Uuids.getOfflinePlayerUuid(name);
|
|
||||||
return Optional.of(new GameProfile(uuid, name));
|
|
||||||
}
|
|
||||||
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) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-6
@@ -1,12 +1,9 @@
|
|||||||
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.PlayerAccess;
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
|
||||||
import net.minecraft.stat.Stat;
|
import net.minecraft.stat.Stat;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
@@ -17,8 +14,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import static com.github.zly2006.carpetslsaddition.ServerMain.*;
|
|
||||||
|
|
||||||
@Mixin(PlayerEntity.class)
|
@Mixin(PlayerEntity.class)
|
||||||
public abstract class MixinPlayerEntity implements PlayerAccess {
|
public abstract class MixinPlayerEntity implements PlayerAccess {
|
||||||
@Shadow public abstract ItemStack getEquippedStack(EquipmentSlot slot);
|
@Shadow public abstract ItemStack getEquippedStack(EquipmentSlot slot);
|
||||||
@@ -31,7 +26,7 @@ public abstract class MixinPlayerEntity implements PlayerAccess {
|
|||||||
private Text displayName = null;
|
private Text displayName = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDisplayName(Text name) {
|
public void carpet_SLS_Addition$setDisplayName(Text name) {
|
||||||
this.displayName = name;
|
this.displayName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,5 @@ package com.github.zly2006.carpetslsaddition.util.access;
|
|||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public interface PlayerAccess {
|
public interface PlayerAccess {
|
||||||
boolean holdingObsidianPickaxe();
|
void carpet_SLS_Addition$setDisplayName(Text name);
|
||||||
|
|
||||||
void setDisplayName(Text name);
|
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
"carpet.rule.skipTicksForJoblessVillager.name": "Skip ticks for jobless villager",
|
"carpet.rule.skipTicksForJoblessVillager.name": "Skip ticks for jobless villager",
|
||||||
"carpet.rule.creativeNoInfinitePickup.name": "Creative mode cannot infinite pickup",
|
"carpet.rule.creativeNoInfinitePickup.name": "Creative mode cannot infinite pickup",
|
||||||
"carpet.rule.noBatSpawning.name": "No bat spawning",
|
"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",
|
"carpet.rule.pcaSyncProtocol.name": "Enable PCA Sync Protocol",
|
||||||
"carpet.rule.pcaSyncPlayerEntity.name": "Set PCA Sync Protocol's entity scope",
|
"carpet.rule.pcaSyncPlayerEntity.name": "Set PCA Sync Protocol's entity scope",
|
||||||
"carpet.rule.emptyShulkerBoxStack.name": "Empty shulker boxes can be stacked",
|
"carpet.rule.emptyShulkerBoxStack.name": "Empty shulker boxes can be stacked",
|
||||||
@@ -28,7 +27,6 @@
|
|||||||
"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.",
|
||||||
"carpet.rule.creativeNoInfinitePickup.desc": "If my inventory is full, don't pick up items in creative mode.",
|
"carpet.rule.creativeNoInfinitePickup.desc": "If my inventory is full, don't pick up items in creative mode.",
|
||||||
"carpet.rule.noBatSpawning.desc": "Prevents bats from spawning.",
|
"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",
|
"carpet.rule.pcaSyncProtocol.desc": "Using PCA protocol to support sync entity and blockEntity from server",
|
||||||
"carpet.rule.pcaSyncPlayerEntity.desc": "Which player entity can be sync",
|
"carpet.rule.pcaSyncPlayerEntity.desc": "Which player entity can be sync",
|
||||||
"carpet.rule.emptyShulkerBoxStack.desc": "Empty shulker boxes stack",
|
"carpet.rule.emptyShulkerBoxStack.desc": "Empty shulker boxes stack",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
"carpet.rule.skipTicksForJoblessVillager.name": "无业村民跳刻",
|
"carpet.rule.skipTicksForJoblessVillager.name": "无业村民跳刻",
|
||||||
"carpet.rule.creativeNoInfinitePickup.name": "创造模式满背包无法拾取",
|
"carpet.rule.creativeNoInfinitePickup.name": "创造模式满背包无法拾取",
|
||||||
"carpet.rule.noBatSpawning.name": "禁止蝙蝠生成",
|
"carpet.rule.noBatSpawning.name": "禁止蝙蝠生成",
|
||||||
"carpet.rule.offlineFakePlayers.name": "假人离线模式",
|
|
||||||
"carpet.rule.pcaSyncProtocol.name": "启动兼容PCA的同步协议",
|
"carpet.rule.pcaSyncProtocol.name": "启动兼容PCA的同步协议",
|
||||||
"carpet.rule.pcaSyncPlayerEntity.name": "PCA同步协议作用范围",
|
"carpet.rule.pcaSyncPlayerEntity.name": "PCA同步协议作用范围",
|
||||||
"carpet.rule.emptyShulkerBoxStack.name": "空潜影盒背包可堆叠",
|
"carpet.rule.emptyShulkerBoxStack.name": "空潜影盒背包可堆叠",
|
||||||
@@ -28,7 +27,6 @@
|
|||||||
"carpet.rule.skipTicksForJoblessVillager.desc": "对于无业/傻子村民,执行设定数量的tick运算后,跳过1tick的运算",
|
"carpet.rule.skipTicksForJoblessVillager.desc": "对于无业/傻子村民,执行设定数量的tick运算后,跳过1tick的运算",
|
||||||
"carpet.rule.creativeNoInfinitePickup.desc": "创造模式下,玩家不能无限制地拾取物品",
|
"carpet.rule.creativeNoInfinitePickup.desc": "创造模式下,玩家不能无限制地拾取物品",
|
||||||
"carpet.rule.noBatSpawning.desc": "禁止任何区域蝙蝠生成",
|
"carpet.rule.noBatSpawning.desc": "禁止任何区域蝙蝠生成",
|
||||||
"carpet.rule.offlineFakePlayers.desc": "由Carpet生成的假玩家,将使用离线皮肤和UUID",
|
|
||||||
"carpet.rule.pcaSyncProtocol.desc": "借助PCA同步协议,支持同步 BlockEntity 和 Entity 到客户端",
|
"carpet.rule.pcaSyncProtocol.desc": "借助PCA同步协议,支持同步 BlockEntity 和 Entity 到客户端",
|
||||||
"carpet.rule.pcaSyncPlayerEntity.desc": "决定哪些玩家的数据将会被同步",
|
"carpet.rule.pcaSyncPlayerEntity.desc": "决定哪些玩家的数据将会被同步",
|
||||||
"carpet.rule.emptyShulkerBoxStack.desc": "空潜影盒可堆叠,但是不会改变容器中潜影盒的堆叠行为",
|
"carpet.rule.emptyShulkerBoxStack.desc": "空潜影盒可堆叠,但是不会改变容器中潜影盒的堆叠行为",
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
accessWidener v1 named
|
accessWidener v1 named
|
||||||
accessible class net/minecraft/world/block/ChainRestrictedNeighborUpdater$Entry
|
accessible class net/minecraft/world/block/ChainRestrictedNeighborUpdater$Entry
|
||||||
accessible class net/minecraft/entity/mob/EndermanEntity$PickUpBlockGoal
|
accessible class net/minecraft/entity/mob/EndermanEntity$PickUpBlockGoal
|
||||||
|
accessible method net/minecraft/entity/Entity unsetRemoved ()V
|
||||||
|
accessible field net/minecraft/entity/player/PlayerEntity PLAYER_MODEL_PARTS Lnet/minecraft/entity/data/TrackedData;
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
"mixins": [
|
"mixins": [
|
||||||
"block.BlockPatternTestTransformInvoker",
|
"block.BlockPatternTestTransformInvoker",
|
||||||
"block.MixinRedstoneWireBlock",
|
"block.MixinRedstoneWireBlock",
|
||||||
"carpet.MixinFakePlayer",
|
|
||||||
"carpet.MixinSettingsManager",
|
"carpet.MixinSettingsManager",
|
||||||
"entity.MixinArmorStandEntity",
|
"entity.MixinArmorStandEntity",
|
||||||
"entity.MixinEnderDragonFight",
|
"entity.MixinEnderDragonFight",
|
||||||
|
|||||||
Reference in new issue
Block a user