Merge remote-tracking branch 'origin/1.19.2' into 1.20
This commit is contained in:
commit
0ea384f3e6
|
|
@ -1,5 +1,10 @@
|
||||||
package org.embeddedt.modernfix.forge.classloading;
|
package org.embeddedt.modernfix.forge.classloading;
|
||||||
|
|
||||||
|
import cpw.mods.jarhandling.SecureJar;
|
||||||
|
import cpw.mods.modlauncher.LaunchPluginHandler;
|
||||||
|
import cpw.mods.modlauncher.Launcher;
|
||||||
|
import cpw.mods.modlauncher.api.NamedPath;
|
||||||
|
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||||
import net.minecraftforge.fml.loading.moddiscovery.ModValidator;
|
import net.minecraftforge.fml.loading.moddiscovery.ModValidator;
|
||||||
|
|
@ -7,9 +12,15 @@ import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||||
import org.embeddedt.modernfix.util.CommonModUtil;
|
import org.embeddedt.modernfix.util.CommonModUtil;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ATInjector {
|
public class ATInjector {
|
||||||
|
|
@ -31,6 +42,80 @@ public class ATInjector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inject into Launcher.INSTANCE.launchPlugins and wrap the mixin plugin, so that mixin transformations
|
||||||
|
// are not applied
|
||||||
|
try {
|
||||||
|
Launcher launcher = Launcher.INSTANCE;
|
||||||
|
Field launchPlugins = Launcher.class.getDeclaredField("launchPlugins");
|
||||||
|
launchPlugins.setAccessible(true);
|
||||||
|
|
||||||
|
LaunchPluginHandler handler = (LaunchPluginHandler) launchPlugins.get(launcher);
|
||||||
|
Field plugins = LaunchPluginHandler.class.getDeclaredField("plugins");
|
||||||
|
plugins.setAccessible(true);
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
Map<String, ILaunchPluginService> map = (Map<String, ILaunchPluginService>) plugins.get(handler);
|
||||||
|
Map<String, ILaunchPluginService> newMap = new HashMap<>(map);
|
||||||
|
NonTransformingLaunchPluginService.class.getName(); // trigger classloading, just to be safe
|
||||||
|
newMap.replaceAll((name, plugin) -> {
|
||||||
|
if(plugin.getClass().getName().startsWith("org.spongepowered.asm.launch.MixinLaunchPlugin")) {
|
||||||
|
ModernFixMixinPlugin.instance.logger.warn("Disabling plugin '{}': {}", name, plugin.getClass().getName());
|
||||||
|
return new NonTransformingLaunchPluginService(plugin);
|
||||||
|
} else {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
plugins.set(handler, newMap);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}, "applying mod ATs in errored state");
|
}, "applying mod ATs in errored state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class NonTransformingLaunchPluginService implements ILaunchPluginService {
|
||||||
|
|
||||||
|
private final ILaunchPluginService delegate;
|
||||||
|
|
||||||
|
NonTransformingLaunchPluginService(ILaunchPluginService delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return delegate.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final EnumSet<Phase> NEVER = EnumSet.noneOf(Phase.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
|
||||||
|
return NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void offerResource(Path resource, String name) {
|
||||||
|
delegate.offerResource(resource, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResources(List<SecureJar> resources) {
|
||||||
|
delegate.addResources(resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeLaunch(ITransformerLoader transformerLoader, NamedPath[] specialPaths) {
|
||||||
|
delegate.initializeLaunch(transformerLoader, specialPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T getExtension() {
|
||||||
|
return delegate.getExtension();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customAuditConsumer(String className, Consumer<String[]> auditDataAcceptor) {
|
||||||
|
delegate.customAuditConsumer(className, auditDataAcceptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import org.embeddedt.modernfix.util.ForwardingInclDefaultsMap;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a list of all known default block/item models in the game, and provides a namespaced version
|
* Stores a list of all known default block/item models in the game, and provides a namespaced version
|
||||||
|
|
@ -28,7 +29,12 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
public class ModelBakeEventHelper {
|
public class ModelBakeEventHelper {
|
||||||
// TODO: make into config option
|
// TODO: make into config option
|
||||||
private static final Set<String> INCOMPATIBLE_MODS = ImmutableSet.of("industrialforegoing", "vampirism", "elevatorid", "embers");
|
private static final Set<String> INCOMPATIBLE_MODS = ImmutableSet.of(
|
||||||
|
"industrialforegoing",
|
||||||
|
"mekanism",
|
||||||
|
"vampirism",
|
||||||
|
"elevatorid",
|
||||||
|
"embers");
|
||||||
private final Map<ResourceLocation, BakedModel> modelRegistry;
|
private final Map<ResourceLocation, BakedModel> modelRegistry;
|
||||||
private final Set<ResourceLocation> topLevelModelLocations;
|
private final Set<ResourceLocation> topLevelModelLocations;
|
||||||
private final MutableGraph<String> dependencyGraph;
|
private final MutableGraph<String> dependencyGraph;
|
||||||
|
|
@ -79,7 +85,7 @@ public class ModelBakeEventHelper {
|
||||||
private void logWarning() {
|
private void logWarning() {
|
||||||
if(!WARNED_MOD_IDS.add(modId))
|
if(!WARNED_MOD_IDS.add(modId))
|
||||||
return;
|
return;
|
||||||
ModernFix.LOGGER.warn("Mod '{}' is accessing Map#keySet/entrySet/values on the model registry map inside its event handler." +
|
ModernFix.LOGGER.warn("Mod '{}' is accessing Map#keySet/entrySet/values/replaceAll on the model registry map inside its event handler." +
|
||||||
" This probably won't work as expected with dynamic resources on. Prefer using Map#get/put and constructing ModelResourceLocations another way.", modId);
|
" This probably won't work as expected with dynamic resources on. Prefer using Map#get/put and constructing ModelResourceLocations another way.", modId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,6 +106,12 @@ public class ModelBakeEventHelper {
|
||||||
logWarning();
|
logWarning();
|
||||||
return super.values();
|
return super.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceAll(BiFunction<? super ResourceLocation, ? super BakedModel, ? extends BakedModel> function) {
|
||||||
|
logWarning();
|
||||||
|
super.replaceAll(function);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,6 +151,19 @@ public class ModelBakeEventHelper {
|
||||||
public boolean containsKey(@Nullable Object key) {
|
public boolean containsKey(@Nullable Object key) {
|
||||||
return ourModelLocations.contains(key) || super.containsKey(key);
|
return ourModelLocations.contains(key) || super.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceAll(BiFunction<? super ResourceLocation, ? super BakedModel, ? extends BakedModel> function) {
|
||||||
|
ModernFix.LOGGER.warn("Mod '{}' is calling replaceAll on the model registry. This requires temporarily loading every model for that mod, which is slow.", modId);
|
||||||
|
List<ResourceLocation> locations = new ArrayList<>(keySet());
|
||||||
|
for(ResourceLocation location : locations) {
|
||||||
|
BakedModel existing = get(location);
|
||||||
|
BakedModel replacement = function.apply(location, existing);
|
||||||
|
if(replacement != existing) {
|
||||||
|
put(location, replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources;
|
package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources;
|
||||||
|
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.client.ForgeHooksClient;
|
import net.minecraftforge.client.ForgeHooksClient;
|
||||||
|
|
@ -9,6 +10,7 @@ import net.minecraftforge.fml.ModContainer;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
import net.minecraftforge.fml.ModLoader;
|
import net.minecraftforge.fml.ModLoader;
|
||||||
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
import org.embeddedt.modernfix.forge.dynresources.ModelBakeEventHelper;
|
import org.embeddedt.modernfix.forge.dynresources.ModelBakeEventHelper;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
@ -16,6 +18,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Mixin(ForgeHooksClient.class)
|
@Mixin(ForgeHooksClient.class)
|
||||||
public class ForgeHooksClientMixin {
|
public class ForgeHooksClientMixin {
|
||||||
|
|
@ -32,11 +35,16 @@ public class ForgeHooksClientMixin {
|
||||||
ModList.get().forEachModContainer((id, mc) -> {
|
ModList.get().forEachModContainer((id, mc) -> {
|
||||||
Map<ResourceLocation, BakedModel> newRegistry = helper.wrapRegistry(id);
|
Map<ResourceLocation, BakedModel> newRegistry = helper.wrapRegistry(id);
|
||||||
ModelEvent.ModifyBakingResult postedEvent = new ModelEvent.ModifyBakingResult(newRegistry, bakeEvent.getModelBakery());
|
ModelEvent.ModifyBakingResult postedEvent = new ModelEvent.ModifyBakingResult(newRegistry, bakeEvent.getModelBakery());
|
||||||
|
Stopwatch timer = Stopwatch.createStarted();
|
||||||
try {
|
try {
|
||||||
acceptEv.invoke(mc, postedEvent);
|
acceptEv.invoke(mc, postedEvent);
|
||||||
} catch(ReflectiveOperationException e) {
|
} catch(ReflectiveOperationException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
timer.stop();
|
||||||
|
if(timer.elapsed(TimeUnit.SECONDS) >= 1) {
|
||||||
|
ModernFix.LOGGER.warn("Mod '{}' took {} in the model bake event", id, timer);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user