9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-27 19:09:08 +00:00

添加指令切换语言

This commit is contained in:
XiaoMoMi
2025-10-17 23:59:43 +08:00
parent b0b7861068
commit f0dd5120e3
12 changed files with 157 additions and 45 deletions

View File

@@ -40,6 +40,8 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
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),

View File

@@ -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<CommandSender> {
public LocaleCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.senderType(Player.class)
.required("locale", StringParser.stringParser())
.handler(context -> {
});
}
@Override
public String getFeatureID() {
return "locale";
}
}

View File

@@ -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<CommandSender> {
public SetLocaleCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.flag(FlagKeys.SILENT_FLAG)
.required("player", PlayerParser.playerParser())
.required("locale", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() {
@Override
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> 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";
}
}

View File

@@ -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<CommandSender> {
public UnsetLocaleCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> 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";
}
}

View File

@@ -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));
}
}
}

View File

@@ -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

View File

@@ -54,8 +54,8 @@ command.search_usage.not_found: "<red>No usage found for this item</red>"
command.search_recipe.no_item: "<red>Please hold an item before running this command</red>"
command.search_usage.no_item: "<red>Please hold an item before running this command</red>"
command.totem_animation.failure.not_totem: "<red>Item '<arg:0>' is not minecraft:totem_of_undying</red>"
commands.totem_animation.success.single: "<white>Played totem animation <arg:0> to <arg:1></white>"
commands.totem_animation.success.multiple: "<white>Played totem animation <arg:0> to <arg:1> players</white>"
command.totem_animation.success.single: "<white>Played totem animation <arg:0> to <arg:1></white>"
command.totem_animation.success.multiple: "<white>Played totem animation <arg:0> to <arg:1> players</white>"
command.resource.enable.success: "<white>Enabled resource <arg:0>. Run <click:run_command:/ce reload all><u>/ce reload all</u></click> to apply changes</white>"
command.resource.enable.failure.unknown: "<red>Unknown resource <arg:0></red>"
command.resource.disable.success: "<white>Disabled resource <arg:0>. Run <click:run_command:/ce reload all><u>/ce reload all</u></click> to apply changes</white>"
@@ -65,6 +65,9 @@ command.upload.failure.not_supported: "<red>Current hosting method '<arg:0>' doe
command.upload.on_progress: "<white>Started uploading progress. Check the console for more information.</white>"
command.send_resource_pack.success.single: "<white>Sent resource pack to <arg:0>.</white>"
command.send_resource_pack.success.multiple: "<white>Send resource packs to <arg:0> players.</white>"
command.locale.set.failure: "<red>Invalid locale format: <arg:0></red>"
command.locale.set.success: "<white>Updated selected locale to <arg:0> for <arg:1></white>"
command.locale.unset.success: "<white>Cleared selected locale for <arg:0></white>"
warning.network.resource_pack.unverified_uuid: "<yellow>Player <arg:0> is attempting to request a resource pack using a UUID (<arg:1>) that is not authenticated by the server.</yellow>"
warning.config.pack.duplicated_files: "<red>Duplicated files Found. Please resolve them through config.yml 'resource-pack.duplicated-files-handler' section.</red>"
warning.config.yaml.duplicated_key: "<red>Issue found in file <arg:0> - Found duplicated key '<arg:1>' at line <arg:2>, this might cause unexpected results.</red>"

View File

@@ -54,8 +54,8 @@ command.search_usage.not_found: "<red>找不到此物品的用途</red>"
command.search_recipe.no_item: "<red>请手持物品后再执行此命令</red>"
command.search_usage.no_item: "<red>请手持物品后再执行此命令</red>"
command.totem_animation.failure.not_totem: "<red>'<arg:0>' 不是 totem_of_undying 类型</red>"
commands.totem_animation.success.single: "<white>已将图腾动画<arg:0>播放给<arg:1></white>"
commands.totem_animation.success.multiple: "<white>已将图腾动画<arg:0>播放给<arg:1>名玩家</white>"
command.totem_animation.success.single: "<white>已将图腾动画<arg:0>播放给<arg:1></white>"
command.totem_animation.success.multiple: "<white>已将图腾动画<arg:0>播放给<arg:1>名玩家</white>"
command.resource.enable.success: "<white>已启用 <arg:0>. 执行 <click:run_command:/ce reload all><u>/ce reload all</u></click> 以应用更改</white>"
command.resource.enable.failure.unknown: "<red>未知资源 <arg:0></red>"
command.resource.disable.success: "<white>已禁用 <arg:0>. 执行 <click:run_command:/ce reload all><u>/ce reload all</u></click> 以应用更改</white>"

View File

@@ -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);
}

View File

@@ -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");
}

View File

@@ -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<Suggestion> ALL_LANG_SUGGESTIONS = ALL_LANG.stream().map(Suggestion::suggestion).toList();
Map<String, List<String>> 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<String> translationKeys();
void log(String id, String... args);

View File

@@ -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