diff --git a/build.gradle b/build.gradle index 49204fd0..9282c0a9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,92 +1,126 @@ plugins { - id "dev.architectury.loom" version "1.1-SNAPSHOT" + id "architectury-plugin" version "3.4-SNAPSHOT" + id "dev.architectury.loom" version "1.1-SNAPSHOT" apply false id "maven-publish" - id 'com.matthewprenger.cursegradle' version '1.4.0' + id 'com.matthewprenger.cursegradle' version '1.4.0' apply false id 'com.palantir.git-version' version '1.0.0' id 'se.bjurr.gitchangelog.git-changelog-gradle-plugin' version '1.79.0' - id "com.modrinth.minotaur" version "2.+" + id "com.modrinth.minotaur" version "2.+" apply false + id("com.diffplug.spotless") version "6.18.0" apply false } -sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 - -group = 'org.embeddedt' -version = gitVersion() - -java { - archivesBaseName = 'modernfix-mc' + minecraft_version +architectury { + minecraft = rootProject.minecraft_version } -loom { - // use this if you are using the official mojang mappings - // and want loom to stop warning you about their license - silentMojangMappingsLicense() +ext.archives_base_name = 'modernfix-mc' + minecraft_version - // since loom 0.10, you are **required** to use the - // "forge" block to configure forge-specific features, - // such as the mixinConfigs array or datagen - forge { - // specify the mixin configs used in this mod - // this will be added to the jar manifest as well! - mixinConfigs = [ - "modernfix.mixins.json" +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" + apply plugin: "com.diffplug.spotless" + + spotless { + java { + removeUnusedImports() + } + } + + group = 'org.embeddedt' + version = gitVersion() + archivesBaseName = rootProject.archives_base_name + '-' + project.name + + sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 + + repositories { + maven { url 'https://modmaven.dev/' } + maven { + url "https://cursemaven.com" + content { + includeGroup "curse.maven" + } + } + maven { + name = 'ParchmentMC' + url = 'https://maven.parchmentmc.org' + } + maven { + // Shedaniel's maven (Architectury API) + url = "https://maven.architectury.dev" + content { + includeGroup "me.shedaniel" + } + } + + maven { + // saps.dev Maven (KubeJS and Rhino) + url = "https://maven.saps.dev/minecraft" + content { + includeGroup "dev.latvian.mods" + } + } + maven { // CTM + url "https://maven.tterrag.com/" + } + maven { url 'https://maven.blamejared.com' } + repositories { + maven { + name = "Fuzs Mod Resources" + url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/" + } + } + } +} + +subprojects { + apply plugin: "dev.architectury.loom" + + loom { + silentMojangMappingsLicense() + } + + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + mappings loom.layered() { + officialMojangMappings() + parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip") + } + } + + processResources { + def mixinFileList = [] + def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/mixin") + fileTree(mixinDirectory).visit { FileVisitDetails details -> + if(details.file.isFile()) { + def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.') + mixinFileList << fileName + } + } + + def mixinClassesStringB = new StringBuilder() + for(int i = 0; i < mixinFileList.size(); i++) { + mixinClassesStringB.append(" \"") + mixinClassesStringB.append(mixinFileList.get(i)) + mixinClassesStringB.append('"') + if(i < (mixinFileList.size() - 1)) + mixinClassesStringB.append(',') + mixinClassesStringB.append('\n') + } + + def replacements = [ + mixin_classes: mixinClassesStringB.toString() ] + + inputs.properties replacements + def filePattern = "modernfix-" + project.name + ".mixins.json" + filesMatching(filePattern) { + expand replacements + } } - mixin.defaultRefmapName = "modernfix.refmap.json" } -repositories { - maven { url 'https://modmaven.dev/' } - maven { - url "https://cursemaven.com" - content { - includeGroup "curse.maven" - } - } - maven { - name = 'ParchmentMC' - url = 'https://maven.parchmentmc.org' - } - maven { - // Shedaniel's maven (Architectury API) - url = "https://maven.architectury.dev" - content { - includeGroup "me.shedaniel" - } - } - - maven { - // saps.dev Maven (KubeJS and Rhino) - url = "https://maven.saps.dev/minecraft" - content { - includeGroup "dev.latvian.mods" - } - } - maven { // CTM - url "https://maven.tterrag.com/" - } - maven { url 'https://maven.blamejared.com' } -} - -dependencies { - // to change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - - // choose what mappings you want to use here - // leave this uncommented if you want to use - // mojang's official mappings, or feel free - // to add your own mappings here (how about - // mojmap layered with parchment, for example?) - mappings loom.layered() { - officialMojangMappings() - parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip") - } - - // uncomment this if you want to use yarn mappings - // mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - - // your forge dependency, this is **required** when using Forge Loom in forge mode! - forge "net.minecraftforge:forge:${project.forge_version}" - +/* modCompileOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") //modRuntimeOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") @@ -104,7 +138,7 @@ dependencies { modCompileOnly files("deps/starlight-1.2.jar") modCompileOnly("appeng:appliedenergistics2:8.4.7") modCompileOnly("vazkii.patchouli:Patchouli:1.16.4-53.3") -} +*/ tasks.withType(JavaCompile) { // ensure that the encoding is set to UTF-8, no matter what the system default is @@ -124,36 +158,6 @@ tasks.withType(JavaCompile) { */ } -processResources { - def mixinFileList = [] - def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/mixin") - fileTree(mixinDirectory).visit { FileVisitDetails details -> - if(details.file.isFile()) { - def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.') - mixinFileList << fileName - } - } - - def mixinClassesStringB = new StringBuilder() - for(int i = 0; i < mixinFileList.size(); i++) { - mixinClassesStringB.append(" \"") - mixinClassesStringB.append(mixinFileList.get(i)) - mixinClassesStringB.append('"') - if(i < (mixinFileList.size() - 1)) - mixinClassesStringB.append(',') - mixinClassesStringB.append('\n') - } - - def replacements = [ - mixin_classes: mixinClassesStringB.toString() - ] - - inputs.properties replacements - filesMatching("modernfix.mixins.json") { - expand replacements - } -} - task generateChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTask) { def details = versionDetails(); if(details.commitDistance > 0) { @@ -170,46 +174,7 @@ task generateChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTas toCommit = "HEAD"; } -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - // withSourcesJar() -} - -// Example for how to get properties into the manifest for reading at runtime. -jar { - manifest { - attributes([ - "Specification-Title" : "modernfix", - "Operative-Class" : "org.embeddedt.modernfix.agent.Agent", - //"Specification-Vendor": "modernfix authors", - "Specification-Version" : "1", // We are version 1 of ourselves - "Implementation-Title" : project.name, - "Implementation-Version" : project.jar.archiveVersion, - //"Implementation-Vendor": "modernfix authors", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) - } -} - -// configure the maven publication -publishing { - publications { - mavenJava(MavenPublication) { - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} - +/* curseforge { if (System.getenv("CURSEFORGE_TOKEN") != null) { apiKey = System.getenv("CURSEFORGE_TOKEN") @@ -253,3 +218,4 @@ tasks.register('publishToModSites') { publishToModSites.dependsOn(tasks.modrinth) publishToModSites.dependsOn(tasks.curseforge) } + */ \ No newline at end of file diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 00000000..de613044 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,33 @@ +architectury { + common(rootProject.enabled_platforms.split(",")) +} + +loom { + accessWidenerPath = file("src/main/resources/modernfix.accesswidener") +} + +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + + modApi("dev.latvian.mods:kubejs:${kubejs_version}") { + transitive = false + } + // Remove the next line if you don't want to depend on the API + // modApi "me.shedaniel:architectury:${rootProject.architectury_version}" +} + +publishing { + publications { + mavenCommon(MavenPublication) { + artifactId = rootProject.archives_base_name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} diff --git a/src/main/java/org/embeddedt/modernfix/FileWalker.java b/common/src/main/java/org/embeddedt/modernfix/FileWalker.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/FileWalker.java rename to common/src/main/java/org/embeddedt/modernfix/FileWalker.java diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFix.java b/common/src/main/java/org/embeddedt/modernfix/ModernFix.java new file mode 100644 index 00000000..d4d2bf64 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -0,0 +1,73 @@ +package org.embeddedt.modernfix; + +import net.minecraft.Util; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerLevel; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import org.embeddedt.modernfix.util.ClassInfoManager; + +import java.lang.management.ManagementFactory; +import java.util.concurrent.*; + +// The value here should match an entry in the META-INF/mods.toml file +public class ModernFix { + + // Directly reference a log4j logger. + public static final Logger LOGGER = LogManager.getLogger("ModernFix"); + + public static final String MODID = "modernfix"; + + public static ModernFix INSTANCE; + + // Used to skip computing the blockstate caches twice + public static boolean runningFirstInjection = false; + + private static Executor resourceReloadService = null; + + static { + if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dedicated_reload_executor.ReloadExecutor")) { + resourceReloadService = Util.makeExecutor("ResourceReload"); + } else { + resourceReloadService = Util.backgroundExecutor(); + } + } + + public static Executor resourceReloadExecutor() { + return resourceReloadService; + } + + + public ModernFix() { + INSTANCE = this; + } + + public void onServerStarted() { + if(ModernFixPlatformHooks.isDedicatedServer()) { + float gameStartTime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f; + ModernFix.LOGGER.warn("Dedicated server took " + gameStartTime + " seconds to load"); + } + ClassInfoManager.clear(); + } + + public void onLoadComplete() { + ClassInfoManager.clear(); + } + + public void onServerDead(MinecraftServer server) { + /* Clear as much data from the integrated server as possible, in case a mod holds on to it */ + try { + for(ServerLevel level : server.getAllLevels()) { + ChunkMap chunkMap = level.getChunkSource().chunkMap; + chunkMap.updatingChunkMap.clear(); + chunkMap.visibleChunkMap.clear(); + chunkMap.pendingUnloads.clear(); + } + } catch(RuntimeException e) { + ModernFix.LOGGER.error("Couldn't clear chunk data", e); + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java new file mode 100644 index 00000000..3c1cf8be --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -0,0 +1,179 @@ +package org.embeddedt.modernfix; + +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.ConnectScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.Entity; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; +import org.embeddedt.modernfix.packet.EntityIDSyncPacket; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import org.embeddedt.modernfix.world.IntegratedWatchdog; + +import java.lang.management.ManagementFactory; +import java.lang.reflect.Field; +import java.util.*; + +public class ModernFixClient { + public static long worldLoadStartTime; + private static int numRenderTicks; + + public static float gameStartTimeSeconds = -1; + + private static boolean recipesUpdated, tagsUpdated = false; + + public String brandingString = null; + + public ModernFixClient() { + // clear reserve as it's not needed + Minecraft.reserve = new byte[0]; + if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) { + brandingString = "ModernFix " + ModernFixPlatformHooks.getVersionString(); + } + } + + public void resetWorldLoadStateMachine() { + numRenderTicks = 0; + worldLoadStartTime = -1; + recipesUpdated = false; + tagsUpdated = false; + } + + public void onScreenOpening(Screen openingScreen) { + if(openingScreen instanceof ConnectScreen) { + worldLoadStartTime = System.nanoTime(); + } else if (openingScreen instanceof TitleScreen && gameStartTimeSeconds < 0) { + gameStartTimeSeconds = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f; + ModernFix.LOGGER.warn("Game took " + gameStartTimeSeconds + " seconds to start"); + } + } + + public void onRecipesUpdated() { + recipesUpdated = true; + } + + public void onTagsUpdated() { + tagsUpdated = true; + } + + public void onRenderTickEnd() { + if(recipesUpdated + && tagsUpdated + && worldLoadStartTime != -1 + && Minecraft.getInstance().player != null + && numRenderTicks++ >= 10) { + float timeSpentLoading = ((float)(System.nanoTime() - worldLoadStartTime) / 1000000000f); + ModernFix.LOGGER.warn("Time from main menu to in-game was " + timeSpentLoading + " seconds"); + ModernFix.LOGGER.warn("Total time to load game and open world was " + (timeSpentLoading + gameStartTimeSeconds) + " seconds"); + resetWorldLoadStateMachine(); + } + } + + /** + * Check if the IDs match and remap them if not. + * @return true if ID remap was needed + */ + private static boolean compareAndSwitchIds(Class eClass, String fieldName, EntityDataAccessor accessor, int newId) { + if(accessor.id != newId) { + ModernFix.LOGGER.warn("Corrected ID mismatch on {} field {}. Client had {} but server wants {}.", + eClass, + fieldName, + accessor.id, + newId); + accessor.id = newId; + return true; + } else { + ModernFix.LOGGER.debug("{} {} ID fine: {}", eClass, fieldName, newId); + return false; + } + } + + /** + * Horrendous hack to allow tracking every synced entity data manager. + * + * This is to ensure we can perform ID fixup on already constructed managers. + */ + public static final Set allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>()); + + private static final Field entriesArrayField; + static { + Field field; + try { + field = SynchedEntityData.class.getDeclaredField("entriesArray"); + field.setAccessible(true); + } catch(ReflectiveOperationException e) { + field = null; + } + entriesArrayField = field; + } + + /** + * Extremely hacky method to detect and correct mismatched entity data parameter IDs on the client and server. + * + * The technique is far from ideal, but it should detect reliably and also not break already constructed entities. + */ + public static void handleEntityIDSync(EntityIDSyncPacket packet) { + Map, List>> info = packet.getFieldInfo(); + boolean fixNeeded = false; + for(Map.Entry, List>> entry : info.entrySet()) { + Class eClass = entry.getKey(); + for(Pair field : entry.getValue()) { + String fieldName = field.getFirst(); + int newId = field.getSecond(); + try { + Field f = eClass.getDeclaredField(fieldName); + f.setAccessible(true); + EntityDataAccessor accessor = (EntityDataAccessor)f.get(null); + if(compareAndSwitchIds(eClass, fieldName, accessor, newId)) + fixNeeded = true; + } catch(NoSuchFieldException e) { + ModernFix.LOGGER.warn("Couldn't find field on {}: {}", eClass, fieldName); + } catch(ReflectiveOperationException e) { + throw new RuntimeException("Unexpected exception", e); + } + } + } + /* Now the ID mappings on synced entity data instances are probably all wrong. Fix that. */ + List dataEntries; + synchronized (allEntityDatas) { + if(fixNeeded) { + dataEntries = new ArrayList<>(allEntityDatas); + for(SynchedEntityData manager : dataEntries) { + Int2ObjectOpenHashMap> fixedMap = new Int2ObjectOpenHashMap<>(); + List> items = new ArrayList<>(manager.itemsById.values()); + for(SynchedEntityData.DataItem item : items) { + fixedMap.put(item.getAccessor().id, item); + } + manager.lock.writeLock().lock(); + try { + manager.itemsById.replaceAll((id, parameter) -> fixedMap.get((int)id)); + if(entriesArrayField != null) { + try { + SynchedEntityData.DataItem[] dataArray = new SynchedEntityData.DataItem[items.size()]; + for(int i = 0; i < dataArray.length; i++) { + dataArray[i] = fixedMap.get(i); + } + entriesArrayField.set(manager, dataArray); + } catch(ReflectiveOperationException e) { + ModernFix.LOGGER.error(e); + } + } + } finally { + manager.lock.writeLock().unlock(); + } + } + } + allEntityDatas.clear(); + } + } + + public void onServerStarted(MinecraftServer server) { + IntegratedWatchdog watchdog = new IntegratedWatchdog(server); + watchdog.start(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java b/common/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java rename to common/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java b/common/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java rename to common/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java diff --git a/common/src/main/java/org/embeddedt/modernfix/blockstate/BlockStateCacheHandler.java b/common/src/main/java/org/embeddedt/modernfix/blockstate/BlockStateCacheHandler.java new file mode 100644 index 00000000..c2be9256 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/blockstate/BlockStateCacheHandler.java @@ -0,0 +1,16 @@ +package org.embeddedt.modernfix.blockstate; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import org.embeddedt.modernfix.duck.IBlockState; + +public class BlockStateCacheHandler { + public static void rebuildParallel(boolean force) { + synchronized (BlockBehaviour.BlockStateBase.class) { + for (BlockState blockState : Block.BLOCK_STATE_REGISTRY) { + ((IBlockState)blockState).clearCache(); + } + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/blockstate/FakeStateMap.java b/common/src/main/java/org/embeddedt/modernfix/blockstate/FakeStateMap.java similarity index 99% rename from src/main/java/org/embeddedt/modernfix/blockstate/FakeStateMap.java rename to common/src/main/java/org/embeddedt/modernfix/blockstate/FakeStateMap.java index 42194e5d..ff7cc745 100644 --- a/src/main/java/org/embeddedt/modernfix/blockstate/FakeStateMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/blockstate/FakeStateMap.java @@ -1,6 +1,5 @@ package org.embeddedt.modernfix.blockstate; -import com.google.common.collect.ImmutableSet; import net.minecraft.world.level.block.state.properties.Property; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java new file mode 100644 index 00000000..7e6e3252 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -0,0 +1,126 @@ +package org.embeddedt.modernfix.core; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig; +import org.embeddedt.modernfix.core.config.Option; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import org.objectweb.asm.tree.*; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.io.File; +import java.util.*; + +public class ModernFixMixinPlugin implements IMixinConfigPlugin { + private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin."; + + public final Logger logger = LogManager.getLogger("ModernFix"); + public ModernFixEarlyConfig config = null; + public static ModernFixMixinPlugin instance; + + public ModernFixMixinPlugin() { + boolean firstConfig = instance == null; + if(firstConfig) { + instance = this; + try { + config = ModernFixEarlyConfig.load(new File("./config/modernfix-mixins.properties")); + } catch (Exception e) { + throw new RuntimeException("Could not load configuration file for ModernFix", e); + } + + this.logger.info("Loaded configuration file for ModernFix: {} options available, {} override(s) found", + config.getOptionCount(), config.getOptionOverrideCount()); + + if(ModernFixEarlyConfig.OPTIFINE_PRESENT) + this.logger.fatal("OptiFine detected. Use of ModernFix with OptiFine is not supported due to its impact on launch time and breakage of Forge features."); + + try { + Class.forName("sun.misc.Unsafe").getDeclaredMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class); + } catch(ReflectiveOperationException | NullPointerException e) { + this.logger.info("Applying Nashorn fix"); + Properties properties = System.getProperties(); + properties.setProperty("nashorn.args", properties.getProperty("nashorn.args", "") + " --anonymous-classes=false"); + } + + /* We abuse the constructor of a mixin plugin as a safe location to start modifying the classloader */ + ModernFixPlatformHooks.injectPlatformSpecificHacks(); + } + } + + + @Override + public void onLoad(String mixinPackage) { + + } + + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + if (!mixinClassName.startsWith(MIXIN_PACKAGE_ROOT)) { + this.logger.error("Expected mixin '{}' to start with package root '{}', treating as foreign and " + + "disabling!", mixinClassName, MIXIN_PACKAGE_ROOT); + + return false; + } + + String mixin = mixinClassName.substring(MIXIN_PACKAGE_ROOT.length()); + if(!instance.isOptionEnabled(mixin)) + return false; + String disabledBecauseMod = instance.config.getPermanentlyDisabledMixins().get(mixin); + return disabledBecauseMod == null; + } + + public boolean isOptionEnabled(String mixin) { + Option option = instance.config.getEffectiveOptionForMixin(mixin); + + if (option == null) { + this.logger.error("No rules matched mixin '{}', treating as foreign and disabling!", mixin); + + return false; + } + + if (option.isOverridden()) { + String source = "[unknown]"; + + if (option.isUserDefined()) { + source = "user configuration"; + } else if (option.isModDefined()) { + source = "mods [" + String.join(", ", option.getDefiningMods()) + "]"; + } + + if (option.isEnabled()) { + this.logger.warn("Force-enabling mixin '{}' as rule '{}' (added by {}) enables it", mixin, + option.getName(), source); + } else { + this.logger.warn("Force-disabling mixin '{}' as rule '{}' (added by {}) disables it and children", mixin, + option.getName(), source); + } + } + + return option.isEnabled(); + } + @Override + public void acceptTargets(Set myTargets, Set otherTargets) { + + } + + @Override + public List getMixins() { + return null; + } + + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + + } + + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + ModernFixPlatformHooks.applyASMTransformers(mixinClassName, targetClass); + } +} \ No newline at end of file diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java similarity index 71% rename from src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java rename to common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index c89ca64b..46f0d5fb 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -1,27 +1,23 @@ package org.embeddedt.modernfix.core.config; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.gson.*; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator; -import net.minecraftforge.forgespi.locating.IModFile; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.TypeAnnotationNode; import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.Stream; public class ModernFixEarlyConfig { private static final Logger LOGGER = LogManager.getLogger("ModernFixConfig"); @@ -46,7 +42,7 @@ public class ModernFixEarlyConfig { if(modId.equals("optifine")) return OPTIFINE_PRESENT; else - return FMLLoader.getLoadingModList().getModFileById(modId) != null; + return ModernFixPlatformHooks.modPresent(modId); } private static final String MIXIN_DESC = "Lorg/spongepowered/asm/mixin/Mixin;"; @@ -61,69 +57,73 @@ public class ModernFixEarlyConfig { } private void scanForAndBuildMixinOptions() { - IModFile file = FMLLoader.getLoadingModList().getModFileById("modernfix").getFile(); - Path mixinFolder = file.getLocator().findPath(file, "org", "embeddedt", "modernfix", "mixin"); - try(Stream mixinFiles = Files.find(mixinFolder, Integer.MAX_VALUE, (p, a) -> true)) { - Splitter dotSplitter = Splitter.on('.'); - // filter via toString - mixinFiles - .filter(p -> { - Path fileName = p.getFileName(); - return fileName != null && fileName.toString().endsWith(".class"); - }) - .forEach(path -> { - try(InputStream stream = Files.newInputStream(path)) { - ClassReader reader = new ClassReader(stream); - ClassNode node = new ClassNode(); - reader.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); - if(node.invisibleAnnotations == null) - return; - boolean isMixin = false, isClientOnly = false, requiredModPresent = true; - String requiredModId = ""; - for(AnnotationNode annotation : node.invisibleAnnotations) { - if(Objects.equals(annotation.desc, MIXIN_DESC)) { - isMixin = true; - } else if(Objects.equals(annotation.desc, MIXIN_CLIENT_ONLY_DESC)) { - isClientOnly = true; - } else if(Objects.equals(annotation.desc, MIXIN_REQUIRES_MOD_DESC)) { - for(int i = 0; i < annotation.values.size(); i += 2) { - if(annotation.values.get(i).equals("value")) { - String modId = (String)annotation.values.get(i + 1); - if(modId != null) { - requiredModPresent = modPresent(modId); - requiredModId = modId; - } - break; - } - } + List configFiles = ImmutableList.of("modernfix-common.mixins.json", "modernfix-fabric.mixins.json", "modernfix-forge.mixins.json"); + List mixinPaths = new ArrayList<>(); + for(String configFile : configFiles) { + InputStream stream = ModernFixEarlyConfig.class.getClassLoader().getResourceAsStream(configFile); + if(stream == null) + continue; + try(Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + JsonObject configObject = (JsonObject)new JsonParser().parse(reader); + JsonArray mixinList = configObject.getAsJsonArray("mixins"); + for(JsonElement mixin : mixinList) { + mixinPaths.add("org/embeddedt/modernfix/mixin/" + mixin.getAsString().replace('.', '/') + ".class"); + } + } catch(IOException | JsonParseException e) { + LOGGER.error("Error loading config " + configFile, e); + } + } + Splitter dotSplitter = Splitter.on('.'); + for(String mixinPath : mixinPaths) { + try(InputStream stream = ModernFixEarlyConfig.class.getClassLoader().getResourceAsStream(mixinPath)) { + ClassReader reader = new ClassReader(stream); + ClassNode node = new ClassNode(); + reader.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); + if(node.invisibleAnnotations == null) + return; + boolean isMixin = false, isClientOnly = false, requiredModPresent = true; + String requiredModId = ""; + for(AnnotationNode annotation : node.invisibleAnnotations) { + if(Objects.equals(annotation.desc, MIXIN_DESC)) { + isMixin = true; + } else if(Objects.equals(annotation.desc, MIXIN_CLIENT_ONLY_DESC)) { + isClientOnly = true; + } else if(Objects.equals(annotation.desc, MIXIN_REQUIRES_MOD_DESC)) { + for(int i = 0; i < annotation.values.size(); i += 2) { + if(annotation.values.get(i).equals("value")) { + String modId = (String)annotation.values.get(i + 1); + if(modId != null) { + requiredModPresent = modPresent(modId); + requiredModId = modId; } + break; } - if(isMixin) { - String mixinClassName = node.name.replace("org/embeddedt/modernfix/mixin/", "").replace('/', '.'); - if(!requiredModPresent) - mixinsMissingMods.put(mixinClassName, requiredModId); - else if(isClientOnly && FMLLoader.getDist() != Dist.CLIENT) - mixinsMissingMods.put(mixinClassName, "[not client]"); - List mixinOptionNames = dotSplitter.splitToList(mixinClassName); - StringBuilder optionBuilder = new StringBuilder(mixinClassName.length()); - optionBuilder.append("mixin"); - for(int i = 0; i < mixinOptionNames.size() - 1; i++) { - optionBuilder.append('.'); - optionBuilder.append(mixinOptionNames.get(i)); - mixinOptions.add(optionBuilder.toString()); - } - } - } catch(IOException e) { - ModernFix.LOGGER.error("Error scanning file " + path, e); } - }); - } catch(IOException e) { - ModernFix.LOGGER.error("Error scanning for mixins", e); + } + } + if(isMixin) { + String mixinClassName = node.name.replace("org/embeddedt/modernfix/mixin/", "").replace('/', '.'); + if(!requiredModPresent) + mixinsMissingMods.put(mixinClassName, requiredModId); + else if(isClientOnly && !ModernFixPlatformHooks.isClient()) + mixinsMissingMods.put(mixinClassName, "[not client]"); + List mixinOptionNames = dotSplitter.splitToList(mixinClassName); + StringBuilder optionBuilder = new StringBuilder(mixinClassName.length()); + optionBuilder.append("mixin"); + for(int i = 0; i < mixinOptionNames.size() - 1; i++) { + optionBuilder.append('.'); + optionBuilder.append(mixinOptionNames.get(i)); + mixinOptions.add(optionBuilder.toString()); + } + } + } catch(IOException e) { + ModernFix.LOGGER.error("Error scanning file " + mixinPath, e); + } } } private static final boolean shouldReplaceSearchTrees; - private static final boolean isDevEnv = !FMLLoader.isProduction() && FMLLoader.getLoadingModList().getModFileById("modernfix").getFile().getLocator() instanceof ExplodedDirectoryLocator;; + private static final boolean isDevEnv = ModernFixPlatformHooks.isDevEnv(); static { shouldReplaceSearchTrees = modPresent("jei"); diff --git a/src/main/java/org/embeddedt/modernfix/core/config/Option.java b/common/src/main/java/org/embeddedt/modernfix/core/config/Option.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/core/config/Option.java rename to common/src/main/java/org/embeddedt/modernfix/core/config/Option.java diff --git a/src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java b/common/src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java rename to common/src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java diff --git a/src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java b/common/src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java rename to common/src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java diff --git a/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java b/common/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java similarity index 99% rename from src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java rename to common/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java index 1083a9f7..b1d78509 100644 --- a/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java +++ b/common/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java @@ -12,7 +12,6 @@ import org.embeddedt.modernfix.ModernFix; import sun.misc.Unsafe; import java.lang.reflect.Field; -import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; diff --git a/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java b/common/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java rename to common/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java index dd9dfbdb..4284e4bc 100644 --- a/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java +++ b/common/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java @@ -1,7 +1,6 @@ package org.embeddedt.modernfix.dfu; import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DataFix; import com.mojang.datafixers.DataFixUtils; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.schemas.Schema; diff --git a/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java b/common/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java similarity index 66% rename from src/main/java/org/embeddedt/modernfix/duck/IBlockState.java rename to common/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java index 208a4c1a..d396f128 100644 --- a/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java +++ b/common/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java @@ -1,6 +1,5 @@ package org.embeddedt.modernfix.duck; -import org.embeddedt.modernfix.util.BakeReason; public interface IBlockState { void clearCache(); diff --git a/src/main/java/org/embeddedt/modernfix/duck/ICachedIngredientJS.java b/common/src/main/java/org/embeddedt/modernfix/duck/ICachedIngredientJS.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/ICachedIngredientJS.java rename to common/src/main/java/org/embeddedt/modernfix/duck/ICachedIngredientJS.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java b/common/src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java rename to common/src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java b/common/src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java rename to common/src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java b/common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java rename to common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/ILevelSave.java b/common/src/main/java/org/embeddedt/modernfix/duck/ILevelSave.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/ILevelSave.java rename to common/src/main/java/org/embeddedt/modernfix/duck/ILevelSave.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/IPaperChunkHolder.java b/common/src/main/java/org/embeddedt/modernfix/duck/IPaperChunkHolder.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/IPaperChunkHolder.java rename to common/src/main/java/org/embeddedt/modernfix/duck/IPaperChunkHolder.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/IServerLevel.java b/common/src/main/java/org/embeddedt/modernfix/duck/IServerLevel.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/IServerLevel.java rename to common/src/main/java/org/embeddedt/modernfix/duck/IServerLevel.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/reuse_datapacks/ICachingResourceClient.java b/common/src/main/java/org/embeddedt/modernfix/duck/reuse_datapacks/ICachingResourceClient.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/reuse_datapacks/ICachingResourceClient.java rename to common/src/main/java/org/embeddedt/modernfix/duck/reuse_datapacks/ICachingResourceClient.java diff --git a/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java rename to common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java index 3b21d552..cb4f81e9 100644 --- a/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java @@ -2,7 +2,6 @@ package org.embeddedt.modernfix.dynamicresources; import com.mojang.math.Transformation; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.BlockModelRotation; import net.minecraft.client.resources.model.BuiltInModel; @@ -11,7 +10,6 @@ import net.minecraft.resources.ResourceLocation; import org.apache.commons.lang3.tuple.Triple; import org.jetbrains.annotations.NotNull; -import javax.annotation.Nullable; import java.util.AbstractMap; import java.util.Collection; import java.util.Map; @@ -75,7 +73,6 @@ public class DynamicBakedModelProvider implements Map untrustedPacks, Set knownLocations, + Collection uncertainLocations, String filePrefix) { + if(untrustedPacks.size() > 0) { + /* Now make a fallback resource manager and use it on the remaining packs to see if they actually contain these files */ + FallbackResourceManager frm = new FallbackResourceManager(PackType.CLIENT_RESOURCES, "dummy"); + for (int i = untrustedPacks.size() - 1; i >= 0; i--) { + frm.add(untrustedPacks.get(i)); + } + for (ResourceLocation blockstate : uncertainLocations) { + if (knownLocations.contains(blockstate)) + continue; // don't check ones we know exist + ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), filePrefix + blockstate.getPath() + ".json"); + try (Resource resource = frm.getResource(fileLocation)) { + knownLocations.add(blockstate); + } catch (IOException ignored) { + } + } + } + } + + private static final int ERROR_THRESHOLD = 200; + + private static void logOrSuppressError(Object2IntOpenHashMap suppressionMap, String type, ResourceLocation location, Throwable e) { + int numErrors; + synchronized (suppressionMap) { + numErrors = suppressionMap.computeInt(location.getNamespace(), (k, oldVal) -> (oldVal == null ? 1 : oldVal + 1)); + } + if(numErrors <= ERROR_THRESHOLD) + ModernFix.LOGGER.error("Error reading {} {}: {}", type, location, e); + } + + public static void gatherModelMaterials(ResourceManager manager, Predicate isTrustedPack, + Set materialSet, Set blockStateFiles, + Set modelFiles, UnbakedModel missingModel, + Function modelDeserializer, + Function bakeryModelGetter) { + Stopwatch stopwatch = Stopwatch.createStarted(); + final Object2IntOpenHashMap blockstateErrors = new Object2IntOpenHashMap<>(); + /* + * First, gather all vanilla packs, and use listResources on them. This will allow us to (hopefully) avoid + * scanning most packs a lot. + */ + List allPackResources = new ArrayList<>(manager.listPacks().collect(Collectors.toList())); + Collections.reverse(allPackResources); + ObjectOpenHashSet allAvailableModels = new ObjectOpenHashSet<>(), allAvailableStates = new ObjectOpenHashSet<>(); + allPackResources.removeIf(pack -> { + if(isTrustedPack.test(pack)) { + for(String namespace : pack.getNamespaces(PackType.CLIENT_RESOURCES)) { + Collection allBlockstates = pack.getResources(PackType.CLIENT_RESOURCES, namespace, "blockstates", Integer.MAX_VALUE, p -> p.endsWith(".json")); + for(ResourceLocation blockstate : allBlockstates) { + allAvailableStates.add(new ResourceLocation(blockstate.getNamespace(), blockstate.getPath().replace("blockstates/", "").replace(".json", ""))); + } + Collection allModels = pack.getResources(PackType.CLIENT_RESOURCES, namespace, "models", Integer.MAX_VALUE, p -> p.endsWith(".json")); + for(ResourceLocation blockstate : allModels) { + allAvailableModels.add(new ResourceLocation(blockstate.getNamespace(), blockstate.getPath().replace("models/", "").replace(".json", ""))); + } + } + return true; + } + ModernFix.LOGGER.debug("Pack with class {} needs manual scan", pack.getClass().getName()); + return false; + }); + + gatherAdditionalViaManualScan(allPackResources, allAvailableStates, blockStateFiles, "blockstates/"); + // We now have a list of all blockstates known to exist. Delete anything that we don't have + blockStateFiles.retainAll(allAvailableStates); + allAvailableStates.clear(); + allAvailableStates.trim(); + + ConcurrentLinkedQueue> blockStateLoadedFiles = new ConcurrentLinkedQueue<>(); + List> blockStateData = new ArrayList<>(); + for(ResourceLocation blockstate : blockStateFiles) { + blockStateData.add(CompletableFuture.runAsync(() -> { + ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), "blockstates/" + blockstate.getPath() + ".json"); + try { + List resources = manager.getResources(fileLocation); + for(Resource resource : resources) { + JsonParser parser = new JsonParser(); + try { + blockStateLoadedFiles.add(Pair.of(blockstate, parser.parse(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)))); + } catch(JsonParseException e) { + logOrSuppressError(blockstateErrors, "blockstate", blockstate, e); + } finally { + resource.close(); + } + } + } catch(IOException e) { + logOrSuppressError(blockstateErrors, "blockstate", blockstate, e); + } + }, ModernFix.resourceReloadExecutor())); + } + blockStateFiles = null; + CompletableFuture.allOf(blockStateData.toArray(new CompletableFuture[0])).join(); + for(Pair pair : blockStateLoadedFiles) { + if(pair.getSecond() != null) { + try { + JsonObject obj = pair.getSecond().getAsJsonObject(); + if(obj.has("variants")) { + JsonObject eachVariant = obj.getAsJsonObject("variants"); + for(Map.Entry entry : eachVariant.entrySet()) { + JsonElement variantData = entry.getValue(); + List variantModels; + if(variantData.isJsonArray()) { + variantModels = new ArrayList<>(); + for(JsonElement model : variantData.getAsJsonArray()) { + variantModels.add(model.getAsJsonObject()); + } + } else + variantModels = Collections.singletonList(variantData.getAsJsonObject()); + for(JsonObject variant : variantModels) { + modelFiles.add(new ResourceLocation(variant.get("model").getAsString())); + } + } + + } else { + JsonArray multipartData = obj.get("multipart").getAsJsonArray(); + for(JsonElement element : multipartData) { + JsonObject self = element.getAsJsonObject(); + JsonElement apply = self.get("apply"); + List applyObjects; + if(apply.isJsonArray()) { + applyObjects = new ArrayList<>(); + for(JsonElement e : apply.getAsJsonArray()) { + applyObjects.add(e.getAsJsonObject()); + } + } else + applyObjects = Collections.singletonList(apply.getAsJsonObject()); + for(JsonObject applyEntry : applyObjects) { + modelFiles.add(new ResourceLocation(applyEntry.get("model").getAsString())); + } + } + + } + } catch(RuntimeException e) { + logOrSuppressError(blockstateErrors, "blockstate", pair.getFirst(), e); + } + + } + } + blockstateErrors.object2IntEntrySet().forEach(entry -> { + if(entry.getIntValue() > ERROR_THRESHOLD) { + ModernFix.LOGGER.error("Suppressed additional {} blockstate errors for domain {}", entry.getIntValue(), entry.getKey()); + } + }); + blockstateErrors.clear(); + blockStateData = null; + blockStateLoadedFiles.clear(); + + /* figure out which models we should actually load */ + gatherAdditionalViaManualScan(allPackResources, allAvailableModels, modelFiles, "models/"); + modelFiles.retainAll(allAvailableModels); + allAvailableModels.clear(); + allAvailableModels.trim(); + + Map basicModels = new HashMap<>(); + basicModels.put(ModelBakery.MISSING_MODEL_LOCATION, (BlockModel)missingModel); + basicModels.put(new ResourceLocation("builtin/generated"), GENERATION_MARKER); + basicModels.put(new ResourceLocation("builtin/entity"), BLOCK_ENTITY_MARKER); + Set> errorSet = Sets.newLinkedHashSet(); + while(modelFiles.size() > 0) { + List>> modelBytes = new ArrayList<>(); + for(ResourceLocation model : modelFiles) { + if(basicModels.containsKey(model)) + continue; + ResourceLocation fileLocation = new ResourceLocation(model.getNamespace(), "models/" + model.getPath() + ".json"); + modelBytes.add(CompletableFuture.supplyAsync(() -> { + try(Resource resource = manager.getResource(fileLocation)) { + JsonParser parser = new JsonParser(); + return Pair.of(model, parser.parse(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))); + } catch(IOException | JsonParseException e) { + logOrSuppressError(blockstateErrors, "model", fileLocation, e); + return Pair.of(fileLocation, null); + } + }, ModernFix.resourceReloadExecutor())); + } + modelFiles.clear(); + CompletableFuture.allOf(modelBytes.toArray(new CompletableFuture[0])).join(); + UVController.useDummyUv.set(Boolean.TRUE); + for(CompletableFuture> future : modelBytes) { + Pair pair = future.join(); + try { + if(pair.getSecond() != null) { + + BlockModel model = modelDeserializer.apply(pair.getSecond()); + model.name = pair.getFirst().toString(); + modelFiles.addAll(model.getDependencies()); + basicModels.put(pair.getFirst(), model); + continue; + } + } catch(Throwable e) { + logOrSuppressError(blockstateErrors, "model", pair.getFirst(), e); + } + basicModels.put(pair.getFirst(), (BlockModel)missingModel); + } + UVController.useDummyUv.set(Boolean.FALSE); + } + blockstateErrors.object2IntEntrySet().forEach(entry -> { + if(entry.getIntValue() > ERROR_THRESHOLD) { + ModernFix.LOGGER.error("Suppressed additional {} model errors for domain {}", entry.getIntValue(), entry.getKey()); + } + }); + modelFiles = null; + Function modelGetter = loc -> { + UnbakedModel m = basicModels.get(loc); + /* fallback to vanilla loader if missing */ + return m != null ? m : bakeryModelGetter.apply(loc); + }; + for(BlockModel model : basicModels.values()) { + materialSet.addAll(model.getMaterials(modelGetter, errorSet)); + } + //errorSet.stream().filter(pair -> !pair.getSecond().equals(MISSING_MODEL_LOCATION_STRING)).forEach(pair -> LOGGER.warn("Unable to resolve texture reference: {} in {}", pair.getFirst(), pair.getSecond())); + stopwatch.stop(); + ModernFix.LOGGER.info("Resolving model textures took " + stopwatch); + } + + private static , V extends T> BlockState setPropertyGeneric(BlockState state, Property prop, Object o) { + return state.setValue(prop, (V)o); + } + + private static > T getValueHelper(Property property, String value) { + return property.getValue(value).orElse((T) null); + } + + private static final Splitter COMMA_SPLITTER = Splitter.on(','); + private static final Splitter EQUAL_SPLITTER = Splitter.on('=').limit(2); + + public static ImmutableList getBlockStatesForMRL(StateDefinition stateDefinition, ModelResourceLocation location) { + if(Objects.equals(location.getVariant(), "inventory")) + return ImmutableList.of(); + Set> fixedProperties = new HashSet<>(); + BlockState fixedState = stateDefinition.any(); + for(String s : COMMA_SPLITTER.split(location.getVariant())) { + Iterator iterator = EQUAL_SPLITTER.split(s).iterator(); + if (iterator.hasNext()) { + String s1 = iterator.next(); + Property property = stateDefinition.getProperty(s1); + if (property != null && iterator.hasNext()) { + String s2 = iterator.next(); + Object value = getValueHelper(property, s2); + if (value == null) { + throw new RuntimeException("Unknown value: '" + s2 + "' for blockstate property: '" + s1 + "' " + property.getPossibleValues()); + } + fixedState = setPropertyGeneric(fixedState, property, value); + fixedProperties.add(property); + } else if (!s1.isEmpty()) { + throw new RuntimeException("Unknown blockstate property: '" + s1 + "'"); + } + } + } + // generate all possible blockstates from the remaining properties + ArrayList> anyProperties = new ArrayList<>(stateDefinition.getProperties()); + anyProperties.removeAll(fixedProperties); + ArrayList finalList = new ArrayList<>(); + finalList.add(fixedState); + for(Property property : anyProperties) { + ArrayList newPermutations = new ArrayList<>(); + for(BlockState state : finalList) { + for(Comparable value : property.getPossibleValues()) { + newPermutations.add(setPropertyGeneric(state, property, value)); + } + } + finalList = newPermutations; + } + return ImmutableList.copyOf(finalList); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelLocationCache.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelLocationCache.java similarity index 82% rename from src/main/java/org/embeddedt/modernfix/dynamicresources/ModelLocationCache.java rename to common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelLocationCache.java index 11938b3b..7370d58a 100644 --- a/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelLocationCache.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelLocationCache.java @@ -3,22 +3,12 @@ package org.embeddedt.modernfix.dynamicresources; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableMap; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import net.minecraft.Util; import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.Registry; import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.registries.IRegistryDelegate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class ModelLocationCache { diff --git a/src/main/java/org/embeddedt/modernfix/dynamicresources/UVController.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/UVController.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/dynamicresources/UVController.java rename to common/src/main/java/org/embeddedt/modernfix/dynamicresources/UVController.java diff --git a/common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java b/common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java new file mode 100644 index 00000000..695076c8 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java @@ -0,0 +1,57 @@ +package org.embeddedt.modernfix.entity; + +import com.mojang.datafixers.util.Pair; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.packet.EntityIDSyncPacket; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EntityDataIDSyncHandler { + private static Map, List>> fieldsToSyncMap; + + @SuppressWarnings("unchecked") + public static void onDatapackSyncEvent(ServerPlayer targetPlayer) { + if(targetPlayer != null) { + /* Compute the current set of serializer IDs in use and send them */ + if(fieldsToSyncMap == null) { + fieldsToSyncMap = new HashMap<>(); + Map, Integer> entityPoolMap = SynchedEntityData.ENTITY_ID_POOL; + List fieldsToSync = new ArrayList<>(); + for(Class eClass : entityPoolMap.keySet()) { + fieldsToSync.clear(); + try { + Field[] classFields = eClass.getDeclaredFields(); + for(Field field : classFields) { + if(!Modifier.isStatic(field.getModifiers())) + continue; + field.setAccessible(true); + Object o = field.get(null); + if(o != null && EntityDataAccessor.class.isAssignableFrom(o.getClass())) { + fieldsToSync.add(field); + } + } + for(Field field : fieldsToSync) { + int id = ((EntityDataAccessor)field.get(null)).id; + fieldsToSyncMap.computeIfAbsent(eClass, k -> new ArrayList<>()).add(Pair.of(field.getName(), id)); + } + } catch(Throwable e) { + ModernFix.LOGGER.error("Skipping entity ID sync for {}: {}", eClass.getName(), e); + } + } + } + EntityIDSyncPacket packet = new EntityIDSyncPacket(fieldsToSyncMap); + ModernFix.LOGGER.debug("Sending ID correction packet to client with " + fieldsToSyncMap.size() + " classes"); + ModernFixPlatformHooks.sendPacket(targetPlayer, packet); + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java b/common/src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java rename to common/src/main/java/org/embeddedt/modernfix/jei/async/IAsyncJeiStarter.java diff --git a/src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java b/common/src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java rename to common/src/main/java/org/embeddedt/modernfix/jei/async/JEILoadingInterruptedException.java diff --git a/src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java b/common/src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java rename to common/src/main/java/org/embeddedt/modernfix/jei/async/JEIReloadThread.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/ServerChunkCacheMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/ServerChunkCacheMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/ServerChunkCacheMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/ServerChunkCacheMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/MinecraftMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/MinecraftMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/MinecraftMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/RenderTypeMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/StaticTagHelperMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/StaticTagHelperMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/StaticTagHelperMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/concurrency/StaticTagHelperMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin_Client.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin_Client.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin_Client.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/mc218112/SynchedEntityDataMixin_Client.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkHolderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkHolderMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkHolderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkMapMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkMapMixin.java similarity index 89% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkMapMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkMapMixin.java index 15f9dd38..bd17c10a 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkMapMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/ChunkMapMixin.java @@ -1,13 +1,10 @@ package org.embeddedt.modernfix.mixin.bugfix.paper_chunk_patches; -import com.mojang.datafixers.util.Either; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; import net.minecraft.util.thread.BlockableEventLoop; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraftforge.fml.server.ServerLifecycleHooks; import org.embeddedt.modernfix.duck.IPaperChunkHolder; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -17,7 +14,6 @@ import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.function.Function; @@ -29,10 +25,10 @@ public class ChunkMapMixin { private Executor mainInvokingExecutor; - @Inject(method = "", at = @At("RETURN"), cancellable = true) + @Inject(method = "", at = @At("RETURN")) private void setup(CallbackInfo ci) { this.mainInvokingExecutor = (runnable) -> { - if(ServerLifecycleHooks.getCurrentServer().isSameThread()) + if(ModernFixPlatformHooks.getCurrentServer().isSameThread()) runnable.run(); else this.mainThreadExecutor.execute(runnable); diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/SortedArraySetMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/SortedArraySetMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/SortedArraySetMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/bugfix/paper_chunk_patches/SortedArraySetMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/core/SynchedEntityDataMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/core/SynchedEntityDataMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/core/SynchedEntityDataMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/core/SynchedEntityDataMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/devenv/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/devenv/MinecraftMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/devenv/MinecraftMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/devenv/MinecraftMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/devenv/NarratorMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/devenv/NarratorMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/devenv/NarratorMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/devenv/NarratorMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/direct_stack_trace/CrashReportMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/direct_stack_trace/CrashReportMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/feature/direct_stack_trace/CrashReportMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/feature/direct_stack_trace/CrashReportMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/BootstrapMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java similarity index 75% rename from src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java index 880c4953..19329d3f 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin.java @@ -8,12 +8,10 @@ import net.minecraft.core.RegistryAccess; import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.LevelStorageSource; import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.ModernFixClient; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.function.Function; @@ -33,9 +31,4 @@ public class MinecraftMixin { float timeSpentReloading = ((float)(System.nanoTime() - datapackReloadStartTime) / 1000000000f); ModernFix.LOGGER.warn("Datapack reload took " + timeSpentReloading + " seconds."); } - - @Inject(method = "loadWorld", at = @At("HEAD"), remap = false) - private void recordWorldLoadStart(String worldName, RegistryAccess.RegistryHolder dynamicRegistries, Function levelSaveToDatapackFunction, Function4 quadFunction, boolean vanillaOnly, Minecraft.ExperimentalDialogType selectionType, boolean creating, CallbackInfo ci) { - ModernFixClient.worldLoadStartTime = System.nanoTime(); - } } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/ProfiledReloadInstanceMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/ProfiledReloadInstanceMixin.java similarity index 94% rename from src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/ProfiledReloadInstanceMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/ProfiledReloadInstanceMixin.java index 9d93fc83..27a1a77f 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/ProfiledReloadInstanceMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/ProfiledReloadInstanceMixin.java @@ -5,7 +5,6 @@ import net.minecraft.server.packs.resources.ProfiledReloadInstance; import org.embeddedt.modernfix.util.NamedPreparableResourceListener; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyVariable; import java.util.ArrayList; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/SimpleReloadableResourceManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/SimpleReloadableResourceManagerMixin.java similarity index 75% rename from src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/SimpleReloadableResourceManagerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/SimpleReloadableResourceManagerMixin.java index 26c2a67f..1164ac16 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/SimpleReloadableResourceManagerMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/SimpleReloadableResourceManagerMixin.java @@ -2,22 +2,20 @@ package org.embeddedt.modernfix.mixin.feature.measure_time; import net.minecraft.server.packs.resources.SimpleReloadableResourceManager; import org.apache.logging.log4j.Logger; -import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(SimpleReloadableResourceManager.class) public class SimpleReloadableResourceManagerMixin { - + // TODO maybe expose as a mixin config + private static final boolean ENABLE_DEBUG_RELOADER = Boolean.getBoolean("modernfix.debugReloader"); /** * @author embeddedt * @reason add ability to use this feature in modpacks */ @Redirect(method = "createReload", at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;isDebugEnabled()Z", remap = false)) private boolean enableDebugReloader(Logger logger) { - return logger.isDebugEnabled() || ModernFixConfig.ENABLE_DEBUG_RELOADER.get(); + return logger.isDebugEnabled() || ENABLE_DEBUG_RELOADER; } } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/biome_zoomer/FuzzyOffsetBiomeZoomerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/biome_zoomer/FuzzyOffsetBiomeZoomerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/biome_zoomer/FuzzyOffsetBiomeZoomerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/biome_zoomer/FuzzyOffsetBiomeZoomerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/boost_worker_count/UtilMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_blockstate_cache_arrays/AbstractBlockStateCacheMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_blockstate_cache_arrays/AbstractBlockStateCacheMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_blockstate_cache_arrays/AbstractBlockStateCacheMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_blockstate_cache_arrays/AbstractBlockStateCacheMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/MultipartMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/MultipartMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/MultipartMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/MultipartMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java index b8cf36a7..7ea2104d 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java @@ -4,9 +4,9 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraftforge.fml.server.ServerLifecycleHooks; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.duck.IServerLevel; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.embeddedt.modernfix.world.StrongholdLocationCache; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -16,7 +16,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; -import java.util.concurrent.ExecutionException; @Mixin(ChunkGenerator.class) public class ChunkGeneratorMixin { @@ -39,7 +38,7 @@ public class ChunkGeneratorMixin { } private ServerLevel searchLevel() { - MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + MinecraftServer server = ModernFixPlatformHooks.getCurrentServer(); if(server != null) { ServerLevel ourLevel = null; for (ServerLevel level : server.getAllLevels()) { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ServerLevelMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ServerLevelMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ServerLevelMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_strongholds/ServerLevelMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_biome_container/MixinBiomeContainer.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockBehaviourMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockBehaviourMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockBehaviourMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockBehaviourMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockStateBaseMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockStateBaseMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/compress_blockstate/BlockStateBaseMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockModelShaperMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockModelShaperMixin.java similarity index 64% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockModelShaperMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockModelShaperMixin.java index 7a4efebf..b0fde164 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockModelShaperMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/BlockModelShaperMixin.java @@ -1,31 +1,16 @@ package org.embeddedt.modernfix.mixin.perf.dynamic_resources; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import net.minecraft.Util; import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; @Mixin(BlockModelShaper.class) @ClientOnlyMixin diff --git a/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelShaperMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelShaperMixin.java new file mode 100644 index 00000000..aaa93b1a --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelShaperMixin.java @@ -0,0 +1,70 @@ +package org.embeddedt.modernfix.mixin.perf.dynamic_resources; + +import net.minecraft.client.renderer.ItemModelShaper; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.world.item.Item; +import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.HashMap; +import java.util.Map; + +@Mixin(ItemModelShaper.class) +public abstract class ItemModelShaperMixin { + + @Shadow public abstract ModelManager getModelManager(); + + private Map overrideLocationsVanilla; + + public ItemModelShaperMixin() { + super(); + } + + private static final ModelResourceLocation SENTINEL_VANILLA = new ModelResourceLocation("modernfix", "sentinel"); + + @Inject(method = "", at = @At("RETURN")) + private void replaceLocationMap(CallbackInfo ci) { + overrideLocationsVanilla = new HashMap<>(); + } + + @Unique + private ModelResourceLocation mfix$getLocation(Item item) { + ModelResourceLocation map = overrideLocationsVanilla.getOrDefault(item, SENTINEL_VANILLA); + if(map == SENTINEL_VANILLA) { + /* generate the appropriate location from our cache */ + map = ModelLocationCache.get(item); + } + return map; + } + + /** + * @reason Get the stored location for that item and meta, and get the model + * from that location from the model manager. + **/ + @Overwrite + public BakedModel getItemModel(Item item) { + ModelResourceLocation map = mfix$getLocation(item); + return map == null ? null : getModelManager().getModel(map); + } + + /** + * @reason Don't get all models during init (with dynamic loading, that would + * generate them all). Just store location instead. + **/ + @Overwrite + public void register(Item item, ModelResourceLocation location) { + overrideLocationsVanilla.put(item, location); + } + + /** + * @reason Disable cache rebuilding (with dynamic loading, that would generate + * all models). + **/ + @Overwrite + public void rebuildCache() {} +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemRendererMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemRendererMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemRendererMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemRendererMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_font_loading/LegacyUnicodeBitmapsProviderMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_font_loading/LegacyUnicodeBitmapsProviderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/faster_font_loading/LegacyUnicodeBitmapsProviderMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_font_loading/LegacyUnicodeBitmapsProviderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_loading/TextureAtlasMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_loading/TextureAtlasMixin.java similarity index 89% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_loading/TextureAtlasMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_loading/TextureAtlasMixin.java index 4e09732e..45964183 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_loading/TextureAtlasMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_loading/TextureAtlasMixin.java @@ -9,11 +9,9 @@ import net.minecraft.client.resources.metadata.animation.AnimationMetadataSectio import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraftforge.client.ForgeHooksClient; -import net.minecraftforge.fml.ModLoader; -import org.apache.commons.lang3.tuple.Triple; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -22,7 +20,6 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.io.IOException; -import java.io.InputStream; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -43,7 +40,7 @@ public abstract class TextureAtlasMixin { */ @Redirect(method = "prepareToStitch", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/texture/TextureAtlas;getBasicSpriteInfos(Lnet/minecraft/server/packs/resources/ResourceManager;Ljava/util/Set;)Ljava/util/Collection;")) private Collection loadImages(TextureAtlas atlas, ResourceManager manager, Set imageLocations) { - usingFasterLoad = ModLoader.isLoadingStateValid(); + usingFasterLoad = ModernFixPlatformHooks.isLoadingNormally(); // bail if Forge is erroring to avoid AT crashes if(!usingFasterLoad) { return getBasicSpriteInfos(manager, imageLocations); @@ -94,9 +91,7 @@ public abstract class TextureAtlasMixin { } else { TextureAtlasSprite sprite = null; try { - sprite = ForgeHooksClient.loadTextureAtlasSprite((TextureAtlas)(Object)this, resourceManager, spriteInfo, pair.getFirst(), width, height, originX, originY, mipmapLevel, pair.getSecond()); - if(sprite == null) - sprite = new TextureAtlasSprite((TextureAtlas)(Object)this, spriteInfo, mipmapLevel, width, height, originX, originY, pair.getSecond()); + sprite = ModernFixPlatformHooks.loadTextureAtlasSprite((TextureAtlas)(Object)this, resourceManager, spriteInfo, pair.getFirst(), width, height, originX, originY, mipmapLevel, pair.getSecond()); } catch(RuntimeException e) { ModernFix.LOGGER.error("Error loading texture {}: {}", spriteInfo.name(), e); } finally { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_stitching/StitcherMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_stitching/StitcherMixin.java similarity index 92% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_stitching/StitcherMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_stitching/StitcherMixin.java index a88830e3..47e1878c 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_stitching/StitcherMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_texture_stitching/StitcherMixin.java @@ -3,19 +3,17 @@ package org.embeddedt.modernfix.mixin.perf.faster_texture_stitching; import com.mojang.datafixers.util.Pair; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.client.renderer.texture.Stitcher; -import net.minecraftforge.fml.ModLoader; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.embeddedt.modernfix.textures.StbStitcher; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -38,7 +36,7 @@ public class StitcherMixin { */ @Inject(method = "stitch", at = @At("HEAD"), cancellable = true) private void stitchFast(CallbackInfo ci) { - if(!ModLoader.isLoadingStateValid()) { + if(!ModernFixPlatformHooks.isLoadingNormally()) { ModernFix.LOGGER.error("Using vanilla stitcher implementation due to invalid loading state"); return; } @@ -59,7 +57,7 @@ public class StitcherMixin { */ @Inject(method = "gatherSprites", at = @At("HEAD"), cancellable = true) private void gatherSpritesFast(Stitcher.SpriteLoader spriteLoader, CallbackInfo ci) { - if(!ModLoader.isLoadingStateValid()) + if(!ModernFixPlatformHooks.isLoadingNormally()) return; ci.cancel(); for(StbStitcher.LoadableSpriteInfo info : loadableSpriteInfos) { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/BooleanPropertyMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/BooleanPropertyMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/BooleanPropertyMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/BooleanPropertyMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/PropertyMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/PropertyMixin.java similarity index 96% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/PropertyMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/PropertyMixin.java index 4d64c0ba..6cb7b18c 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/PropertyMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/PropertyMixin.java @@ -4,7 +4,6 @@ import net.minecraft.world.level.block.state.properties.Property; import org.embeddedt.modernfix.dedup.IdentifierCaches; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(Property.class) diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/SelectorMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/SelectorMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/SelectorMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/SelectorMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/TransformationMatrixMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/TransformationMatrixMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/TransformationMatrixMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/TransformationMatrixMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/nbt_memory_usage/CompoundTagMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/nbt_memory_usage/CompoundTagMixin.java similarity index 90% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/nbt_memory_usage/CompoundTagMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/nbt_memory_usage/CompoundTagMixin.java index 51072a68..76c5ed14 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/nbt_memory_usage/CompoundTagMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/nbt_memory_usage/CompoundTagMixin.java @@ -1,15 +1,12 @@ package org.embeddedt.modernfix.mixin.perf.nbt_memory_usage; -import com.google.common.collect.Maps; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import org.embeddedt.modernfix.util.CanonizingStringMap; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Map; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/nuke_empty_chunk_sections/MixinChunk.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java similarity index 88% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java index 8d76abbb..815d307a 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java @@ -1,18 +1,13 @@ package org.embeddedt.modernfix.mixin.perf.reduce_blockstate_cache_rebuilds; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; -import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.duck.IBlockState; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.concurrent.atomic.AtomicInteger; @Mixin(BlockBehaviour.BlockStateBase.class) public abstract class BlockStateBaseMixin implements IBlockState { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_biome_temperature_cache/BiomeMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_biome_temperature_cache/BiomeMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/remove_biome_temperature_cache/BiomeMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_biome_temperature_cache/BiomeMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/MinecraftServerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/MinecraftServerMixin.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/MinecraftServerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/MinecraftServerMixin.java index ab053461..e6163627 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/MinecraftServerMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/MinecraftServerMixin.java @@ -1,10 +1,8 @@ package org.embeddedt.modernfix.mixin.perf.remove_spawn_chunks; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.DistanceManager; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.TicketType; -import net.minecraft.util.Unit; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.ChunkStatus; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerChunkCacheAccessor.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerChunkCacheAccessor.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerChunkCacheAccessor.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerChunkCacheAccessor.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerLevelMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerLevelMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerLevelMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/remove_spawn_chunks/ServerLevelMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftServerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftServerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftServerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/reuse_datapacks/MinecraftServerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/state_definition_construct/StateDefinitionMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/state_definition_construct/StateDefinitionMixin.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/state_definition_construct/StateDefinitionMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/state_definition_construct/StateDefinitionMixin.java index dd6157c3..867fbc26 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/state_definition_construct/StateDefinitionMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/state_definition_construct/StateDefinitionMixin.java @@ -1,10 +1,10 @@ package org.embeddedt.modernfix.mixin.perf.state_definition_construct; import com.google.common.collect.ImmutableSortedMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.StateHolder; import net.minecraft.world.level.block.state.properties.Property; +import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.blockstate.FakeStateMap; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -15,6 +15,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable; import java.util.Map; @Mixin(StateDefinition.class) +@RequiresMod("ferritecore") public class StateDefinitionMixin> { @Shadow @Final private ImmutableSortedMap> propertiesByName; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java similarity index 90% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java index d725fb22..908e3ae4 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/IntegratedServerMixin.java @@ -11,9 +11,7 @@ import net.minecraft.core.RegistryAccess; import net.minecraft.server.level.progress.ChunkProgressListenerFactory; import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.LevelStorageSource; -import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.core.config.ModernFixConfig; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -24,7 +22,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; public class IntegratedServerMixin { @Inject(method = "", at = @At("RETURN")) private void adjustServerPriority(Thread pServerThread, Minecraft pMinecraft, RegistryAccess.RegistryHolder pRegistryHolder, LevelStorageSource.LevelStorageAccess pStorageSource, PackRepository pPackRepository, ServerResources pResources, WorldData pWorldData, MinecraftSessionService pSessionService, GameProfileRepository pProfileRepository, GameProfileCache pProfileCache, ChunkProgressListenerFactory pProgressListenerfactory, CallbackInfo ci) { - int pri = ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get(); + int pri = 4; //ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get(); pServerThread.setPriority(pri); } } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/UtilMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/UtilMixin.java similarity index 90% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/UtilMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/UtilMixin.java index 986b965a..a764f519 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/UtilMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/perf/thread_priorities/UtilMixin.java @@ -1,8 +1,6 @@ package org.embeddedt.modernfix.mixin.perf.thread_priorities; import net.minecraft.Util; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.core.config.ModernFixConfig; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/safety/BlockColorsMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/safety/BlockColorsMixin.java similarity index 86% rename from src/main/java/org/embeddedt/modernfix/mixin/safety/BlockColorsMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/safety/BlockColorsMixin.java index 5e6930a7..5d1ffed0 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/safety/BlockColorsMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/mixin/safety/BlockColorsMixin.java @@ -1,9 +1,6 @@ package org.embeddedt.modernfix.mixin.safety; -import net.minecraft.world.level.block.Block; -import net.minecraft.client.Minecraft; import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.color.block.BlockColor; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/safety/ItemColorsMixin.java b/common/src/main/java/org/embeddedt/modernfix/mixin/safety/ItemColorsMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/safety/ItemColorsMixin.java rename to common/src/main/java/org/embeddedt/modernfix/mixin/safety/ItemColorsMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/packet/EntityIDSyncPacket.java b/common/src/main/java/org/embeddedt/modernfix/packet/EntityIDSyncPacket.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/packet/EntityIDSyncPacket.java rename to common/src/main/java/org/embeddedt/modernfix/packet/EntityIDSyncPacket.java diff --git a/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java b/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java new file mode 100644 index 00000000..7bdf01ca --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java @@ -0,0 +1,80 @@ +package org.embeddedt.modernfix.platform; + +import com.mojang.blaze3d.platform.NativeImage; +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import org.objectweb.asm.tree.ClassNode; + +import java.nio.file.Path; + +public class ModernFixPlatformHooks { + @ExpectPlatform + public static boolean isClient() { + throw new AssertionError(); + } + + @ExpectPlatform + public static boolean isDedicatedServer() { + throw new AssertionError(); + } + + @ExpectPlatform + public static String getVersionString() { + throw new AssertionError(); + } + + @ExpectPlatform + public static boolean modPresent(String modId) { + throw new AssertionError(); + } + + @ExpectPlatform + public static boolean isDevEnv() { + throw new AssertionError(); + } + + @ExpectPlatform + public static void injectPlatformSpecificHacks() { + throw new AssertionError(); + } + + @ExpectPlatform + public static void applyASMTransformers(String mixinClassName, ClassNode targetClass) { + throw new AssertionError(); + } + + @ExpectPlatform + public static MinecraftServer getCurrentServer() { + throw new AssertionError(); + } + + @ExpectPlatform + public static boolean isLoadingNormally() { + throw new AssertionError(); + } + + @ExpectPlatform + public static TextureAtlasSprite loadTextureAtlasSprite(TextureAtlas atlasTexture, + ResourceManager resourceManager, TextureAtlasSprite.Info textureInfo, + Resource resource, + int atlasWidth, int atlasHeight, + int spriteX, int spriteY, int mipmapLevel, + NativeImage image) { + throw new AssertionError(); + } + + @ExpectPlatform + public static Path getGameDirectory() { + throw new AssertionError(); + } + + @ExpectPlatform + public static void sendPacket(ServerPlayer player, Object packet) { + throw new AssertionError(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/resources/CachedResourcePath.java b/common/src/main/java/org/embeddedt/modernfix/resources/CachedResourcePath.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/resources/CachedResourcePath.java rename to common/src/main/java/org/embeddedt/modernfix/resources/CachedResourcePath.java diff --git a/src/main/java/org/embeddedt/modernfix/resources/PackResourcesCacheEngine.java b/common/src/main/java/org/embeddedt/modernfix/resources/PackResourcesCacheEngine.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/resources/PackResourcesCacheEngine.java rename to common/src/main/java/org/embeddedt/modernfix/resources/PackResourcesCacheEngine.java index 30590ac7..8e2ced85 100644 --- a/src/main/java/org/embeddedt/modernfix/resources/PackResourcesCacheEngine.java +++ b/common/src/main/java/org/embeddedt/modernfix/resources/PackResourcesCacheEngine.java @@ -2,8 +2,6 @@ package org.embeddedt.modernfix.resources; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; diff --git a/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java b/common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java similarity index 91% rename from src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java rename to common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java index 303cc949..efaba2d0 100644 --- a/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java +++ b/common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java @@ -4,18 +4,15 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; -import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; -import javax.annotation.Nullable; - public class ModernFixConfigScreen extends Screen { private OptionList optionList; private Screen lastScreen; public boolean madeChanges = false; private Button doneButton; - public ModernFixConfigScreen(@Nullable Screen lastScreen) { + public ModernFixConfigScreen(Screen lastScreen) { super(new TranslatableComponent("modernfix.config")); this.lastScreen = lastScreen; } diff --git a/src/main/java/org/embeddedt/modernfix/screen/OptionList.java b/common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/screen/OptionList.java rename to common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java index ffe4aa8a..ddd9f35e 100644 --- a/src/main/java/org/embeddedt/modernfix/screen/OptionList.java +++ b/common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java @@ -3,13 +3,10 @@ package org.embeddedt.modernfix.screen; import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.ChatFormatting; -import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.ContainerObjectSelectionList; import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.client.gui.components.toasts.SystemToast; -import net.minecraft.client.gui.screens.controls.ControlList; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.TextComponent; @@ -21,7 +18,6 @@ import org.embeddedt.modernfix.core.config.Option; import java.io.IOException; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.stream.Collectors; public class OptionList extends ContainerObjectSelectionList { @@ -39,7 +35,7 @@ public class OptionList extends ContainerObjectSelectionList { this.mainScreen = arg; int maxW = 0; - Map optionMap = ModernFixMixinPlugin.config.getOptionMap(); + Map optionMap = ModernFixMixinPlugin.instance.config.getOptionMap(); List sortedKeys = optionMap.keySet().stream().filter(key -> !key.equals("mixin.core")).sorted().collect(Collectors.toList()); for(String key : sortedKeys) { Option option = optionMap.get(key); @@ -70,7 +66,7 @@ public class OptionList extends ContainerObjectSelectionList { this.toggleButton = new Button(0, 0, 95, 20, new TextComponent(""), (arg) -> { this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined()); try { - ModernFixMixinPlugin.config.save(); + ModernFixMixinPlugin.instance.config.save(); if(!OptionList.this.mainScreen.madeChanges) { OptionList.this.mainScreen.madeChanges = true; } diff --git a/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java rename to common/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java diff --git a/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java b/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java similarity index 90% rename from src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java rename to common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java index 8839a255..0bde2201 100644 --- a/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java +++ b/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java @@ -1,7 +1,6 @@ package org.embeddedt.modernfix.structure; import com.mojang.datafixers.DataFixer; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; import net.minecraft.SharedConstants; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; @@ -9,16 +8,23 @@ import net.minecraft.nbt.NbtUtils; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import net.minecraftforge.fml.loading.FMLPaths; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.embeddedt.modernfix.util.FileUtil; import java.io.*; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; public class CachingStructureManager { - private static ThreadLocal digestThreadLocal = ThreadLocal.withInitial(() -> LamdbaExceptionUtils.uncheck(() -> MessageDigest.getInstance("SHA-256"))); - private static final File STRUCTURE_CACHE_FOLDER = FileUtil.childFile(FMLPaths.GAMEDIR.get().resolve("modernfix").resolve("structureCacheV1").toFile()); + private static ThreadLocal digestThreadLocal = ThreadLocal.withInitial(() -> { + try { + return MessageDigest.getInstance("SHA-256"); + } catch(NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + }); + private static final File STRUCTURE_CACHE_FOLDER = FileUtil.childFile(ModernFixPlatformHooks.getGameDirectory().resolve("modernfix").resolve("structureCacheV1").toFile()); static { STRUCTURE_CACHE_FOLDER.mkdirs(); diff --git a/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java b/common/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java similarity index 99% rename from src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java rename to common/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java index 60477c28..7ec0c498 100644 --- a/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java +++ b/common/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java @@ -16,7 +16,6 @@ import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; import java.lang.invoke.MethodHandle; -import java.sql.Ref; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/org/embeddedt/modernfix/util/BakeReason.java b/common/src/main/java/org/embeddedt/modernfix/util/BakeReason.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/util/BakeReason.java rename to common/src/main/java/org/embeddedt/modernfix/util/BakeReason.java diff --git a/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java rename to common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java diff --git a/src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java b/common/src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java rename to common/src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java index 34a6d53f..5ee5cd77 100644 --- a/src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java @@ -4,7 +4,6 @@ import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.spongepowered.asm.mixin.transformer.ClassInfo; import java.lang.reflect.Field; -import java.util.Iterator; import java.util.Map; public class ClassInfoManager { diff --git a/src/main/java/org/embeddedt/modernfix/util/DummyList.java b/common/src/main/java/org/embeddedt/modernfix/util/DummyList.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/util/DummyList.java rename to common/src/main/java/org/embeddedt/modernfix/util/DummyList.java diff --git a/src/main/java/org/embeddedt/modernfix/util/DummyServerConfiguration.java b/common/src/main/java/org/embeddedt/modernfix/util/DummyServerConfiguration.java similarity index 92% rename from src/main/java/org/embeddedt/modernfix/util/DummyServerConfiguration.java rename to common/src/main/java/org/embeddedt/modernfix/util/DummyServerConfiguration.java index 96e3fbf1..3a853a59 100644 --- a/src/main/java/org/embeddedt/modernfix/util/DummyServerConfiguration.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/DummyServerConfiguration.java @@ -13,7 +13,6 @@ import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.ServerLevelData; -import javax.annotation.Nullable; import java.util.Set; public class DummyServerConfiguration implements WorldData { @@ -42,14 +41,13 @@ public class DummyServerConfiguration implements WorldData { } - @Nullable @Override public CompoundTag getCustomBossEvents() { return null; } @Override - public void setCustomBossEvents(@Nullable CompoundTag nbt) { + public void setCustomBossEvents(CompoundTag nbt) { } @@ -64,7 +62,7 @@ public class DummyServerConfiguration implements WorldData { } @Override - public CompoundTag createTag(RegistryAccess registries, @Nullable CompoundTag hostPlayerNBT) { + public CompoundTag createTag(RegistryAccess registries, CompoundTag hostPlayerNBT) { return null; } diff --git a/src/main/java/org/embeddedt/modernfix/util/FileUtil.java b/common/src/main/java/org/embeddedt/modernfix/util/FileUtil.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/util/FileUtil.java rename to common/src/main/java/org/embeddedt/modernfix/util/FileUtil.java index 41f2c4f5..62a61f9a 100644 --- a/src/main/java/org/embeddedt/modernfix/util/FileUtil.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/FileUtil.java @@ -1,7 +1,6 @@ package org.embeddedt.modernfix.util; import java.io.File; -import java.util.regex.Pattern; public class FileUtil { public static File childFile(File file) { diff --git a/src/main/java/org/embeddedt/modernfix/util/ItemMesherMap.java b/common/src/main/java/org/embeddedt/modernfix/util/ItemMesherMap.java similarity index 62% rename from src/main/java/org/embeddedt/modernfix/util/ItemMesherMap.java rename to common/src/main/java/org/embeddedt/modernfix/util/ItemMesherMap.java index d3f19f80..b44c8f5d 100644 --- a/src/main/java/org/embeddedt/modernfix/util/ItemMesherMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/ItemMesherMap.java @@ -1,9 +1,7 @@ package org.embeddedt.modernfix.util; import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.IRegistryDelegate; +import net.minecraft.core.Registry; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,16 +10,16 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; -public class ItemMesherMap implements Map, ModelResourceLocation> { - private final Function getLocation; +public class ItemMesherMap implements Map { + private final Function getLocation; - public ItemMesherMap(Function getLocation) { + public ItemMesherMap(Function getLocation) { this.getLocation = getLocation; } @Override public int size() { - return ForgeRegistries.ITEMS.getValues().size(); + return Registry.ITEM.keySet().size(); } @Override @@ -41,12 +39,12 @@ public class ItemMesherMap implements Map, ModelResource @Override public ModelResourceLocation get(Object key) { - return getLocation.apply(((IRegistryDelegate)key).get()); + return getLocation.apply((K)key); } @Nullable @Override - public ModelResourceLocation put(IRegistryDelegate key, ModelResourceLocation value) { + public ModelResourceLocation put(K key, ModelResourceLocation value) { throw new UnsupportedOperationException(); } @@ -56,7 +54,7 @@ public class ItemMesherMap implements Map, ModelResource } @Override - public void putAll(@NotNull Map, ? extends ModelResourceLocation> m) { + public void putAll(@NotNull Map m) { throw new UnsupportedOperationException(); } @@ -67,7 +65,7 @@ public class ItemMesherMap implements Map, ModelResource @NotNull @Override - public Set> keySet() { + public Set keySet() { throw new UnsupportedOperationException(); } @@ -79,7 +77,7 @@ public class ItemMesherMap implements Map, ModelResource @NotNull @Override - public Set, ModelResourceLocation>> entrySet() { + public Set> entrySet() { throw new UnsupportedOperationException(); } } diff --git a/src/main/java/org/embeddedt/modernfix/util/NamedPreparableResourceListener.java b/common/src/main/java/org/embeddedt/modernfix/util/NamedPreparableResourceListener.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/util/NamedPreparableResourceListener.java rename to common/src/main/java/org/embeddedt/modernfix/util/NamedPreparableResourceListener.java diff --git a/src/main/java/org/embeddedt/modernfix/util/PackTypeHelper.java b/common/src/main/java/org/embeddedt/modernfix/util/PackTypeHelper.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/util/PackTypeHelper.java rename to common/src/main/java/org/embeddedt/modernfix/util/PackTypeHelper.java diff --git a/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java b/common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java rename to common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java index 95c7e8ab..150269fe 100644 --- a/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java +++ b/common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java @@ -10,7 +10,6 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.lang.ref.WeakReference; -import java.util.concurrent.TimeUnit; public class IntegratedWatchdog extends Thread { private static final Logger LOGGER = LogManager.getLogger(); diff --git a/src/main/java/org/embeddedt/modernfix/world/StrongholdLocationCache.java b/common/src/main/java/org/embeddedt/modernfix/world/StrongholdLocationCache.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/world/StrongholdLocationCache.java rename to common/src/main/java/org/embeddedt/modernfix/world/StrongholdLocationCache.java index cb408664..341cb7a4 100644 --- a/src/main/java/org/embeddedt/modernfix/world/StrongholdLocationCache.java +++ b/common/src/main/java/org/embeddedt/modernfix/world/StrongholdLocationCache.java @@ -5,7 +5,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.saveddata.SavedData; -import net.minecraftforge.common.util.Constants; import java.util.ArrayList; import java.util.List; @@ -28,7 +27,7 @@ public class StrongholdLocationCache extends SavedData { @Override public void load(CompoundTag arg) { - if(arg.contains("Positions", Constants.NBT.TAG_LONG_ARRAY)) { + if(arg.contains("Positions")) { long[] positions = arg.getLongArray("Positions"); for(long position : positions) { chunkPosList.add(new ChunkPos(position)); diff --git a/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json similarity index 100% rename from src/main/resources/assets/modernfix/lang/en_us.json rename to common/src/main/resources/assets/modernfix/lang/en_us.json diff --git a/src/main/resources/assets/modernfix/lang/zh_cn.json b/common/src/main/resources/assets/modernfix/lang/zh_cn.json similarity index 100% rename from src/main/resources/assets/modernfix/lang/zh_cn.json rename to common/src/main/resources/assets/modernfix/lang/zh_cn.json diff --git a/src/main/resources/modernfix.mixins.json b/common/src/main/resources/modernfix-common.mixins.json similarity index 88% rename from src/main/resources/modernfix.mixins.json rename to common/src/main/resources/modernfix-common.mixins.json index 1cf114ed..08cf8500 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/common/src/main/resources/modernfix-common.mixins.json @@ -4,7 +4,6 @@ "package": "org.embeddedt.modernfix.mixin", "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", "compatibilityLevel": "JAVA_8", - "refmap": "modernfix.refmap.json", "mixins": [ ${mixin_classes} ], diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener new file mode 100644 index 00000000..732462a2 --- /dev/null +++ b/common/src/main/resources/modernfix.accesswidener @@ -0,0 +1,38 @@ +accessWidener v2 named + +accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType +accessible method net/minecraft/client/renderer/RenderType$CompositeRenderType (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V +accessible method net/minecraft/nbt/CompoundTag (Ljava/util/Map;)V + +accessible class net/minecraft/client/Minecraft$ExperimentalDialogType +accessible class net/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache +accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor +accessible field net/minecraft/world/level/block/state/BlockBehaviour properties Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties; +accessible class net/minecraft/client/renderer/block/model/BlockElementFace$Deserializer +accessible class net/minecraft/client/renderer/texture/Stitcher$Holder +accessible field net/minecraft/client/renderer/texture/Stitcher$Holder width I +accessible field net/minecraft/client/renderer/texture/Stitcher$Holder height I +accessible field net/minecraft/network/syncher/EntityDataAccessor id I +mutable field net/minecraft/network/syncher/EntityDataAccessor id I +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isAir Z +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties material Lnet/minecraft/world/level/material/Material; +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties destroyTime F +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties requiresCorrectToolForDrops Z +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties canOcclude Z +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isRedstoneConductor Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isSuffocating Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isViewBlocking Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties hasPostProcess Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; +accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties emissiveRendering Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; +accessible class net/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException +accessible field net/minecraft/network/syncher/SynchedEntityData itemsById Ljava/util/Map; +accessible field net/minecraft/network/syncher/SynchedEntityData ENTITY_ID_POOL Ljava/util/Map; +accessible field net/minecraft/network/syncher/SynchedEntityData lock Ljava/util/concurrent/locks/ReadWriteLock; +accessible method net/minecraft/Util makeExecutor (Ljava/lang/String;)Ljava/util/concurrent/ExecutorService; +accessible field net/minecraft/server/level/ChunkMap updatingChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; +accessible field net/minecraft/server/level/ChunkMap visibleChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; +accessible field net/minecraft/server/level/ChunkMap pendingUnloads Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; +accessible field net/minecraft/client/Minecraft reserve [B +accessible method net/minecraft/resources/ResourceKey (Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V +accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite (Lnet/minecraft/client/renderer/texture/TextureAtlas;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIIILcom/mojang/blaze3d/platform/NativeImage;)V +accessible field net/minecraft/client/renderer/block/model/BlockModel GSON Lcom/google/gson/Gson; \ No newline at end of file diff --git a/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta similarity index 100% rename from src/main/resources/pack.mcmeta rename to common/src/main/resources/pack.mcmeta diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 00000000..a4784f91 --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,113 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +apply plugin: 'com.matthewprenger.cursegradle' +apply plugin: 'com.modrinth.minotaur' + +architectury { + platformSetupLoomIde() + fabric() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common + + modIncludeImplementation + + include.extendsFrom modIncludeImplementation + modImplementation.extendsFrom modIncludeImplementation +} + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modIncludeImplementation(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modIncludeImplementation(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + // Remove the next line if you don't want to depend on the API + // modApi "me.shedaniel:architectury-fabric:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +shadowJar { + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" +} + +remapJar { + injectAccessWidener = true + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null +} + +jar { + classifier "dev" +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenFabric(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} + +curseforge { + if (System.getenv("CURSEFORGE_TOKEN") != null) { + apiKey = System.getenv("CURSEFORGE_TOKEN") + project { + id = "790626" + changelog = file('../CHANGELOG.md') + changelogType = "markdown" + releaseType = "release" + addGameVersion "Fabric" + addGameVersion minecraft_version + mainArtifact remapJar + } + } +} + +modrinth { + token = System.getenv("MODRINTH_TOKEN") + projectId = "modernfix" // This can be the project ID or the slug. Either will work! + versionType = "release" // This is the default -- can also be `beta` or `alpha` + uploadFile = remapJar + gameVersions = [minecraft_version] + loaders = ["fabric"] + changelog.set(provider { file("../CHANGELOG.md").getText('UTF-8') }) +} + +tasks.curseforge.dependsOn(rootProject.generateChangelog) +tasks.modrinth.dependsOn(rootProject.generateChangelog) \ No newline at end of file diff --git a/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java new file mode 100644 index 00000000..a73a29a2 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java @@ -0,0 +1,21 @@ +package org.embeddedt.modernfix; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; + +public class ModernFixClientFabric implements ClientModInitializer { + public static ModernFixClient commonMod; + + @Override + public void onInitializeClient() { + commonMod = new ModernFixClient(); + + ClientTickEvents.END_CLIENT_TICK.register((mc) -> commonMod.onRenderTickEnd()); + ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> commonMod.onScreenOpening(screen)); + ServerLifecycleEvents.SERVER_STARTED.register(server -> { + commonMod.onServerStarted(server); + }); + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/ModernFixFabric.java b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixFabric.java new file mode 100644 index 00000000..10be5040 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixFabric.java @@ -0,0 +1,29 @@ +package org.embeddedt.modernfix; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.minecraft.server.MinecraftServer; + +public class ModernFixFabric implements ModInitializer { + private ModernFix commonMod; + public static MinecraftServer theServer; + @Override + public void onInitialize() { + commonMod = new ModernFix(); + + ServerLifecycleEvents.SERVER_STARTING.register(server -> { + theServer = server; + }); + ServerLifecycleEvents.SERVER_STARTED.register(server -> { + commonMod.onServerStarted(); + }); + ServerLifecycleEvents.SERVER_STOPPED.register(server -> { + commonMod.onServerDead(server); + theServer = null; + }); + + // TODO: implement entity ID desync + } + + +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/mixin/core/ClientPlayNetHandlerMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/mixin/core/ClientPlayNetHandlerMixin.java new file mode 100644 index 00000000..ec2bad9d --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/mixin/core/ClientPlayNetHandlerMixin.java @@ -0,0 +1,21 @@ +package org.embeddedt.modernfix.mixin.core; + +import net.minecraft.client.multiplayer.ClientPacketListener; +import org.embeddedt.modernfix.ModernFixClientFabric; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = ClientPacketListener.class, priority = 1500) +public class ClientPlayNetHandlerMixin { + @Inject(method = "handleUpdateRecipes", at = @At("RETURN")) + private void signalRecipes(CallbackInfo ci) { + ModernFixClientFabric.commonMod.onRecipesUpdated(); + } + + @Inject(method = "handleUpdateTags", at = @At("RETURN")) + private void signalTags(CallbackInfo ci) { + ModernFixClientFabric.commonMod.onTagsUpdated(); + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/GuiMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/GuiMixin.java new file mode 100644 index 00000000..e963119f --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/GuiMixin.java @@ -0,0 +1,18 @@ +package org.embeddedt.modernfix.mixin.feature.branding; + +import net.minecraft.client.gui.components.DebugScreenOverlay; +import org.embeddedt.modernfix.ModernFixClientFabric; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(DebugScreenOverlay.class) +public class GuiMixin { + @Inject(method = "getGameInformation", at = @At("RETURN")) + private void addModernFix(CallbackInfoReturnable> cir) { + cir.getReturnValue().add(ModernFixClientFabric.commonMod.brandingString); + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin_Fabric.java b/fabric/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin_Fabric.java new file mode 100644 index 00000000..b2132f7d --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin_Fabric.java @@ -0,0 +1,18 @@ +package org.embeddedt.modernfix.mixin.feature.measure_time; + +import net.minecraft.client.Minecraft; +import org.embeddedt.modernfix.ModernFixClient; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +@ClientOnlyMixin +public class MinecraftMixin_Fabric { + @Inject(method = "doLoadLevel", at = @At("HEAD")) + private void recordWorldLoadStart(CallbackInfo ci) { + ModernFixClient.worldLoadStartTime = System.nanoTime(); + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java new file mode 100644 index 00000000..5109ccb2 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -0,0 +1,331 @@ +package org.embeddedt.modernfix.mixin.perf.dynamic_resources; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalNotification; +import com.google.common.collect.ImmutableList; +import com.google.gson.JsonElement; +import com.mojang.math.Transformation; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.ItemModelGenerator; +import net.minecraft.client.renderer.texture.AtlasSet; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.ClientPackSource; +import net.minecraft.client.resources.model.*; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.FilePackResources; +import net.minecraft.server.packs.FolderPackResources; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.VanillaPackResources; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.Property; +import org.apache.commons.lang3.tuple.Triple; +import org.apache.logging.log4j.Logger; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.duck.IExtendedModelBakery; +import org.embeddedt.modernfix.dynamicresources.DynamicBakedModelProvider; +import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; +import java.util.function.Function; + +/* high priority so that our injectors are added before other mods' */ +@Mixin(value = ModelBakery.class, priority = 600) +@ClientOnlyMixin +public abstract class ModelBakeryMixin implements IExtendedModelBakery { + + private static final boolean debugDynamicModelLoading = Boolean.getBoolean("modernfix.debugDynamicModelLoading"); + + @Shadow @Final @Mutable public Map unbakedCache; + + @Shadow @Final public static ModelResourceLocation MISSING_MODEL_LOCATION; + + @Shadow protected abstract BlockModel loadBlockModel(ResourceLocation location) throws IOException; + + @Shadow @Final protected ResourceManager resourceManager; + @Shadow private AtlasSet atlasSet; + @Shadow @Final private Set loadingStack; + + @Shadow protected abstract void loadModel(ResourceLocation blockstateLocation) throws Exception; + + @Shadow @Final private static Logger LOGGER; + + @Shadow @Final @Mutable + private Map bakedTopLevelModels; + + @Shadow @Final @Mutable private Map, BakedModel> bakedCache; + + @Shadow @Final public static BlockModel GENERATION_MARKER; + + @Shadow @Final private static ItemModelGenerator ITEM_MODEL_GENERATOR; + + @Shadow public abstract UnbakedModel getModel(ResourceLocation modelLocation); + + @Shadow @Nullable public abstract BakedModel bake(ResourceLocation location, ModelState transform); + + private Cache, BakedModel> loadedBakedModels; + private Cache loadedModels; + + private HashMap smallLoadingCache = new HashMap<>(); + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;push(Ljava/lang/String;)V", ordinal = 0)) + private void replaceTopLevelBakedModels(ProfilerFiller filler, String s) { + this.loadedBakedModels = CacheBuilder.newBuilder() + .expireAfterAccess(3, TimeUnit.MINUTES) + .maximumSize(1000) + .concurrencyLevel(8) + .removalListener(this::onModelRemoved) + .softValues() + .build(); + this.loadedModels = CacheBuilder.newBuilder() + .expireAfterAccess(3, TimeUnit.MINUTES) + .maximumSize(1000) + .concurrencyLevel(8) + .removalListener(this::onModelRemoved) + .softValues() + .build(); + this.bakedCache = loadedBakedModels.asMap(); + this.unbakedCache = loadedModels.asMap(); + this.bakedTopLevelModels = new DynamicBakedModelProvider((ModelBakery)(Object)this, bakedCache); + filler.push(s); + } + + private void onModelRemoved(RemovalNotification notification) { + if(!debugDynamicModelLoading) + return; + Object k = notification.getKey(); + if(k == null) + return; + ResourceLocation rl; + boolean baked = false; + if(k instanceof ResourceLocation) { + rl = (ResourceLocation)k; + } else { + rl = ((Triple)k).getLeft(); + baked = true; + } + ModernFix.LOGGER.warn("Evicted {} model {}", baked ? "baked" : "unbaked", rl); + } + + private UnbakedModel missingModel; + + private Set blockStateFiles; + private Set modelFiles; + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/ModelBakery;loadBlockModel(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/renderer/block/model/BlockModel;", ordinal = 0)) + private BlockModel captureMissingModel(ModelBakery bakery, ResourceLocation location) throws IOException { + this.missingModel = this.loadBlockModel(location); + this.blockStateFiles = new HashSet<>(); + this.modelFiles = new HashSet<>(); + return (BlockModel)this.missingModel; + } + + /** + * @author embeddedt + * @reason don't actually load the model. instead, keep track of if we need to load a blockstate or a model, + * and save the info into the two lists + */ + @Inject(method = "loadTopLevel", at = @At("HEAD"), cancellable = true) + private void addTopLevelFile(ModelResourceLocation location, CallbackInfo ci) { + ci.cancel(); + if(Objects.equals(location.getVariant(), "inventory")) { + modelFiles.add(new ResourceLocation(location.getNamespace(), "item/" + location.getPath())); + } else { + blockStateFiles.add(new ResourceLocation(location.getNamespace(), location.getPath())); + } + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Ljava/util/Set;addAll(Ljava/util/Collection;)Z", ordinal = 0)) + private boolean gatherModelTextures(Set materialSet, Collection collection) { + materialSet.addAll(collection); + gatherModelMaterials(materialSet); + return true; + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Ljava/util/Map;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 0)) + private void fetchStaticDefinitions(Map> map, BiConsumer> func) { + map.forEach((loc, def) -> blockStateFiles.add(loc)); + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;", ordinal = 0)) + private ImmutableList fetchBlocks(StateDefinition def) { + blockStateFiles.add(Registry.BLOCK.getKey(def.any().getBlock())); + return ImmutableList.of(); + } + + private boolean trustedResourcePack(PackResources pack) { + return pack instanceof VanillaPackResources || + pack instanceof ClientPackSource || + pack instanceof FolderPackResources || + pack instanceof FilePackResources; + } + + /** + * Load all blockstate JSONs and model files, collect textures. + */ + private void gatherModelMaterials(Set materialSet) { + Function modelDeserializer = model -> BlockModel.GSON.fromJson(model, BlockModel.class); + ModelBakeryHelpers.gatherModelMaterials(this.resourceManager, this::trustedResourcePack, materialSet, blockStateFiles, + modelFiles, missingModel, modelDeserializer, this::getModel); + loadedModels.invalidateAll(); + loadedModels.put(MISSING_MODEL_LOCATION, missingModel); + } + + @Inject(method = "uploadTextures", at = @At(value = "FIELD", target = "Lnet/minecraft/client/resources/model/ModelBakery;topLevelModels:Ljava/util/Map;", ordinal = 0), cancellable = true) + private void skipBake(TextureManager resourceManager, ProfilerFiller profiler, CallbackInfoReturnable cir) { + profiler.pop(); + // ensure missing model is a permanent override + this.bakedTopLevelModels.put(MISSING_MODEL_LOCATION, this.bake(MISSING_MODEL_LOCATION, BlockModelRotation.X0_Y0)); + cir.setReturnValue(atlasSet); + } + + /** + * Use the already loaded missing model instead of the cache entry (which will probably get evicted). + */ + @Redirect(method = "loadModel", at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", ordinal = 1)) + private Object getMissingModel(Map map, Object rl) { + if(rl == MISSING_MODEL_LOCATION && map == unbakedCache) + return missingModel; + return unbakedCache.get(rl); + } + + @Inject(method = "cacheAndQueueDependencies", at = @At("RETURN")) + private void addToSmallLoadingCache(ResourceLocation location, UnbakedModel model, CallbackInfo ci) { + smallLoadingCache.put(location, model); + } + + + /** + * @author embeddedt + * @reason synchronize + */ + @Inject(method = "getModel", at = @At("HEAD"), cancellable = true) + public void getOrLoadModelDynamic(ResourceLocation modelLocation, CallbackInfoReturnable cir) { + if(modelLocation.equals(MISSING_MODEL_LOCATION)) { + cir.setReturnValue(missingModel); + return; + } + UnbakedModel existing = this.unbakedCache.get(modelLocation); + if (existing != null) { + cir.setReturnValue(existing); + } else { + synchronized(this) { + if (this.loadingStack.contains(modelLocation)) { + throw new IllegalStateException("Circular reference while loading " + modelLocation); + } else { + this.loadingStack.add(modelLocation); + UnbakedModel iunbakedmodel = missingModel; + + while(!this.loadingStack.isEmpty()) { + ResourceLocation resourcelocation = this.loadingStack.iterator().next(); + + try { + existing = this.unbakedCache.get(resourcelocation); + if (existing == null) { + if(debugDynamicModelLoading) + LOGGER.info("Loading {}", resourcelocation); + this.loadModel(resourcelocation); + } else + smallLoadingCache.put(resourcelocation, existing); + } catch (ModelBakery.BlockStateDefinitionException var9) { + LOGGER.warn(var9.getMessage()); + this.unbakedCache.put(resourcelocation, iunbakedmodel); + smallLoadingCache.put(resourcelocation, iunbakedmodel); + } catch (Exception var10) { + LOGGER.warn("Unable to load model: '{}' referenced from: {}: {}", resourcelocation, modelLocation, var10); + this.unbakedCache.put(resourcelocation, iunbakedmodel); + smallLoadingCache.put(resourcelocation, iunbakedmodel); + } finally { + this.loadingStack.remove(resourcelocation); + } + } + + // We have to get the result from the temporary cache used for a model load + // As in pathological cases (e.g. Pedestals on 1.19) unbakedCache can lose + // the model immediately + UnbakedModel result = smallLoadingCache.getOrDefault(modelLocation, iunbakedmodel); + // We are done with loading, so clear this cache to allow GC of any unneeded models + smallLoadingCache.clear(); + cir.setReturnValue(result); + } + } + } + } + + private , V extends T> BlockState setPropertyGeneric(BlockState state, Property prop, Object o) { + return state.setValue(prop, (V)o); + } + @Redirect(method = "loadModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;")) + private ImmutableList loadOnlyRelevantBlockState(StateDefinition stateDefinition, ResourceLocation location) { + return ModelBakeryHelpers.getBlockStatesForMRL(stateDefinition, (ModelResourceLocation)location); + } + + @Override + public ImmutableList getBlockStatesForMRL(StateDefinition stateDefinition, ModelResourceLocation location) { + return loadOnlyRelevantBlockState(stateDefinition, location); + } + + private BakedModel bakedMissingModel = null; + + @Inject(method = "bake", at = @At("HEAD"), cancellable = true) + public void getOrLoadBakedModelDynamic(ResourceLocation arg, ModelState arg2, CallbackInfoReturnable cir) { + Function textureGetter = mat -> this.atlasSet.getSprite(mat); + Triple triple = Triple.of(arg, arg2.getRotation(), arg2.isUvLocked()); + BakedModel existing = this.bakedCache.get(triple); + if (existing != null) { + cir.setReturnValue(existing); + } else if (this.atlasSet == null) { + throw new IllegalStateException("bake called too early"); + } else { + synchronized (this) { + if(debugDynamicModelLoading) + LOGGER.info("Baking {}", arg); + UnbakedModel iunbakedmodel = this.getModel(arg); + iunbakedmodel.getMaterials(this::getModel, new HashSet<>()); + if(iunbakedmodel == missingModel && debugDynamicModelLoading) + LOGGER.warn("Model {} not present", arg); + BakedModel ibakedmodel = null; + if (iunbakedmodel instanceof BlockModel) { + BlockModel blockmodel = (BlockModel)iunbakedmodel; + if (blockmodel.getRootModel() == GENERATION_MARKER) { + ibakedmodel = ITEM_MODEL_GENERATOR.generateBlockModel(textureGetter, blockmodel).bake((ModelBakery)(Object)this, blockmodel, this.atlasSet::getSprite, arg2, arg, false); + } + } + if(ibakedmodel == null) { + if(iunbakedmodel == missingModel) { + // use a shared baked missing model + if(bakedMissingModel == null) { + bakedMissingModel = iunbakedmodel.bake((ModelBakery) (Object) this, textureGetter, arg2, arg); + ((DynamicBakedModelProvider)this.bakedTopLevelModels).setMissingModel(bakedMissingModel); + } + ibakedmodel = bakedMissingModel; + } else + ibakedmodel = iunbakedmodel.bake((ModelBakery) (Object) this, textureGetter, arg2, arg); + } + // TODO event + this.bakedCache.put(triple, ibakedmodel); + cir.setReturnValue(ibakedmodel); + } + } + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java b/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java new file mode 100644 index 00000000..cf174819 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java @@ -0,0 +1,77 @@ +package org.embeddedt.modernfix.platform.fabric; + +import com.mojang.blaze3d.platform.NativeImage; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import org.embeddedt.modernfix.ModernFixFabric; +import org.objectweb.asm.tree.*; + +import java.nio.file.Path; +import java.util.*; + +public class ModernFixPlatformHooksImpl { + public static boolean isClient() { + return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT; + } + + public static boolean isDedicatedServer() { + return FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER; + } + + private static String verString; + + public static String getVersionString() { + if(verString == null) { + ModContainer mfModContainer = FabricLoader.getInstance().getModContainer("modernfix").get(); + verString = mfModContainer.getMetadata().getVersion().getFriendlyString(); + } + return verString; + } + + public static boolean modPresent(String modId) { + return FabricLoader.getInstance().getModContainer(modId).isPresent(); + } + + public static boolean isDevEnv() { + return FabricLoader.getInstance().isDevelopmentEnvironment(); + } + + public static MinecraftServer getCurrentServer() { + return ModernFixFabric.theServer; + } + + public static boolean isLoadingNormally() { + return true; + } + + public static TextureAtlasSprite loadTextureAtlasSprite(TextureAtlas atlasTexture, + ResourceManager resourceManager, TextureAtlasSprite.Info textureInfo, + Resource resource, + int atlasWidth, int atlasHeight, + int spriteX, int spriteY, int mipmapLevel, + NativeImage image) { + return new TextureAtlasSprite(atlasTexture, textureInfo, mipmapLevel, atlasWidth, atlasHeight, spriteX, spriteY, image); + } + + public static Path getGameDirectory() { + return FabricLoader.getInstance().getGameDir(); + } + + public static void sendPacket(ServerPlayer player, Object packet) { + //PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), packet); + } + + public static void injectPlatformSpecificHacks() { + } + + public static void applyASMTransformers(String mixinClassName, ClassNode targetClass) { + + } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..79f1703f --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "id": "modernfix", + "version": "${version}", + "name": "ModernFix", + "description": "Optimization mod", + "authors": [ + "embeddedt" + ], + "contact": { + }, + "license": "LGPL-3.0", + "icon": "assets/modernfix/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "org.embeddedt.modernfix.ModernFixFabric" + ], + "client": [ + "org.embeddedt.modernfix.ModernFixClientFabric" + ] + }, + "mixins": [ + "modernfix-fabric.mixins.json", + "modernfix-common.mixins.json" + ], + "depends": { + "minecraft": ">=1.16.5" + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/modernfix-fabric.mixins.json b/fabric/src/main/resources/modernfix-fabric.mixins.json new file mode 100644 index 00000000..8835aec2 --- /dev/null +++ b/fabric/src/main/resources/modernfix-fabric.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "org.embeddedt.modernfix.mixin", + "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", + "compatibilityLevel": "JAVA_8", + "minVersion": "0.8", + "mixins": [ +${mixin_classes} + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/forge/build.gradle b/forge/build.gradle new file mode 100644 index 00000000..a5d86be3 --- /dev/null +++ b/forge/build.gradle @@ -0,0 +1,145 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +apply plugin: 'com.matthewprenger.cursegradle' +apply plugin: 'com.modrinth.minotaur' + +architectury { + platformSetupLoomIde() + forge() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath + + forge { + convertAccessWideners = true + extraAccessWideners.add loom.accessWidenerPath.get().asFile.name + + mixinConfig "modernfix-common.mixins.json" + mixinConfig "modernfix-forge.mixins.json" + } + mixin.defaultRefmapName = "modernfix.refmap.json" +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentForge.extendsFrom common +} + +dependencies { + forge "net.minecraftforge:forge:${rootProject.forge_version}" + // Remove the next line if you don't want to depend on the API + // modApi "me.shedaniel:architectury-forge:${rootProject.architectury_version}" + + modCompileOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") + //modRuntimeOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") + + modCompileOnly("curse.maven:refinedstorage-243076:${refined_storage_version}") + + modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}") + modCompileOnly("curse.maven:jeresources-240630:3545538") + modCompileOnly("curse.maven:jepb-437558:3172880") + modCompileOnly("curse.maven:babel-436964:3196072") + modCompileOnly("curse.maven:twforest-227639:3575220") + modRuntimeOnly("curse.maven:ferritecore-429235:4074330") + modCompileOnly("team.chisel.ctm:CTM:${ctm_version}") + modCompileOnly("curse.maven:supermartijncore-454372:4455378") + modCompileOnly("curse.maven:valhesiastructures-347488:3476252") + modCompileOnly files("deps/starlight-1.2.jar") + modCompileOnly("appeng:appliedenergistics2:8.4.7") + modCompileOnly("vazkii.patchouli:Patchouli:1.16.4-53.3") + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("META-INF/mods.toml") { + expand "version": project.version + } +} + +shadowJar { + exclude "fabric.mod.json" + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null +} + +jar { + classifier "dev" + manifest { + attributes([ + "Specification-Title" : "modernfix", + "Operative-Class" : "org.embeddedt.modernfix.agent.Agent", + //"Specification-Vendor": "modernfix authors", + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : project.jar.archiveVersion, + //"Implementation-Vendor": "modernfix authors", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenForge(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} + +curseforge { + if (System.getenv("CURSEFORGE_TOKEN") != null) { + apiKey = System.getenv("CURSEFORGE_TOKEN") + project { + id = "790626" + changelog = file('../CHANGELOG.md') + changelogType = "markdown" + releaseType = "release" + addGameVersion "Forge" + addGameVersion minecraft_version + mainArtifact remapJar + } + } +} + +modrinth { + token = System.getenv("MODRINTH_TOKEN") + projectId = "modernfix" // This can be the project ID or the slug. Either will work! + versionType = "release" // This is the default -- can also be `beta` or `alpha` + uploadFile = remapJar + gameVersions = [minecraft_version] + loaders = ["forge"] + changelog.set(provider { file("../CHANGELOG.md").getText('UTF-8') }) +} + +tasks.curseforge.dependsOn(rootProject.generateChangelog) +tasks.modrinth.dependsOn(rootProject.generateChangelog) diff --git a/deps/starlight-1.2.jar b/forge/deps/starlight-1.2.jar similarity index 100% rename from deps/starlight-1.2.jar rename to forge/deps/starlight-1.2.jar diff --git a/forge/gradle.properties b/forge/gradle.properties new file mode 100644 index 00000000..32f842a6 --- /dev/null +++ b/forge/gradle.properties @@ -0,0 +1 @@ +loom.platform=forge \ No newline at end of file diff --git a/forge/src/main/java/org/embeddedt/modernfix/ModernFixClientForge.java b/forge/src/main/java/org/embeddedt/modernfix/ModernFixClientForge.java new file mode 100644 index 00000000..b361e948 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/ModernFixClientForge.java @@ -0,0 +1,98 @@ +package org.embeddedt.modernfix; + +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.DebugScreenOverlay; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.client.event.RecipesUpdatedEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.gui.ForgeIngameGui; +import net.minecraftforge.client.settings.KeyConflictContext; +import net.minecraftforge.event.TagsUpdatedEvent; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.ExtensionPoint; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.server.FMLServerStartedEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import org.embeddedt.modernfix.screen.ModernFixConfigScreen; + +public class ModernFixClientForge { + private static ModernFixClient commonMod; + + public ModernFixClientForge() { + commonMod = new ModernFixClient(); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); + ModLoadingContext.get().registerExtensionPoint( + ExtensionPoint.CONFIGGUIFACTORY, + () -> (mc, screen) -> new ModernFixConfigScreen(screen) + ); + } + + private KeyMapping configKey; + + private void clientSetup(FMLClientSetupEvent event) { + configKey = new KeyMapping("key.modernfix.config", KeyConflictContext.UNIVERSAL, InputConstants.UNKNOWN, "key.modernfix"); + ClientRegistry.registerKeyBinding(configKey); + + } + + @SubscribeEvent + public void onConfigKey(TickEvent.ClientTickEvent event) { + if(event.phase == TickEvent.Phase.START && configKey.consumeClick()) { + Minecraft.getInstance().setScreen(new ModernFixConfigScreen(Minecraft.getInstance().screen)); + } + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onRenderOverlay(RenderGameOverlayEvent.Text event) { + if(commonMod.brandingString != null && Minecraft.getInstance().options.renderDebug) { + event.getLeft().add(""); + event.getLeft().add(commonMod.brandingString); + } + } + + @SubscribeEvent + public void onDisconnect(WorldEvent.Unload event) { + if(event.getWorld().isClientSide()) { + DebugScreenOverlay overlay = ObfuscationReflectionHelper.getPrivateValue(ForgeIngameGui.class, (ForgeIngameGui)Minecraft.getInstance().gui, "debugOverlay"); + if(overlay != null) { + Minecraft.getInstance().tell(overlay::clearChunkCache); + } + } + } + + @SubscribeEvent + public void onServerStarting(FMLServerStartedEvent event) { + commonMod.onServerStarted(event.getServer()); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onRenderTickEnd(TickEvent.RenderTickEvent event) { + if(event.phase == TickEvent.Phase.END) + commonMod.onRenderTickEnd(); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onRecipes(RecipesUpdatedEvent e) { + commonMod.onRecipesUpdated(); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onTags(TagsUpdatedEvent e) { + commonMod.onTagsUpdated(); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onScreen(GuiScreenEvent.InitGuiEvent.Pre event) { + if(event.isCanceled()) + return; + commonMod.onScreenOpening(event.getGui()); + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/ModernFixForge.java b/forge/src/main/java/org/embeddedt/modernfix/ModernFixForge.java new file mode 100644 index 00000000..6444a84c --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/ModernFixForge.java @@ -0,0 +1,97 @@ +package org.embeddedt.modernfix; + +import net.minecraft.world.item.Item; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.OnDatapackSyncEvent; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.*; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; +import net.minecraftforge.fml.event.server.FMLServerStartedEvent; +import net.minecraftforge.fml.event.server.FMLServerStoppedEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.fml.network.FMLNetworkConstants; +import net.minecraftforge.fml.server.ServerLifecycleHooks; +import net.minecraftforge.registries.ForgeRegistries; +import org.apache.commons.lang3.tuple.Pair; +import org.embeddedt.modernfix.classloading.ModFileScanDataDeduplicator; +import org.embeddedt.modernfix.core.config.ModernFixConfig; +import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler; +import org.embeddedt.modernfix.packet.PacketHandler; +import org.embeddedt.modernfix.registry.ObjectHolderClearer; +import org.embeddedt.modernfix.util.KubeUtil; + +@Mod(ModernFix.MODID) +public class ModernFixForge { + private static ModernFix commonMod; + + public ModernFixForge() { + commonMod = new ModernFix(); + // Register ourselves for server and other game events we are interested in + MinecraftForge.EVENT_BUS.register(this); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onLoadComplete); + FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(Item.class, this::registerItems); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClient())); + ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true)); + ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG); + if(ModList.get().isLoaded("kubejs")) + MinecraftForge.EVENT_BUS.register(KubeUtil.class); + PacketHandler.register(); + ModFileScanDataDeduplicator.deduplicate(); + } + + @SubscribeEvent + public void onDatapackSync(OnDatapackSyncEvent event) { + if(event.getPlayer() != null) { + if(!ServerLifecycleHooks.getCurrentServer().isDedicatedServer() && event.getPlayerList().getPlayerCount() == 0) + return; + EntityDataIDSyncHandler.onDatapackSyncEvent(event.getPlayer()); + } + } + + private void registerItems(RegistryEvent event) { + if(Boolean.getBoolean("modernfix.largeRegistryTest")) { + Item.Properties props = new Item.Properties(); + for(int i = 0; i < 1000000; i++) { + ForgeRegistries.ITEMS.register(new Item(props).setRegistryName("modernfix", "item_" + i)); + } + } + } + + private static boolean dfuModPresent() { + for(String modId : new String[] { "lazydfu", "datafixerslayer" }) { + if(ModList.get().isLoaded(modId)) + return true; + } + return !FMLLoader.isProduction(); + } + + @SubscribeEvent + public void commonSetup(FMLCommonSetupEvent event) { + if(!dfuModPresent()) { + event.enqueueWork(() -> { + ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, "modernfix.no_lazydfu")); + }); + } + ObjectHolderClearer.clearThrowables(); + } + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onServerDead(FMLServerStoppedEvent event) { + commonMod.onServerDead(event.getServer()); + } + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onLoadComplete(FMLLoadCompleteEvent event) { + commonMod.onLoadComplete(); + } + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onServerStarted(FMLServerStartedEvent event) { + commonMod.onServerStarted(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/classloading/FastAccessTransformerList.java b/forge/src/main/java/org/embeddedt/modernfix/classloading/FastAccessTransformerList.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/classloading/FastAccessTransformerList.java rename to forge/src/main/java/org/embeddedt/modernfix/classloading/FastAccessTransformerList.java diff --git a/src/main/java/org/embeddedt/modernfix/classloading/ModFileScanDataDeduplicator.java b/forge/src/main/java/org/embeddedt/modernfix/classloading/ModFileScanDataDeduplicator.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/classloading/ModFileScanDataDeduplicator.java rename to forge/src/main/java/org/embeddedt/modernfix/classloading/ModFileScanDataDeduplicator.java diff --git a/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java b/forge/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java rename to forge/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java index 978f8b1a..6c523043 100644 --- a/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java +++ b/forge/src/main/java/org/embeddedt/modernfix/classloading/ModernFixResourceFinder.java @@ -1,11 +1,9 @@ package org.embeddedt.modernfix.classloading; import com.google.common.collect.*; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.LoadingModList; import net.minecraftforge.fml.loading.moddiscovery.*; -import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.forgespi.locating.IModFile; import net.minecraftforge.forgespi.locating.IModLocator; import org.apache.commons.lang3.tuple.Pair; diff --git a/forge/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java b/forge/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java new file mode 100644 index 00000000..5ff68b43 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java @@ -0,0 +1,39 @@ +package org.embeddedt.modernfix.core.config; + +import com.google.common.collect.ImmutableList; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.common.ForgeConfigSpec; + +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class ModernFixConfig { + private static final ForgeConfigSpec.Builder COMMON_BUILDER = new ForgeConfigSpec.Builder(); + public static ForgeConfigSpec COMMON_CONFIG; + + public static ForgeConfigSpec.ConfigValue> BLACKLIST_ASYNC_JEI_PLUGINS; + + private static Set jeiPluginBlacklist; + + static { + Predicate locationValidator = o -> o instanceof String && ((String)o).contains(":"); + BLACKLIST_ASYNC_JEI_PLUGINS = COMMON_BUILDER + .comment("These JEI plugins will be loaded on the main thread") + .defineList("blacklist_async_jei_plugins", ImmutableList.of( + "jepb:jei_plugin" + ), locationValidator); + } + + static { + COMMON_CONFIG = COMMON_BUILDER.build(); + } + + public static Set getJeiPluginBlacklist() { + if(jeiPluginBlacklist == null) { + jeiPluginBlacklist = BLACKLIST_ASYNC_JEI_PLUGINS.get().stream().map(ResourceLocation::new).collect(Collectors.toSet()); + } + return jeiPluginBlacklist; + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/duck/IExtendedForgeModelBakery.java b/forge/src/main/java/org/embeddedt/modernfix/duck/IExtendedForgeModelBakery.java new file mode 100644 index 00000000..0729fd1a --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/duck/IExtendedForgeModelBakery.java @@ -0,0 +1,4 @@ +package org.embeddedt.modernfix.duck; + +public interface IExtendedForgeModelBakery extends IExtendedModelBakery { +} diff --git a/src/main/java/org/embeddedt/modernfix/duck/rs/IFluidExternalStorageCache.java b/forge/src/main/java/org/embeddedt/modernfix/duck/rs/IFluidExternalStorageCache.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/rs/IFluidExternalStorageCache.java rename to forge/src/main/java/org/embeddedt/modernfix/duck/rs/IFluidExternalStorageCache.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/rs/IItemExternalStorageCache.java b/forge/src/main/java/org/embeddedt/modernfix/duck/rs/IItemExternalStorageCache.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/duck/rs/IItemExternalStorageCache.java rename to forge/src/main/java/org/embeddedt/modernfix/duck/rs/IItemExternalStorageCache.java diff --git a/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelBakeEvent.java b/forge/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelBakeEvent.java similarity index 92% rename from src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelBakeEvent.java rename to forge/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelBakeEvent.java index e5b69e7e..312d5a4a 100644 --- a/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelBakeEvent.java +++ b/forge/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelBakeEvent.java @@ -1,12 +1,10 @@ package org.embeddedt.modernfix.dynamicresources; import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.fml.event.lifecycle.IModBusEvent; /** * Fired when a model is baked dynamically. Intended to be used as a replacement for ModelBakeEvent diff --git a/src/main/java/org/embeddedt/modernfix/load/ModWorkManagerQueue.java b/forge/src/main/java/org/embeddedt/modernfix/load/ModWorkManagerQueue.java similarity index 95% rename from src/main/java/org/embeddedt/modernfix/load/ModWorkManagerQueue.java rename to forge/src/main/java/org/embeddedt/modernfix/load/ModWorkManagerQueue.java index e6a870b0..b7ca9080 100644 --- a/src/main/java/org/embeddedt/modernfix/load/ModWorkManagerQueue.java +++ b/forge/src/main/java/org/embeddedt/modernfix/load/ModWorkManagerQueue.java @@ -5,8 +5,6 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; public class ModWorkManagerQueue extends ConcurrentLinkedDeque { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/valhesia/BlockStateBaseMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/valhesia/BlockStateBaseMixin.java similarity index 95% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/valhesia/BlockStateBaseMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/valhesia/BlockStateBaseMixin.java index d2f1d2a5..c6e4f726 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/valhesia/BlockStateBaseMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/chunk_deadlock/valhesia/BlockStateBaseMixin.java @@ -5,7 +5,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; import org.embeddedt.modernfix.annotation.RequiresMod; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/preserve_early_window_pos/WindowMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/preserve_early_window_pos/WindowMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/preserve_early_window_pos/WindowMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/preserve_early_window_pos/WindowMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageCacheMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageCacheMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageCacheMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageCacheMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageMixin.java similarity index 86% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageMixin.java index 629e50bc..83ffc56e 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageMixin.java @@ -2,12 +2,9 @@ package org.embeddedt.modernfix.mixin.bugfix.refinedstorage.te_bug; import com.refinedmods.refinedstorage.apiimpl.storage.externalstorage.FluidExternalStorage; import com.refinedmods.refinedstorage.apiimpl.storage.externalstorage.FluidExternalStorageCache; -import com.refinedmods.refinedstorage.apiimpl.storage.externalstorage.ItemExternalStorageCache; import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.items.IItemHandler; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.duck.rs.IFluidExternalStorageCache; -import org.embeddedt.modernfix.duck.rs.IItemExternalStorageCache; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageProviderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageProviderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageProviderMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/FluidExternalStorageProviderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageCacheMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageCacheMixin.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageCacheMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageCacheMixin.java index c36e8e12..2f2cde14 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageCacheMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageCacheMixin.java @@ -3,7 +3,6 @@ package org.embeddedt.modernfix.mixin.bugfix.refinedstorage.te_bug; import com.refinedmods.refinedstorage.api.network.INetwork; import com.refinedmods.refinedstorage.apiimpl.storage.externalstorage.ItemExternalStorageCache; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandler; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.duck.rs.IItemExternalStorageCache; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageProviderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageProviderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageProviderMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/refinedstorage/te_bug/ItemExternalStorageProviderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/remove_block_chunkloading/RemoveBlockGoalMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/remove_block_chunkloading/RemoveBlockGoalMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/remove_block_chunkloading/RemoveBlockGoalMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/remove_block_chunkloading/RemoveBlockGoalMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java index 42550f4a..e04aecc5 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java @@ -7,7 +7,6 @@ import net.minecraft.world.level.chunk.LightChunkGetter; import org.embeddedt.modernfix.annotation.RequiresMod; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/tf_cme_on_load/TwilightForestModMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/tf_cme_on_load/TwilightForestModMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/tf_cme_on_load/TwilightForestModMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/bugfix/tf_cme_on_load/TwilightForestModMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/BrandingControlMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/BrandingControlMixin.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/mixin/feature/branding/BrandingControlMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/BrandingControlMixin.java index 2afc8190..2ed56969 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/BrandingControlMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/feature/branding/BrandingControlMixin.java @@ -10,7 +10,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import java.util.List; import java.util.Optional; @Mixin(value = BrandingControl.class, remap = false, priority = 1100) diff --git a/forge/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin_Forge.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin_Forge.java new file mode 100644 index 00000000..93c30028 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/feature/measure_time/MinecraftMixin_Forge.java @@ -0,0 +1,19 @@ +package org.embeddedt.modernfix.mixin.feature.measure_time; + +import net.minecraft.client.Minecraft; +import org.embeddedt.modernfix.ModernFixClient; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +@ClientOnlyMixin +public class MinecraftMixin_Forge { + @Inject(method = "loadWorld", at = @At("HEAD"), remap = false) + private void recordWorldLoadStart(CallbackInfo ci) { + ModernFixClient.worldLoadStartTime = System.nanoTime(); + } +} + diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java index 51045e8a..1d23549a 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/ClientLifecycleHandlerMixin.java @@ -84,7 +84,6 @@ public class ClientLifecycleHandlerMixin { cancelPreviousStart(); ModernFix.LOGGER.info("Starting new JEI thread."); JEIReloadThread newThread = new JEIReloadThread(() -> { - ModernFix.waitForWorldLoad(() -> ((JEIReloadThread)Thread.currentThread()).isStopRequested()); if(((JEIReloadThread)Thread.currentThread()).isStopRequested()) return; try { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/IngredientListElementFactoryMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/InputConstantsMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/InputConstantsMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/InputConstantsMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/InputConstantsMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java index 8f01a8ba..6a8796c6 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/JeiStarterMixin.java @@ -10,10 +10,7 @@ import mezz.jei.load.PluginCaller; import mezz.jei.startup.JeiStarter; import net.minecraft.client.Minecraft; import org.embeddedt.modernfix.annotation.RequiresMod; -import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter; -import org.embeddedt.modernfix.jei.async.JEILoadingInterruptedException; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java similarity index 90% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java index db7cf046..37dd6e34 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/PluginCallerMixin.java @@ -14,8 +14,6 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletionException; import java.util.function.Consumer; @Mixin(PluginCaller.class) @@ -30,7 +28,7 @@ public class PluginCallerMixin { @Redirect(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V"), remap = false) private static void runOnMainThreadIfNeeded(Consumer instance, Object pluginObj) { IModPlugin plugin = (IModPlugin)pluginObj; - if(ModernFixConfig.jeiPluginBlacklist.contains(plugin.getPluginUid())) { + if(ModernFixConfig.getJeiPluginBlacklist().contains(plugin.getPluginUid())) { ModernFix.LOGGER.warn("Going to main thread for " + plugin.getPluginUid()); Minecraft.getInstance().executeBlocking(() -> instance.accept(plugin)); } else { diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_jei/RecipeManagerInternalMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/CommandSourceStackAccess.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/DolphinSwimToTreasureGoalMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EnderEyeItemMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/ExplorationMapFunctionMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderAccess.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/EyeOfEnderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java similarity index 87% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java index 997c3e70..12cd19b5 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandAccess.java @@ -1,6 +1,5 @@ package org.embeddedt.modernfix.mixin.perf.async_locator; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.minecraft.server.commands.LocateCommand; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/LocateCommandMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MapItemAccess.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/MerchantOfferAccess.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/async_locator/TreasureMapForEmeraldsMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/IngredientFilterInvoker.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/MinecraftMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/MinecraftMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/MinecraftMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/blast_search_trees/MinecraftMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/LootTableManagerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/datapack_reload_exceptions/RecipeManagerMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelShaperMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java similarity index 78% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelShaperMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java index 2922533d..b7a0758f 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelShaperMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java @@ -5,32 +5,26 @@ import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.world.item.Item; -import net.minecraftforge.client.ItemModelMesherForge; -import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.IRegistryDelegate; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; import org.embeddedt.modernfix.util.ItemMesherMap; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.Set; -@Mixin(ItemModelMesherForge.class) +@Mixin(net.minecraftforge.client.ItemModelMesherForge.class) @ClientOnlyMixin -public abstract class ItemModelShaperMixin extends ItemModelShaper { +public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { @Shadow @Final @Mutable private Map, ModelResourceLocation> locations; private Map, ModelResourceLocation> overrideLocations; - public ItemModelShaperMixin(ModelManager arg) { + public ItemModelMesherForgeMixin(ModelManager arg) { super(arg); } @@ -40,14 +34,15 @@ public abstract class ItemModelShaperMixin extends ItemModelShaper { private void replaceLocationMap(CallbackInfo ci) { overrideLocations = new HashMap<>(); // need to replace this map because mods query locations through it - locations = new ItemMesherMap(this::getLocation); + locations = new ItemMesherMap<>(this::mfix$getLocationForge); } - private ModelResourceLocation getLocation(Item item) { - ModelResourceLocation map = overrideLocations.getOrDefault(item.delegate, SENTINEL); + @Unique + private ModelResourceLocation mfix$getLocationForge(IRegistryDelegate item) { + ModelResourceLocation map = overrideLocations.getOrDefault(item, SENTINEL); if(map == SENTINEL) { /* generate the appropriate location from our cache */ - map = ModelLocationCache.get(item); + map = ModelLocationCache.get(item.get()); } return map; } @@ -59,7 +54,7 @@ public abstract class ItemModelShaperMixin extends ItemModelShaper { @Overwrite @Override public BakedModel getItemModel(Item item) { - ModelResourceLocation map = getLocation(item); + ModelResourceLocation map = mfix$getLocationForge(item.delegate); return map == null ? null : getModelManager().getModel(map); } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java similarity index 50% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java index 22436f8b..d68cf2d3 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -1,35 +1,26 @@ package org.embeddedt.modernfix.mixin.perf.dynamic_resources; -import com.google.common.base.Splitter; -import com.google.common.base.Stopwatch; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalNotification; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.*; -import com.mojang.datafixers.util.Pair; +import com.google.gson.JsonElement; import com.mojang.math.Transformation; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import net.minecraft.Util; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.ItemModelGenerator; import net.minecraft.client.renderer.texture.AtlasSet; -import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.ClientPackSource; import net.minecraft.client.resources.model.*; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.*; -import net.minecraft.server.packs.resources.FallbackResourceManager; -import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.FilePackResources; +import net.minecraft.server.packs.FolderPackResources; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.VanillaPackResources; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; @@ -38,18 +29,20 @@ import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.packs.DelegatingResourcePack; import net.minecraftforge.fml.packs.ModFileResourcePack; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.ForgeRegistryEntry; import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.duck.IExtendedModelBakery; -import org.embeddedt.modernfix.dynamicresources.*; -import org.spongepowered.asm.mixin.*; +import org.embeddedt.modernfix.dynamicresources.DynamicBakedModelProvider; +import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent; +import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -58,17 +51,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import javax.annotation.Nullable; import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; -import java.util.function.BiFunction; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; /* high priority so that our injectors are added before other mods' */ @Mixin(value = ModelBakery.class, priority = 600) @@ -83,8 +69,6 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { @Shadow protected abstract BlockModel loadBlockModel(ResourceLocation location) throws IOException; - @Shadow @Final protected static Set UNREFERENCED_TEXTURES; - @Shadow private Map> atlasPreparations; @Shadow @Final protected ResourceManager resourceManager; @Shadow @Nullable private AtlasSet atlasSet; @Shadow @Final private Set loadingStack; @@ -93,12 +77,6 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { @Shadow @Final private static Logger LOGGER; - @Shadow @Final private static Splitter COMMA_SPLITTER; - @Shadow @Final private static Splitter EQUAL_SPLITTER; - @Shadow @Nullable static > T getValueHelper(Property property, String value) { - throw new AssertionError(); - } - @Shadow @Final @Mutable private Map bakedTopLevelModels; @@ -108,10 +86,6 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { @Shadow @Final private static ItemModelGenerator ITEM_MODEL_GENERATOR; - @Shadow @Final public static BlockModel BLOCK_ENTITY_MARKER; - - @Shadow public abstract Set getSpecialModels(); - @Shadow public abstract UnbakedModel getModel(ResourceLocation modelLocation); @Shadow @Nullable public abstract BakedModel getBakedModel(ResourceLocation arg, ModelState arg2, Function textureGetter); @@ -205,17 +179,6 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { return ImmutableList.of(); } - private static final int ERROR_THRESHOLD = 200; - - private void logOrSuppressError(Object2IntOpenHashMap suppressionMap, String type, ResourceLocation location, Throwable e) { - int numErrors; - synchronized (suppressionMap) { - numErrors = suppressionMap.computeInt(location.getNamespace(), (k, oldVal) -> (oldVal == null ? 1 : oldVal + 1)); - } - if(numErrors <= ERROR_THRESHOLD) - ModernFix.LOGGER.error("Error reading {} {}: {}", type, location, e); - } - private boolean trustedResourcePack(PackResources pack) { return pack instanceof VanillaPackResources || pack instanceof ModFileResourcePack || @@ -225,210 +188,15 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { pack instanceof FilePackResources; } - private void gatherAdditionalViaManualScan(List untrustedPacks, Set knownLocations, - Collection uncertainLocations, String filePrefix) { - if(untrustedPacks.size() > 0) { - /* Now make a fallback resource manager and use it on the remaining packs to see if they actually contain these files */ - FallbackResourceManager frm = new FallbackResourceManager(PackType.CLIENT_RESOURCES, "dummy"); - for (int i = untrustedPacks.size() - 1; i >= 0; i--) { - frm.add(untrustedPacks.get(i)); - } - for (ResourceLocation blockstate : uncertainLocations) { - if (knownLocations.contains(blockstate)) - continue; // don't check ones we know exist - ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), filePrefix + blockstate.getPath() + ".json"); - try (Resource resource = frm.getResource(fileLocation)) { - knownLocations.add(blockstate); - } catch (IOException ignored) { - } - } - } - } - /** * Load all blockstate JSONs and model files, collect textures. */ private void gatherModelMaterials(Set materialSet) { - Stopwatch stopwatch = Stopwatch.createStarted(); - final Object2IntOpenHashMap blockstateErrors = new Object2IntOpenHashMap<>(); - /* - * First, gather all vanilla packs, and use listResources on them. This will allow us to (hopefully) avoid - * scanning most packs a lot. - */ - List allPackResources = new ArrayList<>(this.resourceManager.listPacks().collect(Collectors.toList())); - Collections.reverse(allPackResources); - ObjectOpenHashSet allAvailableModels = new ObjectOpenHashSet<>(), allAvailableStates = new ObjectOpenHashSet<>(); - allPackResources.removeIf(pack -> { - if(trustedResourcePack(pack)) { - for(String namespace : pack.getNamespaces(PackType.CLIENT_RESOURCES)) { - Collection allBlockstates = pack.getResources(PackType.CLIENT_RESOURCES, namespace, "blockstates", Integer.MAX_VALUE, p -> p.endsWith(".json")); - for(ResourceLocation blockstate : allBlockstates) { - allAvailableStates.add(new ResourceLocation(blockstate.getNamespace(), blockstate.getPath().replace("blockstates/", "").replace(".json", ""))); - } - Collection allModels = pack.getResources(PackType.CLIENT_RESOURCES, namespace, "models", Integer.MAX_VALUE, p -> p.endsWith(".json")); - for(ResourceLocation blockstate : allModels) { - allAvailableModels.add(new ResourceLocation(blockstate.getNamespace(), blockstate.getPath().replace("models/", "").replace(".json", ""))); - } - } - return true; - } - ModernFix.LOGGER.debug("Pack with class {} needs manual scan", pack.getClass().getName()); - return false; - }); - - gatherAdditionalViaManualScan(allPackResources, allAvailableStates, blockStateFiles, "blockstates/"); - // We now have a list of all blockstates known to exist. Delete anything that we don't have - blockStateFiles.retainAll(allAvailableStates); - allAvailableStates.clear(); - allAvailableStates.trim(); - - ConcurrentLinkedQueue> blockStateLoadedFiles = new ConcurrentLinkedQueue<>(); - List> blockStateData = new ArrayList<>(); - for(ResourceLocation blockstate : blockStateFiles) { - blockStateData.add(CompletableFuture.runAsync(() -> { - ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), "blockstates/" + blockstate.getPath() + ".json"); - try { - List resources = this.resourceManager.getResources(fileLocation); - for(Resource resource : resources) { - JsonParser parser = new JsonParser(); - try { - blockStateLoadedFiles.add(Pair.of(blockstate, parser.parse(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)))); - } catch(JsonParseException e) { - logOrSuppressError(blockstateErrors, "blockstate", blockstate, e); - } finally { - resource.close(); - } - } - } catch(IOException e) { - logOrSuppressError(blockstateErrors, "blockstate", blockstate, e); - } - }, ModernFix.resourceReloadExecutor())); - } - blockStateFiles = null; - CompletableFuture.allOf(blockStateData.toArray(new CompletableFuture[0])).join(); - for(Pair pair : blockStateLoadedFiles) { - if(pair.getSecond() != null) { - try { - JsonObject obj = pair.getSecond().getAsJsonObject(); - if(obj.has("variants")) { - JsonObject eachVariant = obj.getAsJsonObject("variants"); - for(Map.Entry entry : eachVariant.entrySet()) { - JsonElement variantData = entry.getValue(); - List variantModels; - if(variantData.isJsonArray()) { - variantModels = new ArrayList<>(); - for(JsonElement model : variantData.getAsJsonArray()) { - variantModels.add(model.getAsJsonObject()); - } - } else - variantModels = Collections.singletonList(variantData.getAsJsonObject()); - for(JsonObject variant : variantModels) { - modelFiles.add(new ResourceLocation(variant.get("model").getAsString())); - } - } - - } else { - JsonArray multipartData = obj.get("multipart").getAsJsonArray(); - for(JsonElement element : multipartData) { - JsonObject self = element.getAsJsonObject(); - JsonElement apply = self.get("apply"); - List applyObjects; - if(apply.isJsonArray()) { - applyObjects = new ArrayList<>(); - for(JsonElement e : apply.getAsJsonArray()) { - applyObjects.add(e.getAsJsonObject()); - } - } else - applyObjects = Collections.singletonList(apply.getAsJsonObject()); - for(JsonObject applyEntry : applyObjects) { - modelFiles.add(new ResourceLocation(applyEntry.get("model").getAsString())); - } - } - - } - } catch(RuntimeException e) { - logOrSuppressError(blockstateErrors, "blockstate", pair.getFirst(), e); - } - - } - } - blockstateErrors.object2IntEntrySet().forEach(entry -> { - if(entry.getIntValue() > ERROR_THRESHOLD) { - ModernFix.LOGGER.error("Suppressed additional {} blockstate errors for domain {}", entry.getIntValue(), entry.getKey()); - } - }); - blockstateErrors.clear(); - blockStateData = null; - blockStateLoadedFiles.clear(); - - /* figure out which models we should actually load */ - gatherAdditionalViaManualScan(allPackResources, allAvailableModels, modelFiles, "models/"); - modelFiles.retainAll(allAvailableModels); - allAvailableModels.clear(); - allAvailableModels.trim(); - - Map basicModels = new HashMap<>(); - basicModels.put(MISSING_MODEL_LOCATION, (BlockModel)missingModel); - basicModels.put(new ResourceLocation("builtin/generated"), GENERATION_MARKER); - basicModels.put(new ResourceLocation("builtin/entity"), BLOCK_ENTITY_MARKER); - Set> errorSet = Sets.newLinkedHashSet(); - while(modelFiles.size() > 0) { - List>> modelBytes = new ArrayList<>(); - for(ResourceLocation model : modelFiles) { - if(basicModels.containsKey(model)) - continue; - ResourceLocation fileLocation = new ResourceLocation(model.getNamespace(), "models/" + model.getPath() + ".json"); - modelBytes.add(CompletableFuture.supplyAsync(() -> { - try(Resource resource = this.resourceManager.getResource(fileLocation)) { - JsonParser parser = new JsonParser(); - return Pair.of(model, parser.parse(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))); - } catch(IOException | JsonParseException e) { - logOrSuppressError(blockstateErrors, "model", fileLocation, e); - return Pair.of(fileLocation, null); - } - }, ModernFix.resourceReloadExecutor())); - } - modelFiles.clear(); - CompletableFuture.allOf(modelBytes.toArray(new CompletableFuture[0])).join(); - UVController.useDummyUv.set(Boolean.TRUE); - for(CompletableFuture> future : modelBytes) { - Pair pair = future.join(); - try { - if(pair.getSecond() != null) { - - BlockModel model = ModelLoaderRegistry.ExpandedBlockModelDeserializer.INSTANCE.fromJson(pair.getSecond(), BlockModel.class); - model.name = pair.getFirst().toString(); - modelFiles.addAll(model.getDependencies()); - basicModels.put(pair.getFirst(), model); - continue; - } - } catch(Throwable e) { - logOrSuppressError(blockstateErrors, "model", pair.getFirst(), e); - } - basicModels.put(pair.getFirst(), (BlockModel)missingModel); - } - UVController.useDummyUv.set(Boolean.FALSE); - } - blockstateErrors.object2IntEntrySet().forEach(entry -> { - if(entry.getIntValue() > ERROR_THRESHOLD) { - ModernFix.LOGGER.error("Suppressed additional {} model errors for domain {}", entry.getIntValue(), entry.getKey()); - } - }); - modelFiles = null; - Function modelGetter = loc -> { - UnbakedModel m = basicModels.get(loc); - /* fallback to vanilla loader if missing */ - return m != null ? m : this.getModel(loc); - }; - for(BlockModel model : basicModels.values()) { - materialSet.addAll(model.getMaterials(modelGetter, errorSet)); - } - /* discard whatever garbage was just produced */ + Function modelDeserializer = model -> ModelLoaderRegistry.ExpandedBlockModelDeserializer.INSTANCE.fromJson(model, BlockModel.class); + ModelBakeryHelpers.gatherModelMaterials(this.resourceManager, this::trustedResourcePack, materialSet, blockStateFiles, + modelFiles, missingModel, modelDeserializer, this::getModel); loadedModels.invalidateAll(); loadedModels.put(MISSING_MODEL_LOCATION, missingModel); - //errorSet.stream().filter(pair -> !pair.getSecond().equals(MISSING_MODEL_LOCATION_STRING)).forEach(pair -> LOGGER.warn("Unable to resolve texture reference: {} in {}", pair.getFirst(), pair.getSecond())); - stopwatch.stop(); - ModernFix.LOGGER.info("Resolving model textures took " + stopwatch); } @Inject(method = "uploadTextures", at = @At(value = "FIELD", target = "Lnet/minecraft/client/resources/model/ModelBakery;topLevelModels:Ljava/util/Map;", ordinal = 0), cancellable = true) @@ -517,44 +285,7 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { } @Redirect(method = "loadModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;")) private ImmutableList loadOnlyRelevantBlockState(StateDefinition stateDefinition, ResourceLocation location) { - ModelResourceLocation mrl = (ModelResourceLocation)location; - if(Objects.equals(mrl.getVariant(), "inventory")) - return ImmutableList.of(); - Set> fixedProperties = new HashSet<>(); - BlockState fixedState = stateDefinition.any(); - for(String s : COMMA_SPLITTER.split(mrl.getVariant())) { - Iterator iterator = EQUAL_SPLITTER.split(s).iterator(); - if (iterator.hasNext()) { - String s1 = iterator.next(); - Property property = stateDefinition.getProperty(s1); - if (property != null && iterator.hasNext()) { - String s2 = iterator.next(); - Object value = getValueHelper(property, s2); - if (value == null) { - throw new RuntimeException("Unknown value: '" + s2 + "' for blockstate property: '" + s1 + "' " + property.getPossibleValues()); - } - fixedState = setPropertyGeneric(fixedState, property, value); - fixedProperties.add(property); - } else if (!s1.isEmpty()) { - throw new RuntimeException("Unknown blockstate property: '" + s1 + "'"); - } - } - } - // generate all possible blockstates from the remaining properties - ArrayList> anyProperties = new ArrayList<>(stateDefinition.getProperties()); - anyProperties.removeAll(fixedProperties); - ArrayList finalList = new ArrayList<>(); - finalList.add(fixedState); - for(Property property : anyProperties) { - ArrayList newPermutations = new ArrayList<>(); - for(BlockState state : finalList) { - for(Comparable value : property.getPossibleValues()) { - newPermutations.add(setPropertyGeneric(state, property, value)); - } - } - finalList = newPermutations; - } - return ImmutableList.copyOf(finalList); + return ModelBakeryHelpers.getBlockStatesForMRL(stateDefinition, (ModelResourceLocation)location); } @Override diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ae2/RegistrationMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ae2/RegistrationMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ae2/RegistrationMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ae2/RegistrationMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java similarity index 96% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java index dc5a0302..ccbaa84b 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java @@ -1,10 +1,8 @@ package org.embeddedt.modernfix.mixin.perf.dynamic_resources.ctm; import com.google.common.collect.ImmutableList; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.client.resources.model.MultiPartBakedModel; @@ -15,7 +13,6 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.IRegistryDelegate; import org.embeddedt.modernfix.ModernFix; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java similarity index 96% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java index 0b26663f..65a971f6 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java @@ -1,18 +1,15 @@ package org.embeddedt.modernfix.mixin.perf.dynamic_resources.ctm; import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.SubscribeEvent; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java similarity index 97% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java index 2a1e53a3..0da765e1 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java @@ -7,7 +7,6 @@ import net.minecraft.client.resources.model.BakedModel; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.dynamicresources.DynamicModelBakeEvent; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/jeresources_startup/VillagerEntryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/jeresources_startup/VillagerEntryMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/jeresources_startup/VillagerEntryMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/jeresources_startup/VillagerEntryMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/CustomIngredientMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/CustomIngredientMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/CustomIngredientMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/CustomIngredientMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/IDFilterMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/IDFilterMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/IDFilterMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/IDFilterMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeEventJSMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeEventJSMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeEventJSMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeEventJSMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeJSMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeJSMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeJSMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/RecipeJSMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagIngredientJSMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagIngredientJSMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagIngredientJSMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagIngredientJSMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagWrapperMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagWrapperMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagWrapperMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/kubejs/TagWrapperMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/OBJLoaderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/OBJLoaderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/OBJLoaderMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/model_optimizations/OBJLoaderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/patchouli_deduplicate_books/ClientBookRegistryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/patchouli_deduplicate_books/ClientBookRegistryMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/patchouli_deduplicate_books/ClientBookRegistryMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/patchouli_deduplicate_books/ClientBookRegistryMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockCallbacksMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockCallbacksMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockCallbacksMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/BlockCallbacksMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/GameDataMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/GameDataMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/GameDataMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/reduce_blockstate_cache_rebuilds/GameDataMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/ModFileResourcePackMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java similarity index 96% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java index 54a52349..f7382bd5 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/resourcepacks/VanillaPackMixin.java @@ -2,7 +2,6 @@ package org.embeddedt.modernfix.mixin.perf.resourcepacks; import com.google.common.base.Joiner; import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.server.packs.PackType; @@ -10,7 +9,6 @@ import net.minecraft.server.packs.VanillaPackResources; import net.minecraft.resources.ResourceLocation; import org.apache.commons.lang3.tuple.Pair; import org.embeddedt.modernfix.FileWalker; -import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.util.FileUtil; import org.embeddedt.modernfix.util.PackTypeHelper; import org.spongepowered.asm.mixin.Final; @@ -21,7 +19,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.io.IOException; import java.nio.file.*; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistryMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistryMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistryMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java similarity index 92% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java index b6f6d978..b66539a6 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/LevelSaveMixin.java @@ -1,10 +1,8 @@ package org.embeddedt.modernfix.mixin.perf.skip_first_datapack_reload; -import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.duck.ILevelSave; import org.embeddedt.modernfix.util.DummyServerConfiguration; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java similarity index 93% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java index c44747f2..4d38360d 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/MinecraftMixin.java @@ -8,17 +8,13 @@ import net.minecraft.core.RegistryAccess; import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.LevelStorageSource; import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.ModernFixClient; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.duck.ILevelSave; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.concurrent.ExecutionException; import java.util.function.Function; diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/skip_first_datapack_reload/SaveFormatAccessor.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jepb/PiglinBarteringRecipeBuilderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jepb/PiglinBarteringRecipeBuilderMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jepb/PiglinBarteringRecipeBuilderMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jepb/PiglinBarteringRecipeBuilderMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jeresources/LootTableHelperMixin.java b/forge/src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jeresources/LootTableHelperMixin.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jeresources/LootTableHelperMixin.java rename to forge/src/main/java/org/embeddedt/modernfix/mixin/perf/use_integrated_resources/jeresources/LootTableHelperMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/packet/PacketHandler.java b/forge/src/main/java/org/embeddedt/modernfix/packet/PacketHandler.java similarity index 84% rename from src/main/java/org/embeddedt/modernfix/packet/PacketHandler.java rename to forge/src/main/java/org/embeddedt/modernfix/packet/PacketHandler.java index d4feabf7..4050c595 100644 --- a/src/main/java/org/embeddedt/modernfix/packet/PacketHandler.java +++ b/forge/src/main/java/org/embeddedt/modernfix/packet/PacketHandler.java @@ -26,6 +26,9 @@ public class PacketHandler { } private static void handleSyncPacket(EntityIDSyncPacket packet, Supplier contextSupplier) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ModernFixClient.handleEntityIDSync(packet, contextSupplier)); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { + contextSupplier.get().enqueueWork(() -> ModernFixClient.handleEntityIDSync(packet)); + contextSupplier.get().setPacketHandled(true); + }); } } diff --git a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java similarity index 58% rename from src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java rename to forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java index d552acc0..3125fa82 100644 --- a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java @@ -1,69 +1,133 @@ -package org.embeddedt.modernfix.core; +package org.embeddedt.modernfix.platform.forge; -import com.google.common.collect.ImmutableList; import com.google.common.io.Resources; +import com.mojang.blaze3d.platform.NativeImage; import cpw.mods.modlauncher.*; import cpw.mods.modlauncher.api.INameMappingService; import cpw.mods.modlauncher.api.LamdbaExceptionUtils; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.LoadingModList; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator; +import net.minecraftforge.fml.network.PacketDistributor; +import net.minecraftforge.fml.server.ServerLifecycleHooks; import org.embeddedt.modernfix.classloading.FastAccessTransformerList; import org.embeddedt.modernfix.classloading.ModernFixResourceFinder; -import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig; -import org.embeddedt.modernfix.core.config.Option; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.dfu.DFUBlaster; -import org.embeddedt.modernfix.load.ModWorkManagerQueue; +import org.embeddedt.modernfix.packet.PacketHandler; import org.embeddedt.modernfix.util.DummyList; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.*; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; -import org.spongepowered.asm.mixin.injection.struct.InjectionInfo; import org.spongepowered.asm.mixin.injection.struct.InjectorGroupInfo; -import java.io.File; import java.io.IOException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Path; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -public class ModernFixMixinPlugin implements IMixinConfigPlugin { - private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin."; +public class ModernFixPlatformHooksImpl { + public static boolean isClient() { + return FMLLoader.getDist() == Dist.CLIENT; + } - private final Logger logger = LogManager.getLogger("ModernFix"); - public static ModernFixEarlyConfig config = null; - public static ModernFixMixinPlugin instance; + public static boolean isDedicatedServer() { + return FMLLoader.getDist().isDedicatedServer(); + } - public ModernFixMixinPlugin() { - instance = this; - try { - config = ModernFixEarlyConfig.load(new File("./config/modernfix-mixins.properties")); - } catch (Exception e) { - throw new RuntimeException("Could not load configuration file for ModernFix", e); + private static String verString; + + public static String getVersionString() { + if(verString == null) { + verString = LoadingModList.get().getModFileById("modernfix").getMods().get(0).getVersion().toString(); + } + return verString; + } + + public static boolean modPresent(String modId) { + return FMLLoader.getLoadingModList().getModFileById(modId) != null; + } + + public static boolean isDevEnv() { + return !FMLLoader.isProduction() && FMLLoader.getLoadingModList().getModFileById("modernfix").getFile().getLocator() instanceof ExplodedDirectoryLocator; + } + + public static MinecraftServer getCurrentServer() { + return ServerLifecycleHooks.getCurrentServer(); + } + + public static boolean isLoadingNormally() { + return ModLoader.isLoadingStateValid(); + } + + + public static TextureAtlasSprite loadTextureAtlasSprite(TextureAtlas atlasTexture, + ResourceManager resourceManager, TextureAtlasSprite.Info textureInfo, + Resource resource, + int atlasWidth, int atlasHeight, + int spriteX, int spriteY, int mipmapLevel, + NativeImage image) { + TextureAtlasSprite tas = ForgeHooksClient.loadTextureAtlasSprite(atlasTexture, resourceManager, textureInfo, resource, atlasWidth, atlasHeight, spriteX, spriteY, mipmapLevel, image); + if(tas == null) { + tas = TASConstructor.construct(atlasTexture, resourceManager, textureInfo, resource, atlasWidth, atlasHeight, spriteX, spriteY, mipmapLevel, image); + } + return tas; + } + + static class TASConstructor { + private static final MethodHandle textureAtlasSpriteConstruct; + static { + try { + Constructor constructor = TextureAtlasSprite.class.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + textureAtlasSpriteConstruct = MethodHandles.lookup().unreflectConstructor(constructor); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } } - this.logger.info("Loaded configuration file for ModernFix: {} options available, {} override(s) found", - config.getOptionCount(), config.getOptionOverrideCount()); - - if(ModernFixEarlyConfig.OPTIFINE_PRESENT) - this.logger.fatal("OptiFine detected. Use of ModernFix with OptiFine is not supported due to its impact on launch time and breakage of Forge features."); - - try { - Class.forName("sun.misc.Unsafe").getDeclaredMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class); - } catch(ReflectiveOperationException | NullPointerException e) { - this.logger.info("Applying Nashorn fix"); - Properties properties = System.getProperties(); - properties.setProperty("nashorn.args", properties.getProperty("nashorn.args", "") + " --anonymous-classes=false"); + static TextureAtlasSprite construct(TextureAtlas atlasTexture, + ResourceManager resourceManager, TextureAtlasSprite.Info textureInfo, + Resource resource, + int atlasWidth, int atlasHeight, + int spriteX, int spriteY, int mipmapLevel, + NativeImage image) { + try { + return (TextureAtlasSprite)textureAtlasSpriteConstruct.invokeExact(atlasTexture, textureInfo, mipmapLevel, atlasWidth, atlasHeight, spriteX, spriteY, image); + } catch(Throwable e) { + throw new AssertionError("MethodHandle failed", e); + } } + } + public static Path getGameDirectory() { + return FMLPaths.GAMEDIR.get(); + } + + public static void sendPacket(ServerPlayer player, Object packet) { + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), packet); + } + + public static void injectPlatformSpecificHacks() { /* We abuse the constructor of a mixin plugin as a safe location to start modifying the classloader */ /* Swap the transformer for ours */ ClassLoader loader = Thread.currentThread().getContextClassLoader(); @@ -71,7 +135,7 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { throw new IllegalStateException("Expected a TransformingClassLoader"); } try { - if(isOptionEnabled("launch.class_search_cache.ModernFixResourceFinder")) { + if(ModernFixMixinPlugin.instance.isOptionEnabled("launch.class_search_cache.ModernFixResourceFinder")) { Field resourceFinderField = TransformingClassLoader.class.getDeclaredField("resourceFinder"); /* Construct a new list of resource finders, using similar logic to ML */ resourceFinderField.setAccessible(true); @@ -84,7 +148,7 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { resourceFinderField.set(loader, resourceFinder); } } catch(RuntimeException | ReflectiveOperationException e) { - logger.error("Failed to make classloading changes", e); + ModernFixMixinPlugin.instance.logger.error("Failed to make classloading changes", e); } FastAccessTransformerList.attemptReplace(); @@ -99,7 +163,7 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { InjectorGroupInfo noGroup = (InjectorGroupInfo)noGroupField.get(null); groupMembersField.set(noGroup, new DummyList<>()); } catch(RuntimeException | ReflectiveOperationException e) { - logger.error("Failed to patch mixin memory leak", e); + ModernFixMixinPlugin.instance.logger.error("Failed to patch mixin memory leak", e); } } @@ -115,7 +179,7 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { return (Class)defineClassMethod.invoke(systemLoader, className, newTransformerBytes, 0, newTransformerBytes.length); } - private Function> constructResourceFinder() throws ReflectiveOperationException { + private static Function> constructResourceFinder() throws ReflectiveOperationException { ModernFixResourceFinder.init(); Field servicesHandlerField = Launcher.class.getDeclaredField("transformationServicesHandler"); servicesHandlerField.setAccessible(true); @@ -135,78 +199,7 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { return resourceEnumeratorLocator; } - @Override - public void onLoad(String mixinPackage) { - - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - if (!mixinClassName.startsWith(MIXIN_PACKAGE_ROOT)) { - this.logger.error("Expected mixin '{}' to start with package root '{}', treating as foreign and " + - "disabling!", mixinClassName, MIXIN_PACKAGE_ROOT); - - return false; - } - - String mixin = mixinClassName.substring(MIXIN_PACKAGE_ROOT.length()); - if(!isOptionEnabled(mixin)) - return false; - String disabledBecauseMod = config.getPermanentlyDisabledMixins().get(mixin); - return disabledBecauseMod == null; - } - - public boolean isOptionEnabled(String mixin) { - Option option = config.getEffectiveOptionForMixin(mixin); - - if (option == null) { - this.logger.error("No rules matched mixin '{}', treating as foreign and disabling!", mixin); - - return false; - } - - if (option.isOverridden()) { - String source = "[unknown]"; - - if (option.isUserDefined()) { - source = "user configuration"; - } else if (option.isModDefined()) { - source = "mods [" + String.join(", ", option.getDefiningMods()) + "]"; - } - - if (option.isEnabled()) { - this.logger.warn("Force-enabling mixin '{}' as rule '{}' (added by {}) enables it", mixin, - option.getName(), source); - } else { - this.logger.warn("Force-disabling mixin '{}' as rule '{}' (added by {}) disables it and children", mixin, - option.getName(), source); - } - } - - return option.isEnabled(); - } - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - - } - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + public static void applyASMTransformers(String mixinClassName, ClassNode targetClass) { if(mixinClassName.equals("org.embeddedt.modernfix.mixin.perf.compress_blockstate.BlockStateBaseMixin")) { // Delete unused fields off BlockStateBase Set fieldsToDelete = Stream.of( @@ -223,7 +216,6 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { ).map(name -> ObfuscationReflectionHelper.remapName(INameMappingService.Domain.FIELD, name)).collect(Collectors.toSet()); targetClass.fields.removeIf(field -> { if(fieldsToDelete.contains(field.name)) { - logger.info("Removing " + field.name); return true; } return false; @@ -251,4 +243,4 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { } } } -} \ No newline at end of file +} diff --git a/src/main/java/org/embeddedt/modernfix/registry/FastForgeRegistry.java b/forge/src/main/java/org/embeddedt/modernfix/registry/FastForgeRegistry.java similarity index 99% rename from src/main/java/org/embeddedt/modernfix/registry/FastForgeRegistry.java rename to forge/src/main/java/org/embeddedt/modernfix/registry/FastForgeRegistry.java index 88a65de0..58016fb0 100644 --- a/src/main/java/org/embeddedt/modernfix/registry/FastForgeRegistry.java +++ b/forge/src/main/java/org/embeddedt/modernfix/registry/FastForgeRegistry.java @@ -15,7 +15,6 @@ import java.util.*; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; -import java.util.stream.Collectors; public class FastForgeRegistry> { private final BiMap ids; diff --git a/src/main/java/org/embeddedt/modernfix/registry/ObjectHolderClearer.java b/forge/src/main/java/org/embeddedt/modernfix/registry/ObjectHolderClearer.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/registry/ObjectHolderClearer.java rename to forge/src/main/java/org/embeddedt/modernfix/registry/ObjectHolderClearer.java index 6ca0f948..0e12ff87 100644 --- a/src/main/java/org/embeddedt/modernfix/registry/ObjectHolderClearer.java +++ b/forge/src/main/java/org/embeddedt/modernfix/registry/ObjectHolderClearer.java @@ -7,7 +7,6 @@ import org.embeddedt.modernfix.ModernFix; import java.lang.reflect.Field; import java.util.HashMap; -import java.util.List; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; diff --git a/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java b/forge/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java rename to forge/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java diff --git a/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java b/forge/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java similarity index 99% rename from src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java index 3cf025d0..a5e3b484 100644 --- a/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java +++ b/forge/src/main/java/org/embeddedt/modernfix/structure/AsyncLocator.java @@ -15,11 +15,9 @@ import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import org.embeddedt.modernfix.ModernFix; import org.jetbrains.annotations.NotNull; -import java.sql.Struct; import java.util.Collection; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/logic/CommonLogic.java diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/logic/EnderEyeItemLogic.java diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java similarity index 98% rename from src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java index 9a946946..b78e51b4 100644 --- a/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java +++ b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/ExplorationMapFunctionLogic.java @@ -3,7 +3,6 @@ package org.embeddedt.modernfix.structure.logic; import com.google.common.collect.ImmutableSet; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/logic/EyeOfEnderData.java diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/logic/LocateCommandLogic.java diff --git a/src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java b/forge/src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java rename to forge/src/main/java/org/embeddedt/modernfix/structure/logic/MerchantLogic.java diff --git a/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java b/forge/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java similarity index 90% rename from src/main/java/org/embeddedt/modernfix/util/JEIUtil.java rename to forge/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java index ac90c3d2..a3575441 100644 --- a/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java +++ b/forge/src/main/java/org/embeddedt/modernfix/util/JEIUtil.java @@ -1,9 +1,6 @@ package org.embeddedt.modernfix.util; import com.mojang.blaze3d.vertex.PoseStack; -import mezz.jei.Internal; -import mezz.jei.api.runtime.IIngredientListOverlay; -import mezz.jei.runtime.JeiRuntime; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.network.chat.TranslatableComponent; diff --git a/src/main/java/org/embeddedt/modernfix/util/KubeUtil.java b/forge/src/main/java/org/embeddedt/modernfix/util/KubeUtil.java similarity index 100% rename from src/main/java/org/embeddedt/modernfix/util/KubeUtil.java rename to forge/src/main/java/org/embeddedt/modernfix/util/KubeUtil.java diff --git a/src/main/java/org/embeddedt/modernfix/util/ModUtil.java b/forge/src/main/java/org/embeddedt/modernfix/util/ModUtil.java similarity index 91% rename from src/main/java/org/embeddedt/modernfix/util/ModUtil.java rename to forge/src/main/java/org/embeddedt/modernfix/util/ModUtil.java index 90618d22..2bfade5d 100644 --- a/src/main/java/org/embeddedt/modernfix/util/ModUtil.java +++ b/forge/src/main/java/org/embeddedt/modernfix/util/ModUtil.java @@ -1,14 +1,9 @@ package org.embeddedt.modernfix.util; -import net.minecraftforge.client.event.ModelBakeEvent; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.EventBus; import net.minecraftforge.eventbus.api.EventListenerHelper; -import net.minecraftforge.eventbus.api.IEventListener; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoader; -import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.embeddedt.modernfix.ModernFix; diff --git a/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml similarity index 89% rename from src/main/resources/META-INF/mods.toml rename to forge/src/main/resources/META-INF/mods.toml index 0fbfd925..cf99917f 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -16,10 +16,7 @@ license = "GNU LGPL 3.0" [[mods]] #mandatory # The modid of the mod modId = "modernfix" #mandatory -# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata -# see the associated build.gradle script for how to populate this completely automatically during a build -version = "${file.jarVersion}" #mandatory +version = "${version}" #mandatory # A display name for the mod displayName = "ModernFix" #mandatory # A URL to query for updates for this mod. See the JSON update specification diff --git a/forge/src/main/resources/modernfix-forge.mixins.json b/forge/src/main/resources/modernfix-forge.mixins.json new file mode 100644 index 00000000..8835aec2 --- /dev/null +++ b/forge/src/main/resources/modernfix-forge.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "org.embeddedt.modernfix.mixin", + "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", + "compatibilityLevel": "JAVA_8", + "minVersion": "0.8", + "mixins": [ +${mixin_classes} + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta new file mode 100644 index 00000000..b9e3938c --- /dev/null +++ b/forge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "ModernFix", + "pack_format": 6 + } +} diff --git a/gradle.properties b/gradle.properties index 80b27551..b00b0806 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,9 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G - -# tell architectury loom that this project is a forge project. -# this will enable us to use the "forge" dependency. -# using archloom without this is possible and will give you a -# "standard" loom installation with some extra features. -loom.platform=forge +org.gradle.jvmargs=-Xmx2G mod_id=modernfix minecraft_version=1.16.5 +enabled_platforms=fabric,forge forge_version=1.16.5-36.2.39 lazydfu_version=3249059 mekanism_version=1.16.5-10.1.2.457 @@ -16,4 +11,9 @@ parchment_version=2022.03.06 jei_version=7.7.1.153 refined_storage_version=3807951 kubejs_version=1605.3.19-build.299 -ctm_version=MC1.16.1-1.1.2.6 \ No newline at end of file +ctm_version=MC1.16.1-1.1.2.6 + +fabric_loader_version=0.14.18 +fabric_api_version=0.42.0+1.16 + +forge_config_version=1.0.2 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7bd03562..8a77caf9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,4 +7,8 @@ pluginManagement { } } +include("common") +include("fabric") +include("forge") + rootProject.name = 'modernfix' diff --git a/src/main/java/org/embeddedt/modernfix/ModernFix.java b/src/main/java/org/embeddedt/modernfix/ModernFix.java deleted file mode 100644 index 06924e2c..00000000 --- a/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.embeddedt.modernfix; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import net.minecraft.Util; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.Item; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.*; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; -import net.minecraftforge.fml.event.server.FMLServerStartedEvent; -import net.minecraftforge.fml.event.server.FMLServerStartingEvent; -import net.minecraftforge.fml.event.server.FMLServerStoppedEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.network.FMLNetworkConstants; -import net.minecraftforge.registries.ForgeRegistries; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.embeddedt.modernfix.classloading.ModFileScanDataDeduplicator; -import org.embeddedt.modernfix.core.ModernFixMixinPlugin; -import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler; -import org.embeddedt.modernfix.packet.PacketHandler; -import org.embeddedt.modernfix.registry.ObjectHolderClearer; -import org.embeddedt.modernfix.structure.AsyncLocator; -import org.embeddedt.modernfix.util.ClassInfoManager; -import org.embeddedt.modernfix.util.KubeUtil; - -import java.lang.management.ManagementFactory; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.concurrent.*; -import java.util.function.BooleanSupplier; - -// The value here should match an entry in the META-INF/mods.toml file -@Mod(ModernFix.MODID) -public class ModernFix { - - // Directly reference a log4j logger. - public static final Logger LOGGER = LogManager.getLogger("ModernFix"); - - public static final String MODID = "modernfix"; - - public static ModernFix INSTANCE; - - // Used to skip computing the blockstate caches twice - public static boolean runningFirstInjection = false; - - public static CountDownLatch worldLoadSemaphore = null; - - private static Executor resourceReloadService = null; - - static { - try { - if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dedicated_reload_executor.ReloadExecutor")) { - Method makeExecutorMethod = ObfuscationReflectionHelper.findMethod(Util.class, "func_240979_a_", String.class); - resourceReloadService = (Executor)makeExecutorMethod.invoke(null, "ResourceReload"); - } else { - resourceReloadService = Util.backgroundExecutor(); - } - } catch(RuntimeException | ReflectiveOperationException e) { - LOGGER.error("Could not create resource reload executor", e); - resourceReloadService = Util.backgroundExecutor(); - } - } - - public static Executor resourceReloadExecutor() { - return resourceReloadService; - } - - /** - * Simple mechanism used to delay some background processes until the client is actually in-game, to reduce - * launch time. - */ - public static void waitForWorldLoad(BooleanSupplier exitEarly) { - CountDownLatch latch = worldLoadSemaphore; - if(latch != null) { - try { - while(!latch.await(100, TimeUnit.MILLISECONDS)) { - if(exitEarly.getAsBoolean()) - return; - } - } catch(InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - - - public ModernFix() { - INSTANCE = this; - // Register ourselves for server and other game events we are interested in - MinecraftForge.EVENT_BUS.register(this); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onLoadComplete); - FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(Item.class, this::registerItems); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClient())); - ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true)); - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG); - if(ModList.get().isLoaded("kubejs")) - MinecraftForge.EVENT_BUS.register(KubeUtil.class); - MinecraftForge.EVENT_BUS.register(EntityDataIDSyncHandler.class); - PacketHandler.register(); - ModFileScanDataDeduplicator.deduplicate(); - } - - private void registerItems(RegistryEvent event) { - if(Boolean.getBoolean("modernfix.largeRegistryTest")) { - Item.Properties props = new Item.Properties(); - for(int i = 0; i < 1000000; i++) { - ForgeRegistries.ITEMS.register(new Item(props).setRegistryName("modernfix", "item_" + i)); - } - } - } - - private static boolean dfuModPresent() { - for(String modId : new String[] { "lazydfu", "datafixerslayer" }) { - if(ModList.get().isLoaded(modId)) - return true; - } - return !FMLLoader.isProduction(); - } - - @SubscribeEvent - public void commonSetup(FMLCommonSetupEvent event) { - if(!dfuModPresent()) { - event.enqueueWork(() -> { - ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, "modernfix.no_lazydfu")); - }); - } - ObjectHolderClearer.clearThrowables(); - } - - @SubscribeEvent - public void onServerStarted(FMLServerStartedEvent event) { - if(FMLLoader.getDist() == Dist.DEDICATED_SERVER) { - float gameStartTime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f; - ModernFix.LOGGER.warn("Dedicated server took " + gameStartTime + " seconds to load"); - } - ClassInfoManager.clear(); - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onLoadComplete(FMLLoadCompleteEvent event) { - ClassInfoManager.clear(); - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onServerDead(FMLServerStoppedEvent event) { - /* Clear as much data from the integrated server as possible, in case a mod holds on to it */ - try { - Field updatingMapField = ObfuscationReflectionHelper.findField(ChunkMap.class, "field_219251_e"); - Field visibleMapField = ObfuscationReflectionHelper.findField(ChunkMap.class, "field_219252_f"); - Field pendingUnloadsField = ObfuscationReflectionHelper.findField(ChunkMap.class, "field_219253_g"); - for(ServerLevel level : event.getServer().getAllLevels()) { - ChunkMap chunkMap = level.getChunkSource().chunkMap; - Long2ObjectMap map = (Long2ObjectMap)updatingMapField.get(chunkMap); - map.clear(); - map = (Long2ObjectMap)visibleMapField.get(chunkMap); - map.clear(); - map = (Long2ObjectMap)pendingUnloadsField.get(chunkMap); - map.clear(); - } - } catch(RuntimeException | IllegalAccessException e) { - ModernFix.LOGGER.error("Couldn't clear chunk data", e); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java deleted file mode 100644 index c2223952..00000000 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ /dev/null @@ -1,257 +0,0 @@ -package org.embeddedt.modernfix; - -import com.mojang.blaze3d.platform.InputConstants; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import net.minecraft.client.KeyMapping; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.components.DebugScreenOverlay; -import net.minecraft.client.gui.screens.ConnectScreen; -import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.client.event.*; -import net.minecraftforge.client.gui.ForgeIngameGui; -import net.minecraftforge.client.settings.KeyConflictContext; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.TagsUpdatedEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.world.WorldEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ExtensionPoint; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.server.FMLServerStartingEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.network.NetworkEvent; -import org.embeddedt.modernfix.core.ModernFixMixinPlugin; -import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.embeddedt.modernfix.packet.EntityIDSyncPacket; -import org.embeddedt.modernfix.screen.ModernFixConfigScreen; -import org.embeddedt.modernfix.world.IntegratedWatchdog; - -import java.lang.management.ManagementFactory; -import java.lang.reflect.Field; -import java.util.*; -import java.util.function.Supplier; - -public class ModernFixClient { - public static long worldLoadStartTime; - private static int numRenderTicks; - - public static float gameStartTimeSeconds = -1; - - private static boolean recipesUpdated, tagsUpdated = false; - - private String brandingString = null; - - public ModernFixClient() { - // clear reserve as it's not needed - ObfuscationReflectionHelper.setPrivateValue(Minecraft.class, null, new byte[0], "field_71444_a"); - if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) { - Optional mfContainer = ModList.get().getModContainerById("modernfix"); - if(mfContainer.isPresent()) - brandingString = "ModernFix " + mfContainer.get().getModInfo().getVersion().toString(); - } - - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); - ModLoadingContext.get().registerExtensionPoint( - ExtensionPoint.CONFIGGUIFACTORY, - () -> (mc, screen) -> new ModernFixConfigScreen(screen) - ); - } - - private KeyMapping configKey; - - private void clientSetup(FMLClientSetupEvent event) { - configKey = new KeyMapping("key.modernfix.config", KeyConflictContext.UNIVERSAL, InputConstants.UNKNOWN, "key.modernfix"); - ClientRegistry.registerKeyBinding(configKey); - - } - - @SubscribeEvent - public void onConfigKey(TickEvent.ClientTickEvent event) { - if(event.phase == TickEvent.Phase.START && configKey.consumeClick()) { - Minecraft.getInstance().setScreen(new ModernFixConfigScreen(Minecraft.getInstance().screen)); - } - } - - public void resetWorldLoadStateMachine() { - numRenderTicks = 0; - worldLoadStartTime = -1; - recipesUpdated = false; - tagsUpdated = false; - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onMultiplayerConnect(GuiScreenEvent.InitGuiEvent.Pre event) { - if(event.getGui() instanceof ConnectScreen && !event.isCanceled()) { - worldLoadStartTime = System.nanoTime(); - } else if (event.getGui() instanceof TitleScreen && gameStartTimeSeconds < 0) { - gameStartTimeSeconds = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f; - ModernFix.LOGGER.warn("Game took " + gameStartTimeSeconds + " seconds to start"); - } - } - - @SubscribeEvent(priority = EventPriority.LOW) - public void onRecipesUpdated(RecipesUpdatedEvent event) { - recipesUpdated = true; - } - - @SubscribeEvent(priority = EventPriority.LOW) - public void onTagsUpdated(TagsUpdatedEvent event) { - tagsUpdated = true; - } - - @SubscribeEvent - public void onRenderTickEnd(TickEvent.RenderTickEvent event) { - if(event.phase == TickEvent.Phase.END - && recipesUpdated - && tagsUpdated - && worldLoadStartTime != -1 - && Minecraft.getInstance().player != null - && numRenderTicks++ >= 10) { - float timeSpentLoading = ((float)(System.nanoTime() - worldLoadStartTime) / 1000000000f); - ModernFix.LOGGER.warn("Time from main menu to in-game was " + timeSpentLoading + " seconds"); - ModernFix.LOGGER.warn("Total time to load game and open world was " + (timeSpentLoading + gameStartTimeSeconds) + " seconds"); - resetWorldLoadStateMachine(); - if(ModernFix.worldLoadSemaphore != null) - ModernFix.worldLoadSemaphore.countDown(); - } - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onRenderOverlay(RenderGameOverlayEvent.Text event) { - if(brandingString != null && Minecraft.getInstance().options.renderDebug) { - event.getLeft().add(""); - event.getLeft().add(brandingString); - } - } - - @SubscribeEvent - public void onDisconnect(WorldEvent.Unload event) { - if(event.getWorld().isClientSide()) { - DebugScreenOverlay overlay = ObfuscationReflectionHelper.getPrivateValue(ForgeIngameGui.class, (ForgeIngameGui)Minecraft.getInstance().gui, "debugOverlay"); - if(overlay != null) { - Minecraft.getInstance().tell(overlay::clearChunkCache); - } - } - } - - /** - * Check if the IDs match and remap them if not. - * @return true if ID remap was needed - */ - private static boolean compareAndSwitchIds(Class eClass, String fieldName, EntityDataAccessor accessor, int newId) { - if(accessor.id != newId) { - ModernFix.LOGGER.warn("Corrected ID mismatch on {} field {}. Client had {} but server wants {}.", - eClass, - fieldName, - accessor.id, - newId); - accessor.id = newId; - return true; - } else { - ModernFix.LOGGER.debug("{} {} ID fine: {}", eClass, fieldName, newId); - return false; - } - } - - /** - * Horrendous hack to allow tracking every synced entity data manager. - * - * This is to ensure we can perform ID fixup on already constructed managers. - */ - public static final Set allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>()); - - private static final Field entriesArrayField; - static { - Field field; - try { - field = SynchedEntityData.class.getDeclaredField("entriesArray"); - field.setAccessible(true); - } catch(ReflectiveOperationException e) { - field = null; - } - entriesArrayField = field; - } - - /** - * Extremely hacky method to detect and correct mismatched entity data parameter IDs on the client and server. - * - * The technique is far from ideal, but it should detect reliably and also not break already constructed entities. - */ - public static void handleEntityIDSync(EntityIDSyncPacket packet, Supplier context) { - Map, List>> info = packet.getFieldInfo(); - context.get().enqueueWork(() -> { - boolean fixNeeded = false; - for(Map.Entry, List>> entry : info.entrySet()) { - Class eClass = entry.getKey(); - for(Pair field : entry.getValue()) { - String fieldName = field.getFirst(); - int newId = field.getSecond(); - try { - Field f = eClass.getDeclaredField(fieldName); - f.setAccessible(true); - EntityDataAccessor accessor = (EntityDataAccessor)f.get(null); - if(compareAndSwitchIds(eClass, fieldName, accessor, newId)) - fixNeeded = true; - } catch(NoSuchFieldException e) { - ModernFix.LOGGER.warn("Couldn't find field on {}: {}", eClass, fieldName); - } catch(ReflectiveOperationException e) { - throw new RuntimeException("Unexpected exception", e); - } - } - } - /* Now the ID mappings on synced entity data instances are probably all wrong. Fix that. */ - List dataEntries; - synchronized (allEntityDatas) { - if(fixNeeded) { - dataEntries = new ArrayList<>(allEntityDatas); - for(SynchedEntityData manager : dataEntries) { - Int2ObjectOpenHashMap> fixedMap = new Int2ObjectOpenHashMap<>(); - List> items = new ArrayList<>(manager.itemsById.values()); - for(SynchedEntityData.DataItem item : items) { - fixedMap.put(item.getAccessor().id, item); - } - manager.lock.writeLock().lock(); - try { - manager.itemsById.replaceAll((id, parameter) -> fixedMap.get((int)id)); - if(entriesArrayField != null) { - try { - SynchedEntityData.DataItem[] dataArray = new SynchedEntityData.DataItem[items.size()]; - for(int i = 0; i < dataArray.length; i++) { - dataArray[i] = fixedMap.get(i); - } - entriesArrayField.set(manager, dataArray); - } catch(ReflectiveOperationException e) { - ModernFix.LOGGER.error(e); - } - } - } finally { - manager.lock.writeLock().unlock(); - } - } - } - allEntityDatas.clear(); - } - }); - - context.get().setPacketHandled(true); - } - - @SubscribeEvent - public void onServerStarted(FMLServerStartingEvent event) { - if(ModernFixConfig.INTEGRATED_SERVER_WATCHDOG.get()) { - IntegratedWatchdog watchdog = new IntegratedWatchdog(event.getServer()); - watchdog.start(); - } - - } -} diff --git a/src/main/java/org/embeddedt/modernfix/blockstate/BlockStateCacheHandler.java b/src/main/java/org/embeddedt/modernfix/blockstate/BlockStateCacheHandler.java deleted file mode 100644 index 1c6c83c0..00000000 --- a/src/main/java/org/embeddedt/modernfix/blockstate/BlockStateCacheHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.embeddedt.modernfix.blockstate; - -import com.google.common.base.Stopwatch; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.loading.FMLLoader; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.embeddedt.modernfix.duck.IBlockState; -import org.embeddedt.modernfix.util.BakeReason; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.TimeUnit; - -public class BlockStateCacheHandler { - private static boolean needToBake() { - BakeReason reason = BakeReason.getCurrentBakeReason(); - return !(reason == BakeReason.FREEZE /* startup */ - || reason == BakeReason.REVERT /* crash, in which case cache likely doesn't matter, or exiting world */ - || reason == BakeReason.REMOTE_SNAPSHOT_INJECT /* will be handled when tags are reloaded */ - || (reason == BakeReason.LOCAL_SNAPSHOT_INJECT && FMLLoader.getDist() == Dist.CLIENT /* will be handled when tags are reloaded */)); - } - - public static void rebuildParallel(boolean force) { - synchronized (BlockBehaviour.BlockStateBase.class) { - for (BlockState blockState : Block.BLOCK_STATE_REGISTRY) { - ((IBlockState)blockState).clearCache(); - } - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java deleted file mode 100644 index 56142410..00000000 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.embeddedt.modernfix.core.config; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import org.embeddedt.modernfix.ModernFix; - -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -@Mod.EventBusSubscriber(modid = ModernFix.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class ModernFixConfig { - private static final ForgeConfigSpec.Builder COMMON_BUILDER = new ForgeConfigSpec.Builder(); - public static ForgeConfigSpec COMMON_CONFIG; - - public static ForgeConfigSpec.ConfigValue> BLACKLIST_ASYNC_JEI_PLUGINS; - - public static ForgeConfigSpec.IntValue INTEGRATED_SERVER_PRIORITY; - public static ForgeConfigSpec.BooleanValue ENABLE_DEBUG_RELOADER; - - public static ForgeConfigSpec.BooleanValue REBUILD_BLOCKSTATES_ASYNC; - public static ForgeConfigSpec.BooleanValue INTEGRATED_SERVER_WATCHDOG; - - public static Set jeiPluginBlacklist; - - static { - Predicate locationValidator = o -> o instanceof String && ((String)o).contains(":"); - BLACKLIST_ASYNC_JEI_PLUGINS = COMMON_BUILDER - .comment("These JEI plugins will be loaded on the main thread") - .defineList("blacklist_async_jei_plugins", ImmutableList.of( - "jepb:jei_plugin" - ), locationValidator); - INTEGRATED_SERVER_PRIORITY = COMMON_BUILDER.comment("Thread priority to use for the integrated server. By default this is one less than the client thread, to help prevent the server from lowering FPS.").defineInRange("integratedServerPriority", 4, 1, 10); - ENABLE_DEBUG_RELOADER = COMMON_BUILDER - .comment("Whether Minecraft's built-in profiling logic should be enabled for resource reloading. Can help with diagnosing world load times.") - .define("enable_debug_reloader", false); - REBUILD_BLOCKSTATES_ASYNC = COMMON_BUILDER - .comment("Rebuild blockstate cache asynchronously. Should work with most mods, but can be disabled.") - .define("rebuild_blockstate_cache_async", true); - INTEGRATED_SERVER_WATCHDOG = COMMON_BUILDER - .comment("Automatically output a thread dump if the integrated server spends too long on one tick") - .define("integrated_server_watchdog", true); - } - - static { - COMMON_CONFIG = COMMON_BUILDER.build(); - } - - @SubscribeEvent - public static void onModConfigEvent(final ModConfig.ModConfigEvent configEvent) { - if (configEvent.getConfig().getSpec() == COMMON_CONFIG) { - bakeConfig(); - } - } - - public static void bakeConfig() { - jeiPluginBlacklist = BLACKLIST_ASYNC_JEI_PLUGINS.get().stream().map(ResourceLocation::new).collect(Collectors.toSet()); - } - -} diff --git a/src/main/java/org/embeddedt/modernfix/dynamicresources/ResourcePackHandler.java b/src/main/java/org/embeddedt/modernfix/dynamicresources/ResourcePackHandler.java deleted file mode 100644 index ee6c5fca..00000000 --- a/src/main/java/org/embeddedt/modernfix/dynamicresources/ResourcePackHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.embeddedt.modernfix.dynamicresources; - -import dev.latvian.kubejs.script.data.KubeJSResourcePack; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.PackResources; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraftforge.fml.ModList; -import org.embeddedt.modernfix.util.FileUtil; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class ResourcePackHandler { - private static final List packHandlers = new ArrayList<>(); - public static Collection getExtraResources(ResourceManager manager, String path, Predicate matchPredicate) { - final String normalizedPath = FileUtil.normalize(path); - return manager.listPacks().flatMap(pack -> packHandlers.stream().flatMap(handler -> { - if(handler.shouldHandle(pack)) { - return handler.getExtraResources(pack, normalizedPath, matchPredicate); - } else - return Stream.of(); - })).collect(Collectors.toList()); - } - - interface PackHandler { - Stream getExtraResources(PackResources pack, String path, Predicate matchPredicate); - boolean shouldHandle(PackResources pack); - } - - static class KubeJSPackHandler implements PackHandler { - - @Override - public Stream getExtraResources(PackResources pack, String path, Predicate matchPredicate) { - KubeJSResourcePack p = (KubeJSResourcePack)pack; - return p.getCachedResources().keySet().stream() - .filter(l -> l.getPath().startsWith(path)) - .filter(l -> matchPredicate.test(l.getPath())); - } - - @Override - public boolean shouldHandle(PackResources pack) { - return pack instanceof KubeJSResourcePack; - } - } - - static { - if(ModList.get().isLoaded("kubejs")) { - packHandlers.add(new KubeJSPackHandler()); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java b/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java deleted file mode 100644 index 70fc97cc..00000000 --- a/src/main/java/org/embeddedt/modernfix/entity/EntityDataIDSyncHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.embeddedt.modernfix.entity; - -import com.mojang.datafixers.util.Pair; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.event.OnDatapackSyncEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.fml.network.PacketDistributor; -import net.minecraftforge.fml.server.ServerLifecycleHooks; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.packet.EntityIDSyncPacket; -import org.embeddedt.modernfix.packet.PacketHandler; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class EntityDataIDSyncHandler { - private static Map, List>> fieldsToSyncMap; - @SubscribeEvent(priority = EventPriority.HIGHEST) - @SuppressWarnings("unchecked") - public static void onDatapackSyncEvent(OnDatapackSyncEvent event) { - if(event.getPlayer() != null) { - if(!ServerLifecycleHooks.getCurrentServer().isDedicatedServer() && event.getPlayerList().getPlayerCount() == 0) { - ModernFix.LOGGER.debug("Not syncing IDs on integrated server"); - return; - } - /* Compute the current set of serializer IDs in use and send them */ - try { - if(fieldsToSyncMap == null) { - fieldsToSyncMap = new HashMap<>(); - Field entityPoolField = ObfuscationReflectionHelper.findField(SynchedEntityData.class, "field_187232_a"); - Map, Integer> entityPoolMap = (Map, Integer>)entityPoolField.get(null); - List fieldsToSync = new ArrayList<>(); - for(Class eClass : entityPoolMap.keySet()) { - fieldsToSync.clear(); - try { - Field[] classFields = eClass.getDeclaredFields(); - for(Field field : classFields) { - if(!Modifier.isStatic(field.getModifiers())) - continue; - field.setAccessible(true); - Object o = field.get(null); - if(o != null && EntityDataAccessor.class.isAssignableFrom(o.getClass())) { - fieldsToSync.add(field); - } - } - for(Field field : fieldsToSync) { - int id = ((EntityDataAccessor)field.get(null)).id; - fieldsToSyncMap.computeIfAbsent(eClass, k -> new ArrayList<>()).add(Pair.of(field.getName(), id)); - } - } catch(Throwable e) { - ModernFix.LOGGER.error("Skipping entity ID sync for {}: {}", eClass.getName(), e); - } - } - } - EntityIDSyncPacket packet = new EntityIDSyncPacket(fieldsToSyncMap); - ModernFix.LOGGER.debug("Sending ID correction packet to client with " + fieldsToSyncMap.size() + " classes"); - PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(event::getPlayer), packet); - } catch(ObfuscationReflectionHelper.UnableToFindFieldException | ReflectiveOperationException e) { - e.printStackTrace(); - } - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/core/MinecraftMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/core/MinecraftMixin.java deleted file mode 100644 index d7bd2789..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/core/MinecraftMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.embeddedt.modernfix.mixin.core; - -import com.mojang.datafixers.util.Function4; -import net.minecraft.client.Minecraft; -import net.minecraft.core.RegistryAccess; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.world.level.DataPackConfig; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.WorldData; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.concurrent.CountDownLatch; -import java.util.function.Function; - -@Mixin(Minecraft.class) -@ClientOnlyMixin -public class MinecraftMixin { - @Inject(method = "loadWorld", at = @At("HEAD")) - private void setLatch(String string, RegistryAccess.RegistryHolder arg, Function function, Function4 function4, boolean bl, Minecraft.ExperimentalDialogType arg2, boolean creating, CallbackInfo ci) { - ModernFix.worldLoadSemaphore = new CountDownLatch(1); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/feature/reduce_loading_screen_freezes/ModelBakeryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/feature/reduce_loading_screen_freezes/ModelBakeryMixin.java deleted file mode 100644 index 8297b278..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/feature/reduce_loading_screen_freezes/ModelBakeryMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.embeddedt.modernfix.mixin.feature.reduce_loading_screen_freezes; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.model.ModelBakery; -import net.minecraft.Util; -import net.minecraftforge.fml.loading.progress.StartupMessageManager; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -@Mixin(ModelBakery.class) -@ClientOnlyMixin -public class ModelBakeryMixin { - @Redirect(method = "uploadTextures", at = @At(value = "INVOKE", target = "Ljava/util/Set;forEach(Ljava/util/function/Consumer;)V", ordinal = 0)) - private void bakeAndTickGUI(Set instance, Consumer consumer) { - StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Baking models")); - CompletableFuture modelBakingFuture = CompletableFuture.runAsync(() -> { - instance.forEach(consumer); - }, Util.backgroundExecutor()); - /* allow the GUI to continue running */ - Minecraft.getInstance().managedBlock(modelBakingFuture::isDone); - } -} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg deleted file mode 100644 index 30e53ddd..00000000 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ /dev/null @@ -1,29 +0,0 @@ -public net.minecraft.client.Minecraft$ExperimentalDialogType -public net.minecraft.client.renderer.RenderType$CompositeRenderType -public net.minecraft.client.renderer.RenderType$CompositeRenderType (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V -public net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase$Cache -public net.minecraft.world.phys.shapes.VoxelShape (Lnet/minecraft/util/math/shapes/VoxelShapePart;)V # -public net.minecraft.client.resources.model.ModelBakery$BlockStateDefinitionException -public net.minecraft.client.renderer.model.ModelBakery field_217849_F # unbakedCache -public net.minecraft.client.renderer.texture.Stitcher$Holder -public net.minecraft.util.concurrent.ThreadTaskExecutor func_213160_bf()V # runAllTasks -public net.minecraft.server.MinecraftServer field_211151_aa # nextTickTime -public net.minecraft.client.Minecraft field_213277_ad # progressListener -public-f net.minecraft.network.datasync.DataParameter field_187157_a # id -public-f net.minecraft.network.datasync.EntityDataManager field_187234_c # itemsById -public-f net.minecraft.network.datasync.EntityDataManager field_187235_d # lock -public net.minecraft.block.AbstractBlock field_235684_aB_ # properties -public net.minecraft.block.AbstractBlock$Properties field_200953_a # material -public net.minecraft.block.AbstractBlock$Properties field_226895_m_ # canOcclude -public net.minecraft.block.AbstractBlock$Properties field_235813_o_ # isAir -public net.minecraft.block.AbstractBlock$Properties field_235815_q_ # isRedstoneConductor -public net.minecraft.block.AbstractBlock$Properties field_235816_r_ # isSuffocating -public net.minecraft.block.AbstractBlock$Properties field_235817_s_ # isViewBlocking -public net.minecraft.block.AbstractBlock$Properties field_235818_t_ # hasPostProcess -public net.minecraft.block.AbstractBlock$Properties field_235819_u_ # emissiveRendering -public net.minecraft.block.AbstractBlock$Properties field_235806_h_ # requiresCorrectToolForDrops -public net.minecraft.block.AbstractBlock$Properties field_200959_g # destroyTime -public net.minecraft.world.server.ServerChunkProvider$ChunkExecutor -public net.minecraft.nbt.CompoundNBT (Ljava/util/Map;)V # -public net.minecraft.client.renderer.texture.TextureAtlasSprite (Lnet/minecraft/client/renderer/texture/TextureAtlas;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIIILcom/mojang/blaze3d/platform/NativeImage;)V # -public net.minecraft.resources.ResourceKey (Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V # \ No newline at end of file