diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java index dbb66bbca..aa3cf9baa 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java @@ -40,6 +40,8 @@ public class BukkitCommandManager extends AbstractCommandManager new SearchRecipeAdminCommand(this, plugin), new SearchUsageAdminCommand(this, plugin), new TestCommand(this, plugin), + new SetLocaleCommand(this, plugin), + new UnsetLocaleCommand(this, plugin), new DebugGetBlockStateRegistryIdCommand(this, plugin), new DebugGetBlockInternalIdCommand(this, plugin), new DebugAppearanceStateUsageCommand(this, plugin), diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/LocaleCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/LocaleCommand.java deleted file mode 100644 index a5ef68247..000000000 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/LocaleCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.momirealms.craftengine.bukkit.plugin.command.feature; - -import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.incendo.cloud.Command; -import org.incendo.cloud.parser.standard.StringParser; - -public class LocaleCommand extends BukkitCommandFeature { - - public LocaleCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { - super(commandManager, plugin); - } - - @Override - public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { - return builder - .senderType(Player.class) - .required("locale", StringParser.stringParser()) - .handler(context -> { - - }); - } - - @Override - public String getFeatureID() { - return "locale"; - } -} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetLocaleCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetLocaleCommand.java new file mode 100644 index 000000000..5967f803d --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetLocaleCommand.java @@ -0,0 +1,61 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import net.momirealms.craftengine.core.plugin.command.FlagKeys; +import net.momirealms.craftengine.core.plugin.locale.MessageConstants; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.parser.PlayerParser; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.parser.standard.StringParser; +import org.incendo.cloud.suggestion.Suggestion; +import org.incendo.cloud.suggestion.SuggestionProvider; + +import java.util.Locale; +import java.util.concurrent.CompletableFuture; + +public class SetLocaleCommand extends BukkitCommandFeature { + + public SetLocaleCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { + return builder + .flag(FlagKeys.SILENT_FLAG) + .required("player", PlayerParser.playerParser()) + .required("locale", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + return CompletableFuture.completedFuture(TranslationManager.ALL_LANG_SUGGESTIONS); + } + })) + .handler(context -> { + Player player = context.get("player"); + String localeName = context.get("locale"); + Locale locale = TranslationManager.parseLocale(localeName); + if (locale == null) { + handleFeedback(context, MessageConstants.COMMAND_LOCALE_SET_FAILURE, Component.text(localeName)); + return; + } + BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player); + serverPlayer.setSelectedLocale(locale); + handleFeedback(context, MessageConstants.COMMAND_LOCALE_SET_SUCCESS, Component.text(TranslationManager.formatLocale(locale)), Component.text(player.getName())); + }); + } + + @Override + public String getFeatureID() { + return "set_locale"; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/UnsetLocaleCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/UnsetLocaleCommand.java new file mode 100644 index 000000000..d80adf744 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/UnsetLocaleCommand.java @@ -0,0 +1,39 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import net.momirealms.craftengine.core.plugin.command.FlagKeys; +import net.momirealms.craftengine.core.plugin.locale.MessageConstants; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.parser.PlayerParser; + +public class UnsetLocaleCommand extends BukkitCommandFeature { + + public UnsetLocaleCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { + return builder + .flag(FlagKeys.SILENT_FLAG) + .required("player", PlayerParser.playerParser()) + .handler(context -> { + Player player = context.get("player"); + BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player); + serverPlayer.setSelectedLocale(null); + handleFeedback(context, MessageConstants.COMMAND_LOCALE_UNSET_SUCCESS, Component.text(player.getName())); + }); + } + + @Override + public String getFeatureID() { + return "unset_locale"; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 6e7bc8ecb..9130ac72b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -31,6 +31,7 @@ import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.context.CooldownData; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler; import net.momirealms.craftengine.core.sound.SoundSource; @@ -67,6 +68,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class BukkitServerPlayer extends Player { + public static final Key SELECTED_LOCALE_KEY = Key.of("craftengine:locale"); private final BukkitCraftEngine plugin; // connection state @@ -151,6 +153,8 @@ public class BukkitServerPlayer extends Player { this.name = player.getName(); this.isNameVerified = true; byte[] bytes = player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY), PersistentDataType.BYTE_ARRAY); + String locale = player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(SELECTED_LOCALE_KEY), PersistentDataType.STRING); + this.selectedLocale = TranslationManager.parseLocale(locale); this.trackedChunks = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(512, 0.5f); this.entityTypeView = new ConcurrentHashMap<>(256); try { @@ -1179,4 +1183,14 @@ public class BukkitServerPlayer extends Player { if (this.selectedLocale != null) return this.selectedLocale; return locale(); } + + @Override + public void setSelectedLocale(@Nullable Locale locale) { + this.selectedLocale = locale; + if (locale != null) { + platformPlayer().getPersistentDataContainer().set(KeyUtils.toNamespacedKey(SELECTED_LOCALE_KEY), PersistentDataType.STRING, TranslationManager.formatLocale(locale)); + } else { + platformPlayer().getPersistentDataContainer().remove(KeyUtils.toNamespacedKey(SELECTED_LOCALE_KEY)); + } + } } diff --git a/common-files/src/main/resources/commands.yml b/common-files/src/main/resources/commands.yml index 59a7611d6..f4f3a27ac 100644 --- a/common-files/src/main/resources/commands.yml +++ b/common-files/src/main/resources/commands.yml @@ -23,12 +23,6 @@ upload: - /craftengine upload - /ce upload -locale: - enable: true - permission: ce.command.player.locale - usage: - - /locale - send_resource_pack: enable: true permission: ce.command.admin.send_resource_pack @@ -117,6 +111,18 @@ list_resource: - /craftengine resource list - /ce resource list +set_locale: + enable: true + permission: ce.command.admin.set_locale + usage: + - /ce feature locale set + +unset_locale: + enable: true + permission: ce.command.admin.unset_locale + usage: + - /ce feature locale unset + # Debug commands debug_set_block: enable: true diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index a93c66922..a0b91127d 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -54,8 +54,8 @@ command.search_usage.not_found: "No usage found for this item" command.search_recipe.no_item: "Please hold an item before running this command" command.search_usage.no_item: "Please hold an item before running this command" command.totem_animation.failure.not_totem: "Item '' is not minecraft:totem_of_undying" -commands.totem_animation.success.single: "Played totem animation to " -commands.totem_animation.success.multiple: "Played totem animation to players" +command.totem_animation.success.single: "Played totem animation to " +command.totem_animation.success.multiple: "Played totem animation to players" command.resource.enable.success: "Enabled resource . Run /ce reload all to apply changes" command.resource.enable.failure.unknown: "Unknown resource " command.resource.disable.success: "Disabled resource . Run /ce reload all to apply changes" @@ -65,6 +65,9 @@ command.upload.failure.not_supported: "Current hosting method '' doe command.upload.on_progress: "Started uploading progress. Check the console for more information." command.send_resource_pack.success.single: "Sent resource pack to ." command.send_resource_pack.success.multiple: "Send resource packs to players." +command.locale.set.failure: "Invalid locale format: " +command.locale.set.success: "Updated selected locale to for " +command.locale.unset.success: "Cleared selected locale for " warning.network.resource_pack.unverified_uuid: "Player is attempting to request a resource pack using a UUID () that is not authenticated by the server." warning.config.pack.duplicated_files: "Duplicated files Found. Please resolve them through config.yml 'resource-pack.duplicated-files-handler' section." warning.config.yaml.duplicated_key: "Issue found in file - Found duplicated key '' at line , this might cause unexpected results." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 430bce401..af5069510 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -54,8 +54,8 @@ command.search_usage.not_found: "找不到此物品的用途" command.search_recipe.no_item: "请手持物品后再执行此命令" command.search_usage.no_item: "请手持物品后再执行此命令" command.totem_animation.failure.not_totem: "'' 不是 totem_of_undying 类型" -commands.totem_animation.success.single: "已将图腾动画播放给" -commands.totem_animation.success.multiple: "已将图腾动画播放给名玩家" +command.totem_animation.success.single: "已将图腾动画播放给" +command.totem_animation.success.multiple: "已将图腾动画播放给名玩家" command.resource.enable.success: "已启用 . 执行 /ce reload all 以应用更改" command.resource.enable.failure.unknown: "未知资源 " command.resource.disable.success: "已禁用 . 执行 /ce reload all 以应用更改" diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java index 67f99ef85..8b8d804d0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java @@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.world.Position; import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.craftengine.core.world.WorldPosition; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Locale; @@ -177,4 +178,6 @@ public abstract class Player extends AbstractEntity implements NetWorkUser { public abstract Locale locale(); public abstract Locale selectedLocale(); + + public abstract void setSelectedLocale(@Nullable Locale locale); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java index 91c6db67b..882d17c90 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java @@ -30,6 +30,9 @@ public interface MessageConstants { TranslatableComponent.Builder COMMAND_UPLOAD_ON_PROGRESS = Component.translatable().key("command.upload.on_progress"); TranslatableComponent.Builder COMMAND_SEND_RESOURCE_PACK_SUCCESS_SINGLE = Component.translatable().key("command.send_resource_pack.success.single"); TranslatableComponent.Builder COMMAND_SEND_RESOURCE_PACK_SUCCESS_MULTIPLE = Component.translatable().key("command.send_resource_pack.success.multiple"); - TranslatableComponent.Builder COMMAND_TOTEM_SUCCESS_SINGLE = Component.translatable().key("commands.totem_animation.success.single"); - TranslatableComponent.Builder COMMAND_TOTEM_SUCCESS_MULTIPLE = Component.translatable().key("commands.totem_animation.success.multiple"); + TranslatableComponent.Builder COMMAND_TOTEM_SUCCESS_SINGLE = Component.translatable().key("command.totem_animation.success.single"); + TranslatableComponent.Builder COMMAND_TOTEM_SUCCESS_MULTIPLE = Component.translatable().key("command.totem_animation.success.multiple"); + TranslatableComponent.Builder COMMAND_LOCALE_SET_FAILURE = Component.translatable().key("command.locale.set.failure"); + TranslatableComponent.Builder COMMAND_LOCALE_SET_SUCCESS = Component.translatable().key("command.locale.set.success"); + TranslatableComponent.Builder COMMAND_LOCALE_UNSET_SUCCESS = Component.translatable().key("command.locale.unset.success"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java index e0e2da6d2..89fa4edea 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.translation.Translator; import net.momirealms.craftengine.core.plugin.Manageable; import net.momirealms.craftengine.core.plugin.config.ConfigParser; +import org.incendo.cloud.suggestion.Suggestion; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -32,6 +33,7 @@ public interface TranslationManager extends Manageable { "tt_ru", "tzo_mx", "uk_ua", "val_es", "vec_it", "vi_vn", "vp_vl", "yi_de", "yo_ng", "zh_cn", "zh_hk", "zh_tw", "zlm_arab" ); + List ALL_LANG_SUGGESTIONS = ALL_LANG.stream().map(Suggestion::suggestion).toList(); Map> LOCALE_2_COUNTRIES = ALL_LANG.stream() .map(lang -> lang.split("_")) .filter(split -> split.length >= 2) @@ -62,6 +64,16 @@ public interface TranslationManager extends Manageable { return locale == null || locale.isEmpty() ? null : Translator.parseLocale(locale); } + static String formatLocale(Locale locale) { + String language = locale.getLanguage().toLowerCase(Locale.ROOT); + String country = locale.getCountry().toLowerCase(Locale.ROOT); + if (country.isEmpty()) { + return language; + } else { + return language + "_" + country; + } + } + Set translationKeys(); void log(String id, String... args); diff --git a/gradle.properties b/gradle.properties index 47ca9298b..db50c4b62 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.64.13 +project_version=0.0.64.14 config_version=49 -lang_version=34 +lang_version=35 project_group=net.momirealms latest_supported_version=1.21.10