diff --git a/patches/minecraft/com/mojang/blaze3d/platform/TextureUtil.java.patch b/patches/minecraft/com/mojang/blaze3d/platform/TextureUtil.java.patch deleted file mode 100644 index 745220a2d..000000000 --- a/patches/minecraft/com/mojang/blaze3d/platform/TextureUtil.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/com/mojang/blaze3d/platform/TextureUtil.java -+++ b/com/mojang/blaze3d/platform/TextureUtil.java -@@ -44,7 +44,10 @@ - } - - public static void prepareImage(NativeImage.PixelFormatGLCode p_prepareImage_0_, int p_prepareImage_1_, int p_prepareImage_2_, int p_prepareImage_3_, int p_prepareImage_4_) { -- bind(p_prepareImage_1_); -+ synchronized (net.minecraftforge.fml.client.SplashProgress.class) -+ { -+ bind(p_prepareImage_1_); -+ } - if (p_prepareImage_2_ >= 0) { - GlStateManager.texParameter(3553, 33085, p_prepareImage_2_); - GlStateManager.texParameter(3553, 33082, 0); diff --git a/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch b/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch index d930b7a5c..de7fa3ee7 100644 --- a/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch +++ b/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch @@ -1,42 +1,6 @@ --- a/net/minecraft/client/audio/SoundHandler.java +++ b/net/minecraft/client/audio/SoundHandler.java -@@ -61,6 +61,7 @@ - SoundHandler.Loader soundhandler$loader = new SoundHandler.Loader(); - p_212854_2_.func_219894_a(); - -+ java.util.List> resources = new java.util.LinkedList<>(); - for(String s : p_212854_1_.func_199001_a()) { - p_212854_2_.func_76320_a(s); - -@@ -74,7 +75,9 @@ - p_212854_2_.func_219895_b("register"); - - for(Entry entry : map.entrySet()) { -+ resources.add(new net.minecraft.util.Tuple<>(new ResourceLocation(s, entry.getKey()), () -> { - soundhandler$loader.func_217944_a(new ResourceLocation(s, entry.getKey()), entry.getValue(), p_212854_1_); -+ })); - } - - p_212854_2_.func_76319_b(); -@@ -91,6 +94,17 @@ - p_212854_2_.func_76319_b(); - } - -+ net.minecraftforge.fml.common.progress.StartupProgressManager.start("Loading sounds", resources.size(), bar -> { -+ resources.forEach(entry -> { -+ bar.step(entry.func_76341_a().toString()); -+ try { -+ entry.func_76340_b().run(); -+ } catch (RuntimeException e) { -+ field_147698_b.warn("Invalid sounds.json", e); -+ } -+ }); -+ }); -+ - p_212854_2_.func_219897_b(); - return soundhandler$loader; - } -@@ -210,6 +224,11 @@ +@@ -210,6 +210,11 @@ this.field_147694_f.func_195855_a(p_195478_1_, p_195478_2_); } diff --git a/patches/minecraft/net/minecraft/client/gui/ResourceLoadProgressGui.java.patch b/patches/minecraft/net/minecraft/client/gui/ResourceLoadProgressGui.java.patch index 1c59e480f..d95665f1c 100644 --- a/patches/minecraft/net/minecraft/client/gui/ResourceLoadProgressGui.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/ResourceLoadProgressGui.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/client/gui/ResourceLoadProgressGui.java +++ b/net/minecraft/client/gui/ResourceLoadProgressGui.java -@@ -83,6 +83,7 @@ +@@ -79,6 +79,7 @@ + this.blit(k1, i1, 0, 0, 256, 256); + float f3 = this.field_212975_c.func_219555_b(); + this.field_212978_f = this.field_212978_f * 0.95F + f3 * 0.050000012F; ++ net.minecraftforge.fml.client.ClientModLoader.renderProgressText(); + if (f < 1.0F) { this.func_212972_a(i / 2 - 150, j / 4 * 3, i / 2 + 150, j / 4 * 3 + 10, this.field_212978_f, 1.0F - MathHelper.func_76131_a(f, 0.0F, 1.0F)); } - -+ net.minecraftforge.fml.client.ClientModLoader.renderProgressText(); - if (f >= 2.0F) { - this.field_212974_b.func_213268_a((LoadingGui)null); - } diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch index fce2b918c..7c54b6ef0 100644 --- a/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch @@ -9,28 +9,19 @@ private static final Comparator field_217797_a = Comparator.comparing((p_217793_0_) -> { return -p_217793_0_.field_94201_d; }).thenComparing((p_217795_0_) -> { -@@ -50,15 +52,21 @@ - public void func_94305_f() { - List list = Lists.newArrayList(this.field_94319_a); - list.sort(field_217797_a); -+ try(net.minecraftforge.fml.common.progress.ProgressBar bar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Texture stitching", list.size())) { +@@ -53,6 +55,12 @@ for(Stitcher.Holder stitcher$holder : list) { -+ bar.step(stitcher$holder.field_98151_a.func_195668_m().toString()); if (!this.func_94310_b(stitcher$holder)) { -+ LOGGER.info(String.format("Unable to fit: %s - size: %dx%d - Maybe try a lower resolution resourcepack?", stitcher$holder.field_98151_a.func_195668_m(), stitcher$holder.field_98151_a.func_94211_a(), stitcher$holder.field_98151_a.func_94216_b())); -+ for (Stitcher.Holder h : list) -+ LOGGER.info(" {}", h); ++ LOGGER.info(new net.minecraftforge.fml.loading.AdvancedLogMessageAdapter(sb->{ ++ sb.append("Unable to fit: ").append(stitcher$holder.field_98151_a.func_195668_m()); ++ sb.append(" - size: ").append(stitcher$holder.field_98151_a.func_94211_a()).append("x").append(stitcher$holder.field_98151_a.func_94216_b()); ++ sb.append(" - Maybe try a lower resolution resourcepack?\n"); ++ list.forEach(h-> sb.append("\t").append(h).append("\n")); ++ })); throw new StitcherException(stitcher$holder.field_98151_a); } } - - this.field_94318_c = MathHelper.func_151236_b(this.field_94318_c); - this.field_94315_d = MathHelper.func_151236_b(this.field_94315_d); -+ }; // Forge: end progress bar - } - - public List func_94309_g() { @@ -104,7 +112,7 @@ boolean flag4 = flag2 && j != l; boolean flag; diff --git a/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch b/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch index e9b19a43a..dcaacdbb3 100644 --- a/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch +++ b/patches/minecraft/net/minecraft/resources/SimpleReloadableResourceManager.java.patch @@ -16,7 +16,7 @@ public boolean func_219533_b(ResourceLocation p_219533_1_) { IResourceManager iresourcemanager = this.field_199014_c.get(p_219533_1_.func_110624_b()); return iresourcemanager != null ? iresourcemanager.func_219533_b(p_219533_1_) : false; -@@ -118,18 +116,20 @@ +@@ -118,7 +116,6 @@ return iasyncreloader; } @@ -24,17 +24,3 @@ public IAsyncReloader func_219535_a(Executor p_219535_1_, Executor p_219535_2_, CompletableFuture p_219535_3_) { return this.func_219538_b(p_219535_1_, p_219535_2_, this.field_219539_d, p_219535_3_); } - - public IAsyncReloader func_219537_a(Executor p_219537_1_, Executor p_219537_2_, CompletableFuture p_219537_3_, List p_219537_4_) { -+ net.minecraftforge.fml.common.progress.StartupProgressManager.start("Loading Resources", p_219537_4_.size(), true, bar -> { - this.func_199008_b(); - field_199012_a.info("Reloading ResourceManager: {}", p_219537_4_.stream().map(IResourcePack::func_195762_a).collect(Collectors.joining(", "))); - - for(IResourcePack iresourcepack : p_219537_4_) { -+ bar.step(iresourcepack.func_195762_a()); - this.func_199021_a(iresourcepack); - } -+ }); - - return this.func_219538_b(p_219537_1_, p_219537_2_, this.field_199015_d, p_219537_3_); - } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java index 6080deece..81bdf7795 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.loading; import cpw.mods.modlauncher.api.LamdbaExceptionUtils; diff --git a/src/main/java/net/minecraftforge/client/model/BasicState.java b/src/main/java/net/minecraftforge/client/model/BasicState.java index 9fd97f400..ece88287d 100644 --- a/src/main/java/net/minecraftforge/client/model/BasicState.java +++ b/src/main/java/net/minecraftforge/client/model/BasicState.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.client.model; import net.minecraft.client.renderer.texture.ISprite; diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 343d81f24..6a435e491 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -20,11 +20,7 @@ package net.minecraftforge.common; import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.ExtensionPoint; -import net.minecraftforge.fml.FMLWorldPersistenceHook; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.VersionChecker; -import net.minecraftforge.fml.WorldPersistenceHooks; +import net.minecraftforge.fml.*; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; @@ -103,6 +99,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook modEventBus.register(ForgeConfig.class); // Forge does not display problems when the remote is not matching. ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, ()-> Pair.of(()->"ANY", (remote, isServer)-> true)); + StartupMessageManager.addModMessage("Forge version "+ForgeVersion.getVersion()); } /* diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeContainerType.java b/src/main/java/net/minecraftforge/common/extensions/IForgeContainerType.java index 0f60b3821..3fa1fabc3 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeContainerType.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeContainerType.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.common.extensions; import net.minecraft.entity.player.PlayerInventory; diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgePacketBuffer.java b/src/main/java/net/minecraftforge/common/extensions/IForgePacketBuffer.java index f2b7fdd73..75ca0625c 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgePacketBuffer.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgePacketBuffer.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.common.extensions; import com.google.common.base.Preconditions; diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeSelectionContext.java b/src/main/java/net/minecraftforge/common/extensions/IForgeSelectionContext.java index 61e539df9..79846610d 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeSelectionContext.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeSelectionContext.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.common.extensions; import javax.annotation.Nullable; diff --git a/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java b/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java index 9798c00aa..4e1232ff0 100644 --- a/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java +++ b/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java @@ -41,7 +41,7 @@ public enum LifecycleEventProvider GATHERDATA(()->new GatherDataLifecycleEvent(ModLoadingStage.GATHERDATA), ModList.inlineDispatcher); private final Supplier event; - private final EventHandler>,Executor> eventDispatcher; + private final EventHandler>,Executor, Runnable> eventDispatcher; private Supplier customEventSupplier; private LifecycleEvent.Progression progression = LifecycleEvent.Progression.NEXT; @@ -50,7 +50,7 @@ public enum LifecycleEventProvider this(e, ModList.parallelDispatcher); } - LifecycleEventProvider(Supplier e, EventHandler>,Executor> eventDispatcher) + LifecycleEventProvider(Supplier e, EventHandler>,Executor, Runnable> eventDispatcher) { this.event = e; this.eventDispatcher = eventDispatcher; @@ -64,11 +64,11 @@ public enum LifecycleEventProvider this.progression = progression; } - public void dispatch(Consumer> errorHandler, final Executor executor) { + public void dispatch(Consumer> errorHandler, final Executor executor, final Runnable ticker) { final LifecycleEvent lifecycleEvent = this.event.get(); lifecycleEvent.setCustomEventSupplier(this.customEventSupplier); lifecycleEvent.changeProgression(this.progression); - this.eventDispatcher.dispatchEvent(lifecycleEvent, errorHandler, executor); + this.eventDispatcher.dispatchEvent(lifecycleEvent, errorHandler, executor, ticker); } @@ -148,7 +148,7 @@ public enum LifecycleEventProvider } } - public interface EventHandler>, V extends Executor> { - void dispatchEvent(T event, U exceptionHandler, V executor); + public interface EventHandler>, V extends Executor, R extends Runnable> { + void dispatchEvent(T event, U exceptionHandler, V executor, R ticker); } } diff --git a/src/main/java/net/minecraftforge/fml/ModList.java b/src/main/java/net/minecraftforge/fml/ModList.java index 8e5f44809..14e00634f 100644 --- a/src/main/java/net/minecraftforge/fml/ModList.java +++ b/src/main/java/net/minecraftforge/fml/ModList.java @@ -33,10 +33,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.*; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -81,9 +78,9 @@ public class ModList return INSTANCE; } - static LifecycleEventProvider.EventHandler>, Executor> inlineDispatcher = (event, errors, executor) -> ModList.get().dispatchSynchronousEvent(event, errors, executor); + static LifecycleEventProvider.EventHandler>, Executor, Runnable> inlineDispatcher = (event, errors, executor, ticker) -> ModList.get().dispatchSynchronousEvent(event, errors, executor); - static LifecycleEventProvider.EventHandler>, Executor> parallelDispatcher = (event, errors, executor) -> ModList.get().dispatchParallelEvent(event, errors, executor); + static LifecycleEventProvider.EventHandler>, Executor, Runnable> parallelDispatcher = (event, errors, executor, ticker) -> ModList.get().dispatchParallelEvent(event, errors, executor, ticker); public static ModList get() { return INSTANCE; @@ -113,13 +110,17 @@ public class ModList this.mods.forEach(m->m.transitionState(lifecycleEvent, errorHandler)); FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent)); } - private void dispatchParallelEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent, final Consumer> errorHandler, final Executor executor) { + private void dispatchParallelEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent, final Consumer> errorHandler, final Executor executor, final Runnable ticker) { LOGGER.debug(LOADING, "Dispatching parallel event {}", lifecycleEvent); FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent)); DeferredWorkQueue.clear(); try { - modLoadingThreadPool.submit(()->this.mods.parallelStream().forEach(m->m.transitionState(lifecycleEvent, errorHandler))).get(); + final ForkJoinTask parallelTask = modLoadingThreadPool.submit(() -> this.mods.parallelStream().forEach(m -> m.transitionState(lifecycleEvent, errorHandler))); + while (ticker != null && !parallelTask.isDone()) { + executor.execute(ticker); + } + parallelTask.get(); } catch (InterruptedException | ExecutionException e) { diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index 8a0dc5c3f..a91fca1f3 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -102,7 +102,7 @@ public class ModLoader private final List loadingWarnings; private GatherDataEvent.DataGeneratorConfig dataGeneratorConfig; @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - private Optional> statusConsumer = Optional.empty(); + private final Optional> statusConsumer = StartupMessageManager.modLoaderConsumer(); private ModLoader() { @@ -127,15 +127,15 @@ public class ModLoader DistExecutor.runWhenOn(Dist.CLIENT, ()->()-> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get())); ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get()); statusConsumer.ifPresent(c->c.accept("Mod setup: SETUP")); - dispatchAndHandleError(LifecycleEventProvider.SETUP, mainThreadExecutor); + dispatchAndHandleError(LifecycleEventProvider.SETUP, mainThreadExecutor, null); statusConsumer.ifPresent(c->c.accept("Mod setup: SIDED SETUP")); mainThreadExecutor.execute(()->preSidedRunnable.accept(c->ModList.get().forEachModContainer((mi,mc)->mc.acceptEvent(c.get())))); - dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP, mainThreadExecutor); + dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP, mainThreadExecutor, null); mainThreadExecutor.execute(()->postSidedRunnable.accept(c->ModList.get().forEachModContainer((mi,mc)->mc.acceptEvent(c.get())))); statusConsumer.ifPresent(c->c.accept("Mod setup complete")); } - public void gatherAndInitializeMods() { + public void gatherAndInitializeMods(final Runnable ticker) { statusConsumer.ifPresent(c->c.accept("Loading mods")); final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.toList()), loadingModList.getMods()); if (!this.loadingExceptions.isEmpty()) { @@ -155,22 +155,22 @@ public class ModLoader throw new LoadingFailedException(loadingExceptions); } modList.setLoadedMods(modContainers); - statusConsumer.ifPresent(c->c.accept("Constructing mods")); - dispatchAndHandleError(LifecycleEventProvider.CONSTRUCT, Runnable::run); + statusConsumer.ifPresent(c->c.accept(String.format("Constructing %d mods", modList.size()))); + dispatchAndHandleError(LifecycleEventProvider.CONSTRUCT, Runnable::run, ticker); statusConsumer.ifPresent(c->c.accept("Creating registries")); - GameData.fireCreateRegistryEvents(LifecycleEventProvider.CREATE_REGISTRIES, event -> dispatchAndHandleError(event, Runnable::run)); + GameData.fireCreateRegistryEvents(LifecycleEventProvider.CREATE_REGISTRIES, event -> dispatchAndHandleError(event, Runnable::run, ticker)); ObjectHolderRegistry.findObjectHolders(); CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData()); statusConsumer.ifPresent(c->c.accept("Populating registries")); - GameData.fireRegistryEvents(rl->true, LifecycleEventProvider.LOAD_REGISTRIES, event -> dispatchAndHandleError(event, Runnable::run)); + GameData.fireRegistryEvents(rl->true, LifecycleEventProvider.LOAD_REGISTRIES, event -> dispatchAndHandleError(event, Runnable::run, ticker)); statusConsumer.ifPresent(c->c.accept("Early mod loading complete")); } - private void dispatchAndHandleError(LifecycleEventProvider event, Executor executor) { + private void dispatchAndHandleError(LifecycleEventProvider event, Executor executor, final Runnable ticker) { if (!loadingExceptions.isEmpty()) { LOGGER.error(LOADING,"Skipping lifecycle event {}, {} errors found.", event, loadingExceptions.size()); } else { - event.dispatch(this::accumulateErrors, executor); + event.dispatch(this::accumulateErrors, executor, ticker); } if (!loadingExceptions.isEmpty()) { LOGGER.fatal(LOADING,"Failed to complete lifecycle event {}, {} errors found", event, loadingExceptions.size()); @@ -220,15 +220,15 @@ public class ModLoader public void finishMods(Executor mainThreadExecutor) { statusConsumer.ifPresent(c->c.accept("Mod setup: ENQUEUE IMC")); - dispatchAndHandleError(LifecycleEventProvider.ENQUEUE_IMC, mainThreadExecutor); + dispatchAndHandleError(LifecycleEventProvider.ENQUEUE_IMC, mainThreadExecutor, null); statusConsumer.ifPresent(c->c.accept("Mod setup: PROCESS IMC")); - dispatchAndHandleError(LifecycleEventProvider.PROCESS_IMC, mainThreadExecutor); + dispatchAndHandleError(LifecycleEventProvider.PROCESS_IMC, mainThreadExecutor, null); statusConsumer.ifPresent(c->c.accept("Mod setup: Final completion")); - dispatchAndHandleError(LifecycleEventProvider.COMPLETE, mainThreadExecutor); + dispatchAndHandleError(LifecycleEventProvider.COMPLETE, mainThreadExecutor, null); statusConsumer.ifPresent(c->c.accept("Freezing data")); GameData.freezeData(); NetworkRegistry.lock(); - statusConsumer.ifPresent(c->c.accept("")); + statusConsumer.ifPresent(c->c.accept(String.format("Mod loading complete - %d mods loaded", ModList.get().size()))); } public List getWarnings() @@ -246,16 +246,12 @@ public class ModLoader LOGGER.info("Initializing Data Gatherer for mods {}", mods); Bootstrap.register(); dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, serverGenerators, clientGenerators, devToolGenerators, reportsGenerator, structureValidator); - gatherAndInitializeMods(); - dispatchAndHandleError(LifecycleEventProvider.GATHERDATA, Runnable::run); + gatherAndInitializeMods(null); + dispatchAndHandleError(LifecycleEventProvider.GATHERDATA, Runnable::run, null); dataGeneratorConfig.runAll(); } public Function getDataGeneratorEvent() { return mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.getMods().size() == 1 ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig); } - - public void setStatusConsumer(Consumer consumer) { - this.statusConsumer = Optional.ofNullable(consumer); - } } diff --git a/src/main/java/net/minecraftforge/fml/StartupMessageManager.java b/src/main/java/net/minecraftforge/fml/StartupMessageManager.java new file mode 100644 index 000000000..b409cf773 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/StartupMessageManager.java @@ -0,0 +1,103 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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; + +import com.google.common.base.Ascii; +import com.google.common.base.CharMatcher; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +public class StartupMessageManager { + private static final EnumMap> messages = new EnumMap<>(MessageType.class); + static { + Arrays.stream(MessageType.values()).forEach(mt->messages.computeIfAbsent(mt, k->new CopyOnWriteArrayList<>())); + } + + public static List> getMessages() { + final long ts = System.nanoTime(); + return messages.values().stream().flatMap(Collection::stream). + sorted(Comparator.comparingLong(Message::getTimestamp).thenComparing(Message::getText).reversed()). + map(m -> Pair.of((int) ((ts - m.timestamp) / 1e6), m)). + collect(Collectors.toList()); + } + + public static class Message { + private final String text; + private final MessageType type; + private final long timestamp; + + public Message(final String text, final MessageType type) { + this.text = text; + this.type = type; + this.timestamp = System.nanoTime(); + } + + public String getText() { + return text; + } + + MessageType getType() { + return type; + } + + long getTimestamp() { + return timestamp; + } + + public float[] getTypeColour() { + return type.colour(); + } + } + + enum MessageType { + MC(0.0f, 0.0f, 0.0f), + ML(0.0f, 0.0f, 0.5f), + MOD(0.5f, 0.0f, 0.0f); + + private final float[] colour; + + MessageType(final float r, final float g, final float b) { + colour = new float[] {r,g,b}; + } + + public float[] colour() { + return colour; + } + } + + public static void addModMessage(final String message) { + final String safeMessage = Ascii.truncate(CharMatcher.ascii().retainFrom(message),80,"~"); + final List messages = StartupMessageManager.messages.get(MessageType.MOD); + messages.subList(0, Math.max(0, messages.size() - 20)).clear(); + messages.add(new Message(safeMessage, MessageType.MOD)); + } + + static Optional> modLoaderConsumer() { + return Optional.of(s-> messages.get(MessageType.ML).add(new Message(s, MessageType.ML))); + } + + static Optional> mcLoaderConsumer() { + return Optional.of(s-> messages.get(MessageType.MC).add(new Message(s, MessageType.MC))); + } +} diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index f41f5e039..1323c8bf3 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -64,8 +64,7 @@ public class ClientModLoader SidedProvider.setClient(()->minecraft); LogicalSidedProvider.setClient(()->minecraft); earlyLoaderGUI = new EarlyLoaderGUI(minecraft.mainWindow); - ModLoader.get().setStatusConsumer(earlyLoaderGUI.getStatusConsumer()); - createRunnableWithCatch(ModLoader.get()::gatherAndInitializeMods).run(); + createRunnableWithCatch(() -> ModLoader.get().gatherAndInitializeMods(earlyLoaderGUI::renderTick)).run(); ResourcePackLoader.loadResourcePacks(defaultResourcePacks); mcResourceManager.addReloadListener(ClientModLoader::onreload); mcResourceManager.addReloadListener(BrandingControl.resourceManagerReloadListener()); diff --git a/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java b/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java index cbcccf5a9..5814d2f78 100644 --- a/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java +++ b/src/main/java/net/minecraftforge/fml/client/EarlyLoaderGUI.java @@ -1,18 +1,48 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.client; +import com.google.common.base.Ascii; +import com.google.common.base.CharMatcher; import com.mojang.blaze3d.platform.GlStateManager; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.StartupMessageManager; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL14; import org.lwjgl.stb.STBEasyFont; +import org.lwjgl.stb.STBImage; import org.lwjgl.system.MemoryUtil; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryUsage; import java.nio.ByteBuffer; +import java.util.List; import java.util.function.Consumer; public class EarlyLoaderGUI { private final MainWindow window; - private String message; private boolean handledElsewhere; public EarlyLoaderGUI(final MainWindow window) { @@ -22,51 +52,69 @@ public class EarlyLoaderGUI { window.update(false); } - public Consumer getStatusConsumer() { - return this::update; - } - - private void update(final String message) { - this.message = message; - if (handledElsewhere) return; - doMatrix(); - - GlStateManager.clearColor(1.0f, 1.0f, 1.0f, 1.0f); - GlStateManager.clear(GL11.GL_COLOR_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC); - renderMessage(); - window.update(false); - } - public void handleElsewhere() { this.handledElsewhere = true; } void renderFromGUI() { - doMatrix(); - renderMessage(); + renderMessages(); } - void renderMessage() { + + void renderTick() { + if (handledElsewhere) return; + int guiScale = window.func_216521_a(0, false); + window.func_216525_a(guiScale); + + GlStateManager.clearColor(1.0f, 1.0f, 1.0f, 1.0f); + GlStateManager.clear(GL11.GL_COLOR_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC); + window.func_216522_a(Minecraft.IS_RUNNING_ON_MAC); + renderMessages(); + window.update(false); + } + + private void renderMessages() { + List> messages = StartupMessageManager.getMessages(); + for (int i = 0; i < messages.size(); i++) { + final Pair pair = messages.get(i); + final float fade = MathHelper.clamp((4000.0f - (float) pair.getLeft() - ( i - 4 ) * 1000.0f) / 5000.0f, 0.0f, 1.0f); + if (fade <0.01f) continue; + StartupMessageManager.Message msg = pair.getRight(); + renderMessage(msg.getText(), msg.getTypeColour(), i, fade); + } + renderMemoryInfo(); + } + + private static final float[] memorycolour = new float[] { 0.0f, 0.0f, 0.0f}; + + private void renderMemoryInfo() { + final MemoryUsage heapusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + final MemoryUsage offheapusage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage(); + final float pctmemory = (float) heapusage.getUsed() / heapusage.getMax(); + String memory = String.format("Memory Heap: %d / %d MB (%.1f%%) OffHeap: %d MB", heapusage.getUsed() >> 20, heapusage.getMax() >> 20, pctmemory * 100.0, offheapusage.getUsed() >> 20); + + final int i = MathHelper.hsvToRGB((1.0f - (float)Math.pow(pctmemory, 1.5f)) / 3f, 1.0f, 0.5f); + memorycolour[2] = ((i) & 0xFF) / 255.0f; + memorycolour[1] = ((i >> 8 ) & 0xFF) / 255.0f; + memorycolour[0] = ((i >> 16 ) & 0xFF) / 255.0f; + renderMessage(memory, memorycolour, 21, 1.0f); + } + + void renderMessage(final String message, final float[] colour, int line, float alpha) { GlStateManager.enableClientState(GL11.GL_VERTEX_ARRAY); - ByteBuffer charBuffer = MemoryUtil.memAlloc(this.message.length() * 270); - int quads = STBEasyFont.stb_easy_font_print(0, 0, this.message, null, charBuffer); + ByteBuffer charBuffer = MemoryUtil.memAlloc(message.length() * 270); + int quads = STBEasyFont.stb_easy_font_print(0, 0, message, null, charBuffer); GlStateManager.vertexPointer(2, GL11.GL_FLOAT, 16, charBuffer); - GlStateManager.color3f(0,0,0); + GlStateManager.enableBlend(); + GL14.glBlendColor(0,0,0, alpha); + GlStateManager.blendFunc(GlStateManager.SourceFactor.CONSTANT_ALPHA, GlStateManager.DestFactor.ONE_MINUS_CONSTANT_ALPHA); + GlStateManager.color3f(colour[0],colour[1],colour[2]); GlStateManager.pushMatrix(); - GlStateManager.translatef(10, window.getFramebufferHeight() - 50, 0); - GlStateManager.scalef(3, 3, 0); + GlStateManager.translatef(10, window.getScaledHeight() - 15 - line * 10, 0); + GlStateManager.scalef(1, 1, 0); GlStateManager.drawArrays(GL11.GL_QUADS, 0, quads * 4); GlStateManager.popMatrix(); MemoryUtil.memFree(charBuffer); } - - private void doMatrix() { - GlStateManager.clear(GL11.GL_DEPTH_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC); - GlStateManager.matrixMode(GL11.GL_PROJECTION); - GlStateManager.loadIdentity(); - GlStateManager.ortho(0.0, window.getFramebufferWidth(), window.getFramebufferHeight(), 0.0, -1.0, 1.0); - GlStateManager.matrixMode(GL11.GL_MODELVIEW); - GlStateManager.loadIdentity(); - } } diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientConfig.java b/src/main/java/net/minecraftforge/fml/client/FMLClientConfig.java deleted file mode 100644 index 728673512..000000000 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.client; - -public class FMLClientConfig -{ - -} diff --git a/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java b/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java deleted file mode 100644 index 34acbf13f..000000000 --- a/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.client; - -import net.minecraft.client.gui.screen.Screen; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -public interface IDisplayableError -{ - @OnlyIn(Dist.CLIENT) - Screen createGui(); -} diff --git a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/src/main/java/net/minecraftforge/fml/client/SplashProgress.java deleted file mode 100644 index 2b94a99d7..000000000 --- a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java +++ /dev/null @@ -1,987 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.client; -/* -import static net.minecraftforge.fml.Logging.SPLASH; -import static net.minecraftforge.fml.Logging.fmlLog; -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL12.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.lang.Thread.UncaughtExceptionHandler; -import java.nio.IntBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Iterator; -import java.util.Properties; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.imageio.ImageIO; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; - -import com.google.common.base.CharMatcher; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.resources.DefaultResourcePack; -import net.minecraft.client.resources.FileResourcePack; -import net.minecraft.client.resources.FolderResourcePack; -import net.minecraft.client.resources.IResource; -import net.minecraft.client.resources.IResourcePack; -import net.minecraft.client.resources.SimpleResource; -import net.minecraft.crash.CrashReport; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.CrashReportExtender; -import net.minecraftforge.fml.common.EnhancedRuntimeException; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.ICrashCallable; -import net.minecraftforge.fml.common.ProgressManager; -import net.minecraftforge.fml.common.ProgressManager.ProgressBar; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.lwjgl.BufferUtils; -import org.lwjgl.LWJGLException; -import org.lwjgl.LWJGLUtil; -import org.lwjgl.opengl.Display; -import org.lwjgl.opengl.Drawable; -import org.lwjgl.opengl.SharedDrawable; -import org.lwjgl.util.glu.GLU; - -/** - * Not a fully fleshed out API, may change in future MC versions. - * However feel free to use and suggest additions. - */ -@SuppressWarnings("serial") -public class SplashProgress -{ -/* - private static Drawable d; - private static volatile boolean pause = false; - private static volatile boolean done = false; - private static Thread thread; - private static volatile Throwable threadError; - private static int angle = 0; - private static final Lock lock = new ReentrantLock(true); - private static SplashFontRenderer fontRenderer; - - private static final IResourcePack mcPack = Minecraft.getMinecraft().mcDefaultResourcePack; - private static final IResourcePack fmlPack = mcPack; - private static IResourcePack miscPack; - - private static Texture fontTexture; - private static Texture logoTexture; - private static Texture forgeTexture; - - private static Properties config; - - private static boolean enabled; - private static boolean rotate; - private static int logoOffset; - private static int backgroundColor; - private static int fontColor; - private static int barBorderColor; - private static int barColor; - private static int barBackgroundColor; - private static boolean showMemory; - private static int memoryGoodColor; - private static int memoryWarnColor; - private static int memoryLowColor; - private static float memoryColorPercent; - private static long memoryColorChangeTime; - static boolean isDisplayVSyncForced = false; - private static final int TIMING_FRAME_COUNT = 200; - private static final int TIMING_FRAME_THRESHOLD = TIMING_FRAME_COUNT * 5 * 1000000; // 5 ms per frame, scaled to nanos - - private static final Semaphore mutex = new Semaphore(1); - */ - - public static void processMessages() { - /* - // workaround for windows requiring messages being processed on the main thread - if (LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_WINDOWS) return null; - // If we can't grab the mutex, the update call is blocked, probably in native code, just skip it and carry on - // We'll get another go next time - if (!SplashProgress.mutex.tryAcquire()) return null; - Display.processMessages(); - SplashProgress.mutex.release(); - */ - } - /* - private static String getString(String name, String def) - { - String value = config.getProperty(name, def); - config.setProperty(name, value); - return value; - } - - private static boolean getBool(String name, boolean def) - { - return Boolean.parseBoolean(getString(name, Boolean.toString(def))); - } - - private static int getInt(String name, int def) - { - return Integer.decode(getString(name, Integer.toString(def))); - } - - private static int getHex(String name, int def) - { - return Integer.decode(getString(name, "0x" + Integer.toString(def, 16).toUpperCase())); - } - - public static void start() - { - File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties"); - - File parent = configFile.getParentFile(); - if (!parent.exists()) - parent.mkdirs(); - - config = new Properties(); - try (Reader r = new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8)) - { - config.load(r); - } - catch(IOException e) - { - fmlLog.info(SPLASH, "Could not load splash.properties, will create a default one"); - } - - enabled = getBool("enabled", true); - rotate = getBool("rotate", false); - showMemory = getBool("showMemory", true); - logoOffset = getInt("logoOffset", 0); - backgroundColor = getHex("background", 0xFFFFFF); - fontColor = getHex("font", 0x000000); - barBorderColor = getHex("barBorder", 0xC0C0C0); - barColor = getHex("bar", 0xCB3D35); - barBackgroundColor = getHex("barBackground", 0xFFFFFF); - memoryGoodColor = getHex("memoryGood", 0x78CB34); - memoryWarnColor = getHex("memoryWarn", 0xE6E84A); - memoryLowColor = getHex("memoryLow", 0xE42F2F); - - final ResourceLocation fontLoc = new ResourceLocation(getString("fontTexture", "textures/font/ascii.png")); - final ResourceLocation logoLoc = new ResourceLocation("textures/gui/title/mojang.png"); - final ResourceLocation forgeLoc = new ResourceLocation(getString("forgeTexture", "fml:textures/gui/forge.png")); - final ResourceLocation forgeFallbackLoc = new ResourceLocation("fml:textures/gui/forge.png"); - - File miscPackFile = new File(Minecraft.getMinecraft().mcDataDir, getString("resourcePackPath", "resources")); - - try (Writer w = new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8)) - { - config.store(w, "Splash screen properties"); - } - catch(IOException e) - { - LOGGER.error("Could not save the splash.properties file", e); - } - - miscPack = createResourcePack(miscPackFile); - - if(!enabled) return; - // getting debug info out of the way, while we still can - CrashReportExtender.registerCrashCallable(new ICrashCallable() - { - @Override - public String call() throws Exception - { - return "' Vendor: '" + glGetString(GL_VENDOR) + - "' Version: '" + glGetString(GL_VERSION) + - "' Renderer: '" + glGetString(GL_RENDERER) + - "'"; - } - - @Override - public String getLabel() - { - return "GL info"; - } - }); - CrashReport report = CrashReport.makeCrashReport(new Throwable(), "Loading screen debug info"); - StringBuilder systemDetailsBuilder = new StringBuilder(); - report.getCategory().appendToStringBuilder(systemDetailsBuilder); - fmlLog.info(SPLASH, systemDetailsBuilder.toString()); - - try - { - d = new SharedDrawable(Display.getDrawable()); - Display.getDrawable().releaseContext(); - d.makeCurrent(); - } - catch (LWJGLException e) - { - LOGGER.error("Error starting SplashProgress:", e); - disableSplash(e); - } - - //Call this ASAP if splash is enabled so that threading doesn't cause issues later - getMaxTextureSize(); - - //Thread mainThread = Thread.currentThread(); - thread = new Thread(new Runnable() - { - private final int barWidth = 400; - private final int barHeight = 20; - private final int textHeight2 = 20; - private final int barOffset = 55; - private long updateTiming; - private long framecount; - @Override - public void run() - { - setGL(); - fontTexture = new Texture(fontLoc, null); - logoTexture = new Texture(logoLoc, null, false); - forgeTexture = new Texture(forgeLoc, forgeFallbackLoc); - glEnable(GL_TEXTURE_2D); - fontRenderer = new SplashFontRenderer(); - glDisable(GL_TEXTURE_2D); - while(!done) - { - framecount++; - ProgressBar first = null, penult = null, last = null; - Iterator i = ProgressManager.barIterator(); - while(i.hasNext()) - { - if(first == null) first = i.next(); - else - { - penult = last; - last = i.next(); - } - } - - glClear(GL_COLOR_BUFFER_BIT); - - // matrix setup - int w = Display.getWidth(); - int h = Display.getHeight(); - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(320 - w/2, 320 + w/2, 240 + h/2, 240 - h/2, -1, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // mojang logo - setColor(backgroundColor); - glEnable(GL_TEXTURE_2D); - logoTexture.bind(); - glBegin(GL_QUADS); - logoTexture.texCoord(0, 0, 0); - glVertex2f(320 - 256, 240 - 256); - logoTexture.texCoord(0, 0, 1); - glVertex2f(320 - 256, 240 + 256); - logoTexture.texCoord(0, 1, 1); - glVertex2f(320 + 256, 240 + 256); - logoTexture.texCoord(0, 1, 0); - glVertex2f(320 + 256, 240 - 256); - glEnd(); - glDisable(GL_TEXTURE_2D); - - // memory usage - if (showMemory) - { - glPushMatrix(); - glTranslatef(320 - (float) barWidth / 2, 20, 0); - drawMemoryBar(); - glPopMatrix(); - } - - // bars - if(first != null) - { - glPushMatrix(); - glTranslatef(320 - (float)barWidth / 2, 310, 0); - drawBar(first); - if(penult != null) - { - glTranslatef(0, barOffset, 0); - drawBar(penult); - } - if(last != null) - { - glTranslatef(0, barOffset, 0); - drawBar(last); - } - glPopMatrix(); - } - - angle += 1; - - // forge logo - glColor4f(1, 1, 1, 1); - float fw = (float)forgeTexture.getWidth() / 2; - float fh = (float)forgeTexture.getHeight() / 2; - if(rotate) - { - float sh = Math.max(fw, fh); - glTranslatef(320 + w/2 - sh - logoOffset, 240 + h/2 - sh - logoOffset, 0); - glRotatef(angle, 0, 0, 1); - } - else - { - glTranslatef(320 + w/2 - fw - logoOffset, 240 + h/2 - fh - logoOffset, 0); - } - int f = (angle / 5) % forgeTexture.getFrames(); - glEnable(GL_TEXTURE_2D); - forgeTexture.bind(); - glBegin(GL_QUADS); - forgeTexture.texCoord(f, 0, 0); - glVertex2f(-fw, -fh); - forgeTexture.texCoord(f, 0, 1); - glVertex2f(-fw, fh); - forgeTexture.texCoord(f, 1, 1); - glVertex2f(fw, fh); - forgeTexture.texCoord(f, 1, 0); - glVertex2f(fw, -fh); - glEnd(); - glDisable(GL_TEXTURE_2D); - - // We use mutex to indicate safely to the main thread that we're taking the display global lock - // So the main thread can skip processing messages while we're updating. - // There are system setups where this call can pause for a while, because the GL implementation - // is trying to impose a framerate or other thing is occurring. Without the mutex, the main - // thread would delay waiting for the same global display lock - mutex.acquireUninterruptibly(); - long updateStart = System.nanoTime(); - Display.update(); - // As soon as we're done, we release the mutex. The other thread can now ping the processmessages - // call as often as it wants until we get get back here again - long dur = System.nanoTime() - updateStart; - if (framecount < TIMING_FRAME_COUNT) { - updateTiming += dur; - } - mutex.release(); - if(pause) - { - clearGL(); - setGL(); - } - // Such a hack - if the time taken is greater than 10 milliseconds, we're gonna guess that we're on a - // system where vsync is forced through the swapBuffers call - so we have to force a sleep and let the - // loading thread have a turn - some badly designed mods access Keyboard and therefore GlobalLock.lock - // during splash screen, and mutex against the above Display.update call as a result. - // 4 milliseconds is a guess - but it should be enough to trigger in most circumstances. (Maybe if - // 240FPS is possible, this won't fire?) - if (framecount >= TIMING_FRAME_COUNT && updateTiming > TIMING_FRAME_THRESHOLD) { - if (!isDisplayVSyncForced) - { - isDisplayVSyncForced = true; - fmlLog.info(SPLASH,"Using alternative sync timing : {} frames of Display.update took {} nanos", TIMING_FRAME_COUNT, updateTiming); - } - try { Thread.sleep(16); } catch (InterruptedException ie) {} - } else - { - if (framecount ==TIMING_FRAME_COUNT) { - fmlLog.info("Using sync timing. {} frames of Display.update took {} nanos", TIMING_FRAME_COUNT, updateTiming); - } - Display.sync(100); - } - } - clearGL(); - } - - private void setColor(int color) - { - glColor3ub((byte)((color >> 16) & 0xFF), (byte)((color >> 8) & 0xFF), (byte)(color & 0xFF)); - } - - private void drawBox(int w, int h) - { - glBegin(GL_QUADS); - glVertex2f(0, 0); - glVertex2f(0, h); - glVertex2f(w, h); - glVertex2f(w, 0); - glEnd(); - } - - private void drawBar(ProgressBar b) - { - glPushMatrix(); - // title - message - setColor(fontColor); - glScalef(2, 2, 1); - glEnable(GL_TEXTURE_2D); - fontRenderer.drawString(b.getTitle() + " - " + b.getMessage(), 0, 0, 0x000000); - glDisable(GL_TEXTURE_2D); - glPopMatrix(); - // border - glPushMatrix(); - glTranslatef(0, textHeight2, 0); - setColor(barBorderColor); - drawBox(barWidth, barHeight); - // interior - setColor(barBackgroundColor); - glTranslatef(1, 1, 0); - drawBox(barWidth - 2, barHeight - 2); - // slidy part - setColor(barColor); - int step = b.getStep(); - drawBox((barWidth - 2) * (step + 1) / (b.getTotalSteps() + 1), barHeight - 2); // Step can sometimes be 0. - // progress text - String progress = "" + step + "/" + b.getTotalSteps(); - glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0); - setColor(fontColor); - glScalef(2, 2, 1); - glEnable(GL_TEXTURE_2D); - fontRenderer.drawString(progress, 0, 0, 0x000000); - glPopMatrix(); - } - - private void drawMemoryBar() { - int maxMemory = bytesToMb(Runtime.getRuntime().maxMemory()); - int totalMemory = bytesToMb(Runtime.getRuntime().totalMemory()); - int freeMemory = bytesToMb(Runtime.getRuntime().freeMemory()); - int usedMemory = totalMemory - freeMemory; - float usedMemoryPercent = usedMemory / (float) maxMemory; - - glPushMatrix(); - // title - message - setColor(fontColor); - glScalef(2, 2, 1); - glEnable(GL_TEXTURE_2D); - fontRenderer.drawString("Memory Used / Total", 0, 0, 0x000000); - glDisable(GL_TEXTURE_2D); - glPopMatrix(); - // border - glPushMatrix(); - glTranslatef(0, textHeight2, 0); - setColor(barBorderColor); - drawBox(barWidth, barHeight); - // interior - setColor(barBackgroundColor); - glTranslatef(1, 1, 0); - drawBox(barWidth - 2, barHeight - 2); - // slidy part - - long time = System.currentTimeMillis(); - if (usedMemoryPercent > memoryColorPercent || (time - memoryColorChangeTime > 1000)) - { - memoryColorChangeTime = time; - memoryColorPercent = usedMemoryPercent; - } - - int memoryBarColor; - if (memoryColorPercent < 0.75f) - { - memoryBarColor = memoryGoodColor; - } - else if (memoryColorPercent < 0.85f) - { - memoryBarColor = memoryWarnColor; - } - else - { - memoryBarColor = memoryLowColor; - } - setColor(memoryLowColor); - glPushMatrix(); - glTranslatef((barWidth - 2) * (totalMemory) / (maxMemory) - 2, 0, 0); - drawBox(2, barHeight - 2); - glPopMatrix(); - setColor(memoryBarColor); - drawBox((barWidth - 2) * (usedMemory) / (maxMemory), barHeight - 2); - - // progress text - String progress = getMemoryString(usedMemory) + " / " + getMemoryString(maxMemory); - glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0); - setColor(fontColor); - glScalef(2, 2, 1); - glEnable(GL_TEXTURE_2D); - fontRenderer.drawString(progress, 0, 0, 0x000000); - glPopMatrix(); - } - - private String getMemoryString(int memory) - { - return StringUtils.leftPad(Integer.toString(memory), 4, ' ') + " MB"; - } - - private void setGL() - { - lock.lock(); - try - { - Display.getDrawable().makeCurrent(); - } - catch (LWJGLException e) - { - LOGGER.error("Error setting GL context:", e); - throw new RuntimeException(e); - } - glClearColor((float)((backgroundColor >> 16) & 0xFF) / 0xFF, (float)((backgroundColor >> 8) & 0xFF) / 0xFF, (float)(backgroundColor & 0xFF) / 0xFF, 1); - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - private void clearGL() - { - Minecraft mc = Minecraft.getMinecraft(); - mc.displayWidth = Display.getWidth(); - mc.displayHeight = Display.getHeight(); - mc.resize(mc.displayWidth, mc.displayHeight); - glClearColor(1, 1, 1, 1); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, .1f); - try - { - Display.getDrawable().releaseContext(); - } - catch (LWJGLException e) - { - LOGGER.error("Error releasing GL context:", e); - throw new RuntimeException(e); - } - finally - { - lock.unlock(); - } - } - }); - thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() - { - @Override - public void uncaughtException(Thread t, Throwable e) - { - LOGGER.error("Splash thread Exception", e); - threadError = e; - } - }); - thread.start(); - checkThreadState(); - } - - private static int max_texture_size = -1; - public static int getMaxTextureSize() - { - if (max_texture_size != -1) return max_texture_size; - for (int i = 0x4000; i > 0; i >>= 1) - { - GlStateManager.glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, i, i, 0, GL_RGBA, GL_UNSIGNED_BYTE, null); - if (GlStateManager.glGetTexLevelParameteri(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) != 0) - { - max_texture_size = i; - return i; - } - } - return -1; - } - - private static void checkThreadState() - { - if(thread.getState() == Thread.State.TERMINATED || threadError != null) - { - throw new IllegalStateException("Splash thread", threadError); - } - } - /** - * Call before you need to explicitly modify GL context state during loading. - * Resource loading doesn't usually require this call. - * Call {@link #resume()} when you're done. - * @deprecated not a stable API, will break, don't use this yet - * / - @Deprecated - public static void pause() - { - if(!enabled) return; - checkThreadState(); - pause = true; - lock.lock(); - try - { - d.releaseContext(); - Display.getDrawable().makeCurrent(); - } - catch (LWJGLException e) - { - LOGGER.error("Error setting GL context:", e); - throw new RuntimeException(e); - } - } - - /** - * @deprecated not a stable API, will break, don't use this yet - * / - @Deprecated - public static void resume() - { - if(!enabled) return; - checkThreadState(); - pause = false; - try - { - Display.getDrawable().releaseContext(); - d.makeCurrent(); - } - catch (LWJGLException e) - { - LOGGER.error("Error releasing GL context:", e); - throw new RuntimeException(e); - } - lock.unlock(); - } - - public static void finish() - { - if(!enabled) return; - try - { - checkThreadState(); - done = true; - thread.join(); - glFlush(); // process any remaining GL calls before releaseContext (prevents missing textures on mac) - d.releaseContext(); - Display.getDrawable().makeCurrent(); - fontTexture.delete(); - logoTexture.delete(); - forgeTexture.delete(); - } - catch (Exception e) - { - LOGGER.error("Error finishing SplashProgress:", e); - disableSplash(e); - } - } - - private static boolean disableSplash(Exception e) - { - if (disableSplash()) - { - throw new EnhancedRuntimeException(e) - { - @Override - protected void printStackTrace(WrappedPrintStream stream) - { - stream.println("SplashProgress has detected a error loading Minecraft."); - stream.println("This can sometimes be caused by bad video drivers."); - stream.println("We have automatically disabled the new Splash Screen in config/splash.properties."); - stream.println("Try reloading minecraft before reporting any errors."); - } - }; - } - else - { - throw new EnhancedRuntimeException(e) - { - @Override - protected void printStackTrace(WrappedPrintStream stream) - { - stream.println("SplashProgress has detected a error loading Minecraft."); - stream.println("This can sometimes be caused by bad video drivers."); - stream.println("Please try disabling the new Splash Screen in config/splash.properties."); - stream.println("After doing so, try reloading minecraft before reporting any errors."); - } - }; - } - } - - private static boolean disableSplash() - { - File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties"); - File parent = configFile.getParentFile(); - if (!parent.exists()) - parent.mkdirs(); - - enabled = false; - config.setProperty("enabled", "false"); - - try (Writer w = new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8)) - { - config.store(w, "Splash screen properties"); - } - catch(IOException e) - { - LOGGER.error("Could not save the splash.properties file", e); - return false; - } - return true; - } - - private static IResourcePack createResourcePack(File file) - { - if(file.isDirectory()) - { - return new FolderResourcePack(file); - } - else - { - return new FileResourcePack(file); - } - } - - private static final IntBuffer buf = BufferUtils.createIntBuffer(4 * 1024 * 1024); - - // From FontRenderer.renderCharAtPos - private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000"; - private static final CharMatcher DISALLOWED_CHAR_MATCHER = CharMatcher.anyOf(ALLOWED_CHARS).negate(); - - public static String stripSpecialChars(String message) - { - // We can't handle many unicode points in the splash renderer - return DISALLOWED_CHAR_MATCHER.removeFrom(net.minecraft.util.StringUtils.stripControlCodes(message)); - } - - - @SuppressWarnings("unused") - private static class Texture - { - private final ResourceLocation location; - private final int name; - private final int width; - private final int height; - private final int frames; - private final int size; - - public Texture(ResourceLocation location, @Nullable ResourceLocation fallback) - { - this(location, fallback, true); - } - - public Texture(ResourceLocation location, @Nullable ResourceLocation fallback, boolean allowRP) - { - InputStream s = null; - try - { - this.location = location; - s = open(location, fallback, allowRP); - ImageInputStream stream = ImageIO.createImageInputStream(s); - Iterator readers = ImageIO.getImageReaders(stream); - if(!readers.hasNext()) throw new IOException("No suitable reader found for image" + location); - ImageReader reader = readers.next(); - reader.setInput(stream); - int frames = reader.getNumImages(true); - BufferedImage[] images = new BufferedImage[frames]; - for(int i = 0; i < frames; i++) - { - images[i] = reader.read(i); - } - reader.dispose(); - width = images[0].getWidth(); - int height = images[0].getHeight(); - // Animation strip - if (height > width && height % width == 0) - { - frames = height / width; - BufferedImage original = images[0]; - height = width; - images = new BufferedImage[frames]; - for (int i = 0; i < frames; i++) - { - images[i] = original.getSubimage(0, i * height, width, height); - } - } - this.frames = frames; - this.height = height; - int size = 1; - while((size / width) * (size / height) < frames) size *= 2; - this.size = size; - glEnable(GL_TEXTURE_2D); - synchronized(SplashProgress.class) - { - name = glGenTextures(); - glBindTexture(GL_TEXTURE_2D, name); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null); - checkGLError("Texture creation"); - for(int i = 0; i * (size / width) < frames; i++) - { - for(int j = 0; i * (size / width) + j < frames && j < size / width; j++) - { - buf.clear(); - BufferedImage image = images[i * (size / width) + j]; - for(int k = 0; k < height; k++) - { - for(int l = 0; l < width; l++) - { - buf.put(image.getRGB(l, k)); - } - } - buf.position(0).limit(width * height); - glTexSubImage2D(GL_TEXTURE_2D, 0, j * width, i * height, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf); - checkGLError("Texture uploading"); - } - } - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - } - catch(IOException e) - { - LOGGER.error("Error reading texture from file: {}", location, e); - throw new RuntimeException(e); - } - finally - { - IOUtils.closeQuietly(s); - } - } - - public ResourceLocation getLocation() - { - return location; - } - - public int getName() - { - return name; - } - - public int getWidth() - { - return width; - } - - public int getHeight() - { - return height; - } - - public int getFrames() - { - return frames; - } - - public int getSize() - { - return size; - } - - public void bind() - { - glBindTexture(GL_TEXTURE_2D, name); - } - - public void delete() - { - glDeleteTextures(name); - } - - public float getU(int frame, float u) - { - return width * (frame % (size / width) + u) / size; - } - - public float getV(int frame, float v) - { - return height * (frame / (size / width) + v) / size; - } - - public void texCoord(int frame, float u, float v) - { - glTexCoord2f(getU(frame, u), getV(frame, v)); - } - } - - private static class SplashFontRenderer extends FontRenderer - { - public SplashFontRenderer() - { - super(Minecraft.getMinecraft().gameSettings, fontTexture.getLocation(), null, false); - super.onResourceManagerReload(null); - } - - @Override - protected void bindTexture(@Nonnull ResourceLocation location) - { - if(location != locationFontTexture) throw new IllegalArgumentException(); - fontTexture.bind(); - } - - @Nonnull - @Override - protected IResource getResource(@Nonnull ResourceLocation location) throws IOException - { - DefaultResourcePack pack = Minecraft.getMinecraft().mcDefaultResourcePack; - return new SimpleResource(pack.getPackName(), location, pack.getInputStream(location), null, null); - } - } - - public static void drawVanillaScreen(TextureManager renderEngine) throws LWJGLException - { - if(!enabled) - { - Minecraft.getMinecraft().drawSplashScreen(renderEngine); - } - } - - public static void clearVanillaResources(TextureManager renderEngine, ResourceLocation mojangLogo) - { - if(!enabled) - { - renderEngine.deleteTexture(mojangLogo); - } - } - - public static void checkGLError(String where) - { - int err = glGetError(); - if (err != 0) - { - throw new IllegalStateException(where + ": " + GLU.gluErrorString(err)); - } - } - - private static InputStream open(ResourceLocation loc, @Nullable ResourceLocation fallback, boolean allowResourcePack) throws IOException - { - if (!allowResourcePack) - return mcPack.getInputStream(loc); - - if(miscPack.resourceExists(loc)) - { - return miscPack.getInputStream(loc); - } - else if(fmlPack.resourceExists(loc)) - { - return fmlPack.getInputStream(loc); - } - else if(!mcPack.resourceExists(loc) && fallback != null) - { - return open(fallback, null, true); - } - return mcPack.getInputStream(loc); - } - - private static int bytesToMb(long bytes) - { - return (int) (bytes / 1024L / 1024L); - } - */ -} diff --git a/src/main/java/net/minecraftforge/fml/common/progress/IProgressBarTracker.java b/src/main/java/net/minecraftforge/fml/common/progress/IProgressBarTracker.java deleted file mode 100644 index 1a3fda395..000000000 --- a/src/main/java/net/minecraftforge/fml/common/progress/IProgressBarTracker.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.common.progress; - -public interface IProgressBarTracker -{ - default void onBarCreated(ProgressBar bar) {} - - default void onStepStarted(ProgressBar bar, int step, String message) {} - - default void onStepFinished(ProgressBar bar, int step, String message) {} - - default void onBarFinished(ProgressBar bar, int step, String message) {} -} diff --git a/src/main/java/net/minecraftforge/fml/common/progress/ProgressBar.java b/src/main/java/net/minecraftforge/fml/common/progress/ProgressBar.java deleted file mode 100644 index 554a70d87..000000000 --- a/src/main/java/net/minecraftforge/fml/common/progress/ProgressBar.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.common.progress; - -import net.minecraftforge.fml.common.ClassNameUtils; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.function.Function; - -/** - * Not a fully fleshed out API, may change in future MC versions. - * However feel free to use and suggest additions. - */ -public final class ProgressBar implements AutoCloseable -{ - private final String title; - private final int totalSteps; - private final Function stripChars; - private final IProgressBarTracker tracker; - private volatile int step = 0; - private volatile String message = ""; - - public ProgressBar(String title, int totalSteps, Function stripChars, IProgressBarTracker tracker) - { - this.title = title; - this.totalSteps = totalSteps; - this.stripChars = stripChars; - this.tracker = tracker; - this.tracker.onBarCreated(this); - } - - public void step(Class classToName, String... extra) - { - step(ClassNameUtils.shortName(classToName) + String.join(" ", extra)); - } - - public synchronized void step(String newMessage) - { - if (step > 0) - { - tracker.onStepFinished(this, step, message); - } - step++; - message = stripChars.apply(newMessage); - tracker.onStepStarted(this, step, message);; - } - - /** - * Get the current step and message. - */ - public synchronized Pair getStepAndMessage() - { - return Pair.of(step, message); - } - - /** - * Get the total number of steps. - */ - public int getTotalSteps() - { - return totalSteps; - } - - /** - * Get the current title. - */ - public String getTitle() - { - return title; - } - - @Override - public synchronized void close() - { - if (step > 0) - { - tracker.onStepFinished(this, step, message); - } - tracker.onBarFinished(this, step, message); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/progress/StartupProgressBarTracker.java b/src/main/java/net/minecraftforge/fml/common/progress/StartupProgressBarTracker.java deleted file mode 100644 index dfb797f1b..000000000 --- a/src/main/java/net/minecraftforge/fml/common/progress/StartupProgressBarTracker.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.common.progress; - -import com.google.common.base.Stopwatch; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.client.SplashProgress; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.message.MessageFormatMessage; - -import javax.annotation.Nullable; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import static net.minecraftforge.fml.Logging.SPLASH; - -class StartupProgressBarTracker implements IProgressBarTracker -{ - private static final Logger LOGGER = LogManager.getLogger(); - private static final List bars = new CopyOnWriteArrayList<>(); - - private final boolean timeEachStep; - private final int steps; - private final Stopwatch stopwatch; - @Nullable - private Stopwatch stepStopwatch; - private String logPrefix = ""; - - StartupProgressBarTracker(boolean timeEachStep, int steps) - { - this.timeEachStep = timeEachStep; - this.steps = steps; - this.stopwatch = Stopwatch.createUnstarted(); - } - - @Override - public void onBarCreated(ProgressBar bar) - { - int depth = bars.size(); - logPrefix = StringUtils.repeat(" ", depth); - bars.add(bar); - DistExecutor.runWhenOn(Dist.CLIENT, ()-> SplashProgress::processMessages); - } - - @Override - public void onStepStarted(ProgressBar bar, int step, String message) - { - if (step == 1) - { - if (steps > 1) - { - LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Starting: {1}", logPrefix, bar.getTitle())); - if (timeEachStep) - { - stepStopwatch = Stopwatch.createStarted(); - } - } - else - { - LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Starting: {1} - {2}", logPrefix, bar.getTitle(), message)); - } - stopwatch.start(); - } - if (stepStopwatch != null) - { - LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0} Bar Step: {1} - {2} - starting", logPrefix, bar.getTitle(), message)); - stepStopwatch.reset(); - stepStopwatch.start(); - } - } - - @Override - public void onStepFinished(ProgressBar bar, int step, String message) - { - if (stepStopwatch != null) - { - stepStopwatch.stop(); - LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0} Bar Step: {1} - {2} - took {3}", logPrefix, bar.getTitle(), message, stepStopwatch)); - } - } - - @Override - public void onBarFinished(ProgressBar bar, int step, String message) - { - if (steps > 0) - { - stopwatch.stop(); - bars.remove(bar); - if (steps > 1) - { - LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Finished: {1} - took {2}", logPrefix, bar.getTitle(), stopwatch)); - } - else - { - LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Finished: {1} - {2} - took {3}", logPrefix, bar.getTitle(), message, stopwatch)); - } - DistExecutor.runWhenOn(Dist.CLIENT, () -> SplashProgress::processMessages); - } - } - - /** - * Internal use only. - */ - public static Iterator barIterator() - { - return bars.iterator(); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/progress/StartupProgressManager.java b/src/main/java/net/minecraftforge/fml/common/progress/StartupProgressManager.java deleted file mode 100644 index 39efe6cc6..000000000 --- a/src/main/java/net/minecraftforge/fml/common/progress/StartupProgressManager.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.common.progress; - -import net.minecraftforge.fml.SidedProvider; - -import java.util.Iterator; -import java.util.function.Consumer; -import java.util.function.Function; - -public class StartupProgressManager -{ - private static final Function stripChars = SidedProvider.STRIPCHARS.get(); - - public static void start(String title, int steps, Consumer task) - { - start(title, steps, false, task); - } - - public static void start(String title, int steps, boolean timeEachStep, Consumer task) - { - try (ProgressBar bar = start(title, steps, timeEachStep)) - { - task.accept(bar); - } - } - - public static ProgressBar start(String title, int steps) - { - return start(title, steps, false); - } - - public static ProgressBar start(String title, int steps, boolean timeEachStep) - { - StartupProgressBarTracker tracker = new StartupProgressBarTracker(timeEachStep, steps); - return new ProgressBar(title, steps, stripChars, tracker); - } - - /** - * Internal use only. - */ - public static Iterator barIterator() - { - return StartupProgressBarTracker.barIterator(); - } -} diff --git a/src/main/java/net/minecraftforge/fml/network/IContainerFactory.java b/src/main/java/net/minecraftforge/fml/network/IContainerFactory.java index 1ba71d86e..f66fb9620 100644 --- a/src/main/java/net/minecraftforge/fml/network/IContainerFactory.java +++ b/src/main/java/net/minecraftforge/fml/network/IContainerFactory.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.network; import net.minecraft.entity.player.PlayerInventory; diff --git a/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java b/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java index d54217d47..3ea725344 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java @@ -42,7 +42,7 @@ public class ServerModLoader SidedProvider.setServer(()->dedicatedServer); LogicalSidedProvider.setServer(()->dedicatedServer); LanguageHook.loadForgeAndMCLangs(); - ModLoader.get().gatherAndInitializeMods(); + ModLoader.get().gatherAndInitializeMods(null); ModLoader.get().loadMods(Runnable::run, (a)->{}, (a)->{}); }