From e199e78a4f7e7b31653f2f050d84dc6b9cbc28f9 Mon Sep 17 00:00:00 2001 From: cpw Date: Fri, 5 Oct 2018 21:42:15 -0400 Subject: [PATCH] load languages on the server as well as the client, and fix up a bunch of data packs. --- build.gradle | 13 +++ .../resources/IResourceManager.java.patch | 10 ++ ...SimpleReloadableResourceManager.java.patch | 10 ++ .../text/translation/LanguageMap.java.patch | 39 +------ .../common/ForgeChunkManager.java | 13 ++- .../minecraftforge/fml/ExtensionPoint.java | 3 +- .../net/minecraftforge/fml/LaunchTesting.java | 26 +++-- .../fml/client/ClientModLoader.java | 8 +- .../fml/client/gui/GuiModList.java | 2 +- .../fml/hooks/LanguageHook.java | 76 ------------- .../ModFileResourcePack.java | 20 +++- .../{client => packs}/ResourcePackLoader.java | 63 +++++++++-- .../fml/server/LanguageHook.java | 102 ++++++++++++++++++ .../fml/server/ServerLifecycleHooks.java | 5 + .../fml/server/ServerModLoader.java | 1 + .../forge/tags/blocks/fence_gates/wooden.json | 2 +- .../data/forge/tags/blocks/fences/wooden.json | 2 +- .../data/forge/tags/blocks/stone.json | 2 +- .../data/forge/tags/items/dyes/black.json | 2 +- .../forge/tags/items/fence_gates/wooden.json | 2 +- .../data/forge/tags/items/fences/wooden.json | 2 +- .../forge/tags/items/gems/prismarine.json | 2 +- .../data/forge/tags/items/nuggets.json | 2 +- .../data/forge/tags/items/stone.json | 2 +- 24 files changed, 252 insertions(+), 157 deletions(-) create mode 100644 patches/minecraft/net/minecraft/resources/IResourceManager.java.patch create mode 100644 patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch delete mode 100644 src/main/java/net/minecraftforge/fml/hooks/LanguageHook.java rename src/main/java/net/minecraftforge/fml/{client => packs}/ModFileResourcePack.java (82%) rename src/main/java/net/minecraftforge/fml/{client => packs}/ResourcePackLoader.java (53%) create mode 100644 src/main/java/net/minecraftforge/fml/server/LanguageHook.java diff --git a/build.gradle b/build.gradle index ceb1167b3..e069476c2 100644 --- a/build.gradle +++ b/build.gradle @@ -200,11 +200,24 @@ project(':forge') { doFirst { mkdir 'runserver' } + doFirst { + copy { + from sourceSets.main.resources + into "$buildDir/classes/java/main" + } + } classpath sourceSets.main.runtimeClasspath main 'net.minecraftforge.fml.LaunchTesting' args 'nogui' + systemProperties = [ + "mc.version": "${MC_VERSION}", + "mcp.version": "${MCP_VERSION}", + "forge.version": "${project.version.substring(MC_VERSION.length() + 1)}", + "forge.spec":"${SPEC_VERSION}" + ] environment target:'fmldevserver' workingDir 'runserver' + standardInput = System.in } def extraTxts = [ diff --git a/patches/minecraft/net/minecraft/resources/IResourceManager.java.patch b/patches/minecraft/net/minecraft/resources/IResourceManager.java.patch new file mode 100644 index 000000000..7c263520e --- /dev/null +++ b/patches/minecraft/net/minecraft/resources/IResourceManager.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/resources/IResourceManager.java ++++ b/net/minecraft/resources/IResourceManager.java +@@ -10,7 +10,6 @@ + import net.minecraftforge.api.distmarker.OnlyIn; + + public interface IResourceManager { +- @OnlyIn(Dist.CLIENT) + Set func_199001_a(); + + IResource func_199002_a(ResourceLocation p_199002_1_) throws IOException; diff --git a/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch b/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch new file mode 100644 index 000000000..d216f75c8 --- /dev/null +++ b/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/resources/SimpleReloadableResourceManager.java ++++ b/net/minecraft/resources/SimpleReloadableResourceManager.java +@@ -45,7 +45,6 @@ + + } + +- @OnlyIn(Dist.CLIENT) + public Set func_199001_a() { + return this.field_199016_e; + } diff --git a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch index f599a67f0..97f647595 100644 --- a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch +++ b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch @@ -1,42 +1,11 @@ --- a/net/minecraft/util/text/translation/LanguageMap.java +++ b/net/minecraft/util/text/translation/LanguageMap.java -@@ -26,21 +26,34 @@ - private long field_150511_e; - - public LanguageMap() { -- try { - InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.json"); -+ injectLanguage(this, inputstream); -+ } -+ -+ public static void injectLanguage(InputStream inputStream){ -+ injectLanguage(field_197636_c, inputStream); -+ } -+ -+ private static void injectLanguage(LanguageMap inst, InputStream inputStream){ -+ final Map map = parseLanguageFile(inputStream); -+ inst.field_74816_c.putAll(map); -+ inst.field_150511_e = System.currentTimeMillis(); -+ } -+ -+ private static Map parseLanguageFile(InputStream inputstream) { -+ Map languageList = Maps.newHashMap(); -+ try { - JsonElement jsonelement = (JsonElement)(new Gson()).fromJson(new InputStreamReader(inputstream, StandardCharsets.UTF_8), JsonElement.class); - JsonObject jsonobject = JsonUtils.func_151210_l(jsonelement, "strings"); - - for(Entry entry : jsonobject.entrySet()) { +@@ -35,7 +35,7 @@ String s = field_111053_a.matcher(JsonUtils.func_151206_a(entry.getValue(), entry.getKey())).replaceAll("%$1s"); -- this.field_74816_c.put(entry.getKey(), s); -+ languageList.put(entry.getKey(), s); + this.field_74816_c.put(entry.getKey(), s); } - -- this.field_150511_e = Util.func_211177_b(); ++ net.minecraftforge.fml.server.LanguageHook.captureLanguageMap(this.field_74816_c); + this.field_150511_e = Util.func_211177_b(); } catch (JsonParseException jsonparseexception) { field_201045_a.error("Couldn't read strings from /assets/minecraft/lang/en_us.json", (Throwable)jsonparseexception); - } -- -+ return languageList; - } - - public static LanguageMap func_74808_a() { diff --git a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java index 9754738b5..b42d7c4d7 100644 --- a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java +++ b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java @@ -19,8 +19,7 @@ package net.minecraftforge.common; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; @@ -32,6 +31,7 @@ import java.util.UUID; import javax.annotation.Nullable; +import net.minecraft.nbt.NBTSizeTracker; import net.minecraftforge.versions.forge.ForgeVersion; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -491,9 +491,9 @@ public class ForgeChunkManager ArrayListMultimap loadedTickets = ArrayListMultimap.create(); Map> playerLoadedTickets = Maps.newHashMap(); NBTTagCompound forcedChunkData; - try + try (DataInputStream datainputstream = new DataInputStream(new FileInputStream(chunkLoaderData))) { - forcedChunkData = CompressedStreamTools.read(chunkLoaderData); + forcedChunkData = CompressedStreamTools.read(datainputstream, NBTSizeTracker.INFINITE); } catch (IOException e) { @@ -954,9 +954,8 @@ public class ForgeChunkManager // Write the actual file on the IO thread rather than blocking the server thread ThreadedFileIOBase.getThreadedIOInstance().queueIO(() -> { - try - { - CompressedStreamTools.write(forcedChunkData, chunkLoaderData); + try (DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(chunkLoaderData))) { + CompressedStreamTools.write(forcedChunkData, dataoutputstream); } catch (IOException e) { diff --git a/src/main/java/net/minecraftforge/fml/ExtensionPoint.java b/src/main/java/net/minecraftforge/fml/ExtensionPoint.java index b81ec78bf..6e28d8313 100644 --- a/src/main/java/net/minecraftforge/fml/ExtensionPoint.java +++ b/src/main/java/net/minecraftforge/fml/ExtensionPoint.java @@ -22,10 +22,9 @@ package net.minecraftforge.fml; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.resources.IResourcePack; -import net.minecraftforge.fml.client.ModFileResourcePack; +import net.minecraftforge.fml.packs.ModFileResourcePack; import java.util.function.BiFunction; -import java.util.function.Function; public class ExtensionPoint { diff --git a/src/main/java/net/minecraftforge/fml/LaunchTesting.java b/src/main/java/net/minecraftforge/fml/LaunchTesting.java index de0c56090..84c554042 100644 --- a/src/main/java/net/minecraftforge/fml/LaunchTesting.java +++ b/src/main/java/net/minecraftforge/fml/LaunchTesting.java @@ -20,6 +20,7 @@ package net.minecraftforge.fml; import com.google.common.base.Strings; +import com.google.common.collect.ObjectArrays; import cpw.mods.modlauncher.Launcher; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Filter; @@ -29,6 +30,7 @@ import org.apache.logging.log4j.core.filter.MarkerFilter; import java.io.File; import java.lang.reflect.Field; +import java.util.Objects; public class LaunchTesting { @@ -39,11 +41,13 @@ public class LaunchTesting final MarkerFilter launchpluginFilter = MarkerFilter.createFilter("LAUNCHPLUGIN", Filter.Result.DENY, Filter.Result.NEUTRAL); final MarkerFilter axformFilter= MarkerFilter.createFilter("AXFORM", Filter.Result.DENY, Filter.Result.NEUTRAL); final MarkerFilter eventbusFilter = MarkerFilter.createFilter("EVENTBUS", Filter.Result.DENY, Filter.Result.NEUTRAL); + final MarkerFilter distxformFilter = MarkerFilter.createFilter("DISTXFORM", Filter.Result.DENY, Filter.Result.NEUTRAL); final LoggerContext logcontext = LoggerContext.getContext(false); logcontext.getConfiguration().addFilter(classloadingFilter); logcontext.getConfiguration().addFilter(launchpluginFilter); logcontext.getConfiguration().addFilter(axformFilter); logcontext.getConfiguration().addFilter(eventbusFilter); + logcontext.getConfiguration().addFilter(distxformFilter); logcontext.updateLoggers(); File invsorter = new File("/home/cpw/projects/minecraft/inventorysorter/classes"); if (invsorter.exists()) { @@ -56,14 +60,20 @@ public class LaunchTesting throw new IllegalArgumentException("Environment variable target must be set."); } - hackNatives(); - Launcher.main("--launchTarget", target, - "--gameDir", ".", - "--accessToken", "blah", - "--version", "FMLDev", - "--assetIndex", "1.13", - "--assetsDir", assets, - "--userProperties", "{}"); + if (Objects.equals(target,"fmldevclient")) { + hackNatives(); + Launcher.main("--launchTarget", target, + "--gameDir", ".", + "--accessToken", "blah", + "--version", "FMLDev", + "--assetIndex", "1.13", + "--assetsDir", assets, + "--userProperties", "{}"); + } else if (Objects.equals(target, "fmldevserver")) { + String[] launchargs = ObjectArrays.concat(new String[] {"--launchTarget", target, + "--gameDir", "."}, args, String.class); + Launcher.main(launchargs); + } Thread.sleep(10000); } diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index 966963608..605f60cef 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -24,9 +24,7 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.DownloadingPackFinder; import net.minecraft.client.resources.ResourcePackInfoClient; import net.minecraft.resources.IReloadableResourceManager; -import net.minecraft.resources.IResourcePack; import net.minecraft.resources.ResourcePackList; -import net.minecraft.resources.data.IMetadataSectionSerializer; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.LoadingFailedException; @@ -34,12 +32,8 @@ import net.minecraftforge.fml.LogicalSidedProvider; import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.SidedProvider; import net.minecraftforge.fml.VersionChecker; -import net.minecraftforge.fml.client.gui.GuiNotification; import net.minecraftforge.fml.client.gui.LoadingErrorScreen; -import net.minecraftforge.fml.client.registry.RenderingRegistry; - -import java.io.IOException; -import java.util.List; +import net.minecraftforge.fml.packs.ResourcePackLoader; @OnlyIn(Dist.CLIENT) public class ClientModLoader diff --git a/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java index 63c0024da..a4413b57b 100644 --- a/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java @@ -39,7 +39,7 @@ import net.minecraft.util.text.TextComponentString; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fml.*; import net.minecraftforge.fml.client.ConfigGuiHandler; -import net.minecraftforge.fml.client.ResourcePackLoader; +import net.minecraftforge.fml.packs.ResourcePackLoader; import net.minecraftforge.fml.language.IModInfo; import net.minecraftforge.fml.loading.StringUtils; import net.minecraftforge.fml.loading.moddiscovery.ModInfo; diff --git a/src/main/java/net/minecraftforge/fml/hooks/LanguageHook.java b/src/main/java/net/minecraftforge/fml/hooks/LanguageHook.java deleted file mode 100644 index d63ea1278..000000000 --- a/src/main/java/net/minecraftforge/fml/hooks/LanguageHook.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.hooks; - -import org.apache.commons.io.IOUtils; - -import javax.annotation.Nullable; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Properties; - -public class LanguageHook -{ - /** - * Loads a lang file, first searching for a marker to enable the 'extended' format {escape characters} - * If the marker is not found it simply returns and let the vanilla code load things. - * The Marker is 'PARSE_ESCAPES' by itself on a line starting with '#' as such: - * #PARSE_ESCAPES - * - * @param table The Map to load each key/value pair into. - * @param inputstream Input stream containing the lang file. - * @return A new InputStream that vanilla uses to load normal Lang files, Null if this is a 'enhanced' file and loading is done. - */ - @Nullable - public static InputStream loadLanguage(Map table, InputStream inputstream) throws IOException - { - byte[] data = IOUtils.toByteArray(inputstream); - - boolean isEnhanced = false; - for (String line : IOUtils.readLines(new ByteArrayInputStream(data), StandardCharsets.UTF_8)) - { - if (!line.isEmpty() && line.charAt(0) == '#') - { - line = line.substring(1).trim(); - if (line.equals("PARSE_ESCAPES")) - { - isEnhanced = true; - break; - } - } - } - - if (!isEnhanced) - return new ByteArrayInputStream(data); - - Properties props = new Properties(); - props.load(new InputStreamReader(new ByteArrayInputStream(data), StandardCharsets.UTF_8)); - for (Map.Entry e : props.entrySet()) - { - table.put((String)e.getKey(), (String)e.getValue()); - } - props.clear(); - return null; - } -} diff --git a/src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java b/src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java similarity index 82% rename from src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java rename to src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java index d90e6b711..41b172195 100644 --- a/src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java +++ b/src/main/java/net/minecraftforge/fml/packs/ModFileResourcePack.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.packs; import net.minecraft.resources.AbstractResourcePack; import net.minecraft.resources.ResourcePackType; @@ -69,7 +69,6 @@ public class ModFileResourcePack extends AbstractResourcePack @Override public Collection getAllResourceLocations(ResourcePackType type, String pathIn, int maxDepth, Predicate filter) { - try { return Files.walk(modFile.getLocator().findPath(modFile, type.getDirectoryName())). @@ -97,6 +96,23 @@ public class ModFileResourcePack extends AbstractResourcePack } } + public InputStream getResourceStream(ResourcePackType type, ResourceLocation location) throws IOException { + if (location.getPath().startsWith("lang/")) { + return super.getResourceStream(ResourcePackType.CLIENT_RESOURCES, location); + } else { + return super.getResourceStream(type, location); + } + } + + public boolean resourceExists(ResourcePackType type, ResourceLocation location) { + if (location.getPath().startsWith("lang/")) { + return super.resourceExists(ResourcePackType.CLIENT_RESOURCES, location); + } else { + return super.resourceExists(type, location); + } + } + + @Override public void close() throws IOException { diff --git a/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java b/src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java similarity index 53% rename from src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java rename to src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java index 576276c34..a3d53f632 100644 --- a/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java +++ b/src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java @@ -17,18 +17,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.packs; -import net.minecraft.resources.AbstractResourcePack; -import net.minecraft.resources.FilePack; -import net.minecraft.resources.FolderPack; -import net.minecraft.resources.IResourcePack; -import net.minecraft.resources.ResourcePackInfo; -import net.minecraft.resources.ResourcePackList; +import net.minecraft.resources.*; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.moddiscovery.ModFile; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.util.Map; import java.util.function.Function; @@ -57,12 +56,56 @@ public class ResourcePackLoader map(mf -> new ModFileResourcePack(mf.getFile())). collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity())); forgePack = Files.isDirectory(FMLLoader.getForgePath()) ? - new FolderPack(FMLLoader.getForgePath().toFile()) : - new FilePack(FMLLoader.getForgePath().toFile()); + new ForgeFolderPack(FMLLoader.getForgePath().toFile()) : + new ForgeFilePack(FMLLoader.getForgePath().toFile()); resourcePacks.addPackFinder(new ModPackFinder()); } - private static class ModPackFinder implements net.minecraft.resources.IPackFinder + private static class ForgeFolderPack extends FolderPack { + public ForgeFolderPack(final File folder) { + super(folder); + } + + public InputStream getResourceStream(ResourcePackType type, ResourceLocation location) throws IOException { + if (location.getPath().startsWith("lang/")) { + return super.getResourceStream(ResourcePackType.CLIENT_RESOURCES, location); + } else { + return super.getResourceStream(type, location); + } + } + + public boolean resourceExists(ResourcePackType type, ResourceLocation location) { + if (location.getPath().startsWith("lang/")) { + return super.resourceExists(ResourcePackType.CLIENT_RESOURCES, location); + } else { + return super.resourceExists(type, location); + } + } + } + + private static class ForgeFilePack extends FilePack { + public ForgeFilePack(final File folder) { + super(folder); + } + + public InputStream getResourceStream(ResourcePackType type, ResourceLocation location) throws IOException { + if (location.getPath().startsWith("lang/")) { + return super.getResourceStream(ResourcePackType.CLIENT_RESOURCES, location); + } else { + return super.getResourceStream(type, location); + } + } + + public boolean resourceExists(ResourcePackType type, ResourceLocation location) { + if (location.getPath().startsWith("lang/")) { + return super.resourceExists(ResourcePackType.CLIENT_RESOURCES, location); + } else { + return super.resourceExists(type, location); + } + } + + } + private static class ModPackFinder implements IPackFinder { @Override public void addPackInfosToMap(Map packList, ResourcePackInfo.IFactory factory) diff --git a/src/main/java/net/minecraftforge/fml/server/LanguageHook.java b/src/main/java/net/minecraftforge/fml/server/LanguageHook.java new file mode 100644 index 000000000..4513a9473 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/server/LanguageHook.java @@ -0,0 +1,102 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml.server; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.resources.IResource; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.packs.ResourcePackLoader; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.regex.Pattern; + +public class LanguageHook +{ + private static final Logger LOGGER = LogManager.getLogger(); + private static final Gson GSON = new Gson(); + private static final Pattern PATTERN = Pattern.compile("%(\\d+\\$)?[\\d\\.]*[df]"); + private static List> capturedTables = new ArrayList<>(2); + private static Map modTable; + /** + * Loads lang files on the server + */ + public static void captureLanguageMap(Map table) + { + capturedTables.add(table); + if (modTable != null) { + capturedTables.forEach(t->t.putAll(modTable)); + } + } + + // The below is based on client side net.minecraft.client.resources.Locale code + private static void loadLocaleData(final List allResources) { + allResources.stream().map(IResource::getInputStream).forEach(LanguageHook::loadLocaleData); + } + + private static void loadLocaleData(final InputStream inputstream) { + try + { + JsonElement jsonelement = GSON.fromJson(new InputStreamReader(inputstream, StandardCharsets.UTF_8), JsonElement.class); + JsonObject jsonobject = JsonUtils.getJsonObject(jsonelement, "strings"); + + jsonobject.entrySet().forEach(entry -> { + String s = PATTERN.matcher(JsonUtils.getString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); + modTable.put(entry.getKey(), s); + }); + } + finally + { + IOUtils.closeQuietly(inputstream); + } + } + + private static void loadLanguage(String langName, MinecraftServer server) { + String langFile = String.format("lang/%s.json", langName); + server.getResourceManager().getResourceNamespaces().forEach(namespace -> { + try { + ResourceLocation langResource = new ResourceLocation(namespace, langFile); + loadLocaleData(server.getResourceManager().getAllResources(langResource)); + } catch (FileNotFoundException fnfe) { + } catch (Exception exception) { + LOGGER.warn("Skipped language file: {}:{}", namespace, langFile, exception); + } + }); + + } + static void loadLanguagesOnServer(MinecraftServer server) { + modTable = new HashMap<>(5000); + // Possible multi-language server support? + for (String lang : Arrays.asList("en_us")) { + loadLanguage(lang, server); + } + capturedTables.forEach(t->t.putAll(modTable)); + } +} diff --git a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java index 7d6afdf44..9b5a5b874 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java @@ -25,7 +25,9 @@ import net.minecraft.network.handshake.client.CPacketHandshake; import net.minecraft.network.login.server.SPacketDisconnectLogin; import net.minecraft.server.MinecraftServer; import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.LogicalSidedProvider; import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; @@ -33,6 +35,7 @@ import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; import net.minecraftforge.fml.network.NetworkHooks; +import net.minecraftforge.fml.packs.ResourcePackLoader; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; @@ -53,11 +56,13 @@ public class ServerLifecycleHooks { currentServer = server; LogicalSidedProvider.setServer(()->server); + ResourcePackLoader.loadResourcePacks(currentServer.getResourcePacks()); return !MinecraftForge.EVENT_BUS.post(new FMLServerAboutToStartEvent(server)); } public static boolean handleServerStarting(final MinecraftServer server) { + DistExecutor.runWhenOn(Dist.DEDICATED_SERVER, ()->()->LanguageHook.loadLanguagesOnServer(server)); return !MinecraftForge.EVENT_BUS.post(new FMLServerStartingEvent(server)); } diff --git a/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java b/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java index 5bca2db38..ea9cbc597 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java @@ -23,6 +23,7 @@ import net.minecraft.server.dedicated.DedicatedServer; import net.minecraftforge.fml.LogicalSidedProvider; import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.SidedProvider; +import net.minecraftforge.fml.packs.ResourcePackLoader; public class ServerModLoader { diff --git a/src/main/resources/data/forge/tags/blocks/fence_gates/wooden.json b/src/main/resources/data/forge/tags/blocks/fence_gates/wooden.json index ea7a296ff..7b8030778 100644 --- a/src/main/resources/data/forge/tags/blocks/fence_gates/wooden.json +++ b/src/main/resources/data/forge/tags/blocks/fence_gates/wooden.json @@ -2,7 +2,7 @@ "replace": false, "values": [ "minecraft:oak_fence_gate", - "minecraft:spruce_fence_gate" + "minecraft:spruce_fence_gate", "minecraft:birch_fence_gate", "minecraft:jungle_fence_gate", "minecraft:acacia_fence_gate", diff --git a/src/main/resources/data/forge/tags/blocks/fences/wooden.json b/src/main/resources/data/forge/tags/blocks/fences/wooden.json index 57a8ea065..af77eddec 100644 --- a/src/main/resources/data/forge/tags/blocks/fences/wooden.json +++ b/src/main/resources/data/forge/tags/blocks/fences/wooden.json @@ -2,7 +2,7 @@ "replace": false, "values": [ "minecraft:oak_fence", - "minecraft:spruce_fence" + "minecraft:spruce_fence", "minecraft:birch_fence", "minecraft:jungle_fence", "minecraft:acacia_fence", diff --git a/src/main/resources/data/forge/tags/blocks/stone.json b/src/main/resources/data/forge/tags/blocks/stone.json index cb84752b2..108b95dc0 100644 --- a/src/main/resources/data/forge/tags/blocks/stone.json +++ b/src/main/resources/data/forge/tags/blocks/stone.json @@ -6,7 +6,7 @@ "minecraft:granite", "minecraft:infested_stone", "minecraft:stone", - "minecraft:spolished_andesite", + "minecraft:polished_andesite", "minecraft:polished_diorite", "minecraft:polished_granite" ] diff --git a/src/main/resources/data/forge/tags/items/dyes/black.json b/src/main/resources/data/forge/tags/items/dyes/black.json index 3c014ad06..7c1914cd3 100644 --- a/src/main/resources/data/forge/tags/items/dyes/black.json +++ b/src/main/resources/data/forge/tags/items/dyes/black.json @@ -1,6 +1,6 @@ { "replace": false, "values": [ - "minecraft:ink_sack" + "minecraft:ink_sac" ] } diff --git a/src/main/resources/data/forge/tags/items/fence_gates/wooden.json b/src/main/resources/data/forge/tags/items/fence_gates/wooden.json index ea7a296ff..7b8030778 100644 --- a/src/main/resources/data/forge/tags/items/fence_gates/wooden.json +++ b/src/main/resources/data/forge/tags/items/fence_gates/wooden.json @@ -2,7 +2,7 @@ "replace": false, "values": [ "minecraft:oak_fence_gate", - "minecraft:spruce_fence_gate" + "minecraft:spruce_fence_gate", "minecraft:birch_fence_gate", "minecraft:jungle_fence_gate", "minecraft:acacia_fence_gate", diff --git a/src/main/resources/data/forge/tags/items/fences/wooden.json b/src/main/resources/data/forge/tags/items/fences/wooden.json index 57a8ea065..af77eddec 100644 --- a/src/main/resources/data/forge/tags/items/fences/wooden.json +++ b/src/main/resources/data/forge/tags/items/fences/wooden.json @@ -2,7 +2,7 @@ "replace": false, "values": [ "minecraft:oak_fence", - "minecraft:spruce_fence" + "minecraft:spruce_fence", "minecraft:birch_fence", "minecraft:jungle_fence", "minecraft:acacia_fence", diff --git a/src/main/resources/data/forge/tags/items/gems/prismarine.json b/src/main/resources/data/forge/tags/items/gems/prismarine.json index 5e2b470e1..965cd0ab0 100644 --- a/src/main/resources/data/forge/tags/items/gems/prismarine.json +++ b/src/main/resources/data/forge/tags/items/gems/prismarine.json @@ -1,6 +1,6 @@ { "replace": false, "values": [ - "minecraft:prismarine_crystal" + "minecraft:prismarine_crystals" ] } diff --git a/src/main/resources/data/forge/tags/items/nuggets.json b/src/main/resources/data/forge/tags/items/nuggets.json index c10f18d29..66a7ecba6 100644 --- a/src/main/resources/data/forge/tags/items/nuggets.json +++ b/src/main/resources/data/forge/tags/items/nuggets.json @@ -2,6 +2,6 @@ "replace": false, "values": [ "#forge:nuggets/iron", - "#forge:nuggests/gold" + "#forge:nuggets/gold" ] } diff --git a/src/main/resources/data/forge/tags/items/stone.json b/src/main/resources/data/forge/tags/items/stone.json index 39f65a8a0..839d23326 100644 --- a/src/main/resources/data/forge/tags/items/stone.json +++ b/src/main/resources/data/forge/tags/items/stone.json @@ -5,7 +5,7 @@ "minecraft:diorite", "minecraft:granite", "minecraft:stone", - "minecraft:spolished_andesite", + "minecraft:polished_andesite", "minecraft:polished_diorite", "minecraft:polished_granite" ]