Skip to content

Commit 31feef3

Browse files
committed
Merge remote-tracking branch 'origin/1.19.2' into 1.19.4
2 parents 4cccd8f + 49a8f72 commit 31feef3

File tree

26 files changed

+351
-167
lines changed

26 files changed

+351
-167
lines changed

common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import net.minecraft.server.MinecraftServer;
1212
import net.minecraft.util.MemoryReserve;
1313
import net.minecraft.world.entity.Entity;
14+
import org.embeddedt.modernfix.api.constants.IntegrationConstants;
15+
import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
1416
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
1517
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
1618
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
@@ -22,6 +24,7 @@
2224
import java.lang.management.ManagementFactory;
2325
import java.lang.reflect.Field;
2426
import java.util.*;
27+
import java.util.concurrent.CopyOnWriteArrayList;
2528

2629
public class ModernFixClient {
2730
public static long worldLoadStartTime;
@@ -33,6 +36,11 @@ public class ModernFixClient {
3336

3437
public String brandingString = null;
3538

39+
/**
40+
* The list of loaded client integrations.
41+
*/
42+
public static List<ModernFixClientIntegration> CLIENT_INTEGRATIONS = new CopyOnWriteArrayList<>();
43+
3644
public ModernFixClient() {
3745
// clear reserve as it's not needed
3846
MemoryReserve.release();
@@ -41,6 +49,13 @@ public ModernFixClient() {
4149
}
4250
SearchTreeProviderRegistry.register(JEIBackedSearchTree.PROVIDER);
4351
SearchTreeProviderRegistry.register(REIBackedSearchTree.PROVIDER);
52+
for(String className : ModernFixPlatformHooks.getCustomModOptions().get(IntegrationConstants.CLIENT_INTEGRATION_CLASS)) {
53+
try {
54+
CLIENT_INTEGRATIONS.add((ModernFixClientIntegration)Class.forName(className).getDeclaredConstructor().newInstance());
55+
} catch(ReflectiveOperationException | ClassCastException e) {
56+
ModernFix.LOGGER.error("Could not instantiate integration {}", className, e);
57+
}
58+
}
4459
}
4560

4661
public void resetWorldLoadStateMachine() {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.embeddedt.modernfix.api.constants;
2+
3+
public class IntegrationConstants {
4+
public static final String INTEGRATIONS_KEY = "modernfix:integration";
5+
6+
public static final String CLIENT_INTEGRATION_CLASS = "client_entrypoint";
7+
public static final String INTEGRATION_CLASS = "entrypoint";
8+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.embeddedt.modernfix.api.entrypoint;
2+
3+
import net.minecraft.client.resources.model.BakedModel;
4+
import net.minecraft.client.resources.model.ModelBakery;
5+
import net.minecraft.client.resources.model.ModelState;
6+
import net.minecraft.client.resources.model.UnbakedModel;
7+
import net.minecraft.resources.ResourceLocation;
8+
9+
10+
/**
11+
* Implement this interface in a mod class and add it to "modernfix:integration_v1" in your mod metadata file
12+
* to integrate with ModernFix's features.
13+
*/
14+
public interface ModernFixClientIntegration {
15+
/**
16+
* Called when the dynamic resources status has changed during a model reload so mods know whether to run their
17+
* normal codepath or the dynamic version.
18+
*
19+
* @param enabled whether dynamic resources is enabled
20+
*/
21+
default void onDynamicResourcesStatusChange(boolean enabled) {
22+
}
23+
24+
/**
25+
* Called to allow mods to observe the loading of an unbaked model and either make changes to it or wrap it with their
26+
* own instance.
27+
* @param location the ResourceLocation of the model (this may be a ModelResourceLocation)
28+
* @param originalModel the original model
29+
* @param bakery the model bakery - do not touch internal fields as they probably don't behave the way you expect
30+
* with dynamic resources on
31+
* @return the model which should actually be loaded for this resource location
32+
*/
33+
default UnbakedModel onUnbakedModelLoad(ResourceLocation location, UnbakedModel originalModel, ModelBakery bakery) {
34+
return originalModel;
35+
}
36+
37+
/**
38+
* Called to allow mods to observe the loading of a baked model and either make changes to it or wrap it with their
39+
* own instance.
40+
* @param location the ResourceLocation of the model (this may be a ModelResourceLocation)
41+
* @param originalModel the original model
42+
* @param bakery the model bakery - do not touch internal fields as they probably don't behave the way you expect
43+
* with dynamic resources on
44+
* @return the model which should actually be loaded for this resource location
45+
*/
46+
default BakedModel onBakedModelLoad(ResourceLocation location, UnbakedModel baseModel, BakedModel originalModel, ModelState state, ModelBakery bakery) {
47+
return originalModel;
48+
}
49+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.embeddedt.modernfix.api.helpers;
2+
3+
import com.google.common.collect.ImmutableList;
4+
import net.minecraft.client.resources.model.*;
5+
import net.minecraft.core.registries.BuiltInRegistries;
6+
import net.minecraft.resources.ResourceLocation;
7+
import net.minecraft.world.level.block.Block;
8+
import net.minecraft.world.level.block.state.BlockState;
9+
import net.minecraft.world.level.block.state.StateDefinition;
10+
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
11+
import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers;
12+
import org.embeddedt.modernfix.util.DynamicMap;
13+
import org.jetbrains.annotations.Nullable;
14+
15+
import java.util.Map;
16+
import java.util.Optional;
17+
import java.util.function.BiFunction;
18+
19+
@SuppressWarnings("unused")
20+
public final class ModelHelpers {
21+
/**
22+
* Allows converting a ModelResourceLocation back into the corresponding BlockState(s). Try to avoid calling this
23+
* multiple times if possible.
24+
* @param location the location of the model
25+
* @return a list of all blockstates related to the model
26+
*/
27+
public static ImmutableList<BlockState> getBlockStateForLocation(ModelResourceLocation location) {
28+
Optional<Block> blockOpt = BuiltInRegistries.BLOCK.getOptional(new ResourceLocation(location.getNamespace(), location.getPath()));
29+
if(blockOpt.isPresent())
30+
return ModelBakeryHelpers.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), location);
31+
else
32+
return ImmutableList.of();
33+
}
34+
35+
/**
36+
* Allows converting a ModelResourceLocation back into the corresponding BlockState(s). Faster version of its
37+
* companion function if and only if you know the corresponding Block already for some reason.
38+
* @param definition the state definition for the Block
39+
* @param location the location of the model
40+
* @return a list of all blockstates related to the model
41+
*/
42+
public static ImmutableList<BlockState> getBlockStateForLocation(StateDefinition<Block, BlockState> definition, ModelResourceLocation location) {
43+
return ModelBakeryHelpers.getBlockStatesForMRL(definition, location);
44+
}
45+
46+
/**
47+
* Compatibility helper for mods to use to get a map-like view of the model bakery.
48+
* @param modelGetter the model getter function supplied by the integration class
49+
* @return a fake map of the top-level models
50+
*/
51+
public static Map<ResourceLocation, BakedModel> createFakeTopLevelMap(BiFunction<ResourceLocation, ModelState, BakedModel> modelGetter) {
52+
return new DynamicMap<>(location -> modelGetter.apply(location, BlockModelRotation.X0_Y0));
53+
}
54+
55+
/**
56+
* Provides a ModelBaker for mods to use.
57+
* @param bakery the ModelBakery supplied to your integration
58+
* @return an appropriate ModelBaker
59+
*/
60+
public static ModelBaker adaptBakery(ModelBakery bakery) {
61+
return new ModelBaker() {
62+
@Override
63+
public UnbakedModel getModel(ResourceLocation resourceLocation) {
64+
return bakery.getModel(resourceLocation);
65+
}
66+
67+
@Nullable
68+
@Override
69+
public BakedModel bake(ResourceLocation resourceLocation, ModelState modelState) {
70+
return ((IExtendedModelBakery)bakery).bakeDefault(resourceLocation, modelState);
71+
}
72+
};
73+
}
74+
}

common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.embeddedt.modernfix.common.mixin.perf.blast_search_trees;
22

3+
import net.minecraft.client.KeyMapping;
34
import net.minecraft.client.Minecraft;
45
import net.minecraft.client.searchtree.SearchRegistry;
56
import net.minecraft.world.item.ItemStack;
@@ -8,6 +9,8 @@
89
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
910
import org.embeddedt.modernfix.searchtree.DummySearchTree;
1011
import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry;
12+
import org.lwjgl.glfw.GLFW;
13+
import org.lwjgl.glfw.GLFWErrorCallback;
1114
import org.spongepowered.asm.mixin.Final;
1215
import org.spongepowered.asm.mixin.Mixin;
1316
import org.spongepowered.asm.mixin.Shadow;
@@ -36,6 +39,14 @@ private void replaceSearchTrees(CallbackInfo ci) {
3639
this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, tagSupplier);
3740
this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>());
3841
ModernFixPlatformHooks.registerCreativeSearchTrees(this.searchRegistry, nameSupplier, tagSupplier, this::populateSearchTree);
42+
// grab components for all key mappings in order to prevent them from being loaded off-thread later
43+
// this populates the LazyLoadedValues
44+
// we also need to suppress GLFW errors to prevent crashes if a key is missing
45+
GLFWErrorCallback oldCb = GLFW.glfwSetErrorCallback(null);
46+
for(KeyMapping mapping : KeyMapping.ALL.values()) {
47+
mapping.getTranslatedKeyMessage();
48+
}
49+
GLFW.glfwSetErrorCallback(oldCb);
3950
ci.cancel();
4051
}
4152
}

