Skip to content

Commit

Permalink
Don't blame us forge!
Browse files Browse the repository at this point in the history
- Abort loading of mixins if mod loading exceptions are present
  • Loading branch information
IThundxr committed Oct 31, 2024
1 parent 0a7cc00 commit 8787712
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,66 @@

package com.railwayteam.railways.util;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.jetbrains.annotations.Nullable;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.concurrent.ExecutionException;

@SuppressWarnings("unchecked")
public class MethodVarHandleUtils {
private static final Cache<VarHandleInfo, VarHandle> varHandleCache = CacheBuilder.newBuilder().build();

private static final MethodHandles.Lookup lookup = MethodHandles.lookup();

public static <T> T getStaticField(Class<?> clazz, String fieldName, Class<T> type) throws NoSuchFieldException, IllegalAccessException {
return (T) lookup.findStaticVarHandle(clazz, fieldName, type).get();
T value = null;

try {
value = (T) varHandleCache.get(
new VarHandleInfo(clazz, fieldName, type),
() -> lookup.findStaticVarHandle(clazz, fieldName, type)
).get();
} catch (ExecutionException ignored) {}

return value;
}

public static <T> T getStaticField(Class<?> clazz, String fieldName, Class<T> type, T defaultValue) {
T returnValue = defaultValue;

try {
returnValue = getStaticField(clazz, fieldName, type);
} catch (NoSuchFieldException | IllegalAccessException ignored) {}

return returnValue;
}

public static <T, U> T getPrivateField(U instance, Class<U> clazz, String fieldName, Class<T> type, T defaultValue) {
T returnValue = defaultValue;

VarHandle handle = findPrivateFieldVarHandle(new VarHandleInfo(clazz, fieldName, type));
if (handle != null) {
returnValue = (T) handle.get(instance);
}

return returnValue;
}

@Nullable
public static VarHandle findPrivateFieldVarHandle(VarHandleInfo info) {
try {
return varHandleCache.get(info, () -> {
MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(info.clazz(), lookup);
return privateLookup.findVarHandle(info.clazz(), info.fieldName(), info.type());
});
} catch (ExecutionException ignored) {
return null;
}
}

public record VarHandleInfo(Class<?> clazz, String fieldName, Class<?> type) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import com.railwayteam.railways.forge.asm.ContainerLevelAccessASM;
import com.railwayteam.railways.forge.asm.RollingModeEnumAdder;
import com.railwayteam.railways.util.ConditionalMixinManager;
import com.railwayteam.railways.util.MethodVarHandleUtils;
import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.ModLoadingException;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
Expand All @@ -37,6 +40,16 @@ public void onLoad(String mixinPackage) { } // NO-OP

@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
//noinspection unchecked
Class<List<ModLoadingException>> modLoadingExceptionListClass = (Class<List<ModLoadingException>>)(Class<?>) List.class;

List<ModLoadingException> modLoadingExceptionList = MethodVarHandleUtils.getPrivateField(
ModLoader.get(), ModLoader.class, "loadingExceptions", modLoadingExceptionListClass, null);

if (!modLoadingExceptionList.isEmpty()) {
return false;
}

return ConditionalMixinManager.shouldApply(mixinClassName);
}

Expand Down

0 comments on commit 8787712

Please sign in to comment.