Adds methods to Stargate for easier logging and less redundancy Loads the language loader in two parts to make it available while loading Adds a translated string to the reload-message Uses String.format to make long messages more readable Makes it possible to get strings directly from the backup language to make debugging easier
256 lines
9.7 KiB
Java
256 lines
9.7 KiB
Java
package net.knarcraft.stargate.config;
|
|
|
|
import net.knarcraft.stargate.Stargate;
|
|
import net.knarcraft.stargate.utility.FileHelper;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.BufferedWriter;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* This class is responsible for loading all strings which are translated into several languages
|
|
*/
|
|
public final class LanguageLoader {
|
|
|
|
private final String languageFolder;
|
|
private final Map<String, String> loadedBackupStrings;
|
|
private String chosenLanguage;
|
|
private Map<String, String> loadedStringTranslations;
|
|
|
|
/**
|
|
* Instantiates a new language loader
|
|
*
|
|
* <p>This will only load the backup language. Set the chosen language and reload afterwards.</p>
|
|
*
|
|
* @param languageFolder <p>The folder containing the language files</p>
|
|
*/
|
|
public LanguageLoader(String languageFolder) {
|
|
this.languageFolder = languageFolder;
|
|
File testFile = new File(languageFolder, "en.txt");
|
|
if (!testFile.exists()) {
|
|
if (testFile.getParentFile().mkdirs()) {
|
|
Stargate.debug("LanguageLoader", "Created language folder");
|
|
}
|
|
}
|
|
|
|
//Load english as backup language in case the chosen language is missing newly added text strings
|
|
InputStream inputStream = FileHelper.getInputStreamForInternalFile("/lang/en.txt");
|
|
if (inputStream != null) {
|
|
loadedBackupStrings = load("en", inputStream);
|
|
} else {
|
|
loadedBackupStrings = null;
|
|
Stargate.getConsoleLogger().severe("[stargate] Error loading backup language. " +
|
|
"There may be missing text in-game");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reloads languages from the files on disk
|
|
*/
|
|
public void reload() {
|
|
//Extracts/Updates the language as needed
|
|
updateLanguage(chosenLanguage);
|
|
loadedStringTranslations = load(chosenLanguage);
|
|
}
|
|
|
|
/**
|
|
* Gets the string to display given its name/key
|
|
*
|
|
* @param name <p>The name/key of the string to display</p>
|
|
* @return <p>The string in the user's preferred language</p>
|
|
*/
|
|
public String getString(String name) {
|
|
String value = null;
|
|
if (loadedStringTranslations != null) {
|
|
value = loadedStringTranslations.get(name);
|
|
}
|
|
if (value == null) {
|
|
value = getBackupString(name);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Gets the string to display given its name/key
|
|
*
|
|
* @param name <p>The name/key of the string to display</p>
|
|
* @return <p>The string in the backup language (English)</p>
|
|
*/
|
|
public String getBackupString(String name) {
|
|
String value = null;
|
|
if (loadedBackupStrings != null) {
|
|
value = loadedBackupStrings.get(name);
|
|
}
|
|
if (value == null) {
|
|
return "";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Sets the chosen plugin language
|
|
*
|
|
* @param chosenLanguage <p>The new plugin language</p>
|
|
*/
|
|
public void setChosenLanguage(String chosenLanguage) {
|
|
this.chosenLanguage = chosenLanguage;
|
|
}
|
|
|
|
/**
|
|
* Updates files in the plugin directory with contents from the compiled .jar
|
|
*
|
|
* @param language <p>The language to update</p>
|
|
*/
|
|
private void updateLanguage(String language) {
|
|
Map<String, String> currentLanguageValues = load(language);
|
|
|
|
InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt");
|
|
if (inputStream == null) {
|
|
Stargate.logInfo(String.format("The language %s is not available. Falling back to english, You can add a " +
|
|
"custom language by creating a new text file in the lang directory.", language));
|
|
Stargate.debug("LanguageLoader::updateLanguage", String.format("Unable to load /lang/%s.txt", language));
|
|
return;
|
|
}
|
|
|
|
try {
|
|
readChangedLanguageStrings(inputStream, language, currentLanguageValues);
|
|
} catch (IOException ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reads language strings
|
|
*
|
|
* @param inputStream <p>The input stream to read from</p>
|
|
* @param language <p>The selected language</p>
|
|
* @param currentLanguageValues <p>The current values of the loaded/processed language</p>
|
|
* @throws IOException <p>if unable to read a language file</p>
|
|
*/
|
|
private void readChangedLanguageStrings(InputStream inputStream, String language, Map<String,
|
|
String> currentLanguageValues) throws IOException {
|
|
//Get language values
|
|
BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream);
|
|
Map<String, String> internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader);
|
|
|
|
//If currentLanguageValues is null; the chosen language has not been used before
|
|
if (currentLanguageValues == null) {
|
|
updateLanguageFile(language, internalLanguageValues, null);
|
|
Stargate.logInfo(String.format("Language (%s) has been loaded", language));
|
|
return;
|
|
}
|
|
|
|
//If a key is not found in the language file, add the one in the internal file. Must update the external file
|
|
if (!internalLanguageValues.keySet().equals(currentLanguageValues.keySet())) {
|
|
Map<String, String> newLanguageValues = new HashMap<>();
|
|
boolean updateNecessary = false;
|
|
for (String key : internalLanguageValues.keySet()) {
|
|
if (currentLanguageValues.get(key) == null) {
|
|
newLanguageValues.put(key, internalLanguageValues.get(key));
|
|
//Found at least one value in the internal file not in the external file. Need to update
|
|
updateNecessary = true;
|
|
} else {
|
|
newLanguageValues.put(key, currentLanguageValues.get(key));
|
|
currentLanguageValues.remove(key);
|
|
}
|
|
}
|
|
//Update the file itself
|
|
if (updateNecessary) {
|
|
updateLanguageFile(language, newLanguageValues, currentLanguageValues);
|
|
Stargate.logInfo(String.format("Your language file (%s.txt) has been updated", language));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the language file for a given language
|
|
*
|
|
* @param language <p>The language to update</p>
|
|
* @param languageStrings <p>The updated language strings</p>
|
|
* @param customLanguageStrings <p>Any custom language strings not recognized</p>
|
|
* @throws IOException <p>If unable to write to the language file</p>
|
|
*/
|
|
private void updateLanguageFile(String language, Map<String, String> languageStrings,
|
|
Map<String, String> customLanguageStrings) throws IOException {
|
|
BufferedWriter bufferedWriter = FileHelper.getBufferedWriterFromString(languageFolder + language + ".txt");
|
|
|
|
//Output normal Language data
|
|
for (String key : languageStrings.keySet()) {
|
|
bufferedWriter.write(key + "=" + languageStrings.get(key));
|
|
bufferedWriter.newLine();
|
|
}
|
|
bufferedWriter.newLine();
|
|
//Output any custom language strings the user had
|
|
if (customLanguageStrings != null) {
|
|
for (String key : customLanguageStrings.keySet()) {
|
|
bufferedWriter.write(key + "=" + customLanguageStrings.get(key));
|
|
bufferedWriter.newLine();
|
|
}
|
|
}
|
|
bufferedWriter.close();
|
|
}
|
|
|
|
/**
|
|
* Loads the given language
|
|
*
|
|
* @param lang <p>The language to load</p>
|
|
* @return <p>A mapping between loaded string indexes and the strings to display</p>
|
|
*/
|
|
private Map<String, String> load(String lang) {
|
|
return load(lang, null);
|
|
}
|
|
|
|
/**
|
|
* Loads the given language
|
|
*
|
|
* @param lang <p>The language to load</p>
|
|
* @param inputStream <p>An optional input stream to use. Defaults to using a file input stream</p>
|
|
* @return <p>A mapping between loaded string indexes and the strings to display</p>
|
|
*/
|
|
private Map<String, String> load(String lang, InputStream inputStream) {
|
|
Map<String, String> strings;
|
|
BufferedReader bufferedReader;
|
|
try {
|
|
if (inputStream == null) {
|
|
bufferedReader = FileHelper.getBufferedReaderFromString(languageFolder + lang + ".txt");
|
|
} else {
|
|
bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream);
|
|
}
|
|
strings = FileHelper.readKeyValuePairs(bufferedReader);
|
|
} catch (Exception e) {
|
|
if (Stargate.getStargateConfig().isDebuggingEnabled()) {
|
|
Stargate.getConsoleLogger().info("[Stargate] Unable to load language " + lang);
|
|
}
|
|
return null;
|
|
}
|
|
return strings;
|
|
}
|
|
|
|
/**
|
|
* Prints debug output to the console for checking loaded language strings/translations
|
|
*/
|
|
public void debug() {
|
|
if (loadedStringTranslations != null) {
|
|
Set<String> keys = loadedStringTranslations.keySet();
|
|
for (String key : keys) {
|
|
Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " +
|
|
loadedStringTranslations.get(key));
|
|
}
|
|
}
|
|
if (loadedBackupStrings == null) {
|
|
return;
|
|
}
|
|
Set<String> keys = loadedBackupStrings.keySet();
|
|
for (String key : keys) {
|
|
Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " +
|
|
loadedBackupStrings.get(key));
|
|
}
|
|
}
|
|
|
|
}
|