diff --git a/converter/src/main/java/org/geysermc/pack/converter/converter/lang/LangConverter.java b/converter/src/main/java/org/geysermc/pack/converter/converter/lang/LangConverter.java index da90a7e..fe92ae1 100644 --- a/converter/src/main/java/org/geysermc/pack/converter/converter/lang/LangConverter.java +++ b/converter/src/main/java/org/geysermc/pack/converter/converter/lang/LangConverter.java @@ -73,16 +73,7 @@ public class LangConverter extends BaseConverter { entry.setValue(value); } - // Setup output dir - Path output = context.outputDirectory().resolve(BEDROCK_TEXTS_LOCATION); - - if (Files.notExists(output)) { - Files.createDirectories(output); - } - - Properties properties = new Properties(); - properties.putAll(strings); - properties.store(Files.newOutputStream(output.resolve(language.key().value() + ".lang")), null); + context.bedrockResourcePack().addLanguage(language.key().value(), strings); } } } diff --git a/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/BedrockResourcePack.java b/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/BedrockResourcePack.java index b92f61e..2631c60 100644 --- a/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/BedrockResourcePack.java +++ b/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/BedrockResourcePack.java @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.Map; import static org.geysermc.pack.util.FileUtil.exportJson; +import static org.geysermc.pack.util.FileUtil.exportProperties; /** * Represents a Bedrock resource pack. @@ -68,6 +69,7 @@ public class BedrockResourcePack { private TerrainTexture terrainTexture; private Map attachables; private SoundDefinitions soundDefinitions; + private Languages languages; private Map renderControllers; public BedrockResourcePack(@NotNull Path directory) { @@ -213,6 +215,25 @@ public class BedrockResourcePack { this.soundDefinitions = soundDefinitions; } + /** + * Get the languages of the resource pack. + * + * @return the languages of the resource pack + */ + @Nullable + public Languages languages() { + return this.languages; + } + + /** + * Set the languages of the resource pack. + * + * @param languages the languages of the resource pack + */ + public void languages(@Nullable Languages languages) { + this.languages = languages; + } + /** * Add an item to the resource pack. * @@ -325,6 +346,20 @@ public class BedrockResourcePack { this.soundDefinitions.soundDefinitions().put(id, soundDefinition); } + /** + * Add a language to the resource pack. + * + * @param languageCode the language code + * @param translationStrings the translation strings + */ + public void addLanguage(@NotNull String languageCode, @NotNull Map translationStrings) { + if (this.languages == null) { + this.languages = new Languages(); + } + + this.languages.language(languageCode, translationStrings); + } + /** * Exports the resource pack to the specified directory. * @@ -363,5 +398,13 @@ public class BedrockResourcePack { if (this.soundDefinitions != null) { exportJson(GSON, this.directory.resolve("sounds/sound_definitions.json"), this.soundDefinitions); } + + if (this.languages != null) { + exportJson(GSON, this.directory.resolve("texts/languages.json"), this.languages.languageCodes()); + + for (Map.Entry> language : this.languages.languages().entrySet()) { + exportProperties(this.directory.resolve("texts/" + language.getKey() + ".lang"), language.getValue()); + } + } } } diff --git a/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/Languages.java b/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/Languages.java new file mode 100644 index 0000000..adbeee0 --- /dev/null +++ b/pack-schema/api/src/main/java/org/geysermc/pack/bedrock/resource/Languages.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/PackConverter + * + */ + +package org.geysermc.pack.bedrock.resource; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class Languages { + private final Map> languages = new HashMap<>(); + + public Map> languages() { + return Collections.unmodifiableMap(this.languages); + } + + /** + * Get the language data for a specific language + * + * @param language The language code to get the data for + * @return The language data, or an empty map if the language does not exist + */ + public Map language(String language) { + return this.languages.getOrDefault(getLanguageCode(language), Map.of()); + } + + /** + * Set the language data for a specific language + * + * @param language The language code to set the data for + * @param data The translation strings to put against the language + */ + public void language(String language, Map data) { + this.languages.put(getLanguageCode(language), data); + } + + public String translation(String language, String key) { + return this.language(getLanguageCode(language)).getOrDefault(key, key); + } + + /** + * Set the translation for a specific language + * + * @param language The language code to set the translation for + * @param key The key to set the translation for + * @param value The value to set the translation to + */ + public void translation(String language, String key, String value) { + this.language(getLanguageCode(language)).put(key, value); + } + + /** + * Get a list of all the language codes + * + * @return A list of all the language codes + */ + public String[] languageCodes() { + return this.languages.keySet().toArray(new String[0]); + } + + private String getLanguageCode(String language) { + String[] parts = language.split("_"); + return parts[0] + "_" + parts[1].toUpperCase(); + } +} diff --git a/pack-schema/api/src/main/java/org/geysermc/pack/util/FileUtil.java b/pack-schema/api/src/main/java/org/geysermc/pack/util/FileUtil.java index 24d84ff..8167d04 100644 --- a/pack-schema/api/src/main/java/org/geysermc/pack/util/FileUtil.java +++ b/pack-schema/api/src/main/java/org/geysermc/pack/util/FileUtil.java @@ -33,6 +33,8 @@ import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Map; +import java.util.Properties; /** * Utility class for files. @@ -60,4 +62,18 @@ public class FileUtil { gson.toJson(object, writer); } } + + public static void exportProperties(@NotNull Path location, @NotNull Map properties) throws IOException { + if (Files.notExists(location.getParent())) { + Files.createDirectories(location.getParent()); + } + + if (Files.notExists(location)) { + Files.createFile(location); + } + + Properties propertiesFile = new Properties(); + propertiesFile.putAll(properties); + propertiesFile.store(Files.newOutputStream(location), null); + } }