diff --git a/gradle.properties b/gradle.properties index 4275943..2ce93b1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,9 +8,9 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.14.17 # Mod Properties - mod_version = 0.5 + mod_version = 0.5.1 maven_group = com.github.zly2006 - archives_base_name = carpet-sls-addition + archives_base_name = Carpet-SLS-Addition # Dependencies fabric_version=0.76.0+1.19.4 diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java b/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java index 9424e2e..b6e4417 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/SLSCarpetSettings.java @@ -31,6 +31,12 @@ public class SLSCarpetSettings { @Rule(categories = {CARPET_ID, RuleCategory.FEATURE}) public static boolean offlineFakePlayers = false; + @Rule(categories = {CARPET_ID, RuleCategory.FEATURE}) + public static boolean canUseHatCommand = false; + + @Rule(categories = {CARPET_ID, RuleCategory.FEATURE}) + public static boolean canUseSitCommand = false; + @Rule(categories = {CARPET_ID, PCA, PROTOCOL}) public static boolean pcaSyncProtocol = false; diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java b/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java index d241f8d..b40d769 100644 --- a/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java +++ b/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java @@ -2,8 +2,10 @@ package com.github.zly2006.carpetslsaddition; import carpet.CarpetExtension; import carpet.CarpetServer; +import com.github.zly2006.carpetslsaddition.util.SitEntity; import com.google.common.collect.Maps; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ModInitializer; @@ -11,6 +13,7 @@ import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.Version; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.recipe.Ingredient; @@ -20,10 +23,12 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Style; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; +import net.minecraft.world.World; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -40,7 +45,7 @@ public class ServerMain implements ModInitializer, CarpetExtension { public static final String CARPET_ID = "SLS"; public static final Logger LOGGER = LogManager.getLogger(MOD_ID); - static final Gson GSON = new Gson(); + static final Gson GSON = new GsonBuilder().setLenient().create(); // 使用宽容模式,避免部分开发者在书写JSON时不遵守RFC 4627规范 public static ServerMain INSTANCE; public static MinecraftServer server; @@ -94,7 +99,7 @@ public class ServerMain implements ModInitializer, CarpetExtension { } } GSON.fromJson(jsonFile, JsonObject.class).entrySet().stream() - .filter(entry -> entry.getKey().startsWith("carpet.rule.")) + .filter(entry -> entry.getKey().startsWith("carpet.")) .filter(entry -> entry.getValue().isJsonPrimitive()) .map(entry -> Map.entry(entry.getKey(), entry.getValue().getAsString())) .forEach(entry -> translation.put(entry.getKey(), entry.getValue())); @@ -106,15 +111,44 @@ public class ServerMain implements ModInitializer, CarpetExtension { dispatcher.register(CommandManager.literal("hat") .requires(ServerCommandSource::isExecutedByPlayer) .executes(context -> { - ServerPlayerEntity player = context.getSource().getPlayer(); - assert player != null; - ItemStack stack = player.getMainHandStack(); - ItemStack head = player.getEquippedStack(EquipmentSlot.HEAD); - player.equipStack(EquipmentSlot.HEAD, stack); - player.getInventory().setStack(player.getInventory().selectedSlot, head); - player.currentScreenHandler.syncState(); - return 1; + if(SLSCarpetSettings.canUseHatCommand){ + ServerPlayerEntity player = context.getSource().getPlayer(); + assert player != null; + ItemStack stack = player.getMainHandStack(); + ItemStack head = player.getEquippedStack(EquipmentSlot.HEAD); + player.equipStack(EquipmentSlot.HEAD, stack); + player.getInventory().setStack(player.getInventory().selectedSlot, head); + player.currentScreenHandler.syncState(); + return 1; + } + else { + context.getSource().sendMessage(Text.literal("服务器尚未启用本指令!").setStyle(Style.EMPTY.withColor(Formatting.RED))); + return 0; + } })); + + dispatcher.register(CommandManager.literal("sit") + .requires(ServerCommandSource::isExecutedByPlayer) + .executes(context -> { + if(SLSCarpetSettings.canUseSitCommand){ + ServerPlayerEntity player = context.getSource().getPlayer(); + assert player != null; + World world = player.getWorld(); + + ArmorStandEntity armorStandEntity = new ArmorStandEntity(world, player.getX(), player.getY() - 0.16, player.getZ()); + ((SitEntity) armorStandEntity).setSitEntity(true); + world.spawnEntity(armorStandEntity); + player.setSneaking(false); + player.startRiding(armorStandEntity); + + return 1; + } + else { + context.getSource().sendMessage(Text.literal("服务器尚未启用本指令!").setStyle(Style.EMPTY.withColor(Formatting.RED))); + return 0; + } + }) + ); } public static Identifier createId(String path) { diff --git a/src/main/resources/assets/slsaddition/lang/en_us.json b/src/main/resources/assets/slsaddition/lang/en_us.json index 9ef1a67..5cf10e5 100644 --- a/src/main/resources/assets/slsaddition/lang/en_us.json +++ b/src/main/resources/assets/slsaddition/lang/en_us.json @@ -2,6 +2,24 @@ "carpet.category.pca": "PCA Adaption", "carpet.category.needClient":"Need client support", "carpet.category.protocol":"Protocol", + + + "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", + "carpet.rule.pcaSyncPlayerEntity.name": "Set PCA Sync Protocol's entity scope", + "carpet.rule.emptyShulkerBoxStack.name": "Empty shulker boxes can be stacked", + "carpet.rule.useDyeOnShulkerBox.name": "Shulker box blocks can be dyed", + "carpet.rule.xaeroWorldName.name": "Xaero world name", + "carpet.rule.playerSit.name": "Player can sit", + "carpet.rule.canUseHatCommand.name": "Enable hat command", + "carpet.rule.canUseSitCommand.name": "Enable sit command", + "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.", @@ -14,5 +32,19 @@ "carpet.rule.emptyShulkerBoxStack.desc": "Empty shulker boxes stack", "carpet.rule.useDyeOnShulkerBox.desc": "Dyes can be used on shulker boxes, empty potion will clean color", "carpet.rule.xaeroWorldName.desc": "set xaero world name to sync word id to xaerominimap, \"#none\" is disable.", - "carpet.rule.playerSit.desc": "Player can sit down when fast sneak 3 times." + "carpet.rule.playerSit.desc": "Player can sit down when fast sneak 3 times.", + "carpet.rule.canUseHatCommand.desc": "Allows all players to use the /hat command to place their main hand items in the helmet slot", + "carpet.rule.canUseSitCommand.desc": "Allows all players to use the /sit command to sit down", + + "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", + "carpet.rule.pcaSyncPlayerEntity.extra.0": "NOBODY: nobody will be sync", + "carpet.rule.pcaSyncPlayerEntity.extra.1": "BOT: carpet bot will be sync", + "carpet.rule.pcaSyncPlayerEntity.extra.2": "OPS: carpet bot will be sync, and op can sync everyone's player entity data.", + "carpet.rule.pcaSyncPlayerEntity.extra.3": "OPS_AND_SELF: carpet bot and self data will be sync, and op can sync everyone's player entity data.", + "carpet.rule.pcaSyncPlayerEntity.extra.4": "EVERYONE: everyone's player entity will be sync", + "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" } diff --git a/src/main/resources/assets/slsaddition/lang/zh_cn.json b/src/main/resources/assets/slsaddition/lang/zh_cn.json index 59ca5c7..7540733 100644 --- a/src/main/resources/assets/slsaddition/lang/zh_cn.json +++ b/src/main/resources/assets/slsaddition/lang/zh_cn.json @@ -2,11 +2,29 @@ "carpet.category.pca": "PCA适配", "carpet.category.needClient": "需要客户端支持", "carpet.category.protocol": "协议", + + + "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的同步协议", + "carpet.rule.pcaSyncPlayerEntity.name": "PCA同步协议作用范围", + "carpet.rule.emptyShulkerBoxStack.name": "空潜影盒背包可堆叠", + "carpet.rule.useDyeOnShulkerBox.name": "潜影盒方块可染色", + "carpet.rule.xaeroWorldName.name": "Xaero 小地图世界名", + "carpet.rule.playerSit.name": "玩家可坐下", + "carpet.rule.canUseHatCommand.name": "启用戴帽指令", + "carpet.rule.canUseSitCommand.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.autoUrl.desc": "自动识别URL并为其添加点击事件", "carpet.rule.noBatSpawning.desc": "禁止任何区域蝙蝠生成", "carpet.rule.offlineFakePlayers.desc": "由Carpet生成的假玩家,将使用离线皮肤和UUID", "carpet.rule.pcaSyncProtocol.desc": "借助PCA同步协议,支持同步 BlockEntity 和 Entity 到客户端", @@ -14,5 +32,19 @@ "carpet.rule.emptyShulkerBoxStack.desc": "空潜影盒可堆叠,但是不会改变容器中潜影盒的堆叠行为", "carpet.rule.useDyeOnShulkerBox.desc": "可以使用染料直接对地上的潜影盒染色,用水瓶可以洗掉潜影盒的颜色", "carpet.rule.xaeroWorldName.desc": "设置 Xaero 世界名来同步世界 ID,\"#none\" 表示不同步", - "carpet.rule.playerSit.desc": "在快速潜行 3 次后玩家可以坐下" + "carpet.rule.playerSit.desc": "在快速潜行 3 次后玩家可以坐下", + "carpet.rule.canUseHatCommand.desc": "可让所有玩家使用/hat指令,将手中的物品置于头盔位", + "carpet.rule.canUseSitCommand.desc": "可让所有玩家使用/sit指令,以在原地坐下", + + "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的时候,村民完全卡死", + "carpet.rule.pcaSyncPlayerEntity.extra.0": "NOBODY:所有玩家数据都无法同步", + "carpet.rule.pcaSyncPlayerEntity.extra.1": "BOT:地毯 mod 召唤出的 bot 的数据可以被同步", + "carpet.rule.pcaSyncPlayerEntity.extra.2": "OPS:地毯 mod 召唤出的 bot 的数据可以被同步, op 可以同步所有玩家的数据", + "carpet.rule.pcaSyncPlayerEntity.extra.3": "OPS_AND_SELF:地毯 mod 召唤出的 bot 和玩家自己的数据可以被同步,op 可以同步所有玩家的数据", + "carpet.rule.pcaSyncPlayerEntity.extra.4": "EVERYONE:所有人的数据都可以被同步", + "carpet.rule.emptyShulkerBoxStack.extra.0": "空潜影盒可以在玩家的背包进行自动堆叠,同时玩家可以手动堆叠空潜影盒", + "carpet.rule.emptyShulkerBoxStack.extra.1": "但是空潜影盒无法在容器中自动堆叠,比如箱子,漏斗" }