From 708ec7eb702e72949cca2a448c3b50844426d286 Mon Sep 17 00:00:00 2001 From: Runemoro Date: Thu, 3 Jan 2019 19:10:15 -0500 Subject: [PATCH] Fix incompatibilities with Optifine and Galacticraft --- build.gradle | 6 +- .../java/net/optifine/render/RenderEnv.java | 3 + .../ModCompatibilityMixinPlugin.java | 30 +++++---- .../vanillafix/VanillaFixLoadingPlugin.java | 17 +++--- .../mixins/MixinBlockStateContainer.java | 57 +++++++++++++++--- .../mixins/MixinExtendedBlockState.java | 4 ++ .../MixinBlockModelRendererOptifine.java | 55 +++++++++++++++++ src/main/resources/META-INF/vanillafix_at.cfg | 3 + src/main/resources/launchwrapper-2.0.jar_ | Bin 19112 -> 0 bytes .../resources/mixins.vanillafix.textures.json | 3 +- 10 files changed, 147 insertions(+), 31 deletions(-) create mode 100644 src/api/java/net/optifine/render/RenderEnv.java create mode 100644 src/main/java/org/dimdev/vanillafix/textures/mixins/client/MixinBlockModelRendererOptifine.java delete mode 100644 src/main/resources/launchwrapper-2.0.jar_ diff --git a/build.gradle b/build.gradle index ae88d13..aa7c35a 100644 --- a/build.gradle +++ b/build.gradle @@ -52,13 +52,17 @@ dependencies { def travisBuildNumber = System.getenv("TRAVIS_BUILD_NUMBER") def versionSuffix = travisBuildNumber != null ? travisBuildNumber : "SNAPSHOT" -version "1.0.10-$versionSuffix" +version "1.1-$versionSuffix" group "org.dimdev.vanillafix" archivesBaseName = "VanillaFix" sourceCompatibility = 1.8 targetCompatibility = 1.8 +sourceSets { + main +} + minecraft { version "1.12.2-14.23.4.2703" runDir "run" diff --git a/src/api/java/net/optifine/render/RenderEnv.java b/src/api/java/net/optifine/render/RenderEnv.java new file mode 100644 index 0000000..65cebf2 --- /dev/null +++ b/src/api/java/net/optifine/render/RenderEnv.java @@ -0,0 +1,3 @@ +package net.optifine.render; + +public class RenderEnv {} diff --git a/src/main/java/org/dimdev/vanillafix/ModCompatibilityMixinPlugin.java b/src/main/java/org/dimdev/vanillafix/ModCompatibilityMixinPlugin.java index 7d78505..3780387 100644 --- a/src/main/java/org/dimdev/vanillafix/ModCompatibilityMixinPlugin.java +++ b/src/main/java/org/dimdev/vanillafix/ModCompatibilityMixinPlugin.java @@ -10,15 +10,9 @@ import java.util.Set; public class ModCompatibilityMixinPlugin implements IMixinConfigPlugin { - private boolean spongeInstalled; - @Override public void onLoad(String mixinPackage) { - try { - spongeInstalled = Launch.classLoader.getClassBytes("org.spongepowered.mod.SpongeCoremod") != null; - } catch (IOException e) { - throw new RuntimeException(e); // Should never happen - } + } @Override @@ -27,16 +21,30 @@ public String getRefMapperConfig() { } @Override - @SuppressWarnings("RedundantIfStatement") public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - // Sponge - if (spongeInstalled) { - if (mixinClassName.equals("org.dimdev.vanillafix.profiler.mixins.MixinWorld")) return false; + if (mixinClassName.equals("org.dimdev.vanillafix.profiler.mixins.MixinWorld")) { + return !classExists("org.spongepowered.mod.SpongeCoremod"); + } + + if (mixinClassName.equals("org.dimdev.vanillafix.textures.mixins.client.MixinBlockModelRenderer")) { + return !classExists("optifine.OptiFineForgeTweaker"); + } + + if (mixinClassName.equals("org.dimdev.vanillafix.textures.mixins.client.MixinBlockModelRendererOptifine")) { + return classExists("optifine.OptiFineForgeTweaker"); } return true; } + public boolean classExists(String name) { + try { + return Launch.classLoader.getClassBytes(name) != null; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Override public void acceptTargets(Set myTargets, Set otherTargets) {} diff --git a/src/main/java/org/dimdev/vanillafix/VanillaFixLoadingPlugin.java b/src/main/java/org/dimdev/vanillafix/VanillaFixLoadingPlugin.java index 55dd136..9712143 100644 --- a/src/main/java/org/dimdev/vanillafix/VanillaFixLoadingPlugin.java +++ b/src/main/java/org/dimdev/vanillafix/VanillaFixLoadingPlugin.java @@ -3,10 +3,6 @@ import net.minecraft.launchwrapper.Launch; import net.minecraftforge.common.ForgeVersion; import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; -import net.minecraftforge.fml.relauncher.libraries.LibraryManager; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dimdev.utils.SSLUtils; @@ -17,13 +13,12 @@ import sun.misc.URLClassPath; import javax.annotation.Nullable; -import java.io.*; -import java.lang.management.ManagementFactory; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; -import java.nio.file.Files; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -38,20 +33,21 @@ public class VanillaFixLoadingPlugin implements IFMLLoadingPlugin { private static final Logger log = LogManager.getLogger("VanillaFix"); public static LoadingConfig config; - private static final boolean deobfuscatedEnvironment = VanillaFixLoadingPlugin.class.getResource("/net/minecraft/world/World.class") != null; + // private static final boolean deobfuscatedEnvironment = VanillaFixLoadingPlugin.class.getResource("/net/minecraft/world/World.class") != null; static { log.info("Initializing VanillaFix"); config = new LoadingConfig(new File(Launch.minecraftHome, "config/vanillafix.cfg")); config.improvedLaunchWrapper = false; // TODO: fix this - replaceLaunchWrapper(); + // replaceLaunchWrapper(); trustIdenTrust(); initStacktraceDeobfuscator(); fixMixinClasspathOrder(); initMixin(); } + /* private static void replaceLaunchWrapper() { if (!config.improvedLaunchWrapper) { log.info("LaunchWrapper replacement disabled by config"); @@ -136,6 +132,7 @@ private static String makeNewCommandLine(String newLibraryPath) { return command.toString(); } + */ private static void trustIdenTrust() { // Trust the "IdenTrust DST Root CA X3" certificate (used by Let's Encrypt, which is used by paste.dimdev.org) diff --git a/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinBlockStateContainer.java b/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinBlockStateContainer.java index f2d6ce6..aa508ae 100644 --- a/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinBlockStateContainer.java +++ b/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinBlockStateContainer.java @@ -1,8 +1,6 @@ package org.dimdev.vanillafix.blockstates.mixins; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSortedMap; +import com.google.common.collect.*; import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.BlockStateContainer; @@ -10,6 +8,7 @@ import net.minecraft.util.MapPopulator; import net.minecraft.util.math.Cartesian; import net.minecraft.util.math.MathHelper; +import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; import org.dimdev.vanillafix.blockstates.IPatchedBlockStateContainer; import org.dimdev.vanillafix.blockstates.NumericalBlockState; @@ -18,16 +17,24 @@ import javax.annotation.Nullable; import java.util.*; +@SuppressWarnings({"ResultOfMethodCallIgnored", "ConstructorNotProtectedInAbstractClass"}) @Mixin(BlockStateContainer.class) public abstract class MixinBlockStateContainer implements IPatchedBlockStateContainer { + // @formatter:off @Shadow @Final @Mutable private Block block; @Shadow @Final @Mutable private ImmutableSortedMap> properties; @Shadow public static > String validateProperty(Block block, IProperty property) { return null; } @Shadow protected abstract List>> getAllowedValues(); + @Shadow public abstract Block getBlock(); + @Shadow @Final private ImmutableList validStates; + // @formatter:on + @SuppressWarnings("EqualsBetweenInconvertibleTypes") // mixin + private boolean isNumerical = getClass().equals(BlockStateContainer.class) || getClass().equals(ExtendedBlockState.class); private final ImmutableMap, Optional> unlistedProperties; private final Map, Integer> propertyOffsets = new HashMap<>(); - protected ImmutableList validStatesCache; + protected ImmutableList validStatesCache = null; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) private final Object x; // workaround for mixin bug @Overwrite public MixinBlockStateContainer(Block block, IProperty[] properties, ImmutableMap, Optional> unlistedProperties) { @@ -35,23 +42,49 @@ public MixinBlockStateContainer(Block block, IProperty[] properties, Immutabl this.unlistedProperties = unlistedProperties; // Immutable map builder won't work, some mods have duplicate properties - LinkedHashMap> propertyMap = new LinkedHashMap<>(); + Map> propertyMap = new LinkedHashMap<>(); int offset = 0; for (IProperty property : properties) { validateProperty(block, property); propertyMap.put(property.getName(), property); - NumericalBlockState.makePropertyInfo(property); - propertyOffsets.put(property, offset); - offset += MathHelper.log2(property.getAllowedValues().size()) + 1; + if (isNumerical) { + NumericalBlockState.makePropertyInfo(property); + propertyOffsets.put(property, offset); + offset += MathHelper.log2(property.getAllowedValues().size()) + 1; + } } this.properties = ImmutableSortedMap.copyOf(propertyMap); + + if (!isNumerical) { + Map, Comparable>, BlockStateContainer.StateImplementation> map2 = Maps.newLinkedHashMap(); + List validStates = Lists.newArrayList(); + + for (List> list : Cartesian.cartesianProduct(getAllowedValues())) { + Map, Comparable> map1 = MapPopulator.createMap(this.properties.values(), list); + BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation = createState(block, ImmutableMap.copyOf(map1), unlistedProperties); + map2.put(map1, blockstatecontainer$stateimplementation); + validStates.add(blockstatecontainer$stateimplementation); + } + + for (BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation1 : validStates) { + blockstatecontainer$stateimplementation1.buildPropertyValueTable(map2); + } + + this.validStates = ImmutableList.copyOf(validStates); + } + + x = new Object(); } @Overwrite public ImmutableList getValidStates() { + if (!isNumerical) { + return validStates; + } + if (validStatesCache == null) { ImmutableList.Builder states = ImmutableList.builder(); @@ -69,6 +102,10 @@ public ImmutableList getValidStates() { @Overwrite(remap = false) protected BlockStateContainer.StateImplementation createState(Block block, ImmutableMap, Comparable> properties, @Nullable ImmutableMap, Optional> unlistedProperties) { + if (!isNumerical) { + return new BlockStateContainer.StateImplementation(block, properties); + } + return null; } @@ -83,6 +120,10 @@ protected IBlockState createState(ImmutableMap, Comparable> prop @Overwrite public IBlockState getBaseState() { + if (!isNumerical) { + return validStates.get(0); + } + if (validStatesCache != null) { return validStatesCache.get(0); } diff --git a/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinExtendedBlockState.java b/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinExtendedBlockState.java index 11f8648..14bd07d 100644 --- a/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinExtendedBlockState.java +++ b/src/main/java/org/dimdev/vanillafix/blockstates/mixins/MixinExtendedBlockState.java @@ -29,6 +29,10 @@ protected BlockStateContainer.StateImplementation createState(Block block, Immut @Override protected IBlockState createState(ImmutableMap, Comparable> properties, @Nullable ImmutableMap, Optional> unlistedProperties) { + if (getClass() != MixinExtendedBlockState.class) { + return createState(getBlock(), properties, unlistedProperties); + } + IBlockState normalState = super.createState(properties, unlistedProperties); if (unlistedProperties == null || unlistedProperties.isEmpty()) { return normalState; diff --git a/src/main/java/org/dimdev/vanillafix/textures/mixins/client/MixinBlockModelRendererOptifine.java b/src/main/java/org/dimdev/vanillafix/textures/mixins/client/MixinBlockModelRendererOptifine.java new file mode 100644 index 0000000..e2ed107 --- /dev/null +++ b/src/main/java/org/dimdev/vanillafix/textures/mixins/client/MixinBlockModelRendererOptifine.java @@ -0,0 +1,55 @@ +package org.dimdev.vanillafix.textures.mixins.client; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.BlockModelRenderer; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.chunk.CompiledChunk; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.optifine.render.RenderEnv; +import org.dimdev.vanillafix.textures.IPatchedCompiledChunk; +import org.dimdev.vanillafix.textures.IPatchedTextureAtlasSprite; +import org.dimdev.vanillafix.textures.TemporaryStorage; +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.List; +import java.util.Set; + +@Mixin(BlockModelRenderer.class) +public class MixinBlockModelRendererOptifine { + @Inject(method = "renderQuadsSmooth", remap = false, at = @At("HEAD")) + private void onRenderQuadsSmooth(IBlockAccess blockAccess, IBlockState state, BlockPos pos, BufferBuilder buffer, List quads, RenderEnv renderEnv, CallbackInfo ci) { + markQuads(quads); + } + + @Inject(method = "renderQuadsFlat", remap = false, at = @At("HEAD")) + private void onRenderQuadsFlat(IBlockAccess blockAccess, IBlockState state, BlockPos pos, int brightness, boolean ownBrightness, BufferBuilder buffer, List quads, RenderEnv renderEnv, CallbackInfo ci) { + markQuads(quads); + } + + private static void markQuads(List quads) { + CompiledChunk compiledChunk = TemporaryStorage.currentCompiledChunk.get(); + if (compiledChunk != null) { + Set visibleTextures = ((IPatchedCompiledChunk) compiledChunk).getVisibleTextures(); + + for (BakedQuad quad : quads) { + if (quad.getSprite() != null) { + visibleTextures.add(quad.getSprite()); + } + } + } else { + // Called from non-chunk render thread. Unfortunately, the best we can do + // is assume it's only going to be used once: + for (BakedQuad quad : quads) { + if (quad.getSprite() != null) { + ((IPatchedTextureAtlasSprite) quad.getSprite()).markNeedsAnimationUpdate(); + } + } + } + } +} diff --git a/src/main/resources/META-INF/vanillafix_at.cfg b/src/main/resources/META-INF/vanillafix_at.cfg index bfc852f..3239156 100644 --- a/src/main/resources/META-INF/vanillafix_at.cfg +++ b/src/main/resources/META-INF/vanillafix_at.cfg @@ -41,3 +41,6 @@ public net.minecraft.client.renderer.texture.TextureAtlasSprite (Ljava/lan # dynamicresources.MixinGlStateManager public net.minecraft.client.renderer.GlStateManager$TextureState + +# blockstates.MixinBlockStateContainer +public net.minecraft.block.state.BlockStateContainer$StateImplementation (Lnet/minecraft/block/Block;Lcom/google/common/collect/ImmutableMap;)V diff --git a/src/main/resources/launchwrapper-2.0.jar_ b/src/main/resources/launchwrapper-2.0.jar_ deleted file mode 100644 index 6bf05c4d59583488e6fe0c3fe22a40ec1194730c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19112 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

h4}y`B69Z*-92N9=z{pkTehN_^py5XPv>Su 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