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

  • Автор темы Автор темы Larin
  • Дата начала Дата начала

Larin

Старожил
Пользователь
Баллы
103
Представим ситуацию: сервер многоязычный и нужно локализовать плагин на несколько языков.
В bukkit такое в основном делается через костыли и боль.
Сегодня я покажу, как можно сделать несколько файлов локализации и использовать их.
Приступим.
Нам понадобится всего 2 класса. 1 - для загрузки и поиска в ResourceBundle, 2 - правильный Control для ResourceBundle, чтобы правильно загружать любые кодировки.
1. Загрузчик
Java:
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

Как пользоваться?
Если, к примеру, нам надо будет отправить локализованное сообщение игроку о том, что ему нельзя совершить действие, то мы пишем это:
Java:
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:
Java:
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;
    }
}
 
Последнее редактирование:
Абсолютно бесполезная хрень. Только игроков запутает, если они по тупости выбрали не тот язык.
 
Абсолютно бесполезная хрень. Только игроков запутает, если они по тупости выбрали не тот язык.
Игроки хотят видеть все сообщения в том языке, который выбрали. Русские/английские сообщения будут раздражать игроков, если у них выбран английский или русский язык.
 
Как по мне, большую проблему представляет перевод сообщений со всякими hover/click/showtext и т.д.
 
Назад
Верх Низ