diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index ef2ed28e..b8a1f42a 100644 --- a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -31,7 +31,7 @@ public class ModernFixClient { public static float gameStartTimeSeconds = -1; - private static boolean recipesUpdated, tagsUpdated = false; + public static boolean recipesUpdated, tagsUpdated = false; public String brandingString = null; diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java new file mode 100644 index 00000000..02d346d2 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java @@ -0,0 +1,24 @@ +package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; +import org.embeddedt.modernfix.registry.DirectStorageRegistryObject; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin({ Block.class, Item.class }) +@IgnoreOutsideDev +public class DirectObjectMixin implements DirectStorageRegistryObject { + private ResourceLocation mfix$resourceKey; + + @Override + public ResourceLocation mfix$getResourceKey() { + return mfix$resourceKey; + } + + @Override + public void mfix$setResourceKey(ResourceLocation key) { + mfix$resourceKey = key; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java new file mode 100644 index 00000000..f6e86477 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java @@ -0,0 +1,40 @@ +package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; + +import com.google.common.collect.ImmutableSet; +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.MappedRegistry; +import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; +import org.embeddedt.modernfix.registry.LifecycleMap; +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.callback.CallbackInfo; + +import java.util.Map; + +@Mixin(MappedRegistry.class) +@IgnoreOutsideDev +public abstract class MappedRegistryMixin { + @Shadow + @Final + @Mutable + private Map lifecycles; + + private static final ImmutableSet MFIX$NEW_STORAGE_KEYS = ImmutableSet.of(new ResourceLocation("block"), new ResourceLocation("item")); + + @Inject(method = "(Lnet/minecraft/resources/ResourceKey;Lcom/mojang/serialization/Lifecycle;Z)V", at = @At("RETURN")) + private void replaceStorage(CallbackInfo ci) { + this.lifecycles = new LifecycleMap<>(); + /* + if(MFIX$NEW_STORAGE_KEYS.contains(this.key().location())) { + ModernFixMixinPlugin.instance.logger.info("Using experimental registry storage for {}", this.key()); + this.storage = (BiMap) RegistryStorage.createStorage(); + this.keyStorage = (BiMap, T>)RegistryStorage.createKeyStorage(this.key(), (BiMap)this.storage); + } + */ + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java index 9c81fd6e..9e67dd7b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java @@ -1,5 +1,7 @@ package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size; +import com.google.common.collect.ArrayTable; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; import net.minecraft.world.level.block.state.StateHolder; @@ -23,7 +25,7 @@ public class StateHolderMixin { /* optimize the case where block has no properties */ @Inject(method = "populateNeighbours", at = @At("RETURN"), require = 0) private void replaceEmptyTable(CallbackInfo ci) { - if(this.neighbours.isEmpty()) + if((this.neighbours instanceof ArrayTable || this.neighbours instanceof HashBasedTable) && this.neighbours.isEmpty()) this.neighbours = ImmutableTable.of(); } } diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 8c61f222..6377955f 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -11,6 +11,7 @@ import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; import org.embeddedt.modernfix.annotation.RequiresMod; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Type; @@ -251,6 +252,17 @@ public class ModernFixEarlyConfig { } } + private void readJVMProperties() { + for(String optionKey : this.options.keySet()) { + String value = System.getProperty("modernfix.config." + optionKey); + if(value == null || value.length() == 0) + continue; + boolean isEnabled = Boolean.valueOf(value); + ModernFixMixinPlugin.instance.logger.info("Configured {} to '{}' via JVM property.", optionKey, isEnabled); + this.options.get(optionKey).setEnabled(isEnabled, true); + } + } + private void readProperties(Properties props) { if(ALLOW_OVERRIDE_OVERRIDES) LOGGER.fatal("JVM argument given to override mod overrides. Issues opened with this option present will be ignored unless they can be reproduced without."); @@ -339,6 +351,8 @@ public class ModernFixEarlyConfig { } catch (IOException e) { LOGGER.warn("Could not write configuration file", e); } + + config.readJVMProperties(); } return config; diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java index 06b6a697..d35ba62e 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java @@ -1,5 +1,6 @@ package org.embeddedt.modernfix.dynamicresources; +import com.google.common.collect.ImmutableSet; import com.mojang.math.Transformation; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.renderer.block.model.BakedQuad; @@ -27,6 +28,15 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; public class DynamicBakedModelProvider implements Map { + /** + * The list of blacklisted resource locations that are never baked as top-level models. + * + * This is a hack to get around the fact that we don't really know exactly what models were supposed to end up + * in the baked registry ahead of time. + */ + private static final ImmutableSet BAKE_SKIPPED_TOPLEVEL = ImmutableSet.builder() + .add(new ResourceLocation("custommachinery", "block/custom_machine_block")) + .build(); public static DynamicBakedModelProvider currentInstance = null; private final ModelBakery bakery; private final Map bakedCache; @@ -138,7 +148,10 @@ public class DynamicBakedModelProvider implements Map implements BiMap { + private final Function keyGetter; + private final BiConsumer keySetter; + private final Map forwardMap; + + public DirectStorageBiMap(Function keyGetter, BiConsumer keySetter) { + Objects.requireNonNull(keyGetter); + Objects.requireNonNull(keySetter); + this.keyGetter = keyGetter; + this.keySetter = keySetter; + this.forwardMap = new Object2ObjectOpenHashMap<>(); + } + + @Override + public int size() { + return this.forwardMap.size(); + } + + @Override + public boolean isEmpty() { + return this.forwardMap.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return this.forwardMap.containsKey(o); + } + + @Override + public boolean containsValue(Object o) { + return o != null && keyGetter.apply((V)o) != null; + } + + @Override + public V get(Object o) { + return this.forwardMap.get(o); + } + + @Override + public V put(K key, V value) { + if(this.forwardMap.containsKey(key) || (value != null && keyGetter.apply(value) != null)) + throw new IllegalArgumentException("Already have mapping for " + key); + return forcePut(key, value); + } + + @Override + public V remove(Object o) { + return put((K)o, null); + } + + @Override + public V forcePut(K key, V value) { + V previousValue = this.forwardMap.put(key, value); + if(previousValue != null) + keySetter.accept(previousValue, null); + if(value != null) + keySetter.accept(value, key); + return previousValue; + } + + @Override + public void putAll(Map map) { + map.forEach(this::put); + } + + @Override + public void clear() { + for(V value : this.forwardMap.values()) { + if(value != null) + keySetter.accept(value, null); + } + this.forwardMap.clear(); + } + + @NotNull + @Override + public Set keySet() { + return this.forwardMap.keySet(); + } + + @Override + public Set values() { + return new HashSet<>(this.forwardMap.values()); + } + + @NotNull + @Override + public Set> entrySet() { + return this.forwardMap.entrySet(); + } + + @Override + public BiMap inverse() { + return new Reverse(); + } + + class Reverse implements BiMap { + @Override + public int size() { + return DirectStorageBiMap.this.size(); + } + + @Override + public boolean isEmpty() { + return DirectStorageBiMap.this.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return DirectStorageBiMap.this.containsValue(o); + } + + @Override + public boolean containsValue(Object o) { + return DirectStorageBiMap.this.containsKey(o); + } + + @Override + public K get(Object o) { + return o == null ? null : keyGetter.apply((V)o); + } + + @Override + public K put(V key, K value) { + throw new UnsupportedOperationException(); + } + + @Override + public K remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public K forcePut(V key, K value) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map map) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public Set keySet() { + return DirectStorageBiMap.this.values(); + } + + @Override + public Set values() { + return DirectStorageBiMap.this.keySet(); + } + + @NotNull + @Override + public Set> entrySet() { + return DirectStorageBiMap.this.entrySet().stream() + .map(entry -> new AbstractMap.SimpleImmutableEntry<>(entry.getValue(), entry.getKey())) + .collect(Collectors.toSet()); + } + + @Override + public BiMap inverse() { + return DirectStorageBiMap.this; + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java new file mode 100644 index 00000000..c18ac699 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java @@ -0,0 +1,8 @@ +package org.embeddedt.modernfix.registry; + +import net.minecraft.resources.ResourceLocation; + +public interface DirectStorageRegistryObject { + ResourceLocation mfix$getResourceKey(); + void mfix$setResourceKey(ResourceLocation key); +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java new file mode 100644 index 00000000..76285abd --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java @@ -0,0 +1,20 @@ +package org.embeddedt.modernfix.registry; + +import com.mojang.serialization.Lifecycle; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; + +public class LifecycleMap extends Reference2ReferenceOpenHashMap { + public LifecycleMap() { + this.defaultReturnValue(Lifecycle.stable()); + } + + @Override + public Lifecycle put(T t, Lifecycle lifecycle) { + if(lifecycle != defRetValue) + return super.put(t, lifecycle); + else { + // need the duplicate containsKey/get logic here to override the default return value + return super.containsKey(t) ? super.get(t) : null; + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java b/common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java new file mode 100644 index 00000000..252676d2 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java @@ -0,0 +1,34 @@ +package org.embeddedt.modernfix.registry; + +import com.google.common.collect.BiMap; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; + +import java.util.Map; +import java.util.function.Function; + +public class RegistryStorage { + public static BiMap createStorage() { + return new DirectStorageBiMap<>(DirectStorageRegistryObject::mfix$getResourceKey, DirectStorageRegistryObject::mfix$setResourceKey); + } + + public static BiMap, DirectStorageRegistryObject> createKeyStorage(ResourceKey> registryKey, BiMap storage) { + if(storage instanceof DirectStorageBiMap) { + DirectStorageBiMap directStorageBiMap = (DirectStorageBiMap)storage; + // silently ignore put/putAll calls on this map + return new TransformingBiMap, DirectStorageRegistryObject>(directStorageBiMap, loc -> ResourceKey.create(registryKey, loc), ResourceKey::location, Function.identity(), Function.identity()) { + @Override + public DirectStorageRegistryObject put(ResourceKey key, DirectStorageRegistryObject value) { + return null; + } + + @Override + public void putAll(Map, ? extends DirectStorageRegistryObject> map) { + + } + }; + } else + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java new file mode 100644 index 00000000..2fb1beb1 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java @@ -0,0 +1,224 @@ +package org.embeddedt.modernfix.registry; + +import com.google.common.collect.BiMap; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterators; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.Function; + +public class TransformingBiMap implements BiMap { + private final BiMap delegate; + private final Function keyFwd; + private final Function keyBack; + private final Function valueFwd; + private final Function valueBack; + + public TransformingBiMap(BiMap map, Function keyFwd, Function keyBack, Function valueFwd, Function valueBack) { + this.delegate = map; + this.keyFwd = keyFwd; + this.keyBack = keyBack; + this.valueFwd = valueFwd; + this.valueBack = valueBack; + } + + private KFrom keyBack(KTo key) { + return key == null ? null : this.keyBack.apply(key); + } + + private KTo keyFwd(KFrom key) { + return key == null ? null : this.keyFwd.apply(key); + } + + private VFrom valueBack(VTo value) { + return value == null ? null : this.valueBack.apply(value); + } + + private VTo valueFwd(VFrom value) { + return value == null ? null : this.valueFwd.apply(value); + } + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return this.delegate.containsKey(keyBack((KTo)o)); + } + + @Override + public boolean containsValue(Object o) { + return false; + } + + @Override + public VTo get(Object o) { + return valueFwd(this.delegate.get(keyBack((KTo)o))); + } + + @Override + public VTo put(KTo key, VTo value) { + return valueFwd(this.delegate.put(keyBack(key), valueBack(value))); + } + + @Override + public VTo remove(Object o) { + return valueFwd(this.delegate.remove(keyBack((KTo)o))); + } + + @Override + public VTo forcePut(KTo key, VTo value) { + return valueFwd(this.delegate.forcePut(keyBack(key), valueBack(value))); + } + + @Override + public void putAll(Map map) { + map.forEach((key, value) -> { + this.delegate.put(keyBack(key), valueBack(value)); + }); + } + + @Override + public void clear() { + this.delegate.clear(); + } + + @NotNull + @Override + public Set keySet() { + return new TransformingSet<>(this.delegate.keySet(), this.keyFwd, this.keyBack); + } + + @Override + public Set values() { + return new TransformingSet<>(this.delegate.values(), this.valueFwd, this.valueBack); + } + + @NotNull + @Override + public Set> entrySet() { + return new TransformingSet<>(this.delegate.entrySet(), entry -> { + return new AbstractMap.SimpleImmutableEntry<>(keyFwd(entry.getKey()), valueFwd(entry.getValue())); + }, entry -> { + return new AbstractMap.SimpleImmutableEntry<>(keyBack(entry.getKey()), valueBack(entry.getValue())); + }); + } + + @Override + public BiMap inverse() { + return new TransformingBiMap<>(this.delegate.inverse(), this.valueFwd, this.valueBack, this.keyFwd, this.keyBack); + } + + static class TransformingSet implements Set { + private final Set delegate; + private final Function forward; + private final Function reverse; + + public TransformingSet(Set set, Function forward, Function reverse) { + this.delegate = set; + this.forward = forward; + this.reverse = reverse; + } + + private TypeTo forward(TypeFrom t) { + return t == null ? null : this.forward.apply(t); + } + + private TypeFrom reverse(TypeTo t) { + return t == null ? null : this.reverse.apply(t); + } + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return this.delegate.contains(reverse((TypeTo)o)); + } + + @NotNull + @Override + public Iterator iterator() { + return Iterators.transform(this.delegate.iterator(), this::forward); + } + + @NotNull + @Override + public Object[] toArray() { + Object[] array = this.delegate.toArray(); + for(int i = 0; i < array.length; i++) { + array[i] = this.forward((TypeFrom)array[i]); + } + return array; + } + + @NotNull + @Override + public T[] toArray(@NotNull T[] ts) { + if(ts.length >= this.delegate.size()) { + Object[] setContents = toArray(); + System.arraycopy(setContents, 0, ts, 0, Math.min(setContents.length, ts.length)); + if(ts.length > setContents.length) + ts[setContents.length] = null; + return ts; + } else { + T[] realArray = Arrays.copyOf(ts, this.delegate.size()); + Iterator iterator = this.iterator(); + int i = 0; + while(iterator.hasNext()) + realArray[i++] = (T)iterator.next(); + return realArray; + } + } + + @Override + public boolean add(TypeTo typeFrom) { + return this.delegate.add(reverse(typeFrom)); + } + + @Override + public boolean remove(Object o) { + return this.delegate.remove(reverse((TypeTo)o)); + } + + @Override + public boolean containsAll(@NotNull Collection collection) { + return this.delegate.containsAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj))); + } + + @Override + public boolean addAll(@NotNull Collection collection) { + return this.delegate.addAll(Collections2.transform(collection, this::reverse)); + } + + @Override + public boolean retainAll(@NotNull Collection collection) { + return this.delegate.retainAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj))); + } + + @Override + public boolean removeAll(@NotNull Collection collection) { + return this.delegate.removeAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj))); + } + + @Override + public void clear() { + this.delegate.clear(); + } + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java new file mode 100644 index 00000000..770efcf8 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java @@ -0,0 +1,20 @@ +package org.embeddedt.modernfix.fabric.api.dynresources; + +import net.minecraft.resources.ResourceLocation; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +public class ModelScanController { + public static final List> SCAN_PREDICATES = new ArrayList<>(); + public static boolean shouldScanAndTestWrapping(ResourceLocation location) { + if(SCAN_PREDICATES.size() > 0) { + for(Predicate predicate : SCAN_PREDICATES) { + if(!predicate.test(location)) + return false; + } + } + return true; + } +} diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index 2f707a79..228b8a61 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -2,6 +2,14 @@ apply plugin: "dev.architectury.loom" loom { accessWidenerPath = project(":common").loom.accessWidenerPath + runs { + client { + vmArgs "-Xmx8G" + property("modernfix.config.mixin.perf.blast_search_trees", "true") + property("modernfix.config.mixin.perf.dynamic_resources", "true") + property("modernfix.config.mixin.perf.dynamic_block_codecs", "true") + } + } } dependencies { @@ -18,6 +26,8 @@ dependencies { modImplementation(fabricApi.module("fabric-models-v0", "0.84.0+1.20.1")) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modImplementation(fabricApi.module("fabric-registry-sync-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modImplementation(fabricApi.module("fabric-renderer-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modRuntimeOnly(fabricApi.module("fabric-renderer-indigo", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } implementation project(path: ":common", configuration: "namedElements") diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java index 89f9d5eb..81ef4c3d 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java @@ -17,7 +17,7 @@ public class TestMod implements ModInitializer { public static final String ID = "mfix_testmod"; public static final Logger LOGGER = LogManager.getLogger("ModernFix TestMod"); - public static final int NUM_COLORS = 100; + public static final int NUM_COLORS = 32; public static final int MAX_COLOR = NUM_COLORS - 1; public static final List WOOL_STATES = new ArrayList<>(); @@ -35,7 +35,7 @@ public class TestMod implements ModInitializer { ResourceLocation name = new ResourceLocation(ID, "wool_" + r + "_" + g + "_" + b); TestBlock block = Registry.register(BuiltInRegistries.BLOCK, name, new TestBlock()); WOOL_STATES.add(block.defaultBlockState()); - Registry.register(BuiltInRegistries.ITEM, name, new TestBlockItem(block)); + //Registry.register(BuiltInRegistries.ITEM, name, new TestBlockItem(block)); numRegistered++; if((numRegistered % progressReport) == 0) { LOGGER.info(String.format("Registering... %.02f%%", ((float)numRegistered)/totalToRegister * 100)); @@ -50,11 +50,14 @@ public class TestMod implements ModInitializer { private static final BlockState AIR = Blocks.AIR.defaultBlockState(); public static BlockState getColorCubeStateFor(int chunkX, int chunkY, int chunkZ) { - BlockState blockState = AIR; - if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0 && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) { + BlockState blockState = null; + if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0) { // && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) { + /* chunkX /= 2; chunkY /= 2; chunkZ /= 2; + + */ if(chunkX <= TestMod.MAX_COLOR && chunkY <= TestMod.MAX_COLOR && chunkZ <= TestMod.MAX_COLOR) { blockState = TestMod.WOOL_STATES.get((chunkX * TestMod.NUM_COLORS * TestMod.NUM_COLORS) + (chunkY * TestMod.NUM_COLORS) + chunkZ); } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java index 24f9dbb9..7f82a508 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java @@ -2,7 +2,7 @@ package org.embeddedt.modernfix.testmod.client; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; -import net.minecraft.client.Minecraft; +import org.embeddedt.modernfix.fabric.api.dynresources.ModelScanController; import org.embeddedt.modernfix.testmod.TestMod; import java.util.regex.Matcher; @@ -12,6 +12,7 @@ public class TestModClient implements ClientModInitializer { private static final Pattern RGB_PATTERN = Pattern.compile("^wool_([0-9]+)_([0-9]+)_([0-9]+)$"); @Override public void onInitializeClient() { + ModelScanController.SCAN_PREDICATES.add(rl -> !rl.getNamespace().equals(TestMod.ID)); ModelLoadingRegistry.INSTANCE.registerVariantProvider(resourceManager -> (modelId, context) -> { if(modelId.getNamespace().equals(TestMod.ID)) { Matcher matcher = RGB_PATTERN.matcher(modelId.getPath()); @@ -24,7 +25,5 @@ public class TestModClient implements ClientModInitializer { } return null; }); - // needed to make debug level rendering work correctly - Minecraft.getInstance().smartCull = false; } } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java index 1356aece..142faf51 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java @@ -1,25 +1,21 @@ package org.embeddedt.modernfix.testmod.mixin; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import org.embeddedt.modernfix.testmod.TestMod; -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.callback.CallbackInfoReturnable; @Mixin(LevelChunk.class) public class ChunkMixin { - @Shadow @Final private Level level; - @Inject(method = "getBlockState", at = @At("HEAD"), cancellable = true) private void redirectDebugWorld(BlockPos pos, CallbackInfoReturnable cir) { - if(this.level.isDebug()) { - cir.setReturnValue(TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ())); + BlockState overrideState = TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ()); + if(overrideState != null) { + cir.setReturnValue(overrideState); } } } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java index d37d0480..46f52d31 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java @@ -5,20 +5,22 @@ import net.minecraft.core.SectionPos; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.levelgen.DebugLevelSource; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.FlatLevelSource; import org.embeddedt.modernfix.testmod.TestMod; 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(DebugLevelSource.class) -public class DebugLevelSourceMixin { - @Inject(method = "applyBiomeDecoration", at = @At("HEAD"), cancellable = true) - private void showColorCube(WorldGenLevel level, ChunkAccess chunk, StructureManager structureFeatureManager, CallbackInfo ci) { - ci.cancel(); +@Mixin(FlatLevelSource.class) +public abstract class DebugLevelSourceMixin extends ChunkGenerator { + public DebugLevelSourceMixin(BiomeSource biomeSource) { + super(biomeSource); + } + + @Override + public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureFeatureManager) { BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); ChunkPos chunkPos = chunk.getPos(); int i = chunkPos.x; diff --git a/forge/build.gradle b/forge/build.gradle index dffacfb1..b85c3218 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -27,6 +27,22 @@ configurations { runtimeClasspath.extendsFrom common } +def extraModsDir = "extra-mods" + +repositories { + exclusiveContent { + forRepository { + flatDir { + name "extra-mods" + dir file(extraModsDir) + } + } + filter { + includeGroup "extra-mods" + } + } +} + dependencies { forge "net.minecraftforge:forge:${rootProject.forge_version}" // Remove the next line if you don't want to depend on the API @@ -45,6 +61,16 @@ dependencies { modCompileOnly("curse.maven:blueprint-382216:3991478") + // runtime remapping at home + for (extraModJar in fileTree(dir: extraModsDir, include: '*.jar')) { + def basename = extraModJar.name.substring(0, extraModJar.name.length() - ".jar".length()) + def versionSep = basename.lastIndexOf('-') + assert versionSep != -1 + def artifactId = basename.substring(0, versionSep) + def version = basename.substring(versionSep + 1) + modRuntimeOnly("extra-mods:$artifactId:$version") + } + common(project(path: ":common", configuration: "namedElements")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } } diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java index f412dae2..9a9d5dd5 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java @@ -7,6 +7,7 @@ import net.minecraft.network.chat.Component; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.ModernFixClient; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.util.CommonModUtil; @@ -16,11 +17,11 @@ import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; import java.util.function.Function; public class NightConfigFixer { public static final LinkedHashSet configsToReload = new LinkedHashSet<>(); + public static void monitorFileWatcher() { if(!ModernFixMixinPlugin.instance.isOptionEnabled("bugfix.fix_config_crashes.NightConfigFixerMixin")) return; @@ -49,6 +50,7 @@ public class NightConfigFixer { } } ModernFix.LOGGER.info("Processed {} config reloads", runnablesToRun.size()); + couldShowMessage = true; } static class MonitoringMap extends ConcurrentHashMap { @@ -74,13 +76,13 @@ public class NightConfigFixer { } } - private static long lastConfigTrigger = System.nanoTime(); + private static boolean couldShowMessage = true; private static void triggerConfigMessage() { - if((System.nanoTime() - lastConfigTrigger) >= TimeUnit.SECONDS.toNanos(5)) { - lastConfigTrigger = System.nanoTime(); + if(couldShowMessage && Minecraft.getInstance().level != null && ModernFixClient.recipesUpdated && ModernFixClient.tagsUpdated) { Minecraft.getInstance().execute(() -> { if(Minecraft.getInstance().level != null) { + couldShowMessage = false; Minecraft.getInstance().gui.getChat().addMessage(Component.translatable("modernfix.message.reload_config")); } }); @@ -102,8 +104,9 @@ public class NightConfigFixer { synchronized(configsToReload) { if(FMLLoader.getDist().isClient()) triggerConfigMessage(); - if(configsToReload.size() == 0) + if(configsToReload.size() == 0) { ModernFixMixinPlugin.instance.logger.info("Please use /{} to reload any changed mod config files", FMLLoader.getDist().isDedicatedServer() ? "mfsrc" : "mfrc"); + } configsToReload.add(configTracker); } }