1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Туториал [Описание] ResourceBundle и Sponge

Тема в разделе "Sponge", создана пользователем Larin, 29 апр 2017.

  1. Автор темы
    Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Представим ситуацию: сервер многоязычный и нужно локализовать плагин на несколько языков.
    В bukkit такое в основном делается через костыли и боль.
    Сегодня я покажу, как можно сделать несколько файлов локализации и использовать их.
    Приступим.
    Нам понадобится всего 2 класса. 1 - для загрузки и поиска в ResourceBundle, 2 - правильный Control для ResourceBundle, чтобы правильно загружать любые кодировки.
    1. Загрузчик
    Код:
    import org.spongepowered.api.text.Text;
    import org.spongepowered.api.text.translation.ResourceBundleTranslation;
    
    import javax.annotation.Nullable;
    import java.util.Locale;
    import java.util.ResourceBundle;
    import java.util.function.Function;
    
    public class TranslationHelper {
        private static final Function<Locale, ResourceBundle> LOOKUP_FUNC = new Function<Locale, ResourceBundle>() {
            @Nullable
            @Override
            public ResourceBundle apply(Locale input) {
                return ResourceBundle.getBundle("locale", input, new UTF8Control());
            }
        };
    
        private TranslationHelper() {}
    
        public static Text getTranslation(String key, Object... args) {
            return Text.of(new ResourceBundleTranslation(key, LOOKUP_FUNC));
        }
    }
    
    Что здесь мы делаем? Мы объявляем функцию для поиска ResourceBundle.
    Первый аргумент у getBundle отвечает за базовое имя переводов.
    К примеру базовое имя locale, то тогда у нас будет несколько файлов:
    locale.properties <-- базовый файл с переводами, тут используется Locale.DEFAULT(для sponge это en_US)
    Для английского(США)
    locale.properties
    Для русского языка у нас будет так:
    locale_ru_RU.properties

    Как пользоваться?
    Если, к примеру, нам надо будет отправить локализованное сообщение игроку о том, что ему нельзя совершить действие, то мы пишем это:
    Код:
    TranslationHelper.getTranslation("player.nopermission")
    Мы получим объект Text, который содержит варианты переводов. Если перевода для какой-то локали не будет, то будет использована базовая локаль(en_US, locale.properties)

    В locale.properties у нас будет такая строчка:
    Код:
    player.nopermission=You don't have permission
    А в locale_ru_RU.properties будет такая запись:
    Код:
    player.nopermission=У Вас нет доступа к этому действию
    Если locale_ru_RU будет отсутствовать или же в нем не будет строчки с переводом, то будет использоваться перевод по-умолчанию(locale.properties), если же такой строчки не будет в переводе по-умолчанию, то игроку выведется ключ перевода(player.nopermission)

    Как отправить игроку? Как обычное сообщение, Sponge сам решит, в какой локали отправить игроку.

    Так-же прилагаю исправленный Control для правильной загрузки текста в UTF-8:
    Код:
    public class UTF8Control extends ResourceBundle.Control {
        public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
                throws IllegalAccessException, InstantiationException, IOException {
            // The below is a copy of the default implementation.
            String bundleName = toBundleName(baseName, locale);
            String resourceName = toResourceName(bundleName, "properties");
            ResourceBundle bundle = null;
            InputStream stream = null;
            if (reload) {
                URL url = loader.getResource(resourceName);
                if (url != null) {
                    URLConnection connection = url.openConnection();
                    if (connection != null) {
                        connection.setUseCaches(false);
                        stream = connection.getInputStream();
                    }
                }
            } else {
                stream = loader.getResourceAsStream(resourceName);
            }
            if (stream != null) {
                try {
                    // Only this line is changed to make it to read properties files as UTF-8.
                    bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
                } finally {
                    stream.close();
                }
            }
            return bundle;
        }
    }
     
    Последнее редактирование: 1 май 2017
  2. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Абсолютно бесполезная хрень. Только игроков запутает, если они по тупости выбрали не тот язык.
     
  3. Автор темы
    Larin

    Larin Старожил Пользователь

    Баллы:
    103
    Игроки хотят видеть все сообщения в том языке, который выбрали. Русские/английские сообщения будут раздражать игроков, если у них выбран английский или русский язык.
     
  4. CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Как по мне, большую проблему представляет перевод сообщений со всякими hover/click/showtext и т.д.
     

Поделиться этой страницей