From 9714512c3191e5f12d29852798ecc5c572490071 Mon Sep 17 00:00:00 2001 From: Paint_Ninja Date: Fri, 16 Aug 2024 22:49:11 +0100 Subject: [PATCH] [1.21.1] ModLoading cleanup and optimisations (#10052) --- .../minecraftforge/fml/DeferredWorkQueue.java | 6 +- .../net/minecraftforge/fml/InterModComms.java | 16 +- .../net/minecraftforge/fml/ModContainer.java | 7 +- .../java/net/minecraftforge/fml/ModList.java | 31 +- .../net/minecraftforge/fml/ModLoader.java | 79 ++-- .../minecraftforge/fml/ModLoadingState.java | 5 +- .../minecraftforge/fml/ModStateManager.java | 10 +- .../minecraftforge/fml/ModWorkManager.java | 38 +- .../net/minecraftforge/fml/OptionalMod.java | 6 +- .../fml/config/ConfigFileTypeHandler.java | 20 +- .../fml/config/ConfigTracker.java | 12 +- .../minecraftforge/fml/config/ModConfig.java | 1 - .../fml/earlydisplay/SimpleFont.java | 2 +- .../common/asm/CapabilityTokenSubclass.java | 10 +- .../common/asm/ObjectHolderDefinalize.java | 13 +- .../fml/common/asm/RuntimeEnumExtender.java | 32 +- .../minecraftforge/fml/loading/FMLLoader.java | 26 +- .../fml/loading/FMLServiceProvider.java | 11 +- .../fml/loading/LoadingModList.java | 10 +- .../fml/loading/MCPNamingService.java | 2 +- .../fml/loading/MavenCoordinateResolver.java | 2 +- .../minecraftforge/fml/loading/ModSorter.java | 38 +- .../fml/loading/RuntimeDistCleaner.java | 4 +- .../fml/loading/StringSubstitutor.java | 13 +- .../fml/loading/UniqueModListBuilder.java | 23 +- .../fml/loading/VersionSupportMatrix.java | 52 ++- .../fml/loading/log4j/ForgeHighlight.java | 5 +- .../moddiscovery/AbstractModProvider.java | 8 +- .../moddiscovery/BackgroundScanHandler.java | 11 +- .../moddiscovery/ClasspathLocator.java | 11 +- .../fml/loading/moddiscovery/CoreModFile.java | 2 +- .../JarInJarDependencyLocator.java | 18 +- .../moddiscovery/MinecraftLocator.java | 8 +- .../loading/moddiscovery/ModDiscoverer.java | 25 +- .../fml/loading/moddiscovery/ModFile.java | 3 +- .../fml/loading/moddiscovery/ModFileInfo.java | 11 +- .../fml/loading/moddiscovery/ModInfo.java | 340 ++++++++---------- .../loading/moddiscovery/ModValidator.java | 6 +- .../moddiscovery/NightConfigWrapper.java | 51 ++- .../fml/loading/moddiscovery/Scanner.java | 23 +- .../fml/loading/targets/ArgumentList.java | 10 +- .../targets/CommonDevLaunchHandler.java | 2 +- .../loading/targets/CommonLaunchHandler.java | 8 +- .../targets/ForgeDevLaunchHandler.java | 10 +- .../fml/loading/targets/ForgeDevLocator.java | 14 +- .../targets/ForgeProdLaunchHandler.java | 6 +- .../targets/ForgeUserdevLaunchHandler.java | 10 +- .../loading/targets/ForgeUserdevLocator.java | 2 +- .../StronglyConnectedComponentDetector.java | 3 +- .../FMLJavaModLanguageProvider.java | 17 +- .../fml/javafmlmod/FMLModContainer.java | 4 +- .../fml/lowcodemod/LowCodeModContainer.java | 9 +- .../MinecraftModLanguageProvider.java | 4 - .../client/ClientBrandRetriever.java.patch | 2 +- .../client/gui/screens/TitleScreen.java.patch | 4 +- .../server/MinecraftServer.java.patch | 2 +- settings.gradle | 4 +- .../client/ForgeHooksClient.java | 79 ++-- .../client/ItemDecoratorHandler.java | 5 +- .../client/PresetEditorManager.java | 8 +- .../client/RecipeBookManager.java | 14 +- .../client/event/ForgeEventFactoryClient.java | 3 +- .../RegisterRecipeBookCategoriesEvent.java | 13 +- .../client/textures/ForgeTextureMetadata.java | 36 +- .../TextureAtlasSpriteLoaderManager.java | 16 +- .../minecraftforge/common/BiomeManager.java | 2 +- .../common/CreativeModeTabRegistry.java | 7 +- .../common/ForgeConfigSpec.java | 10 +- .../net/minecraftforge/common/ForgeI18n.java | 4 +- .../common/ForgeInternalHandler.java | 10 +- .../net/minecraftforge/common/ForgeMod.java | 4 +- .../common/ForgeSpawnEggItem.java | 4 +- .../common/VillagerTradingManager.java | 20 +- .../common/WorldWorkerManager.java | 2 +- .../common/command/EntitySelectorManager.java | 11 +- .../common/crafting/ConditionalRecipe.java | 11 +- .../crafting/SimpleCraftingContainer.java | 2 +- .../ingredients/CompoundIngredient.java | 2 +- .../ingredients/PartialNBTIngredient.java | 2 +- .../common/data/SoundDefinitionsProvider.java | 4 +- .../common/data/SpriteSourceProvider.java | 6 +- .../common/util/CenterChunkPosComparator.java | 4 +- .../common/util/ConcatenatedListView.java | 2 +- .../minecraftforge/common/util/HexDumper.java | 2 +- .../common/util/LevelCapabilityData.java | 2 +- .../common/util/MutableHashedLinkedMap.java | 6 +- .../common/util/SortedProperties.java | 3 +- .../minecraftforge/common/util/TextTable.java | 4 +- .../common/util/TransformationHelper.java | 19 +- .../world/BiomeGenerationSettingsBuilder.java | 8 +- .../internal/BrandingControl.java | 62 ++-- .../internal/ForgeBindings.java | 26 +- .../logging/CrashReportExtender.java | 2 +- .../network/ChannelListManager.java | 8 +- .../registries/ForgeRegistry.java | 69 ++-- .../minecraftforge/registries/GameData.java | 4 +- .../registries/NamespacedWrapper.java | 20 +- .../registries/ObjectHolderRegistry.java | 11 +- .../registries/RegistryBuilder.java | 29 +- .../registries/RegistryManager.java | 15 +- .../registries/RegistryObject.java | 5 +- 101 files changed, 837 insertions(+), 841 deletions(-) diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java b/fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java index 8b43e4c83a..5db7d4b21a 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java @@ -57,7 +57,9 @@ public class DeferredWorkQueue LOGGER.debug(LOADING, "Dispatching synchronous work for work queue {}: {} jobs", modLoadingStage, tasks.size()); RuntimeException aggregate = new RuntimeException(); Stopwatch timer = Stopwatch.createStarted(); - tasks.forEach(t -> makeRunnable(t, Runnable::run, aggregate)); + for (TaskInfo t : tasks) { + makeRunnable(t, Runnable::run, aggregate); + } timer.stop(); if (aggregate.getSuppressed().length > 0) { LOGGER.fatal( @@ -114,7 +116,7 @@ public class DeferredWorkQueue return future; } - private static class TaskInfo { + private static final class TaskInfo { private final ModContainer owner; private Runnable task; private CompletableFuture future; diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java b/fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java index b0e03885f5..92b31df72f 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/InterModComms.java @@ -61,7 +61,7 @@ public class InterModComms } } - private static ConcurrentMap> containerQueues = new ConcurrentHashMap<>(); + private static final ConcurrentMap> containerQueues = new ConcurrentHashMap<>(); /** * Send IMC to remote. Sender will default to the active modcontainer, or minecraft if not. @@ -115,16 +115,14 @@ public class InterModComms return getMessages(modId, s->Boolean.TRUE); } - private static class QueueFilteringSpliterator implements Spliterator - { - private final ConcurrentLinkedQueue queue; - private final Predicate methodFilter; - private final Iterator iterator; + private record QueueFilteringSpliterator( + ConcurrentLinkedQueue queue, + Predicate methodFilter, + Iterator iterator + ) implements Spliterator { public QueueFilteringSpliterator(final ConcurrentLinkedQueue queue, final Predicate methodFilter) { - this.queue = queue; - this.iterator = queue.iterator(); - this.methodFilter = methodFilter; + this(queue, methodFilter, queue.iterator()); } @Override diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java index 7c872074b9..0b07d18455 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModContainer.java @@ -45,7 +45,7 @@ public abstract class ModContainer protected final IModInfo modInfo; protected ModLoadingStage modLoadingStage; protected Supplier contextExtension; - protected final Map activityMap = new HashMap<>(); + protected final Map activityMap = new EnumMap<>(ModLoadingStage.class); protected final Map>, Supplier> extensionPoints = new IdentityHashMap<>(); protected final EnumMap configs = new EnumMap<>(ModConfig.Type.class); @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @@ -168,7 +168,10 @@ public abstract class ModContainer } public void dispatchConfigEvent(IConfigEvent event) { - configHandler.ifPresent(configHandler->configHandler.accept(event)); + var handler = configHandler.orElse(null); + if (handler != null) { + handler.accept(event); + } } /** diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java index 057a071829..e2ffdfa997 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java @@ -74,11 +74,12 @@ public class ModList } private String fileToLine(IModFile mf) { + var mainMod = mf.getModInfos().getFirst(); return String.format(Locale.ENGLISH, "%-50.50s|%-30.30s|%-30.30s|%-20.20s|%-10.10s|Manifest: %s", mf.getFileName(), - mf.getModInfos().get(0).getDisplayName(), - mf.getModInfos().get(0).getModId(), - mf.getModInfos().get(0).getVersion(), - getModContainerState(mf.getModInfos().get(0).getModId()), + mainMod.getDisplayName(), + mainMod.getModId(), + mainMod.getVersion(), + getModContainerState(mainMod.getModId()), ((ModFileInfo)mf.getModFileInfo()).getCodeSigningFingerprint().orElse("NOSIGNATURE")); } private String crashReport() { @@ -95,14 +96,6 @@ public class ModList return INSTANCE; } - private static ForkJoinWorkerThread newForkJoinWorkerThread(ForkJoinPool pool) { - ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); - thread.setName("modloading-worker-" + thread.getPoolIndex()); - // The default sets it to the SystemClassloader, so copy the current one. - thread.setContextClassLoader(Thread.currentThread().getContextClassLoader()); - return thread; - } - public List getModFiles() { return modFiles; @@ -131,16 +124,18 @@ public class ModList CompletableFuture cf = new CompletableFuture<>(); final RuntimeException accumulator = new RuntimeException(); cf.completeExceptionally(accumulator); - throwables.forEach(exception -> { + for (Throwable exception : throwables) { if (exception instanceof CompletionException) { exception = exception.getCause(); } - if (exception.getSuppressed().length!=0) { - Arrays.stream(exception.getSuppressed()).forEach(accumulator::addSuppressed); + if (exception.getSuppressed().length != 0) { + for (Throwable throwable : exception.getSuppressed()) { + accumulator.addSuppressed(throwable); + } } else { accumulator.addSuppressed(exception); } - }); + } return cf; } } @@ -148,11 +143,11 @@ public class ModList static CompletableFuture>> gather(List> futures) { List> list = new ArrayList<>(futures.size()); CompletableFuture[] results = new CompletableFuture[futures.size()]; - futures.forEach(future -> { + for (var future : futures) { int i = list.size(); list.add(null); results[i] = future.whenComplete((result, exception) -> list.set(i, new AbstractMap.SimpleImmutableEntry<>(result, exception))); - }); + } return CompletableFuture.allOf(results).handle((r, th)->null).thenApply(res -> list); } diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java index 58b61679fa..5d61beb0ad 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -77,13 +77,13 @@ import static net.minecraftforge.fml.Logging.LOADING; public class ModLoader { private static final Logger LOGGER = LogManager.getLogger(); - private static ModLoader INSTANCE; private final LoadingModList loadingModList; private final List loadingExceptions; + private final Set erroredModInfos; private final List loadingWarnings; private final ModStateManager stateManager; - private boolean loadingStateValid; + private static boolean loadingStateValid; @SuppressWarnings("OptionalUsedAsFieldOrParameterType") private final Optional> statusConsumer = StartupNotificationManager.modLoaderConsumer(); private final Set completedStates = new HashSet<>(); @@ -91,7 +91,6 @@ public class ModLoader private ModLoader() { - INSTANCE = this; this.loadingModList = FMLLoader.getLoadingModList(); this.loadingExceptions = this.loadingModList.getErrors().stream() .flatMap(ModLoadingException::fromEarlyException) @@ -99,24 +98,32 @@ public class ModLoader this.loadingWarnings = this.loadingModList.getBrokenFiles().stream() .map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName())) .collect(Collectors.toList()); + if (this.loadingExceptions.isEmpty()) { + this.erroredModInfos = Collections.emptySet(); + } else { + this.erroredModInfos = Collections.newSetFromMap(new IdentityHashMap<>()); + this.erroredModInfos.addAll(this.loadingExceptions.stream().map(ModLoadingException::getModInfo).toList()); + } this.loadingModList.getModFiles().stream() .filter(ModFileInfo::missingLicense) - .filter(modFileInfo -> modFileInfo.getMods().stream().noneMatch(thisModInfo -> this.loadingExceptions.stream().map(ModLoadingException::getModInfo).anyMatch(otherInfo -> otherInfo == thisModInfo))) //Ignore files where any other mod already encountered an error + .filter(modFileInfo -> modFileInfo.getMods().stream().noneMatch(this.erroredModInfos::contains)) //Ignore files where any other mod already encountered an error .map(modFileInfo -> new ModLoadingException(null, ModLoadingStage.VALIDATE, "fml.modloading.missinglicense", null, modFileInfo.getFile())) .forEach(this.loadingExceptions::add); this.stateManager = new ModStateManager(); CrashReportCallables.registerCrashCallable("ModLauncher", FMLLoader::getLauncherInfo); CrashReportCallables.registerCrashCallable("ModLauncher launch target", FMLLoader::launcherHandlerName); CrashReportCallables.registerCrashCallable("ModLauncher naming", FMLLoader::getNaming); - CrashReportCallables.registerCrashCallable("ModLauncher services", this::computeModLauncherServiceList); - CrashReportCallables.registerCrashCallable("FML Language Providers", this::computeLanguageList); + CrashReportCallables.registerCrashCallable("ModLauncher services", ModLoader::computeModLauncherServiceList); + CrashReportCallables.registerCrashCallable("FML Language Providers", ModLoader::computeLanguageList); } - private String computeLanguageList() { - return "\n"+FMLLoader.getLanguageLoadingProvider().applyForEach(lp->lp.name() +"@"+ lp.getClass().getPackage().getImplementationVersion()).collect(Collectors.joining("\n\t\t", "\t\t", "")); + private static String computeLanguageList() { + return "\n" + FMLLoader.getLanguageLoadingProvider() + .applyForEach(lp -> lp.name() + "@" + lp.getClass().getPackage().getImplementationVersion()) + .collect(Collectors.joining("\n\t\t", "\t\t", "")); } - private String computeModLauncherServiceList() { + private static String computeModLauncherServiceList() { final List> mods = FMLLoader.modLauncherModList(); return "\n"+mods.stream().map(mod->mod.getOrDefault("file","nofile")+ " "+mod.getOrDefault("name", "missing")+ @@ -125,9 +132,13 @@ public class ModLoader collect(Collectors.joining("\n\t\t","\t\t","")); } - public static ModLoader get() - { - return INSTANCE == null ? INSTANCE = new ModLoader() : INSTANCE; + public static ModLoader get() { + return LazyInit.INSTANCE; + } + + private static final class LazyInit { + private static final ModLoader INSTANCE = new ModLoader(); + private LazyInit() {} } /** @@ -144,7 +155,7 @@ public class ModLoader final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).toList(), loadingModList.getMods()); if (!this.loadingExceptions.isEmpty()) { - LOGGER.fatal(CORE, "Error during pre-loading phase", loadingExceptions.get(0)); + LOGGER.fatal(CORE, "Error during pre-loading phase", loadingExceptions.getFirst()); statusConsumer.ifPresent(c->c.accept("ERROR DURING MOD LOADING")); modList.setLoadedMods(Collections.emptyList()); loadingStateValid = false; @@ -152,7 +163,7 @@ public class ModLoader } List failedBounds = loadingModList.getMods().stream() .map(ModInfo::getForgeFeatures) - .flatMap(Collection::stream) + .flatMap(List::stream) .filter(bound -> !ForgeFeature.testFeature(FMLEnvironment.dist, bound)) .toList(); @@ -169,10 +180,10 @@ public class ModLoader final List modContainers = loadingModList.getModFiles().stream() .map(ModFileInfo::getFile) .map(this::buildMods) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .toList(); if (!loadingExceptions.isEmpty()) { - LOGGER.fatal(CORE, "Failed to initialize mod containers", loadingExceptions.get(0)); + LOGGER.fatal(CORE, "Failed to initialize mod containers", loadingExceptions.getFirst()); statusConsumer.ifPresent(c->c.accept("ERROR DURING MOD LOADING")); modList.setLoadedMods(Collections.emptyList()); loadingStateValid = false; @@ -181,22 +192,28 @@ public class ModLoader modList.setLoadedMods(modContainers); this.modList = modList; var stateList = stateManager.getStates(ModLoadingPhase.GATHER); - var progress = StartupMessageManager.addProgressBar("Mod Gather", stateList.stream().mapToInt(mls -> mls.size().applyAsInt(modList)).sum()); - stateList.forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask, progress)); + var progress = StartupMessageManager.addProgressBar("Mod Gather", stateList.stream().mapToInt(mls -> mls.size().applyAsInt(this.modList)).sum()); + for (IModLoadingState mls : stateList) { + dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask, progress); + } progress.complete(); } public void loadMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) { var stateList = stateManager.getStates(ModLoadingPhase.LOAD); var progress = StartupMessageManager.addProgressBar("Mod Loading", stateList.stream().mapToInt(mls -> mls.size().applyAsInt(modList)).sum()); - stateList.forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask, progress)); + for (IModLoadingState mls : stateList) { + dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask, progress); + } progress.complete(); } public void finishMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) { var stateList = stateManager.getStates(ModLoadingPhase.COMPLETE); var progress = StartupMessageManager.addProgressBar("Mod Complete", stateList.stream().mapToInt(mls -> mls.size().applyAsInt(modList)).sum()); - stateList.forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask, progress)); + for (IModLoadingState mls : stateList) { + dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask, progress); + } statusConsumer.ifPresent(c->c.accept(String.format("Mod loading complete - %d mods loaded", this.modList.size()))); progress.complete(); } @@ -206,10 +223,15 @@ public class ModLoader LOGGER.error("Cowardly refusing to process mod state change request from {}", state); return; } - progressBar.label(progressBar.name()+ " working"); + progressBar.label(progressBar.name() + " working"); syncExecutor.drive(ticker); - state.inlineRunnable().ifPresent(a->this.handleInlineTransition(a, state, syncExecutor, ticker)); - state.buildTransition(syncExecutor, parallelExecutor, progressBar).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t)); + + var inlineRunnable = state.inlineRunnable().orElse(null); + if (inlineRunnable != null) handleInlineTransition(inlineRunnable, state, syncExecutor, ticker); + + var transition = state.buildTransition(syncExecutor, parallelExecutor, progressBar).orElse(null); + if (transition != null) waitForTransition(state, syncExecutor, ticker, transition); + completedStates.add(state); } @@ -286,9 +308,12 @@ public class ModLoader try { final String modId = idToProviderEntry.getKey(); final IModLanguageProvider.IModLanguageLoader languageLoader = idToProviderEntry.getValue(); - IModInfo info = Optional.ofNullable(modInfoMap.get(modId)). - // throw a missing metadata error if there is no matching modid in the modInfoMap from the mods.toml file - orElseThrow(()->new ModLoadingException(null, ModLoadingStage.CONSTRUCT, "fml.modloading.missingmetadata", null, modId)); + + IModInfo info = modInfoMap.get(modId); + // throw a missing metadata error if there is no matching modid in the modInfoMap from the mods.toml file + if (info == null) + throw new ModLoadingException(null, ModLoadingStage.CONSTRUCT, "fml.modloading.missingmetadata", null, modId); + return languageLoader.loadMod(info, modFile.getScanResult(), FMLLoader.getGameLayer()); } catch (ModLoadingException mle) { // exceptions are caught and added to the error list for later handling @@ -303,7 +328,7 @@ public class ModLoader * and don't want to cause extraneous crashes due to trying to do things that aren't possible in a "broken load" */ public static boolean isLoadingStateValid() { - return get().loadingStateValid; + return loadingStateValid; } public boolean hasCompletedState(final String stateName) { diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java index d34421d39a..ddb7d94fab 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModLoadingState.java @@ -39,7 +39,10 @@ public record ModLoadingState(String name, String previous, final ProgressMeter progressBar, final Function> preSyncTask, final Function> postSyncTask) { - return transition.map(t -> t.build(name, syncExecutor, parallelExecutor, progressBar, preSyncTask, postSyncTask)); + var transition = this.transition.orElse(null); + return transition == null + ? Optional.empty() + : Optional.ofNullable(transition.build(name, syncExecutor, parallelExecutor, progressBar, preSyncTask, postSyncTask)); } /** diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java index 7cd81e69df..de1e6f8971 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModStateManager.java @@ -16,15 +16,13 @@ import java.util.stream.Collectors; @SuppressWarnings("UnstableApiUsage") public class ModStateManager { - static ModStateManager INSTANCE; private final EnumMap> stateMap; public ModStateManager() { - INSTANCE = this; final var sp = ServiceLoader.load(FMLLoader.getGameLayer(), IModStateProvider.class); this.stateMap = ServiceLoaderUtils.streamWithErrorHandling(sp, sce->{}) .map(IModStateProvider::getAllStates) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .collect(Collectors.groupingBy(IModLoadingState::phase, ()->new EnumMap<>(ModLoadingPhase.class), Collectors.toUnmodifiableList())); } @@ -36,14 +34,16 @@ public class ModStateManager { var dummy = ModLoadingState.empty("", "", phase); nodes.forEach(graph::addNode); graph.addNode(dummy); - nodes.forEach(n->graph.putEdge(lookup.getOrDefault(n.previous(), dummy), n)); + for (IModLoadingState node : nodes) { + graph.putEdge(lookup.getOrDefault(node.previous(), dummy), node); + } return TopologicalSort.topologicalSort(graph, Comparator.comparingInt(nodes::indexOf)).stream().filter(st->st!=dummy).toList(); } public IModLoadingState findState(final String stateName) { return stateMap.values() .stream() - .flatMap(Collection::stream) + .flatMap(List::stream) .filter(mls -> mls.name().equals(stateName)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Unknown IModLoadingState: " + stateName)); diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModWorkManager.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModWorkManager.java index 20e9ad7bb9..cf37948b42 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModWorkManager.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModWorkManager.java @@ -17,6 +17,7 @@ import static net.minecraftforge.fml.Logging.LOADING; public class ModWorkManager { private static final Logger LOGGER = LogManager.getLogger(); private static final long PARK_TIME = TimeUnit.MILLISECONDS.toNanos(1); + public interface DrivenExecutor extends Executor { boolean selfDriven(); boolean driveOne(); @@ -33,8 +34,11 @@ public class ModWorkManager { } } } - private static class SyncExecutor implements DrivenExecutor { - private ConcurrentLinkedDeque tasks = new ConcurrentLinkedDeque<>(); + + private record SyncExecutor(ConcurrentLinkedDeque tasks) implements DrivenExecutor { + public SyncExecutor() { + this(new ConcurrentLinkedDeque<>()); + } @Override public boolean driveOne() { @@ -56,13 +60,7 @@ public class ModWorkManager { } } - private static class WrappingExecutor implements DrivenExecutor { - private final Executor wrapped; - - public WrappingExecutor(final Executor executor) { - this.wrapped = executor; - } - + private record WrappingExecutor(Executor wrapped) implements DrivenExecutor { @Override public boolean selfDriven() { return true; @@ -79,11 +77,9 @@ public class ModWorkManager { } } - private static SyncExecutor syncExecutor; + private static final SyncExecutor syncExecutor = new SyncExecutor(); public static DrivenExecutor syncExecutor() { - if (syncExecutor == null) - syncExecutor = new SyncExecutor(); return syncExecutor; } @@ -91,14 +87,8 @@ public class ModWorkManager { return new WrappingExecutor(executor); } - private static ForkJoinPool parallelThreadPool; public static Executor parallelExecutor() { - if (parallelThreadPool == null) { - final int loadingThreadCount = FMLConfig.getIntConfigValue(FMLConfig.ConfigValue.MAX_THREADS); - LOGGER.debug(LOADING, "Using {} threads for parallel mod-loading", loadingThreadCount); - parallelThreadPool = new ForkJoinPool(loadingThreadCount, ModWorkManager::newForkJoinWorkerThread, null, false); - } - return parallelThreadPool; + return LazyInit.PARALLEL_EXECUTOR; } private static ForkJoinWorkerThread newForkJoinWorkerThread(ForkJoinPool pool) { @@ -109,4 +99,14 @@ public class ModWorkManager { return thread; } + private static final class LazyInit { + private LazyInit() {} + private static final ForkJoinPool PARALLEL_EXECUTOR; + + static { + final int loadingThreadCount = FMLConfig.getIntConfigValue(FMLConfig.ConfigValue.MAX_THREADS); + LOGGER.debug(LOADING, "Using {} threads for parallel mod-loading", loadingThreadCount); + PARALLEL_EXECUTOR = new ForkJoinPool(loadingThreadCount, ModWorkManager::newForkJoinWorkerThread, null, false); + } + } } diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/OptionalMod.java b/fmlcore/src/main/java/net/minecraftforge/fml/OptionalMod.java index 92b93d4fa6..31a686f3b4 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/OptionalMod.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/OptionalMod.java @@ -23,7 +23,7 @@ public final class OptionalMod return new OptionalMod<>(modId); } - private static OptionalMod EMPTY = new OptionalMod<>(true); + private static final OptionalMod EMPTY = new OptionalMod<>(true); private static OptionalMod empty() { @SuppressWarnings("unchecked") OptionalMod t = (OptionalMod) EMPTY; @@ -213,8 +213,8 @@ public final class OptionalMod public boolean equals(Object obj) { if (this == obj) return true; - if (obj instanceof OptionalMod) { - return Objects.equals(((OptionalMod)obj).modId, modId); + if (obj instanceof OptionalMod optionalMod) { + return Objects.equals(optionalMod.modId, modId); } return false; } diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java index cea04ae8d5..64ecee8e71 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigFileTypeHandler.java @@ -25,7 +25,7 @@ import static net.minecraftforge.fml.config.ConfigTracker.CONFIG; public class ConfigFileTypeHandler { private static final Logger LOGGER = LogUtils.getLogger(); - static ConfigFileTypeHandler TOML = new ConfigFileTypeHandler(); + static final ConfigFileTypeHandler TOML = new ConfigFileTypeHandler(); private static final Path defaultConfigPath = FMLPaths.GAMEDIR.get().resolve(FMLConfig.getConfigValue(FMLConfig.ConfigValue.DEFAULT_CONFIG_PATH)); public Function reader(Path configBasePath) { @@ -62,7 +62,7 @@ public class ConfigFileTypeHandler { } } - private boolean setupConfigFile(final ModConfig modConfig, final Path file, final ConfigFormat conf) throws IOException { + private static boolean setupConfigFile(final ModConfig modConfig, final Path file, final ConfigFormat conf) throws IOException { if (!Files.isDirectory(file.getParent())) { Files.createDirectories(file.getParent()); } @@ -109,17 +109,11 @@ public class ConfigFileTypeHandler { } } - private static class ConfigWatcher implements Runnable { - private final ModConfig modConfig; - private final CommentedFileConfig commentedFileConfig; - private final ClassLoader realClassLoader; - - ConfigWatcher(final ModConfig modConfig, final CommentedFileConfig commentedFileConfig, final ClassLoader classLoader) { - this.modConfig = modConfig; - this.commentedFileConfig = commentedFileConfig; - this.realClassLoader = classLoader; - } - + private record ConfigWatcher( + ModConfig modConfig, + CommentedFileConfig commentedFileConfig, + ClassLoader realClassLoader + ) implements Runnable { @Override public void run() { // Force the regular classloader onto the special thread diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java index 02ce9623c5..f47d7da415 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java @@ -47,15 +47,19 @@ public class ConfigTracker { public void loadConfigs(ModConfig.Type type, Path configBasePath) { LOGGER.debug(CONFIG, "Loading configs type {}", type); - this.configSets.get(type).forEach(config -> openConfig(config, configBasePath)); + for (ModConfig config : this.configSets.get(type)) { + openConfig(config, configBasePath); + } } public void unloadConfigs(ModConfig.Type type, Path configBasePath) { LOGGER.debug(CONFIG, "Unloading configs type {}", type); - this.configSets.get(type).forEach(config -> closeConfig(config, configBasePath)); + for (ModConfig config : this.configSets.get(type)) { + closeConfig(config, configBasePath); + } } - private void openConfig(final ModConfig config, final Path configBasePath) { + private static void openConfig(final ModConfig config, final Path configBasePath) { LOGGER.trace(CONFIG, "Loading config file type {} at {} for {}", config.getType(), config.getFileName(), config.getModId()); final CommentedFileConfig configData = config.getHandler().reader(configBasePath).apply(config); config.setConfigData(configData); @@ -63,7 +67,7 @@ public class ConfigTracker { config.save(); } - private void closeConfig(final ModConfig config, final Path configBasePath) { + private static void closeConfig(final ModConfig config, final Path configBasePath) { if (config.getConfigData() != null) { LOGGER.trace(CONFIG, "Closing config file type {} at {} for {}", config.getType(), config.getFileName(), config.getModId()); // stop the filewatcher before we save the file and close it, so reload doesn't fire diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java b/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java index 2016fb9855..671866891b 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/config/ModConfig.java @@ -24,7 +24,6 @@ public class ModConfig private final ModContainer container; private final ConfigFileTypeHandler configHandler; private CommentedConfig configData; - private Callable saveHandler; public ModConfig(final Type type, final IConfigSpec spec, final ModContainer container, final String fileName) { this.type = type; diff --git a/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/SimpleFont.java b/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/SimpleFont.java index c79e9362e4..2482c5a0ab 100644 --- a/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/SimpleFont.java +++ b/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/SimpleFont.java @@ -25,7 +25,7 @@ public class SimpleFont { private final int lineSpacing; private final int descent; private final int GLYPH_COUNT = 127-32; - private Glyph[] glyphs; + private final Glyph[] glyphs; private record Glyph(char c, int charwidth, int[] pos, float[] uv) { Pos loadQuad(Pos pos, int colour, SimpleBufferBuilder bb) { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/CapabilityTokenSubclass.java b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/CapabilityTokenSubclass.java index 594c1ee28c..981bc70515 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/CapabilityTokenSubclass.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/CapabilityTokenSubclass.java @@ -36,9 +36,9 @@ import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; */ public class CapabilityTokenSubclass implements ILaunchPluginService { - private final String FUNC_NAME = "getType"; - private final String FUNC_DESC = "()Ljava/lang/String;"; - private final String CAP_INJECT = "net/minecraftforge/common/capabilities/CapabilityToken"; //Don't directly reference this to prevent class loading. + private static final String FUNC_NAME = "getType"; + private static final String FUNC_DESC = "()Ljava/lang/String;"; + private static final String CAP_INJECT = "net/minecraftforge/common/capabilities/CapabilityToken"; //Don't directly reference this to prevent class loading. @Override public String name() { @@ -67,7 +67,7 @@ public class CapabilityTokenSubclass implements ILaunchPluginService { SignatureReader reader = new SignatureReader(classNode.signature); // Having a node version of this would probably be useful. reader.accept(new SignatureVisitor(Opcodes.ASM9) { - Deque stack = new ArrayDeque<>(); + final Deque stack = new ArrayDeque<>(); @Override public void visitClassType(final String name) { @@ -100,7 +100,7 @@ public class CapabilityTokenSubclass implements ILaunchPluginService { } } - private static class Holder { + private static final class Holder { String value; } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java index 517adc0631..4a4b9e28b6 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.java @@ -34,8 +34,9 @@ public class ObjectHolderDefinalize implements ILaunchPluginService { new VanillaObjectHolderData("net.minecraft.world.effect.MobEffects", "mob_effect", "net.minecraft.world.effect.MobEffect"), new VanillaObjectHolderData("net.minecraft.core.particles.ParticleTypes", "particle_type", "net.minecraft.core.particles.ParticleType"), new VanillaObjectHolderData("net.minecraft.sounds.SoundEvents", "sound_event", "net.minecraft.sounds.SoundEvent") - ).collect(Collectors.toMap(VanillaObjectHolderData::holderClass, Function.identity())); - private final String OBJECT_HOLDER = "Lnet/minecraftforge/registries/ObjectHolder;"; //Don't directly reference this to prevent class loading. + ).collect(Collectors.toUnmodifiableMap(VanillaObjectHolderData::holderClass, Function.identity())); + private static final String OBJECT_HOLDER = "Lnet/minecraftforge/registries/ObjectHolder;"; //Don't directly reference this to prevent class loading. + private static final int PUBLIC_STATIC_FINAL_FLAGS = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; @Override public String name() { @@ -51,8 +52,7 @@ public class ObjectHolderDefinalize implements ILaunchPluginService { return isEmpty ? NAY : YAY; } - private boolean hasHolder(List lst) - { + private static boolean hasHolder(List lst) { return lst != null && lst.stream().anyMatch(n -> n.desc.equals(OBJECT_HOLDER)); } @@ -76,10 +76,9 @@ public class ObjectHolderDefinalize implements ILaunchPluginService { { final AtomicBoolean changes = new AtomicBoolean(); //Must be public static finals, and non-array objects - final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; //Fix Annotated Fields before injecting from class level - classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.startsWith("L") && hasHolder(f.visibleAnnotations)).forEach(f -> + classNode.fields.stream().filter(f -> ((f.access & PUBLIC_STATIC_FINAL_FLAGS) == PUBLIC_STATIC_FINAL_FLAGS) && f.desc.startsWith("L") && hasHolder(f.visibleAnnotations)).forEach(f -> { int prev = f.access; f.access &= ~Opcodes.ACC_FINAL; //Strip final @@ -89,7 +88,7 @@ public class ObjectHolderDefinalize implements ILaunchPluginService { if (VANILLA_OBJECT_HOLDERS.containsKey(classType.getClassName())) //Class level, de-finalize all fields and add @ObjectHolder to them! { - classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.startsWith("L")).forEach(f -> + classNode.fields.stream().filter(f -> ((f.access & PUBLIC_STATIC_FINAL_FLAGS) == PUBLIC_STATIC_FINAL_FLAGS) && f.desc.startsWith("L")).forEach(f -> { int prev = f.access; f.access &= ~Opcodes.ACC_FINAL; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java index 32bc948558..e10120f79a 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java @@ -28,15 +28,16 @@ import org.slf4j.Logger; public class RuntimeEnumExtender implements ILaunchPluginService { private static final Logger LOGGER = LogUtils.getLogger(); - private final Type STRING = Type.getType(String.class); - private final Type ENUM = Type.getType(Enum.class); - private final Type MARKER_IFACE = Type.getType("Lnet/minecraftforge/common/IExtensibleEnum;"); - private final Type ARRAY_UTILS = Type.getType("Lorg/apache/commons/lang3/ArrayUtils;"); //Don't directly reference this to prevent class loading. - private final String ADD_DESC = Type.getMethodDescriptor(Type.getType(Object[].class), Type.getType(Object[].class), Type.getType(Object.class)); - private final Type UNSAFE_HACKS = Type.getType("Lnet/minecraftforge/fml/unsafe/UnsafeHacks;"); //Again, not direct reference to prevent class loading. - private final String CLEAN_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Class.class)); - private final String NAME_DESC = Type.getMethodDescriptor(STRING); - private final String EQUALS_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, STRING); + private static final Type STRING = Type.getType(String.class); + private static final Type ENUM = Type.getType(Enum.class); + private static final Type MARKER_IFACE = Type.getType("Lnet/minecraftforge/common/IExtensibleEnum;"); + private static final Type ARRAY_UTILS = Type.getType("Lorg/apache/commons/lang3/ArrayUtils;"); //Don't directly reference this to prevent class loading. + private static final String ADD_DESC = Type.getMethodDescriptor(Type.getType(Object[].class), Type.getType(Object[].class), Type.getType(Object.class)); + private static final Type UNSAFE_HACKS = Type.getType("Lnet/minecraftforge/fml/unsafe/UnsafeHacks;"); //Again, not direct reference to prevent class loading. + private static final String CLEAN_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Class.class)); + private static final String NAME_DESC = Type.getMethodDescriptor(STRING); + private static final String EQUALS_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, STRING); + private static final int FLAGS = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC; @Override public String name() { @@ -59,9 +60,9 @@ public class RuntimeEnumExtender implements ILaunchPluginService { return ComputeFlags.NO_REWRITE; Type array = Type.getType("[" + classType.getDescriptor()); - final int flags = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC; + String arrayDesc = array.getDescriptor(); - FieldNode values = classNode.fields.stream().filter(f -> f.desc.contentEquals(array.getDescriptor()) && ((f.access & flags) == flags)).findFirst().orElse(null); + FieldNode values = classNode.fields.stream().filter(f -> f.desc.equals(arrayDesc) && ((f.access & FLAGS) == FLAGS)).findFirst().orElse(null); if (!classNode.interfaces.contains(MARKER_IFACE.getInternalName())) { return ComputeFlags.NO_REWRITE; @@ -70,13 +71,13 @@ public class RuntimeEnumExtender implements ILaunchPluginService { //Static methods named "create" with first argument as a string List candidates = classNode.methods.stream() .filter(m -> ((m.access & Opcodes.ACC_STATIC) != 0) && m.name.equals("create")) - .collect(Collectors.toList()); + .toList(); if (candidates.isEmpty()) { throw new IllegalStateException("IExtensibleEnum has no candidate factory methods: " + classType.getClassName()); } - candidates.forEach(mtd -> + for (var mtd : candidates) { Type[] args = Type.getArgumentTypes(mtd.desc); if (args.length == 0 || !args[0].equals(STRING)) { @@ -108,8 +109,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService { Type[] ctrArgs = new Type[args.length + 1]; ctrArgs[0] = STRING; ctrArgs[1] = Type.INT_TYPE; - for (int x = 1; x < args.length; x++) - ctrArgs[1 + x] = args[x]; + System.arraycopy(args, 1, ctrArgs, 2, args.length - 1); String desc = Type.getMethodDescriptor(Type.VOID_TYPE, ctrArgs); @@ -231,7 +231,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService { ins.load(vars, classType); ins.areturn(classType); } - }); + } return ComputeFlags.COMPUTE_FRAMES; } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java index 94006fa508..d068a25915 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java @@ -17,11 +17,9 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.loading.targets.CommonLaunchHandler; import net.minecraftforge.forgespi.Environment; import net.minecraftforge.forgespi.coremod.ICoreModProvider; -import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -36,7 +34,6 @@ import static net.minecraftforge.fml.loading.LogMarkers.SCAN; public class FMLLoader { private static final Logger LOGGER = LogUtils.getLogger(); private static AccessTransformerService accessTransformer; - private static ModDiscoverer modDiscoverer; private static ICoreModProvider coreModProvider; private static LanguageLoadingProvider languageLoadingProvider; private static Dist dist; @@ -62,7 +59,7 @@ public class FMLLoader { /*eventBus =*/ getPlugin(env, "eventbus", "1.0", "EventBus"); runtimeDistCleaner = getPlugin(env, "runtimedistcleaner", "1.0", "RuntimeDistCleaner"); coreModProvider = getSingleService(ICoreModProvider.class, "CoreMod"); - LOGGER.debug(CORE,"FML found CoreMod version : {}", JarVersionLookupHandler.getInfo(coreModProvider.getClass()).impl().version().orElse("MISSING")); + LOGGER.debug(CORE, "FML found CoreMod version : {}", JarVersionLookupHandler.getInfo(coreModProvider.getClass()).impl().version().orElse("MISSING")); checkPackage(Environment.class, "2.0", "ForgeSPI"); try { @@ -74,14 +71,15 @@ public class FMLLoader { } } + @SuppressWarnings("unchecked") private static T getPlugin(IEnvironment env, String id, String version, String name) throws IncompatibleEnvironmentException { - @SuppressWarnings("unchecked") - var plugin = (T)env.findLaunchPlugin(id).orElseThrow(() -> { + var plugin = env.findLaunchPlugin(id).orElse(null); + if (plugin == null) { LOGGER.error(CORE, "{} library is missing, we need this to run", name); - return new IncompatibleEnvironmentException("Missing " + name + ", cannot run"); - }); + throw new IncompatibleEnvironmentException("Missing " + name + ", cannot run"); + } checkPackage(plugin.getClass(), version, name); - return plugin; + return (T) plugin; } private static void checkPackage(Class cls, String version, String name) throws IncompatibleEnvironmentException { @@ -137,20 +135,20 @@ public class FMLLoader { } commonLaunchHandler = (CommonLaunchHandler)launchHandler.get(); launchHandlerName = launchHandler.get().name(); - gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".").toAbsolutePath()); + gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Path.of(".").toAbsolutePath()); naming = commonLaunchHandler.getNaming(); dist = commonLaunchHandler.getDist(); production = commonLaunchHandler.isProduction(); - accessTransformer.getExtension().accept(Pair.of(naming, "srg")); + accessTransformer.getExtension().accept(Map.entry(naming, "srg")); runtimeDistCleaner.getExtension().accept(dist); } public static List beginModScan(final Map arguments) { LOGGER.debug(SCAN,"Scanning for Mod Locators"); - modDiscoverer = new ModDiscoverer(arguments); + var modDiscoverer = new ModDiscoverer(arguments); modValidator = modDiscoverer.discoverMods(); var pluginResources = modValidator.getPluginResources(); return List.of(pluginResources); @@ -172,10 +170,6 @@ public class FMLLoader { return languageLoadingProvider; } - static ModDiscoverer getModDiscoverer() { - return modDiscoverer; - } - public static CommonLaunchHandler getLaunchHandler() { return commonLaunchHandler; } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java index f3601c77e5..48dabecee5 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java @@ -24,7 +24,7 @@ import static net.minecraftforge.fml.loading.LogMarkers.CORE; public class FMLServiceProvider implements ITransformationService { private static final Logger LOGGER = LogUtils.getLogger(); - private Map arguments; + private final Map arguments = new HashMap<>(); public FMLServiceProvider() { var markers = System.getProperty("forge.logging.markers", "").split(","); @@ -45,7 +45,6 @@ public class FMLServiceProvider implements ITransformationService { FMLConfig.load(); LOGGER.debug(CORE, "Preparing ModFile"); environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), k->ModFile::new); - arguments = new HashMap<>(); LOGGER.debug(CORE, "Preparing launch handler"); FMLLoader.setupLaunchHandler(environment, arguments); FMLEnvironment.setupInteropEnvironment(environment); @@ -68,14 +67,6 @@ public class FMLServiceProvider implements ITransformationService { FMLLoader.onInitialLoad(environment, otherServices); } - @Override - public void arguments(BiFunction argumentBuilder) { - } - - @Override - public void argumentValues(OptionResult option) { - } - @SuppressWarnings("rawtypes") @Override public @NotNull List transformers() { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java index 6f48b42b46..65b34a6cd4 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java @@ -78,9 +78,13 @@ public class LoadingModList public void addAccessTransformers() { - modFiles.stream() - .map(ModFileInfo::getFile) - .forEach(mod -> mod.getAccessTransformer().ifPresent(path -> FMLLoader.addAccessTransformer(path, mod))); + for (ModFileInfo modFile : modFiles) { + ModFile mod = modFile.getFile(); + var at = mod.getAccessTransformer().orElse(null); + if (at != null) { + FMLLoader.addAccessTransformer(at, mod); + } + } } public void addForScanning(BackgroundScanHandler backgroundScanHandler) diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java index 40715abc0d..ca908d0470 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MCPNamingService.java @@ -36,7 +36,7 @@ public class MCPNamingService implements INameMappingService { @Override public Map.Entry understanding() { - return Pair.of("srg", "mcp"); + return Map.entry("srg", "mcp"); } @Override diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java index 49c19d9bc1..fe3e595b06 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/MavenCoordinateResolver.java @@ -34,7 +34,7 @@ public class MavenCoordinateResolver { (!extension.isEmpty() ? "." + extension : ".jar"); String[] groups = groupId.split("\\."); - Path result = Paths.get(groups[0]); + Path result = Path.of(groups[0]); for (int i = 1; i < groups.length; i++) { result = result.resolve(groups[i]); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java index 4f944f7b66..5ae65c60f6 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ModSorter.java @@ -57,13 +57,13 @@ public class ModSorter // Note this will never actually throw an error because the duplicate checks are done in ModDiscovererer before we get to this phase // So all this is really doing is wasting time. // But i'm leaving it here until I rewrite all of cpw's mod loading code because its such a clusterfuck. - return LoadingModList.of(ms.systemMods, ms.systemMods.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).collect(toList()), e); + return LoadingModList.of(ms.systemMods, ms.systemMods.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).toList(), e); } // try and validate dependencies final List failedList = Stream.concat(ms.verifyDependencyVersions().stream(), errors.stream()).toList(); // if we miss one or the other, we abort now if (!failedList.isEmpty()) { - return LoadingModList.of(ms.systemMods, ms.systemMods.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).collect(toList()), new EarlyLoadingException("failure to validate mod list", null, failedList)); + return LoadingModList.of(ms.systemMods, ms.systemMods.stream().map(mf->(ModInfo)mf.getModInfos().get(0)).toList(), new EarlyLoadingException("failure to validate mod list", null, failedList)); } else { // Otherwise, lets try and sort the modlist and proceed EarlyLoadingException earlyLoadingException = null; @@ -89,9 +89,9 @@ public class ModSorter infos.keySet().forEach(graph::addNode); modFiles.stream() .map(ModFile::getModInfos) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .map(IModInfo::getDependencies) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .forEach(dep -> addDependency(graph, dep)); final List sorted; @@ -107,7 +107,7 @@ public class ModSorter LOGGER.error(LOADING, "Mod Sorting failed.\nDetected Cycles: {}\n", cycles); } var dataList = cycles.stream() - .mapMulti(Iterable::forEach) + .flatMap(Set::stream) .mapMulti((mf,c)->mf.getMods().forEach(c)) .map(IModInfo::getModId) .map(list -> new ExceptionData("fml.modloading.cycle", list)) @@ -116,7 +116,7 @@ public class ModSorter } this.sortedList = sorted.stream() .map(ModFileInfo::getMods) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .map(ModInfo.class::cast) .collect(toList()); this.modFiles = sorted.stream() @@ -126,12 +126,14 @@ public class ModSorter private void addDependency(MutableGraph topoGraph, IModInfo.ModVersion dep) { - final ModFileInfo self = (ModFileInfo)dep.getOwner().getOwningFile(); final IModInfo targetModInfo = modIdNameLookup.get(dep.getModId()); // soft dep that doesn't exist. Just return. No edge required. if (targetModInfo == null || !(targetModInfo.getOwningFile() instanceof final ModFileInfo target)) return; + + final ModFileInfo self = (ModFileInfo)dep.getOwner().getOwningFile(); if (self == target) return; // in case a jar has two mods that have dependencies between + switch (dep.getOrdering()) { case BEFORE -> topoGraph.putEdge(self, target); case AFTER -> topoGraph.putEdge(target, self); @@ -165,7 +167,7 @@ public class ModSorter var container = modFilesByFirstId.get(systemMod); if (container != null && !container.isEmpty()) { LOGGER.debug("Found system mod: {}", systemMod); - this.systemMods.add((ModFile) container.get(0)); + this.systemMods.add(container.getFirst()); } else { throw new IllegalStateException("Failed to find system mod: " + systemMod); } @@ -176,23 +178,23 @@ public class ModSorter { final var modVersions = modFiles.stream() .map(ModFile::getModInfos) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .collect(toMap(IModInfo::getModId, IModInfo::getVersion)); final var modVersionDependencies = modFiles.stream() .map(ModFile::getModInfos) - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .collect(groupingBy(Function.identity(), flatMapping(e -> e.getDependencies().stream(), toList()))); final var modRequirements = modVersionDependencies.values().stream() - .mapMulti(Iterable::forEach) + .flatMap(List::stream) .filter(mv -> mv.getSide().isCorrectSide()) .collect(toSet()); final long mandatoryRequired = modRequirements.stream().filter(IModInfo.ModVersion::isMandatory).count(); LOGGER.debug(LOADING, "Found {} mod requirements ({} mandatory, {} optional)", modRequirements.size(), mandatoryRequired, modRequirements.size() - mandatoryRequired); final var missingVersions = modRequirements.stream() - .filter(mv -> (mv.isMandatory() || modVersions.containsKey(mv.getModId())) && this.modVersionNotContained(mv, modVersions)) + .filter(mv -> (mv.isMandatory() || modVersions.containsKey(mv.getModId())) && !modVersionContained(mv, modVersions)) .collect(toSet()); final long mandatoryMissing = missingVersions.stream().filter(IModInfo.ModVersion::isMandatory).count(); LOGGER.debug(LOADING, "Found {} mod requirements missing ({} mandatory, {} optional)", missingVersions.size(), mandatoryMissing, missingVersions.size() - mandatoryMissing); @@ -240,9 +242,13 @@ public class ModSorter ); } - private boolean modVersionNotContained(final IModInfo.ModVersion mv, final Map modVersions) - { - return !(VersionSupportMatrix.testVersionSupportMatrix(mv.getVersionRange(), mv.getModId(), "mod", (modId, range) -> modVersions.containsKey(modId) && - (range.containsVersion(modVersions.get(modId)) || modVersions.get(modId).toString().equals("0.0NONE")))); + private static boolean modVersionContained(IModInfo.ModVersion mv, Map modVersions) { + var modId = mv.getModId(); + var range = mv.getVersionRange(); + if (modVersions.containsKey(modId) + && (range.containsVersion(modVersions.get(modId)) || modVersions.get(modId).toString().equals("0.0NONE"))) + return true; + + return VersionSupportMatrix.testVersionSupportMatrix(mv.getVersionRange(), mv.getModId(), "mod"); } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java index 7b43e334b3..d3fbaacfe2 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java @@ -173,7 +173,7 @@ public class RuntimeDistCleaner implements ILaunchPluginService return unpacked; } - private boolean remove(final List anns, final String side) + private static boolean remove(final List anns, final String side) { var onlyIns = unpack(anns); @@ -193,7 +193,7 @@ public class RuntimeDistCleaner implements ILaunchPluginService return false; } - private boolean hasOnlyInWithModAnnotation(final List anns) + private static boolean hasOnlyInWithModAnnotation(final List anns) { if (anns == null) { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/StringSubstitutor.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/StringSubstitutor.java index 484d5392b2..21c3e625f8 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/StringSubstitutor.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/StringSubstitutor.java @@ -14,16 +14,17 @@ import org.apache.commons.lang3.text.StrSubstitutor; @SuppressWarnings("deprecation") public class StringSubstitutor { + private static final Map GLOBALS = Map.of( + "mcVersion", FMLLoader.versionInfo().mcVersion(), + "forgeVersion", FMLLoader.versionInfo().forgeVersion() + ); + public static String replace(final String in, final ModFile file) { return new StrSubstitutor(getStringLookup(file)).replace(in); } private static StrLookup getStringLookup(final ModFile file) { - var globals = Map.of( - "mcVersion", FMLLoader.versionInfo().mcVersion(), - "forgeVersion", FMLLoader.versionInfo().forgeVersion() - ); - return new StrLookup() { + return new StrLookup<>() { @Override public String lookup(String key) { var parts = key.split("\\."); @@ -32,7 +33,7 @@ public class StringSubstitutor { var pfx = parts[0]; if ("global".equals(pfx)) - return globals.get(parts[1]); + return GLOBALS.get(parts[1]); else if ("file".equals(pfx) && file != null) return String.valueOf(file.getSubstitutionMap().get().get(parts[1])); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/UniqueModListBuilder.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/UniqueModListBuilder.java index 086de27f98..467cc6dc56 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/UniqueModListBuilder.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/UniqueModListBuilder.java @@ -47,12 +47,12 @@ public class UniqueModListBuilder // Select the newest by artifact version sorting of non-unique files thus identified uniqueModList = modFilesByFirstId.entrySet().stream() - .map(this::selectNewestModInfo) + .map(UniqueModListBuilder::selectNewestModInfo) .toList(); // Select the newest by artifact version sorting of non-unique files thus identified uniqueLibListWithVersion = libFilesWithVersionByModuleName.entrySet().stream() - .map(this::selectNewestModInfo) + .map(UniqueModListBuilder::selectNewestModInfo) .toList(); // Transform to the full mod id list @@ -75,7 +75,7 @@ public class UniqueModListBuilder final List dupedModErrors = modIds.values().stream() .filter(modInfos -> modInfos.size() > 1) .map(mods -> String.format("\tMod ID: '%s' from mod files: %s", - mods.get(0).getModId(), + mods.getFirst().getModId(), mods.stream() .map(modInfo -> modInfo.getOwningFile().getFile().getFileName()).collect(joining(", ")) )).toList(); @@ -91,9 +91,8 @@ public class UniqueModListBuilder final List dupedLibErrors = versionedLibIds.values().stream() .filter(modFiles -> modFiles.size() > 1) .map(mods -> String.format("\tLibrary: '%s' from files: %s", - getModId(mods.get(0)), - mods.stream() - .map(modFile -> modFile.getFileName()).collect(joining(", ")) + getModId(mods.getFirst()), + mods.stream().map(ModFile::getFileName).collect(joining(", ")) )).toList(); if (!dupedLibErrors.isEmpty()) { @@ -107,25 +106,23 @@ public class UniqueModListBuilder final Map> uniqueModFilesByFirstId = uniqueModList.stream() .collect(groupingBy(UniqueModListBuilder::getModId)); - final List loadedList = new ArrayList<>(); - loadedList.addAll(uniqueModList); + final List loadedList = new ArrayList<>(uniqueModList); loadedList.addAll(uniqueLibListWithVersion); return new UniqueModListData(loadedList, uniqueModFilesByFirstId); } - private ModFile selectNewestModInfo(Map.Entry> fullList) { + private static ModFile selectNewestModInfo(Map.Entry> fullList) { List modInfoList = fullList.getValue(); if (modInfoList.size() > 1) { LOGGER.debug("Found {} mods for first modid {}, selecting most recent based on version data", modInfoList.size(), fullList.getKey()); - modInfoList.sort(Comparator.comparing(this::getVersion).reversed()); - LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.get(0).getFileName(), fullList.getKey(), this.getVersion(modInfoList.get(0))); + modInfoList.sort(Comparator.comparing(UniqueModListBuilder::getVersion).reversed()); + LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.getFirst().getFileName(), fullList.getKey(), getVersion(modInfoList.getFirst())); } return modInfoList.get(0); } - private ArtifactVersion getVersion(final ModFile mf) - { + private static ArtifactVersion getVersion(final ModFile mf) { if (mf.getModFileInfo() == null || mf.getModInfos() == null || mf.getModInfos().isEmpty()) { return mf.getJarVersion(); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/VersionSupportMatrix.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/VersionSupportMatrix.java index 7d118b9535..d13935a811 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/VersionSupportMatrix.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/VersionSupportMatrix.java @@ -5,33 +5,53 @@ package net.minecraftforge.fml.loading; -import net.minecraftforge.forgespi.language.MavenVersionAdapter; import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.VersionRange; +import org.jetbrains.annotations.ApiStatus; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.function.BiPredicate; +@ApiStatus.Internal // since 1.21.1, will be made non-public in a later MC version public class VersionSupportMatrix { - private static final HashMap> overrideVersions = new HashMap<>(); + private static final Map> OVERRIDE_VERSIONS; + static { - final ArtifactVersion version = new DefaultArtifactVersion(FMLLoader.versionInfo().mcVersion()); - if (MavenVersionAdapter.createFromVersionSpec("[1.21.1]").containsVersion(version)) { - // 1.21.1 is Compatible with 1.21 - add("languageloader.javafml", "51"); - add("mod.minecraft", "1.21"); - add("mod.forge", "51.0.33"); + if ("1.21.1".equals(FMLLoader.versionInfo().mcVersion())) { + OVERRIDE_VERSIONS = Map.ofEntries( + // 1.21.1 is compatible with 1.21 + entry("languageloader.javafml", "51"), + entry("mod.minecraft", "1.21"), + entry("mod.forge", "51.0.33") + ); + } else { + OVERRIDE_VERSIONS = Collections.emptyMap(); } } - private static void add(String key, String value) { - overrideVersions.computeIfAbsent(key, k -> new ArrayList<>()).add(new DefaultArtifactVersion(value)); - } - public static boolean testVersionSupportMatrix(VersionRange declaredRange, String lookupId, String type, BiPredicate standardLookup) { + + /** + * @deprecated Use {@link #testVersionSupportMatrix(VersionRange, String, String)} instead, unwrapping your BiPredicate. + */ + @Deprecated(forRemoval = true, since = "1.21.1") + public static boolean testVersionSupportMatrix(VersionRange declaredRange, String lookupId, String type, BiPredicate standardLookup) { if (standardLookup.test(lookupId, declaredRange)) return true; - List custom = overrideVersions.get(type + "." + lookupId); - return custom == null ? false : custom.stream().anyMatch(declaredRange::containsVersion); + return testVersionSupportMatrix(declaredRange, lookupId, type); + } + + public static boolean testVersionSupportMatrix(VersionRange declaredRange, String lookupId, String type) { + if (OVERRIDE_VERSIONS.isEmpty()) return false; + List custom = OVERRIDE_VERSIONS.get(type + "." + lookupId); + return custom != null && custom.stream().anyMatch(declaredRange::containsVersion); + } + + private static Map.Entry> entry(String typeAndLookupId, String declaredRange) { + return Map.entry(typeAndLookupId, List.of(new DefaultArtifactVersion(declaredRange))); + } + + private static Map.Entry> entry(String typeAndLookupId, List declaredRanges) { + return Map.entry(typeAndLookupId, declaredRanges.stream().map(DefaultArtifactVersion::new).map(it -> (ArtifactVersion) it).toList()); } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/log4j/ForgeHighlight.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/log4j/ForgeHighlight.java index 006d3988af..168a3d6621 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/log4j/ForgeHighlight.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/log4j/ForgeHighlight.java @@ -49,10 +49,7 @@ public class ForgeHighlight { LOGGER.warn("Failed to invoke initializeTerminal on TCA", e); } if (!TerminalConsoleAppender.isAnsiSupported() && Arrays.stream(options).noneMatch(s -> s.equals("disableAnsi=true"))) { - List optionList = new ArrayList<>(); - optionList.add(options[0]); - optionList.add("disableAnsi=true"); - options = optionList.toArray(new String[0]); + options = new String[] { options[0], "disableAnsi=true" }; } return HighlightConverter.newInstance(config, options); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java index e30aad435b..c768c5ce12 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/AbstractModProvider.java @@ -81,6 +81,11 @@ public abstract class AbstractModProvider implements IModProvider { var mf = mod.getSecureJar().moduleDataProvider().getManifest().getMainAttributes(); var license = mf.getValue("LICENSE"); var dummy = new IConfigurable() { + @Override + public Optional getConfigElement(String key) { + return Optional.empty(); + } + @Override public Optional getConfigElement(String... key) { return Optional.empty(); @@ -140,10 +145,11 @@ public abstract class AbstractModProvider implements IModProvider { } private static final class Holder { - T value; + private T value; } private record DefaultModFileInfo(IModFile mod, String license, IConfigurable configurable) implements IModFileInfo, IConfigurable { + @Override public Optional getConfigElement(final String string) { return Optional.empty(); } @Override public Optional getConfigElement(final String... strings) { return Optional.empty(); } @Override public List getConfigList(final String... strings) { return null; } @Override public List getMods() { return Collections.emptyList(); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java index 21f03ae4f1..a42a501904 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java @@ -29,6 +29,7 @@ public class BackgroundScanHandler } private static final Logger LOGGER = LogUtils.getLogger(); + private static final boolean DEBUG = LOGGER.isErrorEnabled(LogMarkers.SCAN); private final ExecutorService modContentScanner; private final List modFiles; private ScanStatus status; @@ -55,16 +56,16 @@ public class BackgroundScanHandler } status = ScanStatus.RUNNING; ImmediateWindowHandler.updateProgress("Scanning mod candidates"); - final CompletableFuture future = CompletableFuture.supplyAsync(file::compileContent, modContentScanner) - .whenComplete(file::setScanResult) - .whenComplete((r,t)-> this.addCompletedFile(file,r,t)); + CompletableFuture future = CompletableFuture.supplyAsync(file::compileContent, modContentScanner) + .whenComplete(file::setScanResult); + if (DEBUG) future = future.whenComplete((r, t) -> addCompletedFile(file, t)); file.setFutureScanResult(future); } - private void addCompletedFile(final ModFile file, final ModFileScanData modFileScanData, final Throwable throwable) { + private void addCompletedFile(final ModFile file, final Throwable throwable) { if (throwable != null) { status = ScanStatus.ERRORED; - LOGGER.error(LogMarkers.SCAN,"An error occurred scanning file {}", file, throwable); + LOGGER.error(LogMarkers.SCAN, "An error occurred scanning file {}", file, throwable); } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java index c75218cf42..7d8ba90442 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java @@ -18,9 +18,9 @@ import java.io.IOException; import java.net.URI; import java.net.URL; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.jar.Attributes; @@ -28,7 +28,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; @ApiStatus.Internal -public class ClasspathLocator extends AbstractModProvider implements IModLocator { +public final class ClasspathLocator extends AbstractModProvider implements IModLocator { private static final Logger LOGGER = LogUtils.getLogger(); private static final Attributes.Name MOD_TYPE = new Attributes.Name("FMLModType"); @@ -80,11 +80,11 @@ public class ClasspathLocator extends AbstractModProvider implements IModLocator return ret; } - private List getUrls(ClassLoader cl, String resource) { + private static List getUrls(ClassLoader cl, String resource) { try { var lst = Collections.list(cl.getResources(resource)); if (LOGGER.isDebugEnabled(LogMarkers.SCAN)) { - Collections.sort(lst, (a, b) -> a.toString().compareTo(b.toString())); + lst.sort(Comparator.comparing(URL::toString)); LOGGER.debug(LogMarkers.SCAN, "Scanning Classloader: {} for {}", cl, resource); for (var url : lst) LOGGER.debug(LogMarkers.SCAN, "\t{}", url); @@ -104,8 +104,7 @@ public class ClasspathLocator extends AbstractModProvider implements IModLocator len += 2; } str = str.substring(0, str.length() - len); - var path = Paths.get(URI.create(str)); - return path; + return Path.of(URI.create(str)); } private static Path getPathFromResource(ClassLoader cl, String resource) { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/CoreModFile.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/CoreModFile.java index 21c051c52c..f6328221d2 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/CoreModFile.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/CoreModFile.java @@ -15,7 +15,7 @@ import java.nio.file.Path; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal -public class CoreModFile implements ICoreModFile { +public final class CoreModFile implements ICoreModFile { private final Path internalPath; private final ModFile file; private final String name; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/JarInJarDependencyLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/JarInJarDependencyLocator.java index fb73e9677e..557b77c89a 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/JarInJarDependencyLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/JarInJarDependencyLocator.java @@ -6,7 +6,6 @@ package net.minecraftforge.fml.loading.moddiscovery; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; import com.mojang.logging.LogUtils; import net.minecraftforge.fml.loading.EarlyLoadingException; import net.minecraftforge.forgespi.language.IModInfo; @@ -26,6 +25,7 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -51,7 +51,7 @@ public class JarInJarDependencyLocator extends AbstractModProvider implements ID @Override public List scanMods(Iterable loadedMods) { - final List sources = Lists.newArrayList(); + final List sources = new ArrayList<>(); loadedMods.forEach(sources::add); var dependenciesToLoad = JarSelector.detectAndSelect( @@ -102,34 +102,34 @@ public class JarInJarDependencyLocator extends AbstractModProvider implements ID protected EarlyLoadingException exception(Collection> failedDependencies) { final List errors = failedDependencies.stream() .filter(entry -> !entry.sources().isEmpty()) //Should never be the case, but just to be sure - .map(this::buildExceptionData) + .map(JarInJarDependencyLocator::buildExceptionData) .toList(); return new EarlyLoadingException(failedDependencies.size() + " Dependency restrictions were not met.", null, errors); } @NotNull - private EarlyLoadingException.ExceptionData buildExceptionData(JarSelector.ResolutionFailureInformation entry) { + private static EarlyLoadingException.ExceptionData buildExceptionData(JarSelector.ResolutionFailureInformation entry) { return new EarlyLoadingException.ExceptionData( getErrorTranslationKey(entry), entry.identifier().group() + ":" + entry.identifier().artifact(), entry.sources() .stream() - .flatMap(this::getModWithVersionRangeStream) - .map(this::formatError) + .flatMap(JarInJarDependencyLocator::getModWithVersionRangeStream) + .map(JarInJarDependencyLocator::formatError) .collect(Collectors.joining(", ")) ); } @NotNull - private String getErrorTranslationKey(JarSelector.ResolutionFailureInformation entry) { + private static String getErrorTranslationKey(JarSelector.ResolutionFailureInformation entry) { return entry.failureReason() == JarSelector.FailureReason.VERSION_RESOLUTION_FAILED ? "fml.dependencyloading.conflictingdependencies" : "fml.dependencyloading.mismatchedcontaineddependencies"; } @NotNull - private Stream getModWithVersionRangeStream(JarSelector.SourceWithRequestedVersionRange file) { + private static Stream getModWithVersionRangeStream(JarSelector.SourceWithRequestedVersionRange file) { return file.sources() .stream() .map(IModFile::getModFileInfo) @@ -152,7 +152,7 @@ public class JarInJarDependencyLocator extends AbstractModProvider implements ID } @NotNull - private String formatError(ModWithVersionRange modWithVersionRange){ + private static String formatError(ModWithVersionRange modWithVersionRange){ return YELLOW + modWithVersionRange.modInfo().getModId() + RESET + " - " + RED + modWithVersionRange.versionRange().toString() + RESET + " - " + GREEN + modWithVersionRange.artifactVersion().toString() + RESET; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/MinecraftLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/MinecraftLocator.java index 7bb15b499c..42b725bb36 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/MinecraftLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/MinecraftLocator.java @@ -18,7 +18,7 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal -public class MinecraftLocator extends AbstractModProvider implements IModLocator { +public final class MinecraftLocator extends AbstractModProvider implements IModLocator { @Override public List scanMods() { var minecraft = FMLLoader.getLaunchHandler().getMinecraftPaths(); @@ -29,13 +29,13 @@ public class MinecraftLocator extends AbstractModProvider implements IModLocator jar -> meta, minecraft.toArray(Path[]::new) ); - var mc = ModFileFactory.FACTORY.build(mcjar, this, this::buildMinecraftTOML); + var mc = ModFileFactory.FACTORY.build(mcjar, this, MinecraftLocator::buildMinecraftTOML); meta.setModFile(mc); return List.of(new ModFileOrException(mc, null)); } - private IModFileInfo buildMinecraftTOML(final IModFile iModFile) { + private static IModFileInfo buildMinecraftTOML(final IModFile iModFile) { // We haven't changed this in years, and I can't be asked right now to special case this one file in the path. final var conf = Config.inMemory(); conf.set("modLoader", "minecraft"); @@ -52,7 +52,7 @@ public class MinecraftLocator extends AbstractModProvider implements IModLocator conf.set("mods", List.of(mods)); var configWrapper = new NightConfigWrapper(conf); - return new ModFileInfo((ModFile)iModFile, configWrapper, configWrapper::setFile, List.of()); + return new ModFileInfo((ModFile) iModFile, configWrapper, configWrapper::setFile); } @Override diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java index 9dc87dbd9d..0f805b284c 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java @@ -6,7 +6,6 @@ package net.minecraftforge.fml.loading.moddiscovery; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; import com.mojang.logging.LogUtils; import cpw.mods.modlauncher.Launcher; import cpw.mods.modlauncher.api.IModuleLayerManager; @@ -28,6 +27,7 @@ import org.jetbrains.annotations.ApiStatus; import org.slf4j.Logger; import java.util.ArrayList; +import java.util.EnumMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -49,17 +49,19 @@ public class ModDiscoverer { modLocators = ServiceLoader.load(moduleLayerManager.getLayer(IModuleLayerManager.Layer.SERVICE).orElseThrow(), IModLocator.class); dependencyLocators = ServiceLoader.load(moduleLayerManager.getLayer(IModuleLayerManager.Layer.SERVICE).orElseThrow(), IDependencyLocator.class); modLocatorList = ServiceLoaderUtils.streamServiceLoader(()-> modLocators, sce->LOGGER.error("Failed to load mod locator list", sce)).collect(Collectors.toList()); - modLocatorList.forEach(l->l.initArguments(arguments)); + for (IModLocator iModLocator : modLocatorList) { + iModLocator.initArguments(arguments); + } dependencyLocatorList = ServiceLoaderUtils.streamServiceLoader(()-> dependencyLocators, sce->LOGGER.error("Failed to load dependency locator list", sce)).collect(Collectors.toList()); - dependencyLocatorList.forEach(l->l.initArguments(arguments)); + for (IDependencyLocator l : dependencyLocatorList) { + l.initArguments(arguments); + } if (LOGGER.isDebugEnabled(LogMarkers.CORE)) { LOGGER.debug(LogMarkers.CORE, "Found Mod Locators : {}", modLocatorList.stream() .map(modLocator -> "(%s:%s)".formatted(modLocator.name(), modLocator.getClass().getPackage().getImplementationVersion())).collect(Collectors.joining(","))); - } - if (LOGGER.isDebugEnabled(LogMarkers.CORE)) - { + LOGGER.debug(LogMarkers.CORE, "Found Dependency Locators : {}", dependencyLocatorList.stream() .map(dependencyLocator -> "(%s:%s)".formatted(dependencyLocator.name(), dependencyLocator.getClass().getPackage().getImplementationVersion())).collect(Collectors.joining(","))); @@ -126,7 +128,7 @@ public class ModDiscoverer { } //First processing run of the mod list. Any duplicates will cause resolution failure and dependency loading will be skipped. - Map> modFilesMap = Maps.newHashMap(); + Map> modFilesMap = new EnumMap<>(IModFile.Type.class); try { final UniqueModListBuilder modsUniqueListBuilder = new UniqueModListBuilder(loadedFiles); final UniqueModListBuilder.UniqueModListData uniqueModsData = modsUniqueListBuilder.buildUniqueList(); @@ -134,7 +136,7 @@ public class ModDiscoverer { //Grab the temporary results. //This allows loading to continue to a base state, in case dependency loading fails. modFilesMap = uniqueModsData.modFiles().stream() - .collect(Collectors.groupingBy(IModFile::getType)); + .collect(Collectors.groupingBy(IModFile::getType, () -> new EnumMap<>(IModFile.Type.class), Collectors.toList())); loadedFiles = uniqueModsData.modFiles(); } catch (EarlyLoadingException exception) { @@ -171,11 +173,11 @@ public class ModDiscoverer { //We now only need the mod files map, not the list. modFilesMap = uniqueModsAndDependenciesData.modFiles().stream() - .collect(Collectors.groupingBy(IModFile::getType)); + .collect(Collectors.groupingBy(IModFile::getType, () -> new EnumMap<>(IModFile.Type.class), Collectors.toList())); } catch (EarlyLoadingException exception) { LOGGER.error(LogMarkers.SCAN, "Failed to build unique mod list after dependency discovery.", exception); discoveryErrorData.addAll(exception.getAllData()); - modFilesMap = loadedFiles.stream().collect(Collectors.groupingBy(IModFile::getType)); + modFilesMap = loadedFiles.stream().collect(Collectors.groupingBy(IModFile::getType, () -> new EnumMap<>(IModFile.Type.class), Collectors.toList())); } } else { @@ -190,8 +192,7 @@ public class ModDiscoverer { return validator; } - private void handleLocatedFiles(final List loadedFiles, final List locatedFiles) - { + private static void handleLocatedFiles(final List loadedFiles, final List locatedFiles) { var locatedModFiles = locatedFiles.stream().filter(ModFile.class::isInstance).map(ModFile.class::cast).toList(); for (IModFile mf : locatedModFiles) { LOGGER.info(LogMarkers.SCAN, "Found mod file {} of type {} with provider {}", mf.getFileName(), mf.getType(), mf.getProvider()); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java index 76475da581..4bb161a0e8 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java @@ -45,7 +45,6 @@ public class ModFile implements IModFile { private Throwable scanError; private final SecureJar jar; private final Type modFileType; - private final Manifest manifest; private final IModProvider provider; private IModFileInfo modFileInfo; private ModFileScanData fileModFileScanData; @@ -65,7 +64,7 @@ public class ModFile implements IModFile { this.jar = jar; this.parser = parser; - manifest = this.jar.moduleDataProvider().getManifest(); + var manifest = this.jar.moduleDataProvider().getManifest(); modFileType = Type.valueOf(type); jarVersion = Optional.ofNullable(manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION)).orElse("0.0NONE"); this.modFileInfo = ModFileParser.readModList(this, this.parser); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java index 804aa848c4..4316c5f40b 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java @@ -104,11 +104,11 @@ public class ModFileInfo implements IModFileInfo, IConfigurable { this.modFile.setFileProperties(this.properties); final List modConfigs = config.getConfigList("mods"); - if (modConfigs.isEmpty()) + if (modConfigs == null || modConfigs.isEmpty()) throw new InvalidModFileException("Missing mods list", this); this.mods = modConfigs.stream() - .map(mi-> (IModInfo)new ModInfo(this, mi)) + .map(mi -> (IModInfo) ModInfo.of(this, mi)) .toList(); if (LOGGER.isDebugEnabled(LogMarkers.LOADING)) { @@ -158,6 +158,11 @@ public class ModFileInfo implements IModFileInfo, IConfigurable { return this.showAsDataPack; } + @Override + public Optional getConfigElement(final String key) { + return this.config.getConfigElement(key); + } + @Override public Optional getConfigElement(final String... key) { return this.config.getConfigElement(key); @@ -186,7 +191,7 @@ public class ModFileInfo implements IModFileInfo, IConfigurable { return Strings.isNullOrEmpty(license); } - private final char[] HEX = "0123456789ABCDEF".toCharArray(); + private static final char[] HEX = "0123456789ABCDEF".toCharArray(); public Optional getCodeSigningFingerprint() { var signers = this.modFile.getSecureJar().getManifestSigners(); if (signers == null) diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java index a4fccb38af..f41741e423 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java @@ -27,211 +27,181 @@ import java.util.Optional; import java.util.regex.Pattern; @ApiStatus.Internal -public class ModInfo implements IModInfo, IConfigurable { +public record ModInfo( + ModFileInfo getOwningFile, + IConfigurable getConfig, + + String getModId, + String getNamespace, + ArtifactVersion getVersion, + + String getDisplayName, + String getDescription, + Optional getLogoFile, + boolean getLogoBlur, + Optional getUpdateURL, + Optional getModURL, + + Holder> dependencies, + Holder> forgeFeatures, + Map getModProperties +) implements IModInfo, IConfigurable { private static final Logger LOGGER = LogUtils.getLogger(); private static final DefaultArtifactVersion DEFAULT_VERSION = new DefaultArtifactVersion("1"); private static final Pattern VALID_MODID = Pattern.compile("^[a-z][a-z0-9_]{1,63}$"); private static final Pattern VALID_NAMESPACE = Pattern.compile("^[a-z][a-z0-9_.-]{1,63}$"); private static final Pattern VALID_VERSION = Pattern.compile("^\\d+.*"); - private final ModFileInfo owningFile; - private final String modId; - private final String namespace; - private final ArtifactVersion version; - private final String displayName; - private final String description; - private final Optional logoFile; - private final boolean logoBlur; - private final Optional updateJSONURL; - private final List dependencies; - - private final List features; - private final Map properties; - private final IConfigurable config; - private final Optional modUrl; - - public ModInfo(final ModFileInfo owningFile, final IConfigurable config) { - Optional ownFile = Optional.ofNullable(owningFile); - this.owningFile = owningFile; - this.config = config; - + public static ModInfo of(ModFileInfo owningFile, IConfigurable config) { // These are sourced from the mod specific [[mod]] entry - this.modId = config.getConfigElement("modId") - .orElseThrow(() -> new InvalidModFileException("Missing modId", owningFile)); + String modId = config.getConfigElement("modId").orElse(null); + if (modId == null) + throw new InvalidModFileException("Missing modId", owningFile); // verify we have a valid modid - if (!VALID_MODID.matcher(this.modId).matches()) { - LOGGER.error(LogUtils.FATAL_MARKER, "Invalid modId found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.modId, VALID_MODID.pattern()); - throw new InvalidModFileException("Invalid modId found : " + this.modId, owningFile); + if (!VALID_MODID.matcher(modId).matches()) { + LOGGER.error(LogUtils.FATAL_MARKER, "Invalid modId found in file {} - {} does not match the standard: {}", owningFile.getFile().getFilePath(), modId, VALID_MODID.pattern()); + throw new InvalidModFileException("Invalid modId found : " + modId, owningFile); } - this.namespace = config.getConfigElement("namespace") - .orElse(this.modId); + String namespace = config.getConfigElement("namespace") + .orElse(modId); // verify our namespace is valid - if (!VALID_NAMESPACE.matcher(this.namespace).matches()) { - LOGGER.error(LogUtils.FATAL_MARKER, "Invalid override namespace found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.namespace, VALID_NAMESPACE.pattern()); - throw new InvalidModFileException("Invalid override namespace found : " + this.namespace, owningFile); + if (!VALID_NAMESPACE.matcher(namespace).matches()) { + LOGGER.error(LogUtils.FATAL_MARKER, "Invalid override namespace found in file {} - {} does not match the standard: {}", owningFile.getFile().getFilePath(), namespace, VALID_NAMESPACE.pattern()); + throw new InvalidModFileException("Invalid override namespace found : " + namespace, owningFile); } - this.version = config.getConfigElement("version") - .map(s -> StringSubstitutor.replace(s, ownFile.map(ModFileInfo::getFile).orElse(null))) + ArtifactVersion version = config.getConfigElement("version") + .map(s -> StringSubstitutor.replace(s, owningFile.getFile())) .map(DefaultArtifactVersion::new) .orElse(DEFAULT_VERSION); // verify we have a valid mod version - if (!VALID_VERSION.matcher(this.version.toString()).matches()) - throw new InvalidModFileException("Illegal version number specified " + this.version, this.getOwningFile()); + if (!VALID_VERSION.matcher(version.toString()).matches()) + throw new InvalidModFileException("Illegal version number specified " + version, owningFile); // The remaining properties all default to sensible values and are not essential - this.displayName = config.getConfigElement("displayName") - .orElse(this.modId); - this.description = config.getConfigElement("description") + String displayName = config.getConfigElement("displayName") + .orElse(modId); + + String description = config.getConfigElement("description") .orElse("MISSING DESCRIPTION") .replace("\r\n", "\n").stripIndent(); - this.logoFile = Optional.ofNullable(config.getConfigElement("logoFile") - .orElseGet(() -> ownFile.flatMap(mf -> mf.getConfigElement("logoFile")) - .orElse(null))); - this.logoBlur = config.getConfigElement("logoBlur") - .orElseGet(() -> ownFile.flatMap(mf -> mf.getConfigElement("logoBlur")) - .orElse(true)); - this.updateJSONURL = config.getConfigElement("updateJSONURL") - .map(StringUtils::toURL); - this.modUrl = config.getConfigElement("modUrl") + + Optional logoFile = Optional.ofNullable( + config.getConfigElement("logoFile") + .orElseGet(() -> owningFile.getConfigElement("logoFile").orElse(null)) + ); + + Boolean logoBlur = config.getConfigElement("logoBlur").orElse(null); + if (logoBlur == null) + logoBlur = owningFile.getConfigElement("logoBlur").orElse(true); + + Optional updateJSONURL = config.getConfigElement("updateJSONURL") .map(StringUtils::toURL); - // These are sourced from the file rather than the mod-specific block, but with a modid tag - if (ownFile.isEmpty()) { - this.dependencies = Collections.emptyList(); - this.features = Collections.emptyList(); - this.properties = Collections.emptyMap(); - } else { - var deps = this.owningFile.getConfigList("dependencies", this.modId); - if (deps == null || deps.isEmpty()) { - this.dependencies = Collections.emptyList(); - } else { - var tmp = new ArrayList(); - for (var dep : deps) - tmp.add(new ModVersion(this, dep)); - this.dependencies = Collections.unmodifiableList(tmp); - } + Optional modUrl = config.getConfigElement("modUrl") + .map(StringUtils::toURL); - var feats = this.owningFile.>getConfigElement("features", this.modId).orElse(null); - if (feats == null) { - this.features = Collections.emptyList(); - } else { - var tmp = new ArrayList(); - for (var entry : feats.entrySet()) { - if (!(entry.getValue() instanceof String val)) - throw new InvalidModFileException("Invalid feature bound {" + entry.getValue() + "} for key {" + entry.getKey() + "} only strings are accepted", this.owningFile); - tmp.add(new ForgeFeature.Bound(entry.getKey(), val, this)); - } - this.features = Collections.unmodifiableList(tmp); - } + // dependencies and features are done after the constructor as they need to reference the ModInfo we are creating + List dependencies = Collections.emptyList(); + List forgeFeatures = Collections.emptyList(); - var props = this.owningFile.>getConfigElement("modproperties", this.modId).orElse(null); - if (props == null) - this.properties = Collections.emptyMap(); - else - this.properties = Collections.unmodifiableMap(props); + Map modProperties = owningFile.>getConfigElement("modproperties", modId) + .map(Collections::unmodifiableMap) + .orElse(Collections.emptyMap()); + + return new ModInfo( + owningFile, config, + modId, namespace, version, + displayName, description, logoFile, logoBlur, updateJSONURL, modUrl, + new Holder<>(dependencies), new Holder<>(forgeFeatures), modProperties + ).setupDependencies().setupForgeFeatures(); + } + + private ModInfo setupDependencies() { + var deps = getOwningFile.getConfigList("dependencies", getModId); + if (deps == null || deps.isEmpty()) { + dependencies.value = Collections.emptyList(); + return this; } + + var tmp = new ModVersion[deps.size()]; + for (int i = 0; i < deps.size(); i++) { + tmp[i] = ModVersion.of(this, deps.get(i)); + } + dependencies.value = List.of(tmp); + return this; } - @Override - public ModFileInfo getOwningFile() { - return owningFile; - } + private ModInfo setupForgeFeatures() { + var feats = getOwningFile.>getConfigElement("features", getModId).orElse(null); + if (feats == null) { + forgeFeatures.value = Collections.emptyList(); + return this; + } - @Override - public String getModId() { - return modId; - } - - @Override - public String getDisplayName() { - return this.displayName; - } - - @Override - public String getDescription() { - return this.description; - } - - @Override - public ArtifactVersion getVersion() { - return version; - } - - @Override - public List getDependencies() { - return this.dependencies; - } - - @Override - public String getNamespace() { - return this.namespace; - } - - @Override - public Map getModProperties() { - return this.properties; - } - - @Override - public Optional getUpdateURL() { - return this.updateJSONURL; - } - - @Override - public Optional getLogoFile() { - return this.logoFile; - } - - @Override - public boolean getLogoBlur() { - return this.logoBlur; - } - - @Override - public IConfigurable getConfig() { + var tmp = new ArrayList(); + for (var entry : feats.entrySet()) { + if (!(entry.getValue() instanceof String val)) + throw new InvalidModFileException("Invalid feature bound {" + entry.getValue() + "} for key {" + entry.getKey() + "} only strings are accepted", getOwningFile); + tmp.add(new ForgeFeature.Bound(entry.getKey(), val, this)); + } + forgeFeatures.value = List.copyOf(tmp); return this; } @Override - public List getForgeFeatures() { - return this.features; + public Optional getConfigElement(String key) { + return getConfig.getConfigElement(key); } @Override - public Optional getConfigElement(final String... key) { - return this.config.getConfigElement(key); + public Optional getConfigElement(String... key) { + return getConfig.getConfigElement(key); } @Override - public List getConfigList(final String... key) { + public List getConfigList(String... key) { return null; } @Override - public Optional getModURL() { - return modUrl; + public List getDependencies() { + return dependencies.value; } - class ModVersion implements net.minecraftforge.forgespi.language.IModInfo.ModVersion { - private IModInfo owner; - private final String modId; - private final VersionRange versionRange; - private final boolean mandatory; - private final Ordering ordering; - private final DependencySide side; - private final Optional referralUrl; + @Override + public List getForgeFeatures() { + return forgeFeatures.value; + } - public ModVersion(final IModInfo owner, final IConfigurable config) { - this.owner = owner; - this.modId = config.getConfigElement("modId") - .orElseThrow(()->new InvalidModFileException("Missing required field modid in dependency", getOwningFile())); + private static final class Holder { + private T value; - if (this.modId.equals("forge")) { + public Holder(T value) { + this.value = value; + } + } + + private record ModVersion( + Holder owner, + + String getModId, + VersionRange getVersionRange, + boolean isMandatory, + Ordering getOrdering, + DependencySide getSide, + Optional getReferralURL + ) implements IModInfo.ModVersion { + public static ModVersion of(IModInfo owner, IConfigurable config) { + var modId = config.getConfigElement("modId").orElse(null); + if (modId == null) + throw new InvalidModFileException("Missing required field modid in dependency", owner.getOwningFile()); + + if (modId.equals("forge")) { var fileProps = owner.getOwningFile().getFileProperties(); // Checking containsKey to avoid a possible exception if the property is not present (due to Collections.emptyMap()) if (!fileProps.isEmpty() && fileProps.containsKey(ModFileInfo.NOT_A_FORGE_MOD_PROP)) { @@ -241,65 +211,41 @@ public class ModInfo implements IModInfo, IConfigurable { } } - var mandatory = config.getConfigElement("mandatory"); - if (mandatory.isPresent()) - this.mandatory = mandatory.get(); + boolean mandatory; + var mandatoryValue = config.getConfigElement("mandatory"); + if (mandatoryValue.isPresent()) + mandatory = mandatoryValue.get(); else if (owner.getOwningFile().getFileProperties().containsKey(ModFileInfo.NOT_A_FORGE_MOD_PROP)) - this.mandatory = true; + mandatory = true; else - throw new InvalidModFileException("Missing required field mandatory in dependency", getOwningFile()); + throw new InvalidModFileException("Missing required field mandatory in dependency", owner.getOwningFile()); - this.versionRange = config.getConfigElement("versionRange") + var versionRange = config.getConfigElement("versionRange") .map(MavenVersionAdapter::createFromVersionSpec) .orElse(UNBOUNDED); - this.ordering = config.getConfigElement("ordering") + var ordering = config.getConfigElement("ordering") .map(Ordering::valueOf) .orElse(Ordering.NONE); - this.side = config.getConfigElement("side") + var side = config.getConfigElement("side") .map(DependencySide::valueOf) .orElse(DependencySide.BOTH); - this.referralUrl = config.getConfigElement("referralUrl") + var referralUrl = config.getConfigElement("referralUrl") .map(StringUtils::toURL); - } - @Override - public String getModId() { - return modId; - } - - @Override - public VersionRange getVersionRange() { - return versionRange; - } - - @Override - public boolean isMandatory() { - return mandatory; - } - - @Override - public Ordering getOrdering() { - return ordering; - } - - @Override - public DependencySide getSide() { - return side; - } - - @Override - public void setOwner(final IModInfo owner) { - this.owner = owner; + return new ModVersion( + new Holder<>(owner), + modId, versionRange, mandatory, ordering, side, referralUrl + ); } @Override public IModInfo getOwner() { - return owner; + return owner.value; } @Override - public Optional getReferralURL() { - return referralUrl; + public void setOwner(IModInfo newOwner) { + owner.value = newOwner; } } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java index 021e5fab45..3bac307894 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModValidator.java @@ -64,7 +64,7 @@ public class ModValidator { } @NotNull - private List validateFiles(final List mods) { + private static List validateFiles(final List mods) { final List brokenFiles = new ArrayList<>(); for (Iterator iterator = mods.iterator(); iterator.hasNext();) { ModFile modFile = iterator.next(); @@ -106,8 +106,8 @@ public class ModValidator { private List validateLanguages() { List errorData = new ArrayList<>(); - for (Iterator iterator = this.candidateMods.iterator(); iterator.hasNext(); ) { - final ModFile modFile = iterator.next(); + for (Iterator iterator = this.candidateMods.iterator(); iterator.hasNext();) { + var modFile = iterator.next(); try { modFile.identifyLanguage(); } catch (EarlyLoadingException e) { diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java index 702e41179a..3453bd184f 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java @@ -18,11 +18,12 @@ import java.util.Optional; import java.util.stream.Collectors; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import static java.util.Arrays.asList; @ApiStatus.Internal -class NightConfigWrapper implements IConfigurable { +final class NightConfigWrapper implements IConfigurable { private final UnmodifiableConfig config; private IModFileInfo file; @@ -30,39 +31,51 @@ class NightConfigWrapper implements IConfigurable { this.config = config; } - NightConfigWrapper setFile(IModFileInfo file) { + private NightConfigWrapper(UnmodifiableConfig config, IModFileInfo file) { + this.config = config; + this.file = file; + } + + void setFile(IModFileInfo file) { this.file = file; - return this; } @Override - @SuppressWarnings("unchecked") + public Optional getConfigElement(String key) { + var path = List.of(key); + return Optional.ofNullable(validate(this.config.get(path), path)); + } + + @Override public Optional getConfigElement(final String... key) { var path = asList(key); - return this.config.getOptional(path).map(value -> { - if (value instanceof UnmodifiableConfig cfg) { - // New Night config doesn't implement valueMap(), so do a copy. - var builder = ImmutableMap.builder(); - for (var e: cfg.entrySet()) - builder.put(e.getKey(), e.getValue()); - return (T)builder.build(); - } else if (value instanceof ArrayList al && al.size() > 0 && al.get(0) instanceof UnmodifiableConfig) { - throw new InvalidModFileException("The configuration path " + path + " is invalid. I wasn't expecting a multi-object list - remove one of the [[ ]]", file); - } - return (T) value; - }); + return Optional.ofNullable(validate(this.config.get(path), path)); + } + + @SuppressWarnings("unchecked") + private T validate(@Nullable T value, List path) { + if (value instanceof UnmodifiableConfig cfg) { + // New Night config doesn't implement valueMap(), so do a copy. + var entries = cfg.entrySet(); + var builder = ImmutableMap.builderWithExpectedSize(entries.size()); + for (var e : entries) + builder.put(e.getKey(), e.getValue()); + return (T) builder.build(); + } else if (value instanceof ArrayList al && !al.isEmpty() && al.getFirst() instanceof UnmodifiableConfig) { + throw new InvalidModFileException("The configuration path " + path + " is invalid. I wasn't expecting a multi-object list - remove one of the [[ ]]", file); + } + return value; } @Override public List getConfigList(final String... key) { final List path = asList(key); if (this.config.contains(path) && !(this.config.get(path) instanceof Collection)) { - throw new InvalidModFileException("The configuration path "+path+" is invalid. Expecting a collection!", file); + throw new InvalidModFileException("The configuration path " + path + " is invalid. Expecting a collection!", file); } final Collection nestedConfigs = this.config.getOrElse(path, ArrayList::new); return nestedConfigs.stream() - .map(NightConfigWrapper::new) - .map(cw->cw.setFile(file)) + .map(conf -> new NightConfigWrapper(conf, file)) .collect(Collectors.toList()); } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java index c4c7374dab..bb28c28d1a 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java @@ -21,37 +21,36 @@ import java.nio.file.Path; import java.util.List; @ApiStatus.Internal -class Scanner { +record Scanner(ModFile fileToScan, ModFileScanData result) { private static final Logger LOGGER = LogUtils.getLogger(); - private final ModFile fileToScan; + private static final boolean DEBUG = LOGGER.isDebugEnabled(LogMarkers.SCAN); - public Scanner(final ModFile fileToScan) { - this.fileToScan = fileToScan; + public Scanner(ModFile fileToScan) { + this(fileToScan, new ModFileScanData()); } public ModFileScanData scan() { - ModFileScanData result = new ModFileScanData(); result.addModFileInfo(fileToScan.getModFileInfo()); - fileToScan.scanFile(p -> fileVisitor(p, result)); + fileToScan.scanFile(this::fileVisitor); final List loaders = fileToScan.getLoaders(); if (loaders != null) { - loaders.forEach(loader -> { - LOGGER.debug(LogMarkers.SCAN, "Scanning {} with language loader {}", fileToScan.getFilePath(), loader.name()); + for (IModLanguageProvider loader : loaders) { + if (DEBUG) LOGGER.debug("Scanning {} with language loader {}", fileToScan.getFilePath(), loader.name()); loader.getFileVisitor().accept(result); - }); + } } return result; } - private void fileVisitor(final Path path, final ModFileScanData result) { - LOGGER.debug(LogMarkers.SCAN,"Scanning {} path {}", fileToScan, path); - try (InputStream in = Files.newInputStream(path)){ + private void fileVisitor(final Path path) { + try (InputStream in = Files.newInputStream(path)) { ModClassVisitor mcv = new ModClassVisitor(); ClassReader cr = new ClassReader(in); cr.accept(mcv, 0); mcv.buildData(result.getClasses(), result.getAnnotations()); } catch (IOException | IllegalArgumentException e) { // mark path bad + if (DEBUG) LOGGER.warn("Failed scanning {} path {}", fileToScan, path); } } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java index cf17ddf779..3f212a2a49 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ArgumentList.java @@ -24,8 +24,8 @@ import java.util.function.Supplier; @ApiStatus.Internal class ArgumentList { private static final Logger LOGGER = LogUtils.getLogger(); - private List> entries = new ArrayList<>(); - private Map values = new HashMap<>(); + private final List> entries = new ArrayList<>(); + private final Map values = new HashMap<>(); public static ArgumentList from(String... args) { ArgumentList ret = new ArgumentList(); @@ -77,8 +77,8 @@ class ArgumentList { public String[] getArguments() { return entries.stream() - .flatMap(e -> Arrays.asList(e.get()).stream()) - .toArray(size -> new String[size]); + .flatMap(e -> Arrays.stream(e.get())) + .toArray(String[]::new); } public boolean hasValue(String key) { @@ -122,7 +122,7 @@ class ArgumentList { return ent.getValue(); } - private class EntryValue implements Supplier { + private static final class EntryValue implements Supplier { private final String prefix; private final String key; private final boolean split; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java index 426c644ec0..c001bd6aa5 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonDevLaunchHandler.java @@ -40,7 +40,7 @@ abstract class CommonDevLaunchHandler extends CommonLaunchHandler { String username = args.get("username"); if (username != null) { // Replace '#' placeholders with random numbers Matcher m = Pattern.compile("#+").matcher(username); - StringBuffer replaced = new StringBuffer(); + StringBuilder replaced = new StringBuilder(); while (m.find()) { m.appendReplacement(replaced, getRandomNumbers(m.group().length())); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java index 79b7d4ae9f..abcfe7c3eb 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/CommonLaunchHandler.java @@ -7,7 +7,6 @@ package net.minecraftforge.fml.loading.targets; import com.mojang.logging.LogUtils; import cpw.mods.modlauncher.api.ILaunchHandlerService; -import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder; import cpw.mods.modlauncher.api.ServiceRunner; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.api.distmarker.Dist; @@ -19,7 +18,6 @@ import org.slf4j.Logger; import java.io.IOException; import java.net.URI; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; /** @@ -47,10 +45,6 @@ public abstract class CommonLaunchHandler implements ILaunchHandlerService { public abstract List getMinecraftPaths(); - @Override - public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) { - } - protected String[] preLaunch(String[] arguments, ModuleLayer layer) { URI uri; try (var reader = layer.configuration().findModule("net.minecraftforge.fmlloader").orElseThrow().reference().open()) { @@ -107,7 +101,7 @@ public abstract class CommonLaunchHandler implements ILaunchHandlerService { len += 2; } str = str.substring(0, str.length() - len); - var path = Paths.get(URI.create(str)); + var path = Path.of(URI.create(str)); return path; } } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java index 00a1e90e7c..dd3c84deae 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLaunchHandler.java @@ -9,7 +9,7 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal -abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler { +sealed abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler { private ForgeDevLaunchHandler(LaunchType type) { super(type, "forge_dev_"); } @@ -33,25 +33,25 @@ abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler { return List.of(filtered); } - public static class Client extends ForgeDevLaunchHandler { + public static final class Client extends ForgeDevLaunchHandler { public Client() { super(CLIENT); } } - public static class Data extends ForgeDevLaunchHandler { + public static final class Data extends ForgeDevLaunchHandler { public Data() { super(DATA); } } - public static class Server extends ForgeDevLaunchHandler { + public static final class Server extends ForgeDevLaunchHandler { public Server() { super(SERVER); } } - public static class ServerGameTest extends ForgeDevLaunchHandler { + public static final class ServerGameTest extends ForgeDevLaunchHandler { public ServerGameTest() { super(SERVER_GAMETEST); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLocator.java index 5e9f53fd12..19edc71adc 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeDevLocator.java @@ -35,7 +35,7 @@ import net.minecraftforge.fml.loading.moddiscovery.AbstractModProvider; import net.minecraftforge.forgespi.locating.IModLocator; @ApiStatus.Internal -public class ForgeDevLocator extends AbstractModProvider implements IModLocator { +public final class ForgeDevLocator extends AbstractModProvider implements IModLocator { private static final String PACK_META = "pack.mcmeta"; @Override @@ -60,7 +60,7 @@ public class ForgeDevLocator extends AbstractModProvider implements IModLocator return ret; } - private List getMods() { + private static List getMods() { // Forge is an exploded directory as well var minecraft = ForgeDevLaunchHandler.getPathFromResource("net/minecraft/client/Minecraft.class"); var forge = ForgeDevLaunchHandler.getPathFromResource("net/minecraftforge/common/MinecraftForge.class"); @@ -84,7 +84,7 @@ public class ForgeDevLocator extends AbstractModProvider implements IModLocator return ret; } - private List explodeTestMods(Path path) { + private static List explodeTestMods(Path path) { var mod = new ArrayList(); var memory = Jimfs.newFileSystem(); @@ -137,7 +137,7 @@ public class ForgeDevLocator extends AbstractModProvider implements IModLocator // Find all the @Mods so we can generate tomls, and so we can pick packages. Right now it doesn't allow mods in parent directories, // I could make it merge all the way up, but I think this would be fine. - private Map> findTestModPackages(Path path) { + private static Map> findTestModPackages(Path path) { var mods = new HashMap>(); try (var files = Files.walk(path)) { var classes = files @@ -190,7 +190,7 @@ public class ForgeDevLocator extends AbstractModProvider implements IModLocator } // Builds or update the mods.toml file for all @Mods in this package - private void buildModsToml(Set resources, Set modids, Path root) { + private static void buildModsToml(Set resources, Set modids, Path root) { var toml = resources.stream() .map(p -> p.resolve(MODS_TOML)) .filter(Files::exists) @@ -226,7 +226,7 @@ public class ForgeDevLocator extends AbstractModProvider implements IModLocator } for (var modid : modids) { - if (!modlist.stream().anyMatch(c -> modid.equals(c.get("modId")))) { + if (modlist.stream().noneMatch(c -> modid.equals(c.get("modId")))) { modified = true; var tmp = Config.inMemory(); tmp.set("modId", modid); @@ -248,7 +248,7 @@ public class ForgeDevLocator extends AbstractModProvider implements IModLocator } // This is optional, it just hides a warning screen when starting up. I should probably remove this once I restructure how data gen for test mods work and make it generate there. - private void buildPackMeta(Set paths, Path root) { + private static void buildPackMeta(Set paths, Path root) { var existing = paths.stream() .map(p -> p.resolve(PACK_META)) .filter(Files::exists) diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java index 4651575ccc..1488be3a7a 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeProdLaunchHandler.java @@ -10,7 +10,7 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal -abstract class ForgeProdLaunchHandler extends CommonLaunchHandler { +sealed abstract class ForgeProdLaunchHandler extends CommonLaunchHandler { protected ForgeProdLaunchHandler(LaunchType type) { super(type, "forge_"); } @@ -18,7 +18,7 @@ abstract class ForgeProdLaunchHandler extends CommonLaunchHandler { @Override public String getNaming() { return "mcp"; } @Override public boolean isProduction() { return true; } - public static class Client extends ForgeProdLaunchHandler { + public static final class Client extends ForgeProdLaunchHandler { public Client() { super(CLIENT); } @@ -29,7 +29,7 @@ abstract class ForgeProdLaunchHandler extends CommonLaunchHandler { } } - public static class Server extends ForgeProdLaunchHandler { + public static final class Server extends ForgeProdLaunchHandler { public Server() { super(SERVER); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java index a8aaa440a0..295afc91b9 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLaunchHandler.java @@ -14,7 +14,7 @@ import org.jetbrains.annotations.ApiStatus; import cpw.mods.jarhandling.SecureJar; @ApiStatus.Internal -abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler { +sealed abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler { private ForgeUserdevLaunchHandler(LaunchType type) { super(type, "forge_userdev_"); } @@ -33,25 +33,25 @@ abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler { return List.of(minecraft); } - public static class Client extends ForgeUserdevLaunchHandler { + public static final class Client extends ForgeUserdevLaunchHandler { public Client() { super(CLIENT); } } - public static class Data extends ForgeUserdevLaunchHandler { + public static final class Data extends ForgeUserdevLaunchHandler { public Data() { super(DATA); } } - public static class Server extends ForgeUserdevLaunchHandler { + public static final class Server extends ForgeUserdevLaunchHandler { public Server() { super(SERVER); } } - public static class ServerGameTest extends ForgeUserdevLaunchHandler { + public static final class ServerGameTest extends ForgeUserdevLaunchHandler { public ServerGameTest() { super(SERVER_GAMETEST); } diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLocator.java index 6f86c6060b..9234b395b4 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/targets/ForgeUserdevLocator.java @@ -12,7 +12,7 @@ import net.minecraftforge.fml.loading.moddiscovery.AbstractModProvider; import net.minecraftforge.forgespi.locating.IModLocator; @ApiStatus.Internal -public class ForgeUserdevLocator extends AbstractModProvider implements IModLocator { +public final class ForgeUserdevLocator extends AbstractModProvider implements IModLocator { @Override public String name() { return "forge_userdev_locator"; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/StronglyConnectedComponentDetector.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/StronglyConnectedComponentDetector.java index 9a5bf05def..f70535b93e 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/StronglyConnectedComponentDetector.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/toposort/StronglyConnectedComponentDetector.java @@ -25,7 +25,7 @@ import java.util.Set; */ public class StronglyConnectedComponentDetector { private final Graph graph; - private Map ids; + private final Map ids = new HashMap<>(); private T[] elements; private int[] dfn; private int[] low; @@ -49,7 +49,6 @@ public class StronglyConnectedComponentDetector { private void calculate() { components = new HashSet<>(); int t = 0; - ids = new HashMap<>(); Set nodes = graph.nodes(); elements = (T[]) new Object[nodes.size()]; for (T node : nodes) { diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java index 0de1c5d700..49bbeb9d46 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java @@ -31,21 +31,8 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider { private static final Logger LOGGER = LogManager.getLogger(); - private static class FMLModTarget implements IModLanguageProvider.IModLanguageLoader { + private record FMLModTarget(String className, String modId) implements IModLanguageProvider.IModLanguageLoader { private static final Logger LOGGER = FMLJavaModLanguageProvider.LOGGER; - private final String className; - private final String modId; - - private FMLModTarget(String className, String modId) - { - this.className = className; - this.modId = modId; - } - - public String getModId() - { - return modId; - } @SuppressWarnings("unchecked") @Override @@ -94,7 +81,7 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider .filter(ad -> ad.annotationType().equals(MODANNOTATION)) .peek(ad -> LOGGER.debug(SCAN, "Found @Mod class {} with id {}", ad.clazz().getClassName(), ad.annotationData().get("value"))) .map(ad -> new FMLModTarget(ad.clazz().getClassName(), (String)ad.annotationData().get("value"))) - .collect(Collectors.toMap(FMLModTarget::getModId, Function.identity(), (a,b)->a)); + .collect(Collectors.toMap(FMLModTarget::modId, Function.identity(), (a,b)->a)); scanResult.addLanguageLoader(modTargetMap); }; } diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index d007a437b2..f8566aa88e 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -38,7 +38,7 @@ public class FMLModContainer extends ModContainer { LOGGER.debug(LOADING,"Creating FMLModContainer instance for {}", className); this.scanResults = modFileScanResults; activityMap.put(ModLoadingStage.CONSTRUCT, this::constructMod); - this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build(); + this.eventBus = BusBuilder.builder().setExceptionHandler(FMLModContainer::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build(); this.configHandler = Optional.of(ce->this.eventBus.post(ce.self())); final FMLJavaModLoadingContext contextExtension = new FMLJavaModLoadingContext(this); this.contextExtension = () -> contextExtension; @@ -56,7 +56,7 @@ public class FMLModContainer extends ModContainer { } } - private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) { + private static void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) { LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable)); } diff --git a/lowcodelanguage/src/main/java/net/minecraftforge/fml/lowcodemod/LowCodeModContainer.java b/lowcodelanguage/src/main/java/net/minecraftforge/fml/lowcodemod/LowCodeModContainer.java index 049ccdfbe1..d55bc1935d 100644 --- a/lowcodelanguage/src/main/java/net/minecraftforge/fml/lowcodemod/LowCodeModContainer.java +++ b/lowcodelanguage/src/main/java/net/minecraftforge/fml/lowcodemod/LowCodeModContainer.java @@ -21,14 +21,12 @@ import static net.minecraftforge.fml.loading.LogMarkers.LOADING; public class LowCodeModContainer extends ModContainer { private static final Logger LOGGER = LogUtils.getLogger(); - private final ModFileScanData scanResults; - private Object modInstance; + private final Object modInstance; public LowCodeModContainer(IModInfo info, ModFileScanData modFileScanResults, ModuleLayer gameLayer) { super(info); LOGGER.debug(LOADING, "Creating LowCodeModContainer for {}", info.getModId()); - this.scanResults = modFileScanResults; this.modInstance = new Object(); this.contextExtension = () -> null; this.extensionPoints.remove(IExtensionPoint.DisplayTest.class); @@ -45,9 +43,4 @@ public class LowCodeModContainer extends ModContainer { return modInstance; } - - @Override - protected void acceptEvent(final T e) - { - } } diff --git a/mclanguage/src/main/java/net/minecraftforge/fml/mclanguageprovider/MinecraftModLanguageProvider.java b/mclanguage/src/main/java/net/minecraftforge/fml/mclanguageprovider/MinecraftModLanguageProvider.java index debfdc9044..c51514d5df 100644 --- a/mclanguage/src/main/java/net/minecraftforge/fml/mclanguageprovider/MinecraftModLanguageProvider.java +++ b/mclanguage/src/main/java/net/minecraftforge/fml/mclanguageprovider/MinecraftModLanguageProvider.java @@ -5,7 +5,6 @@ package net.minecraftforge.fml.mclanguageprovider; -import net.minecraftforge.fml.ModContainer; import net.minecraftforge.forgespi.language.ILifecycleEvent; import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.forgespi.language.IModLanguageProvider; @@ -15,14 +14,11 @@ import org.apache.logging.log4j.Logger; import java.lang.reflect.InvocationTargetException; import java.util.Map; -import java.util.Objects; import java.util.function.Consumer; import java.util.function.Supplier; import static net.minecraftforge.fml.Logging.LOADING; -import net.minecraftforge.forgespi.language.IModLanguageProvider.IModLanguageLoader; - public class MinecraftModLanguageProvider implements IModLanguageProvider { private static final Logger LOGGER = LogManager.getLogger(); @Override diff --git a/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch b/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch index c61a6ce71e..c48665e519 100644 --- a/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch +++ b/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch @@ -5,6 +5,6 @@ @DontObfuscate public static String getClientModName() { - return "vanilla"; -+ return net.minecraftforge.internal.BrandingControl.getClientBranding(); ++ return net.minecraftforge.internal.BrandingControl.getBranding(); } } diff --git a/patches/minecraft/net/minecraft/client/gui/screens/TitleScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/TitleScreen.java.patch index 1bc4e8ca9d..0c78647e6f 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/TitleScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/TitleScreen.java.patch @@ -46,11 +46,11 @@ } - p_282860_.drawString(this.font, s, 2, this.height - 10, 16777215 | i); -+ net.minecraftforge.internal.BrandingControl.forEachLine(true, true, (brdline, brd) -> ++ net.minecraftforge.internal.BrandingControl.forEachLine(true, true, (brd, brdline) -> + p_282860_.drawString(this.font, brd, 2, this.height - ( 10 + brdline * (this.font.lineHeight + 1)), 16777215 | i) + ); + -+ net.minecraftforge.internal.BrandingControl.forEachAboveCopyrightLine((brdline, brd) -> ++ net.minecraftforge.internal.BrandingControl.forEachAboveCopyrightLine((brd, brdline) -> + p_282860_.drawString(this.font, brd, this.width - font.width(brd), this.height - (10 + (brdline + 1) * ( this.font.lineHeight + 1)), 16777215 | i) + ); + diff --git a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch index 1d5b2de7db..7cd2453a73 100644 --- a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch @@ -162,7 +162,7 @@ @DontObfuscate public String getServerModName() { - return "vanilla"; -+ return net.minecraftforge.internal.BrandingControl.getServerBranding(); ++ return net.minecraftforge.internal.BrandingControl.getBranding(); } public SystemReport fillSystemReport(SystemReport p_177936_) { diff --git a/settings.gradle b/settings.gradle index 6b7d7c87d7..990bd564b4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,9 +23,9 @@ plugins { dependencyResolutionManagement { versionCatalogs { libs { - library('forgespi', 'net.minecraftforge:forgespi:7.1.4') // Needs modlauncher + library('forgespi', 'net.minecraftforge:forgespi:7.1.5') // Needs modlauncher library('modlauncher', 'net.minecraftforge:modlauncher:10.2.1') // Needs securemodules - library('securemodules', 'net.minecraftforge:securemodules:2.2.19') // Needs unsafe + library('securemodules', 'net.minecraftforge:securemodules:2.2.20') // Needs unsafe library('unsafe', 'net.minecraftforge:unsafe:0.9.2') library('accesstransformers', 'net.minecraftforge:accesstransformers:8.2.0') library('coremods', 'net.minecraftforge:coremods:5.1.6') diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 4fcd4c776b..04b9c30ba3 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -141,7 +141,6 @@ import net.minecraftforge.common.ForgeConfig; import net.minecraftforge.common.ForgeI18n; import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModList; @@ -202,7 +201,7 @@ public class ForgeHooksClient { } public static void clearGuiLayers(Minecraft minecraft) { - while(guiLayers.size() > 0) + while (!guiLayers.isEmpty()) popGuiLayerInternal(minecraft); } @@ -221,7 +220,7 @@ public class ForgeHooksClient { } public static void popGuiLayer(Minecraft minecraft) { - if (guiLayers.size() == 0) { + if (guiLayers.isEmpty()) { minecraft.setScreen(null); return; } @@ -310,7 +309,7 @@ public class ForgeHooksClient { if (idx == -1) return base + complex; - String name = complex.substring(idx + 1, complex.length()); + String name = complex.substring(idx + 1); if (idx > 1) { String domain = complex.substring(0, idx); return domain + ':' + base + name; @@ -320,9 +319,7 @@ public class ForgeHooksClient { } public static float getFieldOfViewModifier(Player entity, float fovModifier) { - ComputeFovModifierEvent fovModifierEvent = new ComputeFovModifierEvent(entity, fovModifier); - MinecraftForge.EVENT_BUS.post(fovModifierEvent); - return fovModifierEvent.getNewFovModifier(); + return MinecraftForge.EVENT_BUS.fire(new ComputeFovModifierEvent(entity, fovModifier)).getNewFovModifier(); } /** @@ -333,41 +330,52 @@ public class ForgeHooksClient { //RenderingRegistry.registerBlockHandler(RenderBlockFluid.instance); } + private static VersionChecker.Status getForgeVersionStatus() { + final class LazyInit { + private static final VersionChecker.Status INSTANCE = ForgeVersion.getStatus(); + + static { + forgeStatusLine = switch (INSTANCE) { + // case FAILED -> " Version check failed"; + // case UP_TO_DATE -> "Forge up to date"; + // case AHEAD -> "Using non-recommended Forge build, issues may arise."; + case OUTDATED, BETA_OUTDATED -> I18n.get("forge.update.newversion", ForgeVersion.getTarget()); + default -> null; + }; + } + + private LazyInit() {} + } + + return LazyInit.INSTANCE; + } + public static void renderMainMenu(TitleScreen gui, GuiGraphics graphics, Font font, int width, int height, int alpha) { - VersionChecker.Status status = ForgeVersion.getStatus(); + VersionChecker.Status status = getForgeVersionStatus(); if (status == VersionChecker.Status.BETA || status == VersionChecker.Status.BETA_OUTDATED) { // Render a warning at the top of the screen Component line = Component.translatable("forge.update.beta.1", ChatFormatting.RED, ChatFormatting.RESET).withStyle(ChatFormatting.RED); - graphics.drawCenteredString(font, line, width / 2, 4 + (0 * (font.lineHeight + 1)), 0xFFFFFF | alpha); + graphics.drawCenteredString(font, line, width / 2, 4, 0xFFFFFF | alpha); line = Component.translatable("forge.update.beta.2"); - graphics.drawCenteredString(font, line, width / 2, 4 + (1 * (font.lineHeight + 1)), 0xFFFFFF | alpha); + graphics.drawCenteredString(font, line, width / 2, 4 + (font.lineHeight + 1), 0xFFFFFF | alpha); } - - forgeStatusLine = switch(status) { - // case FAILED -> " Version check failed"; - // case UP_TO_DATE -> "Forge up to date"; - // case AHEAD -> "Using non-recommended Forge build, issues may arise."; - case OUTDATED, BETA_OUTDATED -> I18n.get("forge.update.newversion", ForgeVersion.getTarget()); - default -> null; - }; } public static String forgeStatusLine; + @Nullable public static SoundInstance playSound(SoundEngine manager, SoundInstance sound) { - PlaySoundEvent e = new PlaySoundEvent(manager, sound); - MinecraftForge.EVENT_BUS.post(e); - return e.getSound(); + return MinecraftForge.EVENT_BUS.fire(new PlaySoundEvent(manager, sound)).getSound(); } public static void drawScreen(Screen screen, GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { guiGraphics.pose().pushPose(); - guiLayers.forEach(layer -> { + for (Screen layer : guiLayers) { // Prevent the background layers from thinking the mouse is over their controls and showing them as highlighted. drawScreenInternal(layer, guiGraphics, Integer.MAX_VALUE, Integer.MAX_VALUE, partialTick); guiGraphics.pose().translate(0, 0, 10000); - }); + } drawScreenInternal(screen, guiGraphics, mouseX, mouseY, partialTick); guiGraphics.pose().popPose(); } @@ -535,8 +543,7 @@ public class ForgeHooksClient { public static void onClientChangeGameType(PlayerInfo info, GameType currentGameMode, GameType newGameMode) { if (currentGameMode != newGameMode) { - ClientPlayerChangeGameTypeEvent evt = new ClientPlayerChangeGameTypeEvent(info, currentGameMode, newGameMode); - MinecraftForge.EVENT_BUS.post(evt); + MinecraftForge.EVENT_BUS.post(new ClientPlayerChangeGameTypeEvent(info, currentGameMode, newGameMode)); } } @@ -563,8 +570,7 @@ public class ForgeHooksClient { } public static void onRecipesUpdated(RecipeManager mgr) { - Event event = new RecipesUpdatedEvent(mgr); - MinecraftForge.EVENT_BUS.post(event); + MinecraftForge.EVENT_BUS.post(new RecipesUpdatedEvent(mgr)); } public static void onKeyInput(int key, int scanCode, int action, int modifiers) { @@ -589,7 +595,7 @@ public class ForgeHooksClient { public static SpriteContents loadSpriteContents(ResourceLocation name, Resource resource, FrameSize frameSize, NativeImage image, ResourceMetadata animationMeta) { try { ForgeTextureMetadata forgeMeta = ForgeTextureMetadata.forResource(resource); - return forgeMeta.getLoader() == null ? null : forgeMeta.getLoader().loadContents(name, resource, frameSize, image, animationMeta, forgeMeta); + return forgeMeta.loader() == null ? null : forgeMeta.loader().loadContents(name, resource, frameSize, image, animationMeta, forgeMeta); } catch (IOException e) { LOGGER.error("Unable to get Forge metadata for {}, falling back to vanilla loading", name); e.printStackTrace(); @@ -599,10 +605,10 @@ public class ForgeHooksClient { @Nullable public static TextureAtlasSprite loadTextureAtlasSprite(ResourceLocation atlasName, SpriteContents contents, int atlasWidth, int atlasHeight, int spriteX, int spriteY, int mipmapLevel) { - if (contents.forgeMeta == null || contents.forgeMeta.getLoader() == null) + if (contents.forgeMeta == null || contents.forgeMeta.loader() == null) return null; - return contents.forgeMeta.getLoader().makeSprite(atlasName, contents, atlasWidth, atlasHeight, spriteX, spriteY, mipmapLevel); + return contents.forgeMeta.loader().makeSprite(atlasName, contents, atlasWidth, atlasHeight, spriteX, spriteY, mipmapLevel); } private static final Map> layerDefinitions = new HashMap<>(); @@ -612,7 +618,9 @@ public class ForgeHooksClient { } public static void loadLayerDefinitions(ImmutableMap.Builder builder) { - layerDefinitions.forEach((k, v) -> builder.put(k, v.get())); + for (var entry : layerDefinitions.entrySet()) { + builder.put(entry.getKey(), entry.getValue().get()); + } } public static void processForgeListPingData(ServerStatus packet, ServerData target) { @@ -716,7 +724,7 @@ public class ForgeHooksClient { } private static Connection getClientConnection() { - return Minecraft.getInstance().getConnection()!=null ? Minecraft.getInstance().getConnection().getConnection() : null; + return Minecraft.getInstance().getConnection() != null ? Minecraft.getInstance().getConnection().getConnection() : null; } public static void handleClientLevelClosing(ClientLevel level) { @@ -825,8 +833,7 @@ public class ForgeHooksClient { Font font = getTooltipFont(stack, fallbackFont); var event = new RenderTooltipEvent.GatherComponents(stack, screenWidth, screenHeight, elements, -1); - MinecraftForge.EVENT_BUS.post(event); - if (event.isCanceled()) return List.of(); + if (MinecraftForge.EVENT_BUS.post(event)) return List.of(); // text wrapping int tooltipTextWidth = event.getTooltipElements().stream() @@ -891,9 +898,7 @@ public class ForgeHooksClient { } public static ScreenEvent.RenderInventoryMobEffects onScreenPotionSize(Screen screen, int availableSpace, boolean compact, int horizontalOffset) { - final ScreenEvent.RenderInventoryMobEffects event = new ScreenEvent.RenderInventoryMobEffects(screen, availableSpace, compact, horizontalOffset); - MinecraftForge.EVENT_BUS.post(event); - return event; + return MinecraftForge.EVENT_BUS.fire(new ScreenEvent.RenderInventoryMobEffects(screen, availableSpace, compact, horizontalOffset)); } public static boolean onToastAdd(Toast toast) { diff --git a/src/main/java/net/minecraftforge/client/ItemDecoratorHandler.java b/src/main/java/net/minecraftforge/client/ItemDecoratorHandler.java index d282c0e1f7..0c2649372f 100644 --- a/src/main/java/net/minecraftforge/client/ItemDecoratorHandler.java +++ b/src/main/java/net/minecraftforge/client/ItemDecoratorHandler.java @@ -45,7 +45,10 @@ public final class ItemDecoratorHandler var event = new RegisterItemDecorationsEvent(decorators); ModLoader.get().postEventWrapContainerInModOrder(event); var builder = new ImmutableMap.Builder(); - decorators.forEach((item, itemDecorators) -> builder.put(item, new ItemDecoratorHandler(itemDecorators))); + for (var entry : decorators.entrySet()) { + Item item = entry.getKey(); + builder.put(item, new ItemDecoratorHandler(entry.getValue())); + } DECORATOR_LOOKUP = builder.build(); } diff --git a/src/main/java/net/minecraftforge/client/PresetEditorManager.java b/src/main/java/net/minecraftforge/client/PresetEditorManager.java index 6f0e79935d..ea6c8976b5 100644 --- a/src/main/java/net/minecraftforge/client/PresetEditorManager.java +++ b/src/main/java/net/minecraftforge/client/PresetEditorManager.java @@ -7,6 +7,7 @@ package net.minecraftforge.client; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -31,7 +32,12 @@ public final class PresetEditorManager Map, PresetEditor> gatheredEditors = new HashMap<>(); // Vanilla's map uses Optionals as its keys. // As far as we can tell there's no good reason for this, so we'll just use regular keys. - PresetEditor.EDITORS.forEach((k, v) -> k.ifPresent(key -> gatheredEditors.put(key, v))); + for (var entry : PresetEditor.EDITORS.entrySet()) { + var key = entry.getKey().orElse(null); + if (key != null) { + gatheredEditors.put(key, entry.getValue()); + } + } // Gather mods' entries RegisterPresetEditorsEvent event = new RegisterPresetEditorsEvent(gatheredEditors); diff --git a/src/main/java/net/minecraftforge/client/RecipeBookManager.java b/src/main/java/net/minecraftforge/client/RecipeBookManager.java index de621fe8ad..00c1c4e809 100644 --- a/src/main/java/net/minecraftforge/client/RecipeBookManager.java +++ b/src/main/java/net/minecraftforge/client/RecipeBookManager.java @@ -5,8 +5,6 @@ package net.minecraftforge.client; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import net.minecraft.client.RecipeBookCategories; import net.minecraft.world.inventory.RecipeBookType; import net.minecraft.world.item.crafting.Recipe; @@ -57,14 +55,14 @@ public final class RecipeBookManager { @ApiStatus.Internal public static void init() { // The ImmutableMap is the patched out value of AGGREGATE_CATEGORIES - var aggregateCategories = new HashMap<>(ImmutableMap.of( - RecipeBookCategories.CRAFTING_SEARCH, ImmutableList.of(RecipeBookCategories.CRAFTING_EQUIPMENT, RecipeBookCategories.CRAFTING_BUILDING_BLOCKS, RecipeBookCategories.CRAFTING_MISC, RecipeBookCategories.CRAFTING_REDSTONE), - RecipeBookCategories.FURNACE_SEARCH, ImmutableList.of(RecipeBookCategories.FURNACE_FOOD, RecipeBookCategories.FURNACE_BLOCKS, RecipeBookCategories.FURNACE_MISC), - RecipeBookCategories.BLAST_FURNACE_SEARCH, ImmutableList.of(RecipeBookCategories.BLAST_FURNACE_BLOCKS, RecipeBookCategories.BLAST_FURNACE_MISC), - RecipeBookCategories.SMOKER_SEARCH, ImmutableList.of(RecipeBookCategories.SMOKER_FOOD) + var aggregateCategories = new HashMap<>(Map.of( + RecipeBookCategories.CRAFTING_SEARCH, List.of(RecipeBookCategories.CRAFTING_EQUIPMENT, RecipeBookCategories.CRAFTING_BUILDING_BLOCKS, RecipeBookCategories.CRAFTING_MISC, RecipeBookCategories.CRAFTING_REDSTONE), + RecipeBookCategories.FURNACE_SEARCH, List.of(RecipeBookCategories.FURNACE_FOOD, RecipeBookCategories.FURNACE_BLOCKS, RecipeBookCategories.FURNACE_MISC), + RecipeBookCategories.BLAST_FURNACE_SEARCH, List.of(RecipeBookCategories.BLAST_FURNACE_BLOCKS, RecipeBookCategories.BLAST_FURNACE_MISC), + RecipeBookCategories.SMOKER_SEARCH, List.of(RecipeBookCategories.SMOKER_FOOD) )); - var typeCategories = new HashMap>(); + var typeCategories = new HashMap>(); var recipeCategoryLookups = new HashMap, Function, RecipeBookCategories>>(); var event = new RegisterRecipeBookCategoriesEvent(aggregateCategories, typeCategories, recipeCategoryLookups); ModLoader.get().postEventWrapContainerInModOrder(event); diff --git a/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java b/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java index a1e77d8468..727e01bb38 100644 --- a/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java +++ b/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java @@ -78,8 +78,7 @@ public final class ForgeEventFactoryClient { * @return the event object passed in and possibly modified by listeners */ private static E fire(E e) { - post(e); - return e; + return MinecraftForge.EVENT_BUS.fire(e); } /** diff --git a/src/main/java/net/minecraftforge/client/event/RegisterRecipeBookCategoriesEvent.java b/src/main/java/net/minecraftforge/client/event/RegisterRecipeBookCategoriesEvent.java index 4c8a7aabe2..f39eb7c3b3 100644 --- a/src/main/java/net/minecraftforge/client/event/RegisterRecipeBookCategoriesEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RegisterRecipeBookCategoriesEvent.java @@ -5,7 +5,6 @@ package net.minecraftforge.client.event; -import com.google.common.collect.ImmutableList; import net.minecraft.client.RecipeBookCategories; import net.minecraft.world.inventory.RecipeBookType; import net.minecraft.world.item.crafting.Recipe; @@ -31,14 +30,14 @@ import java.util.function.Function; */ public class RegisterRecipeBookCategoriesEvent extends Event implements IModBusEvent { - private final Map> aggregateCategories; - private final Map> typeCategories; + private final Map> aggregateCategories; + private final Map> typeCategories; private final Map, Function, RecipeBookCategories>> recipeCategoryLookups; @ApiStatus.Internal public RegisterRecipeBookCategoriesEvent( - Map> aggregateCategories, - Map> typeCategories, + Map> aggregateCategories, + Map> typeCategories, Map, Function, RecipeBookCategories>> recipeCategoryLookups) { this.aggregateCategories = aggregateCategories; @@ -51,7 +50,7 @@ public class RegisterRecipeBookCategoriesEvent extends Event implements IModBusE */ public void registerAggregateCategory(RecipeBookCategories category, List others) { - aggregateCategories.put(category, ImmutableList.copyOf(others)); + aggregateCategories.put(category, List.copyOf(others)); } /** @@ -59,7 +58,7 @@ public class RegisterRecipeBookCategoriesEvent extends Event implements IModBusE */ public void registerBookCategories(RecipeBookType type, List categories) { - typeCategories.put(type, ImmutableList.copyOf(categories)); + typeCategories.put(type, List.copyOf(categories)); } /** diff --git a/src/main/java/net/minecraftforge/client/textures/ForgeTextureMetadata.java b/src/main/java/net/minecraftforge/client/textures/ForgeTextureMetadata.java index a983f3b94a..4593f21960 100644 --- a/src/main/java/net/minecraftforge/client/textures/ForgeTextureMetadata.java +++ b/src/main/java/net/minecraftforge/client/textures/ForgeTextureMetadata.java @@ -21,60 +21,44 @@ import java.util.Optional; /** * The "forge" section of texture metadata files (.mcmeta). Currently used only to specify custom * TextureAtlasSprite loaders. + * * @see ITextureAtlasSpriteLoader */ -public final class ForgeTextureMetadata -{ +public record ForgeTextureMetadata(@Nullable ITextureAtlasSpriteLoader loader) { public static final ForgeTextureMetadata EMPTY = new ForgeTextureMetadata(null); public static final MetadataSectionSerializer SERIALIZER = new Serializer(); public static ForgeTextureMetadata forResource(Resource resource) throws IOException { Optional metadata = resource.metadata().getSection(SERIALIZER); - return metadata.isEmpty() ? EMPTY : metadata.get(); + return metadata.orElse(EMPTY); } @Nullable - private final ITextureAtlasSpriteLoader loader; - - public ForgeTextureMetadata(@Nullable ITextureAtlasSpriteLoader loader) - { - this.loader = loader; - } - - @Nullable - public ITextureAtlasSpriteLoader getLoader() - { + public ITextureAtlasSpriteLoader getLoader() { return loader; } - private static final class Serializer implements MetadataSectionSerializer - { + private static final class Serializer implements MetadataSectionSerializer { @Override @NotNull - public String getMetadataSectionName() - { + public String getMetadataSectionName() { return "forge"; } @Override @NotNull - public ForgeTextureMetadata fromJson(JsonObject json) - { + public ForgeTextureMetadata fromJson(JsonObject json) { @Nullable ITextureAtlasSpriteLoader loader; - if (json.has("loader")) - { + if (json.has("loader")) { ResourceLocation loaderName = ResourceLocation.parse(GsonHelper.getAsString(json, "loader")); loader = TextureAtlasSpriteLoaderManager.get(loaderName); - if (loader == null) - { + if (loader == null) { throw new JsonSyntaxException("Unknown TextureAtlasSpriteLoader " + loaderName); } - } - else - { + } else { loader = null; } return new ForgeTextureMetadata(loader); diff --git a/src/main/java/net/minecraftforge/client/textures/TextureAtlasSpriteLoaderManager.java b/src/main/java/net/minecraftforge/client/textures/TextureAtlasSpriteLoaderManager.java index 06d0b6ab47..1ab167c070 100644 --- a/src/main/java/net/minecraftforge/client/textures/TextureAtlasSpriteLoaderManager.java +++ b/src/main/java/net/minecraftforge/client/textures/TextureAtlasSpriteLoaderManager.java @@ -13,35 +13,31 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.HashMap; +import java.util.Map; /** * Manager for {@link ITextureAtlasSpriteLoader} instances. *

* Provides a lookup. */ -public final class TextureAtlasSpriteLoaderManager -{ - private static ImmutableMap LOADERS; +public final class TextureAtlasSpriteLoaderManager { + private static Map LOADERS; /** * Finds the loader with the given name, or null if none is registered. */ @Nullable - public static ITextureAtlasSpriteLoader get(ResourceLocation name) - { + public static ITextureAtlasSpriteLoader get(ResourceLocation name) { return LOADERS.get(name); } @ApiStatus.Internal - public static void init() - { + public static void init() { var loaders = new HashMap(); var event = new RegisterTextureAtlasSpriteLoadersEvent(loaders); ModLoader.get().postEventWrapContainerInModOrder(event); LOADERS = ImmutableMap.copyOf(loaders); } - private TextureAtlasSpriteLoaderManager() - { - } + private TextureAtlasSpriteLoaderManager() {} } diff --git a/src/main/java/net/minecraftforge/common/BiomeManager.java b/src/main/java/net/minecraftforge/common/BiomeManager.java index b5c8429b15..54f418c56c 100644 --- a/src/main/java/net/minecraftforge/common/BiomeManager.java +++ b/src/main/java/net/minecraftforge/common/BiomeManager.java @@ -21,7 +21,7 @@ import net.minecraft.world.level.biome.Biome; public class BiomeManager { - private static TrackedList[] biomes = setupBiomes(); + private static final TrackedList[] biomes = setupBiomes(); private static final List> additionalOverworldBiomes = new ArrayList<>(); private static final List> additionalOverworldBiomesView = Collections.unmodifiableList(additionalOverworldBiomes); diff --git a/src/main/java/net/minecraftforge/common/CreativeModeTabRegistry.java b/src/main/java/net/minecraftforge/common/CreativeModeTabRegistry.java index 4b97a9a474..9f4ec5ad39 100644 --- a/src/main/java/net/minecraftforge/common/CreativeModeTabRegistry.java +++ b/src/main/java/net/minecraftforge/common/CreativeModeTabRegistry.java @@ -109,7 +109,7 @@ public final class CreativeModeTabRegistry { @Override protected void apply(@NotNull JsonObject data, @NotNull ResourceManager resourceManager, ProfilerFiller p) { try { - if (data.size() > 0) { + if (!data.isEmpty()) { JsonArray order = GsonHelper.getAsJsonArray(data, "order"); List customOrder = new ArrayList<>(); for (JsonElement entry : order) { @@ -183,8 +183,9 @@ public final class CreativeModeTabRegistry { DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.get(CreativeModeTabs.OP_BLOCKS)); DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.get(CreativeModeTabs.INVENTORY)); - final List> indexed = new ArrayList<>(); - BuiltInRegistries.CREATIVE_MODE_TAB.holders().filter(c -> !DEFAULT_TABS.contains(c.get())).forEach(indexed::add); + final List> indexed = BuiltInRegistries.CREATIVE_MODE_TAB.holders() + .filter(c -> !DEFAULT_TABS.contains(c.get())) + .collect(Collectors.toList()); int vanillaTabs = 10; for (int i = 0; i < vanillaTabs; i++) { // Vanilla ordering diff --git a/src/main/java/net/minecraftforge/common/ForgeConfigSpec.java b/src/main/java/net/minecraftforge/common/ForgeConfigSpec.java index 5a19964ba8..285aa59a2c 100644 --- a/src/main/java/net/minecraftforge/common/ForgeConfigSpec.java +++ b/src/main/java/net/minecraftforge/common/ForgeConfigSpec.java @@ -632,7 +632,7 @@ public class ForgeConfigSpec extends UnmodifiableConfigWrapper currentPath.size()) throw new IllegalArgumentException("Attempted to pop " + count + " elements when we only had: " + currentPath); for (int x = 0; x < count; x++) - currentPath.remove(currentPath.size() - 1); + currentPath.removeLast(); return this; } @@ -644,10 +644,14 @@ public class ForgeConfigSpec extends UnmodifiableConfigWrapper valueCfg.set(v.getPath(), v)); + for (ConfigValue value : values) { + valueCfg.set(value.getPath(), value); + } ForgeConfigSpec ret = new ForgeConfigSpec(storage, valueCfg, levelComments, levelTranslationKeys); - values.forEach(v -> v.spec = ret); + for (ConfigValue v : values) { + v.spec = ret; + } return ret; } diff --git a/src/main/java/net/minecraftforge/common/ForgeI18n.java b/src/main/java/net/minecraftforge/common/ForgeI18n.java index 4d043727b0..045f2084e9 100644 --- a/src/main/java/net/minecraftforge/common/ForgeI18n.java +++ b/src/main/java/net/minecraftforge/common/ForgeI18n.java @@ -30,8 +30,8 @@ public class ForgeI18n { // 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(); - private static Map i18n; - private static Map customFactories; + private static Map i18n; + private static final Map customFactories; // From StringUtils private static final Pattern PATTERN_CONTROL_CODE = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); diff --git a/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java b/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java index ebf7a241b1..6d5ddfd601 100644 --- a/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java +++ b/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java @@ -60,11 +60,11 @@ public class ForgeInternalHandler { WorldWorkerManager.tick(false); } - @SubscribeEvent - public void checkSettings(ClientTickEvent event) { - //if (event.phase == Phase.END) - // CloudRenderer.updateCloudSettings(); - } +// @SubscribeEvent +// public void checkSettings(ClientTickEvent event) { +// if (event.phase == Phase.END) +// CloudRenderer.updateCloudSettings(); +// } @SubscribeEvent public void onChunkUnload(ChunkEvent.Unload event) { diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 925ce4ae0d..7a55c2447f 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -399,7 +399,9 @@ public class ForgeMod { modEventBus.addListener(this::registerFluids); modEventBus.addListener(this::registerVanillaDisplayContexts); modEventBus.register(this); - registries.forEach(r -> r.register(modEventBus)); + for (DeferredRegister r : registries) { + r.register(modEventBus); + } MinecraftForge.EVENT_BUS.addListener(this::serverStopping); ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec); diff --git a/src/main/java/net/minecraftforge/common/ForgeSpawnEggItem.java b/src/main/java/net/minecraftforge/common/ForgeSpawnEggItem.java index c53f1c4694..3e55ffb047 100644 --- a/src/main/java/net/minecraftforge/common/ForgeSpawnEggItem.java +++ b/src/main/java/net/minecraftforge/common/ForgeSpawnEggItem.java @@ -92,14 +92,14 @@ public class ForgeSpawnEggItem extends SpawnEggItem { private static class ColorRegisterHandler { @SubscribeEvent(priority = EventPriority.HIGHEST) public static void registerSpawnEggColors(RegisterColorHandlersEvent.Item event) { - MOD_EGGS.forEach(egg -> { + for (ForgeSpawnEggItem egg : MOD_EGGS) { event.register((stack, layer) -> { int color = egg.getColor(layer); if (FastColor.ARGB32.alpha(color) == 0) color = FastColor.ARGB32.opaque(color); return color; }, egg); - }); + } } } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/VillagerTradingManager.java b/src/main/java/net/minecraftforge/common/VillagerTradingManager.java index d4cac7d638..bbf9aa6b3c 100644 --- a/src/main/java/net/minecraftforge/common/VillagerTradingManager.java +++ b/src/main/java/net/minecraftforge/common/VillagerTradingManager.java @@ -29,11 +29,12 @@ public class VillagerTradingManager static { - VillagerTrades.TRADES.entrySet().forEach(e -> - { + VillagerTrades.TRADES.forEach((key, value) -> { Int2ObjectMap copy = new Int2ObjectOpenHashMap<>(); - e.getValue().int2ObjectEntrySet().forEach(ent -> copy.put(ent.getIntKey(), Arrays.copyOf(ent.getValue(), ent.getValue().length))); - VANILLA_TRADES.put(e.getKey(), copy); + for (var ent : value.int2ObjectEntrySet()) { + copy.put(ent.getIntKey(), Arrays.copyOf(ent.getValue(), ent.getValue().length)); + } + VANILLA_TRADES.put(key, copy); }); VillagerTrades.WANDERING_TRADER_TRADES.int2ObjectEntrySet().forEach(e -> WANDERER_TRADES.put(e.getIntKey(), Arrays.copyOf(e.getValue(), e.getValue().length))); } @@ -71,13 +72,14 @@ public class VillagerTradingManager { mutableTrades.put(i, NonNullList.create()); } - trades.int2ObjectEntrySet().forEach(e -> - { - Arrays.stream(e.getValue()).forEach(mutableTrades.get(e.getIntKey())::add); - }); + for (var entry : trades.int2ObjectEntrySet()) { + Arrays.stream(entry.getValue()).forEach(mutableTrades.get(entry.getIntKey())::add); + } MinecraftForge.EVENT_BUS.post(new VillagerTradesEvent(mutableTrades, prof)); Int2ObjectMap newTrades = new Int2ObjectOpenHashMap<>(); - mutableTrades.int2ObjectEntrySet().forEach(e -> newTrades.put(e.getIntKey(), e.getValue().toArray(new ItemListing[0]))); + for (var entry : mutableTrades.int2ObjectEntrySet()) { + newTrades.put(entry.getIntKey(), entry.getValue().toArray(new ItemListing[0])); + } VillagerTrades.TRADES.put(prof, newTrades); } } diff --git a/src/main/java/net/minecraftforge/common/WorldWorkerManager.java b/src/main/java/net/minecraftforge/common/WorldWorkerManager.java index 388c77ebb1..cd5834cd37 100644 --- a/src/main/java/net/minecraftforge/common/WorldWorkerManager.java +++ b/src/main/java/net/minecraftforge/common/WorldWorkerManager.java @@ -10,7 +10,7 @@ import java.util.List; public class WorldWorkerManager { - private static List workers = new ArrayList(); + private static final List workers = new ArrayList<>(); private static long startTime = -1; private static int index = 0; diff --git a/src/main/java/net/minecraftforge/common/command/EntitySelectorManager.java b/src/main/java/net/minecraftforge/common/command/EntitySelectorManager.java index 9ad36dac81..57bf6235b7 100644 --- a/src/main/java/net/minecraftforge/common/command/EntitySelectorManager.java +++ b/src/main/java/net/minecraftforge/common/command/EntitySelectorManager.java @@ -13,6 +13,8 @@ import net.minecraft.commands.arguments.selector.EntitySelectorParser; import java.util.Arrays; import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Allows modders to register custom entity selectors by assigning an {@link IEntitySelectorType} to a String token.
@@ -21,6 +23,7 @@ import java.util.HashMap; public class EntitySelectorManager { private static final HashMap REGISTRY = new HashMap<>(); + private static final List RESERVED_TOKENS = List.of("p", "a", "r", "s", "e"); /** * Registers a new {@link IEntitySelectorType} for the given {@code token}.
@@ -34,7 +37,7 @@ public class EntitySelectorManager throw new IllegalArgumentException("Token must not be empty"); } - if (Arrays.asList("p", "a", "r", "s", "e").contains(token)) + if (RESERVED_TOKENS.contains(token)) { throw new IllegalArgumentException("Token clashes with vanilla @" + token); } @@ -78,6 +81,10 @@ public class EntitySelectorManager */ public static void fillSelectorSuggestions(SuggestionsBuilder suggestionBuilder) { - REGISTRY.forEach((token, type) -> suggestionBuilder.suggest("@" + token, type.getSuggestionTooltip())); + for (var entry : REGISTRY.entrySet()) { + String token = entry.getKey(); + IEntitySelectorType type = entry.getValue(); + suggestionBuilder.suggest("@" + token, type.getSuggestionTooltip()); + } } } diff --git a/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java b/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java index ab183aa777..a54bc2cfb7 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java +++ b/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java @@ -7,6 +7,7 @@ package net.minecraftforge.common.crafting; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import java.util.stream.Stream; @@ -61,10 +62,10 @@ public class ConditionalRecipe { } public static class Builder { - private List recipes = new ArrayList<>(); - private List advancements = new ArrayList<>(); + private final List recipes = new ArrayList<>(); + private final List advancements = new ArrayList<>(); - private RecipeOutput bouncer = new RecipeOutput() { + private final RecipeOutput bouncer = new RecipeOutput() { @Override public void accept(ResourceLocation id, Recipe value, @Nullable AdvancementHolder advancement) { recipe(id, value, advancement); @@ -221,7 +222,7 @@ public class ConditionalRecipe { var count = new Holder(); count.value = -1; var ret = stream.map(entry -> accept(context, ops, count, entry)) - .filter(entry -> entry != null) + .filter(Objects::nonNull) .findFirst() .orElse(null); @@ -273,7 +274,7 @@ public class ConditionalRecipe { } }; - private static class Holder { + private static final class Holder { private T value; } } diff --git a/src/main/java/net/minecraftforge/common/crafting/SimpleCraftingContainer.java b/src/main/java/net/minecraftforge/common/crafting/SimpleCraftingContainer.java index 0d69aa0c28..b09f993375 100644 --- a/src/main/java/net/minecraftforge/common/crafting/SimpleCraftingContainer.java +++ b/src/main/java/net/minecraftforge/common/crafting/SimpleCraftingContainer.java @@ -59,7 +59,7 @@ public class SimpleCraftingContainer { int height = this.rows.size(); if (height == 0) throw new IllegalStateException("Invalid builder, empty inventory"); - int width = this.rows.get(0).length(); + int width = this.rows.getFirst().length(); var items = NonNullList.withSize(width * height, ItemStack.EMPTY); int idx = 0; diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java index ea9f0f1c5e..cfe87cb469 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java @@ -35,7 +35,7 @@ public class CompoundIngredient extends AbstractIngredient { return new CompoundIngredient(Arrays.asList(children)); } - private List children; + private final List children; private ItemStack[] stacks; private IntList itemIds; private final boolean isSimple; diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/PartialNBTIngredient.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/PartialNBTIngredient.java index 610fe9bb47..93a78060af 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/PartialNBTIngredient.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/PartialNBTIngredient.java @@ -109,7 +109,7 @@ public class PartialNBTIngredient extends AbstractIngredient { }; public static class Builder { - private List items = new ArrayList<>(); + private final List items = new ArrayList<>(); private CompoundTag nbt; public Builder nbt(CompoundTag value) { diff --git a/src/main/java/net/minecraftforge/common/data/SoundDefinitionsProvider.java b/src/main/java/net/minecraftforge/common/data/SoundDefinitionsProvider.java index 77ec3fe606..f79b6f2f2c 100644 --- a/src/main/java/net/minecraftforge/common/data/SoundDefinitionsProvider.java +++ b/src/main/java/net/minecraftforge/common/data/SoundDefinitionsProvider.java @@ -253,10 +253,10 @@ public abstract class SoundDefinitionsProvider implements DataProvider private CompletableFuture save(final CachedOutput cache, final Path targetFile) { - return DataProvider.saveStable(cache, this.mapToJson(this.sounds), targetFile); + return DataProvider.saveStable(cache, mapToJson(this.sounds), targetFile); } - private JsonObject mapToJson(final Map map) + private static JsonObject mapToJson(final Map map) { final JsonObject obj = new JsonObject(); // namespaces are ignored when serializing diff --git a/src/main/java/net/minecraftforge/common/data/SpriteSourceProvider.java b/src/main/java/net/minecraftforge/common/data/SpriteSourceProvider.java index 52c654fffd..37843949f3 100644 --- a/src/main/java/net/minecraftforge/common/data/SpriteSourceProvider.java +++ b/src/main/java/net/minecraftforge/common/data/SpriteSourceProvider.java @@ -49,7 +49,11 @@ public abstract class SpriteSourceProvider extends JsonCodecProvider> consumer) { addSources(); - atlases.forEach((atlas, srcList) -> consumer.accept(atlas, srcList.sources)); + for (var entry : atlases.entrySet()) { + ResourceLocation atlas = entry.getKey(); + SourceList srcList = entry.getValue(); + consumer.accept(atlas, srcList.sources); + } } protected abstract void addSources(); diff --git a/src/main/java/net/minecraftforge/common/util/CenterChunkPosComparator.java b/src/main/java/net/minecraftforge/common/util/CenterChunkPosComparator.java index 033e3bad60..3a7e2733fc 100644 --- a/src/main/java/net/minecraftforge/common/util/CenterChunkPosComparator.java +++ b/src/main/java/net/minecraftforge/common/util/CenterChunkPosComparator.java @@ -11,8 +11,8 @@ import net.minecraft.world.level.ChunkPos; // Sorter to load nearby chunks first public class CenterChunkPosComparator implements java.util.Comparator { - private int x; - private int z; + private final int x; + private final int z; public CenterChunkPosComparator(ServerPlayer entityplayer) { diff --git a/src/main/java/net/minecraftforge/common/util/ConcatenatedListView.java b/src/main/java/net/minecraftforge/common/util/ConcatenatedListView.java index 55600db154..82ce32dc4f 100644 --- a/src/main/java/net/minecraftforge/common/util/ConcatenatedListView.java +++ b/src/main/java/net/minecraftforge/common/util/ConcatenatedListView.java @@ -30,7 +30,7 @@ public class ConcatenatedListView implements List { return switch (members.size()) { case 0 -> List.of(); - case 1 -> Collections.unmodifiableList(members.get(0)); + case 1 -> Collections.unmodifiableList(members.getFirst()); default -> new ConcatenatedListView<>(members); }; } diff --git a/src/main/java/net/minecraftforge/common/util/HexDumper.java b/src/main/java/net/minecraftforge/common/util/HexDumper.java index 0857fbf9e1..97cde42156 100644 --- a/src/main/java/net/minecraftforge/common/util/HexDumper.java +++ b/src/main/java/net/minecraftforge/common/util/HexDumper.java @@ -46,7 +46,7 @@ public class HexDumper { private static final String HEX = "0123456789ABCDEF"; private final int marked; private final StringBuilder buf; - private char[] ascii = new char[16]; + private final char[] ascii = new char[16]; private int index = 0; private Instance(int marked, int size) { diff --git a/src/main/java/net/minecraftforge/common/util/LevelCapabilityData.java b/src/main/java/net/minecraftforge/common/util/LevelCapabilityData.java index 31341b4690..f1d4da68bf 100644 --- a/src/main/java/net/minecraftforge/common/util/LevelCapabilityData.java +++ b/src/main/java/net/minecraftforge/common/util/LevelCapabilityData.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.Nullable; public class LevelCapabilityData extends SavedData { public static final String ID = "capabilities"; - private INBTSerializable serializable; + private final INBTSerializable serializable; private CompoundTag capNBT = null; public LevelCapabilityData(@Nullable INBTSerializable serializable) { diff --git a/src/main/java/net/minecraftforge/common/util/MutableHashedLinkedMap.java b/src/main/java/net/minecraftforge/common/util/MutableHashedLinkedMap.java index 3249098de4..5cea000ae2 100644 --- a/src/main/java/net/minecraftforge/common/util/MutableHashedLinkedMap.java +++ b/src/main/java/net/minecraftforge/common/util/MutableHashedLinkedMap.java @@ -325,7 +325,7 @@ public class MutableHashedLinkedMap implements Iterable> Value apply(Key key, Value left, Value right); } - private class Entry implements Map.Entry + private final class Entry implements Map.Entry { private final K key; private V value; @@ -374,7 +374,7 @@ public class MutableHashedLinkedMap implements Iterable> } } - private static class BasicStrategy implements Strategy { + private static final class BasicStrategy implements Strategy { @Override public int hashCode(Object o) { return Objects.hashCode(o); @@ -386,7 +386,7 @@ public class MutableHashedLinkedMap implements Iterable> } } - private static class IdentityStrategy implements Strategy { + private static final class IdentityStrategy implements Strategy { @Override public int hashCode(Object o) { return System.identityHashCode(o); diff --git a/src/main/java/net/minecraftforge/common/util/SortedProperties.java b/src/main/java/net/minecraftforge/common/util/SortedProperties.java index 7e1ace3c0f..5f9f0c3fca 100644 --- a/src/main/java/net/minecraftforge/common/util/SortedProperties.java +++ b/src/main/java/net/minecraftforge/common/util/SortedProperties.java @@ -8,6 +8,7 @@ package net.minecraftforge.common.util; import java.io.IOException; import java.io.Writer; import java.util.Collections; +import java.util.Comparator; import java.util.Enumeration; import java.util.Map; import java.util.Properties; @@ -25,7 +26,7 @@ public class SortedProperties extends Properties { @Override public Set> entrySet() { - Set> ret = new TreeSet<>((left, right) -> left.getKey().toString().compareTo(right.getKey().toString())); + Set> ret = new TreeSet<>(Comparator.comparing(entry -> entry.getKey().toString())); ret.addAll(super.entrySet()); return ret; } diff --git a/src/main/java/net/minecraftforge/common/util/TextTable.java b/src/main/java/net/minecraftforge/common/util/TextTable.java index 6ba0df3000..503104290c 100644 --- a/src/main/java/net/minecraftforge/common/util/TextTable.java +++ b/src/main/java/net/minecraftforge/common/util/TextTable.java @@ -125,9 +125,9 @@ public class TextTable public static class Column { - private String header; + private final String header; private int width; - private Alignment alignment; + private final Alignment alignment; public Column(String header) { diff --git a/src/main/java/net/minecraftforge/common/util/TransformationHelper.java b/src/main/java/net/minecraftforge/common/util/TransformationHelper.java index 08a18c6cc4..913c339a8e 100644 --- a/src/main/java/net/minecraftforge/common/util/TransformationHelper.java +++ b/src/main/java/net/minecraftforge/common/util/TransformationHelper.java @@ -302,19 +302,12 @@ public final class TransformationHelper Quaternionf ret; try { - if (entry.getKey().equals("x")) - { - ret = Axis.XP.rotationDegrees(entry.getValue().getAsNumber().floatValue()); - } - else if (entry.getKey().equals("y")) - { - ret = Axis.YP.rotationDegrees(entry.getValue().getAsNumber().floatValue()); - } - else if (entry.getKey().equals("z")) - { - ret = Axis.ZP.rotationDegrees(entry.getValue().getAsNumber().floatValue()); - } - else throw new JsonParseException("Axis rotation: expected single axis key, got: " + entry.getKey()); + ret = switch (entry.getKey()) { + case "x" -> Axis.XP.rotationDegrees(entry.getValue().getAsNumber().floatValue()); + case "y" -> Axis.YP.rotationDegrees(entry.getValue().getAsNumber().floatValue()); + case "z" -> Axis.ZP.rotationDegrees(entry.getValue().getAsNumber().floatValue()); + default -> throw new JsonParseException("Axis rotation: expected single axis key, got: " + entry.getKey()); + }; } catch(ClassCastException ex) { diff --git a/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java b/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java index 42ca795153..9412a7ee28 100644 --- a/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java +++ b/src/main/java/net/minecraftforge/common/world/BiomeGenerationSettingsBuilder.java @@ -17,10 +17,12 @@ public class BiomeGenerationSettingsBuilder extends BiomeGenerationSettings.Plai { public BiomeGenerationSettingsBuilder(BiomeGenerationSettings orig) { - orig.getCarvingStages().forEach(k -> { + for (GenerationStep.Carving k : orig.getCarvingStages()) { carvers.put(k, new ArrayList<>()); - orig.getCarvers(k).forEach(v -> carvers.get(k).add(v)); - }); + for (Holder> v : orig.getCarvers(k)) { + carvers.get(k).add(v); + } + } orig.features().forEach(l -> { final ArrayList> featureList = new ArrayList<>(); l.forEach(featureList::add); diff --git a/src/main/java/net/minecraftforge/internal/BrandingControl.java b/src/main/java/net/minecraftforge/internal/BrandingControl.java index 3c18302484..e176e5a672 100644 --- a/src/main/java/net/minecraftforge/internal/BrandingControl.java +++ b/src/main/java/net/minecraftforge/internal/BrandingControl.java @@ -5,11 +5,9 @@ package net.minecraftforge.internal; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; +import java.util.Collections; import java.util.List; -import java.util.function.BiConsumer; -import java.util.stream.IntStream; +import java.util.function.ObjIntConsumer; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManagerReloadListener; @@ -19,20 +17,20 @@ import net.minecraftforge.fml.ModList; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; -public class BrandingControl { +public final class BrandingControl { + private BrandingControl() {} + private static List brandings; private static List brandingsNoMC; - private static List overCopyrightBrandings; private static void computeBranding() { if (brandings == null) { - ImmutableList.Builder brd = ImmutableList.builder(); - brd.add("Forge " + ForgeVersion.getVersion()); - brd.add("Minecraft " + MCPVersion.getMCVersion()); - brd.add("MCP " + MCPVersion.getMCPVersion()); - int tModCount = ModList.get().size(); - brd.add(ForgeI18n.parseMessage("fml.menu.loadingmods", tModCount)); - brandings = brd.build(); + brandings = List.of( + "Forge " + ForgeVersion.getVersion(), + "Minecraft " + MCPVersion.getMCVersion(), + "MCP " + MCPVersion.getMCPVersion(), + ForgeI18n.parseMessage("fml.menu.loadingmods", ModList.get().size()) + ); brandingsNoMC = brandings.subList(1, brandings.size()); } } @@ -40,34 +38,36 @@ public class BrandingControl { private static List getBrandings(boolean includeMC, boolean reverse) { computeBranding(); if (includeMC) - return reverse ? Lists.reverse(brandings) : brandings; + return reverse ? brandings.reversed() : brandings; else - return reverse ? Lists.reverse(brandingsNoMC) : brandingsNoMC; + return reverse ? brandingsNoMC.reversed() : brandingsNoMC; } - private static void computeOverCopyrightBrandings() { - if (overCopyrightBrandings == null) { - ImmutableList.Builder brd = ImmutableList.builder(); - if (ForgeHooksClient.forgeStatusLine != null) brd.add(ForgeHooksClient.forgeStatusLine); - overCopyrightBrandings = brd.build(); + public static List getOverCopyrightBrandings() { + final class LazyInit { + private static final List INSTANCE = ForgeHooksClient.forgeStatusLine == null + ? Collections.emptyList() + : List.of(ForgeHooksClient.forgeStatusLine); + + private LazyInit() {} } + + return LazyInit.INSTANCE; } - public static void forEachLine(boolean includeMC, boolean reverse, BiConsumer lineConsumer) { - final List brandings = getBrandings(includeMC, reverse); - IntStream.range(0, brandings.size()).boxed().forEachOrdered(idx -> lineConsumer.accept(idx, brandings.get(idx))); + public static void forEachLine(boolean includeMC, boolean reverse, ObjIntConsumer lineConsumer) { + var brandings = getBrandings(includeMC, reverse); + for (int idx = 0; idx < brandings.size(); idx++) + lineConsumer.accept(brandings.get(idx), idx); } - public static void forEachAboveCopyrightLine(BiConsumer lineConsumer) { - computeOverCopyrightBrandings(); - IntStream.range(0, overCopyrightBrandings.size()).boxed().forEachOrdered(idx->lineConsumer.accept(idx, overCopyrightBrandings.get(idx))); + public static void forEachAboveCopyrightLine(ObjIntConsumer lineConsumer) { + var overCopyrightBrandings = getOverCopyrightBrandings(); + for (int idx = 0; idx < overCopyrightBrandings.size(); idx++) + lineConsumer.accept(overCopyrightBrandings.get(idx), idx); } - public static String getClientBranding() { - return "forge"; - } - - public static String getServerBranding() { + public static String getBranding() { return "forge"; } diff --git a/src/main/java/net/minecraftforge/internal/ForgeBindings.java b/src/main/java/net/minecraftforge/internal/ForgeBindings.java index 716ca44161..9eb184a05f 100644 --- a/src/main/java/net/minecraftforge/internal/ForgeBindings.java +++ b/src/main/java/net/minecraftforge/internal/ForgeBindings.java @@ -15,15 +15,9 @@ import net.minecraftforge.fml.event.config.ModConfigEvent; import java.util.function.Supplier; -public class ForgeBindings implements IBindingsProvider { - @Override - public Supplier getForgeBusSupplier() { - return ()-> MinecraftForge.EVENT_BUS; - } - - @Override - public Supplier getMessageParser() { - return ()->new I18NParser() { +public final class ForgeBindings implements IBindingsProvider { + private static final class LazyInit { + private static final Supplier INSTANCE = () -> new I18NParser() { @Override public String parseMessage(final String i18nMessage, final Object... args) { return ForgeI18n.parseMessage(i18nMessage, args); @@ -34,10 +28,22 @@ public class ForgeBindings implements IBindingsProvider { return ForgeI18n.stripControlCodes(toStrip); } }; + + private LazyInit() {} + } + + @Override + public Supplier getForgeBusSupplier() { + return () -> MinecraftForge.EVENT_BUS; + } + + @Override + public Supplier getMessageParser() { + return LazyInit.INSTANCE; } @Override public Supplier getConfigConfiguration() { - return ()->new IConfigEvent.ConfigConfig(ModConfigEvent.Loading::new, ModConfigEvent.Reloading::new, ModConfigEvent.Unloading::new); + return () -> new IConfigEvent.ConfigConfig(ModConfigEvent.Loading::new, ModConfigEvent.Reloading::new, ModConfigEvent.Unloading::new); } } diff --git a/src/main/java/net/minecraftforge/logging/CrashReportExtender.java b/src/main/java/net/minecraftforge/logging/CrashReportExtender.java index e35ede8f40..acea58bf7f 100644 --- a/src/main/java/net/minecraftforge/logging/CrashReportExtender.java +++ b/src/main/java/net/minecraftforge/logging/CrashReportExtender.java @@ -22,7 +22,7 @@ import java.text.SimpleDateFormat; import java.util.*; public class CrashReportExtender { - private static final String LINE_SEPARATOR = System.getProperty( "line.separator" ); + private static final String LINE_SEPARATOR = System.lineSeparator(); public static void extendSystemReport(final SystemReport systemReport) { for (final ISystemReportExtender call : CrashReportCallables.allCrashCallables()) { if (call.isActive()) diff --git a/src/main/java/net/minecraftforge/network/ChannelListManager.java b/src/main/java/net/minecraftforge/network/ChannelListManager.java index f014cd33c7..403ba1a296 100644 --- a/src/main/java/net/minecraftforge/network/ChannelListManager.java +++ b/src/main/java/net/minecraftforge/network/ChannelListManager.java @@ -44,8 +44,8 @@ public class ChannelListManager { .build(); private record Register(List channels) implements CustomPacketPayload { - private static Type TYPE = CustomPacketPayload.createType("register"); - private static StreamCodec CODEC = StreamCodec.of( + private static final Type TYPE = CustomPacketPayload.createType("register"); + private static final StreamCodec CODEC = StreamCodec.of( (buf, v) -> encode(buf, v.channels), buf -> new Register(decode(buf)) ); @@ -57,8 +57,8 @@ public class ChannelListManager { } private record Unregister(List channels) implements CustomPacketPayload { - private static Type TYPE = CustomPacketPayload.createType("unregister"); - private static StreamCodec CODEC = StreamCodec.of( + private static final Type TYPE = CustomPacketPayload.createType("unregister"); + private static final StreamCodec CODEC = StreamCodec.of( (buf, v) -> encode(buf, v.channels), buf -> new Unregister(decode(buf)) ); diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index 8357de27f7..a461cfbbb0 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -31,6 +31,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntRBTreeMap; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; +import net.minecraft.nbt.Tag; import net.minecraft.tags.TagKey; import net.minecraftforge.common.util.LogMessageAdapter; import net.minecraftforge.fml.ModLoadingContext; @@ -794,7 +795,11 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist //Public for tests public Snapshot makeSnapshot() { Snapshot ret = new Snapshot(); - this.ids.forEach((id, value) -> ret.ids.put(getKey(value), id)); + for (Entry entry : this.ids.entrySet()) { + Integer id = entry.getKey(); + V value = entry.getValue(); + ret.ids.put(getKey(value), id.intValue()); + } ret.aliases.putAll(this.aliases); ret.blocked.addAll(this.blocked); ret.overrides.putAll(getOverrideOwners()); @@ -862,19 +867,19 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist data.put("ids", ids); ListTag aliases = new ListTag(); - this.aliases.entrySet().forEach(e -> { + this.aliases.forEach((k, v) -> { CompoundTag tag = new CompoundTag(); - tag.putString("K", e.getKey().toString()); - tag.putString("V", e.getValue().toString()); + tag.putString("K", k.toString()); + tag.putString("V", v.toString()); aliases.add(tag); }); data.put("aliases", aliases); ListTag overrides = new ListTag(); - this.overrides.entrySet().forEach(e -> { + this.overrides.forEach((k, v) -> { CompoundTag tag = new CompoundTag(); - tag.putString("K", e.getKey().toString()); - tag.putString("V", e.getValue()); + tag.putString("K", k.toString()); + tag.putString("V", v); overrides.add(tag); }); data.put("overrides", overrides); @@ -891,22 +896,22 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return ret; ListTag list = nbt.getList("ids", 10); - list.forEach(e -> { - CompoundTag comp = (CompoundTag)e; + for (Tag tag : list) { + CompoundTag comp = (CompoundTag) tag; ret.ids.put(ResourceLocation.parse(comp.getString("K")), comp.getInt("V")); - }); + } list = nbt.getList("aliases", 10); - list.forEach(e -> { - CompoundTag comp = (CompoundTag)e; + for (Tag tag : list) { + CompoundTag comp = (CompoundTag) tag; ret.aliases.put(ResourceLocation.parse(comp.getString("K")), ResourceLocation.parse(comp.getString("V"))); - }); + } list = nbt.getList("overrides", 10); - list.forEach(e -> { - CompoundTag comp = (CompoundTag)e; + for (Tag tag : list) { + CompoundTag comp = (CompoundTag) tag; ret.overrides.put(ResourceLocation.parse(comp.getString("K")), comp.getString("V")); - }); + } int[] blocked = nbt.getIntArray("blocked"); for (int i : blocked) @@ -976,20 +981,24 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } } else { // block item missing, warn as requested and block the id - if (action == MissingMappingsEvent.Action.DEFAULT) { - V m = this.missing == null ? null : this.missing.createMissing(remap.key, injectNetworkDummies); - if (m == null) - defaulted.add(remap.key); - else - this.add(remap.id, remap.key, m, remap.key.getNamespace()); - } else if (action == MissingMappingsEvent.Action.IGNORE) { - LOGGER.debug(REGISTRIES,"Ignoring {}", remap.key); - ignored++; - } else if (action == MissingMappingsEvent.Action.FAIL) { - LOGGER.debug(REGISTRIES,"Failing {}!", remap.key); - failed.add(remap.key); - } else if (action == MissingMappingsEvent.Action.WARN) { - LOGGER.warn(REGISTRIES,"{} may cause world breakage!", remap.key); + switch (action) { + case DEFAULT -> { + V m = this.missing == null ? null : this.missing.createMissing(remap.key, injectNetworkDummies); + if (m == null) + defaulted.add(remap.key); + else + this.add(remap.id, remap.key, m, remap.key.getNamespace()); + } + case IGNORE -> { + LOGGER.debug(REGISTRIES, "Ignoring {}", remap.key); + ignored++; + } + case FAIL -> { + LOGGER.debug(REGISTRIES, "Failing {}!", remap.key); + failed.add(remap.key); + } + case WARN -> LOGGER.warn(REGISTRIES, "{} may cause world breakage!", remap.key); + case null, default -> {} } this.block(remap.id); } diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index ba412ae443..27dc649ec5 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -514,12 +514,12 @@ public class GameData { throw new IllegalStateException("Could not get holder for " + key + " " + obj); } - obj.matchingStates().forEach((state) -> { + for (BlockState state : obj.matchingStates()) { var oldType = map.put(state, holder); if (oldType != null) { throw new IllegalStateException(String.format(Locale.ENGLISH, "Point of interest types %s and %s both list %s in their blockstates, this is not allowed. Blockstates can only have one point of interest type each.", oldType, obj, state)); } - }); + } } @Override diff --git a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java index 45479c678b..3e811e5af4 100644 --- a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java +++ b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java @@ -53,10 +53,10 @@ class NamespacedWrapper extends MappedRegistry implements ILockableRegistr Lifecycle registryLifecycle = Lifecycle.stable(); private boolean frozen = false; // Frozen is vanilla's variant of locked, but it can be unfrozen private List> holdersSorted; - private ObjectList> holdersById = new ObjectArrayList<>(256); - private Map> holdersByName = new HashMap<>(); - private Map> holders = new IdentityHashMap<>(); - private RegistryManager stage; + private final ObjectList> holdersById = new ObjectArrayList<>(256); + private final Map> holdersByName = new HashMap<>(); + private final Map> holders = new IdentityHashMap<>(); + private final RegistryManager stage; private volatile Map, HolderSet.Named> tags = new IdentityHashMap<>(); private final Map, RegistrationInfo> registrationInfos = new IdentityHashMap<>(); @@ -323,7 +323,9 @@ class NamespacedWrapper extends MappedRegistry implements ILockableRegistr @Override public void bindTags(Map, List>> newTags) { Map, List>> holderToTag = new IdentityHashMap<>(); - this.holdersByName.values().forEach(v -> holderToTag.put(v, new ArrayList<>())); + for (Holder.Reference tReference : this.holdersByName.values()) { + holderToTag.put(tReference, new ArrayList<>()); + } newTags.forEach((name, values) -> values.forEach(holder -> addTagToHolder(holderToTag, name, holder))); Set> set = new HashSet<>(Sets.difference(this.tags.keySet(), newTags.keySet())); @@ -336,15 +338,17 @@ class NamespacedWrapper extends MappedRegistry implements ILockableRegistr newTags.forEach((k, v) -> tmpTags.computeIfAbsent(k, this::createTag).bind(v)); Set> defaultedTags = Sets.difference(this.optionalTags.keySet(), newTags.keySet()); - defaultedTags.forEach(name -> { + for (TagKey name : defaultedTags) { List> defaults = this.optionalTags.get(name).stream() .map(valueSupplier -> getHolder(valueSupplier.get()).orElse(null)) .filter(Objects::nonNull) .distinct() .toList(); - defaults.forEach(holder -> addTagToHolder(holderToTag, name, holder)); + for (Holder holder : defaults) { + addTagToHolder(holderToTag, name, holder); + } tmpTags.computeIfAbsent(name, this::createTag).bind(defaults); - }); + } holderToTag.forEach(Holder.Reference::bindTags); this.tags = tmpTags; diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java b/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java index 4cd7dca3d9..c2e91a3294 100644 --- a/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java @@ -221,16 +221,13 @@ public class ObjectHolderRegistry public static void applyObjectHolders(Predicate filter) { RuntimeException aggregate = new RuntimeException("Failed to apply some object holders, see suppressed exceptions for details"); - objectHolders.forEach(objectHolder -> { - try - { + for (Consumer> objectHolder : objectHolders) { + try { objectHolder.accept(filter); - } - catch (Exception e) - { + } catch (Exception e) { aggregate.addSuppressed(e); } - }); + } if (aggregate.getSuppressed().length > 0) { diff --git a/src/main/java/net/minecraftforge/registries/RegistryBuilder.java b/src/main/java/net/minecraftforge/registries/RegistryBuilder.java index 5e4374389c..fd595f4dd3 100644 --- a/src/main/java/net/minecraftforge/registries/RegistryBuilder.java +++ b/src/main/java/net/minecraftforge/registries/RegistryBuilder.java @@ -5,7 +5,6 @@ package net.minecraftforge.registries; -import com.google.common.collect.Lists; import net.minecraft.core.Holder; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.registries.IForgeRegistry.AddCallback; @@ -15,6 +14,8 @@ import net.minecraftforge.registries.IForgeRegistry.CreateCallback; import net.minecraftforge.registries.IForgeRegistry.MissingFactory; import net.minecraftforge.registries.IForgeRegistry.ValidateCallback; import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -39,18 +40,18 @@ public class RegistryBuilder { private ResourceLocation optionalDefaultKey; private int minId = 0; private int maxId = MAX_ID; - private List> addCallback = Lists.newArrayList(); - private List> clearCallback = Lists.newArrayList(); - private List> createCallback = Lists.newArrayList(); - private List> validateCallback = Lists.newArrayList(); - private List> bakeCallback = Lists.newArrayList(); + private final List> addCallback = new ArrayList<>(); + private final List> clearCallback = new ArrayList<>(); + private final List> createCallback = new ArrayList<>(); + private final List> validateCallback = new ArrayList<>(); + private final List> bakeCallback = new ArrayList<>(); private boolean saveToDisc = true; private boolean sync = true; private boolean allowOverrides = true; private boolean allowModifications = false; private boolean hasWrapper = false; private MissingFactory missingFactory; - private Set legacyNames = new HashSet<>(); + private final Set legacyNames = new HashSet<>(); @Nullable private Function> intrusiveHolderCallback = null; @@ -206,8 +207,8 @@ public class RegistryBuilder { IForgeRegistry create() { if (hasWrapper) { GameData.WrapperFactory wrapper = GameData.createWrapperFactory(getDefault() != null); - this.addCallback.add(0, wrapper); - this.createCallback.add(0, wrapper); + this.addCallback.addFirst(wrapper); + this.createCallback.addFirst(wrapper); } return RegistryManager.ACTIVE.createRegistry(registryName, this); } @@ -217,7 +218,7 @@ public class RegistryBuilder { if (addCallback.isEmpty()) return null; if (addCallback.size() == 1) - return addCallback.get(0); + return addCallback.getFirst(); var tmp = this.addCallback; return (owner, stage, id, key, obj, old) -> { @@ -231,7 +232,7 @@ public class RegistryBuilder { if (clearCallback.isEmpty()) return null; if (clearCallback.size() == 1) - return clearCallback.get(0); + return clearCallback.getFirst(); var tmp = this.clearCallback; return (owner, stage) -> { @@ -245,7 +246,7 @@ public class RegistryBuilder { if (createCallback.isEmpty()) return null; if (createCallback.size() == 1) - return createCallback.get(0); + return createCallback.getFirst(); var tmp = this.createCallback; return (owner, stage) -> { @@ -259,7 +260,7 @@ public class RegistryBuilder { if (validateCallback.isEmpty()) return null; if (validateCallback.size() == 1) - return validateCallback.get(0); + return validateCallback.getFirst(); var tmp = this.validateCallback; return (owner, stage, id, key, obj) -> { @@ -273,7 +274,7 @@ public class RegistryBuilder { if (bakeCallback.isEmpty()) return null; if (bakeCallback.size() == 1) - return bakeCallback.get(0); + return bakeCallback.getFirst(); var tmp = this.bakeCallback; return (owner, stage) -> { diff --git a/src/main/java/net/minecraftforge/registries/RegistryManager.java b/src/main/java/net/minecraftforge/registries/RegistryManager.java index 150b910e5f..8efe2ca511 100644 --- a/src/main/java/net/minecraftforge/registries/RegistryManager.java +++ b/src/main/java/net/minecraftforge/registries/RegistryManager.java @@ -7,14 +7,13 @@ package net.minecraftforge.registries; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.google.common.collect.Sets; -import com.mojang.serialization.Lifecycle; import net.minecraft.core.RegistrationInfo; import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.BuiltInRegistries; @@ -35,10 +34,10 @@ public class RegistryManager { private static Set vanillaRegistryKeys = Set.of(); BiMap> registries = HashBiMap.create(); - private Map> registryView = Collections.unmodifiableMap(registries); - private Set persisted = Sets.newHashSet(); - private Set synced = Sets.newHashSet(); - private Map legacyNames = new HashMap<>(); + private final Map> registryView = Collections.unmodifiableMap(registries); + private final Set persisted = new HashSet<>(); + private final Set synced = new HashSet<>(); + private final Map legacyNames = new HashMap<>(); private final String name; RegistryManager() { @@ -152,7 +151,9 @@ public class RegistryManager { public Map takeSnapshot(boolean savingToDisc) { Map ret = new HashMap<>(); var keys = savingToDisc ? this.persisted : this.synced; - keys.forEach(name -> ret.put(name, getRegistry(name).makeSnapshot())); + for (ResourceLocation key : keys) { + ret.put(key, getRegistry(key).makeSnapshot()); + } return ret; } diff --git a/src/main/java/net/minecraftforge/registries/RegistryObject.java b/src/main/java/net/minecraftforge/registries/RegistryObject.java index 29f7767401..32b28dea4e 100644 --- a/src/main/java/net/minecraftforge/registries/RegistryObject.java +++ b/src/main/java/net/minecraftforge/registries/RegistryObject.java @@ -26,7 +26,7 @@ public final class RegistryObject implements Supplier { @Nullable private final ResourceLocation name; @Nullable - private ResourceKey key; + private final ResourceKey key; private final boolean optionalRegistry; @Nullable private T value; @@ -189,7 +189,8 @@ public final class RegistryObject implements Supplier { @Override public T get() { T ret = this.value; - Objects.requireNonNull(ret, () -> "Registry Object not present: " + this.name); + if (ret == null) + throw new NullPointerException("Registry Object not present: " + this.name); return ret; }