common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
2020
public static ModernFixMixinPlugin instance;
2121

2222
public ModernFixMixinPlugin() {
23+
/* invoke early to ensure it gets read on one thread */
24+
ModernFixPlatformHooks.getCustomModOptions();
2325
boolean firstConfig = instance == null;
2426
if(firstConfig) {
2527
instance = this;

common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ private ModernFixEarlyConfig(File file) {
183183
disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me");
184184
disableIfModPresent("mixin.perf.reuse_datapacks", "tac");
185185
disableIfModPresent("mixin.launch.class_search_cache", "optifine");
186+
disableIfModPresent("mixin.perf.faster_texture_stitching", "optifine");
186187
disableIfModPresent("mixin.perf.datapack_reload_exceptions", "cyanide");
187-
disableIfModPresent("mixin.perf.faster_texture_loading", "stitch");
188+
disableIfModPresent("mixin.perf.faster_texture_loading", "stitch", "optifine");
188189
}
189190

190191
private void disableIfModPresent(String configName, String... ids) {

common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.google.common.collect.ImmutableList;
44
import net.minecraft.client.resources.model.BakedModel;
55
import net.minecraft.client.resources.model.ModelResourceLocation;
6+
import net.minecraft.client.resources.model.ModelState;
67
import net.minecraft.client.resources.model.UnbakedModel;
78
import net.minecraft.resources.ResourceLocation;
89
import net.minecraft.world.level.block.Block;
@@ -11,7 +12,7 @@
1112

1213
public interface IExtendedModelBakery {
1314
ImmutableList<BlockState> getBlockStatesForMRL(StateDefinition<Block, BlockState> stateDefinition, ModelResourceLocation location);
14-
BakedModel bakeDefault(ResourceLocation modelLocation);
15+
BakedModel bakeDefault(ResourceLocation modelLocation, ModelState state);
1516
BakedModel getBakedMissingModel();
1617
void setBakedMissingModel(BakedModel m);
1718
UnbakedModel mfix$getUnbakedMissingModel();

common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import net.minecraft.world.level.block.state.BlockState;
1616
import org.apache.commons.lang3.tuple.Triple;
1717
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
18+
import org.embeddedt.modernfix.ModernFix;
1819
import org.jetbrains.annotations.NotNull;
1920
import org.jetbrains.annotations.Nullable;
2021

@@ -109,7 +110,12 @@ public BakedModel get(Object o) {
109110
if(model != SENTINEL)
110111
return model;
111112
else {
112-
model = ((IExtendedModelBakery)bakery).bakeDefault((ResourceLocation)o);
113+
try {
114+
model = ((IExtendedModelBakery)bakery).bakeDefault((ResourceLocation)o, BlockModelRotation.X0_Y0);
115+
} catch(RuntimeException e) {
116+
ModernFix.LOGGER.error("Exception baking {}: {}", o, e);
117+
model = missingModel;
118+
}
113119
if(model == missingModel) {
114120
// to correctly emulate the original map, we return null for missing models
115121
permanentOverrides.put((ResourceLocation) o, null);

common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package org.embeddedt.modernfix.platform;
22

3-
import dev.architectury.injectables.annotations.ExpectPlatform;
3+
import com.google.common.collect.Multimap;
44
import com.mojang.brigadier.CommandDispatcher;
5+
import dev.architectury.injectables.annotations.ExpectPlatform;
56
import net.minecraft.client.searchtree.SearchRegistry;
67
import net.minecraft.commands.CommandSourceStack;
78
import net.minecraft.server.MinecraftServer;
@@ -75,6 +76,11 @@ public static void onServerCommandRegister(Consumer<CommandDispatcher<CommandSou
7576
throw new AssertionError();
7677
}
7778

79+
@ExpectPlatform
80+
public static Multimap<String, String> getCustomModOptions() {
81+
throw new AssertionError();
82+
}
83+
7884
@ExpectPlatform
7985
public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier<ItemStack> nameSupplier, SearchRegistry.TreeBuilderSupplier<ItemStack> tagSupplier, BiConsumer<SearchRegistry.Key<ItemStack>, List<ItemStack>> populator) {
8086
throw new AssertionError();

0 commit comments

Comments
 (0)