Skip to content

Commit 6279f88

Browse files
authored
Fix datagen sometimes crashing because of concurrent keybind registration (#4771)
1 parent 53a2aea commit 6279f88

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

src/main/java/com/gregtechceu/gtceu/core/mixins/GTMixinPlugin.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ public String getRefMapperConfig() {
2626
private static final String MIXIN_PACKAGE = "com.gregtechceu.gtceu.core.mixins.";
2727
private static final Map<String, String> MOD_COMPAT_MIXINS = new HashMap<>();
2828

29-
private static final String DEV_PACKAGE = MIXIN_PACKAGE + "dev.";
29+
private static final String DEV_PACKAGE = "dev.";
30+
private static final String DATAGEN_PACKAGE = "datagen.";
3031

3132
static {
32-
MOD_COMPAT_MIXINS.put("roughlyenoughitems", MIXIN_PACKAGE + "rei");
33+
MOD_COMPAT_MIXINS.put("roughlyenoughitems", "rei.");
3334
addModCompatMixin("emi");
3435
addModCompatMixin("jei");
3536
addModCompatMixin("top");
@@ -40,8 +41,24 @@ public String getRefMapperConfig() {
4041

4142
@Override
4243
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
44+
if (!mixinClassName.startsWith(MIXIN_PACKAGE)) {
45+
// skip checking mixins that aren't in our package
46+
// this should never happen, but better safe than sorry
47+
return true;
48+
}
49+
mixinClassName = mixinClassName.substring(MIXIN_PACKAGE.length());
50+
4351
if (mixinClassName.startsWith(DEV_PACKAGE)) {
44-
return !FMLLoader.isProduction();
52+
if (FMLLoader.isProduction()) {
53+
// don't load dev-only mixins in prod
54+
return false;
55+
}
56+
mixinClassName = mixinClassName.substring(DEV_PACKAGE.length());
57+
if (mixinClassName.startsWith(DATAGEN_PACKAGE)) {
58+
// only load datagen mixins in datagen
59+
return FMLLoader.getLaunchHandler().isData();
60+
}
61+
return true;
4562
}
4663
for (var compatMod : MOD_COMPAT_MIXINS.entrySet()) {
4764
if (mixinClassName.startsWith(compatMod.getValue())) {
@@ -66,7 +83,7 @@ public void preApply(String targetClassName, ClassNode targetClass, String mixin
6683
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
6784

6885
private static void addModCompatMixin(String modId) {
69-
MOD_COMPAT_MIXINS.put(modId, MIXIN_PACKAGE + modId);
86+
MOD_COMPAT_MIXINS.put(modId, modId + ".");
7087
}
7188

7289
private static boolean isModLoaded(String modId) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.gregtechceu.gtceu.core.mixins.dev.datagen;
2+
3+
import net.minecraft.client.KeyMapping;
4+
import net.minecraftforge.client.settings.KeyMappingLookup;
5+
6+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
7+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
8+
import com.mojang.blaze3d.platform.InputConstants;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.injection.At;
11+
12+
import java.util.EnumMap;
13+
import java.util.List;
14+
import java.util.concurrent.ConcurrentHashMap;
15+
16+
/**
17+
* This mixin is only loaded in datagen contexts
18+
*/
19+
@Mixin(value = KeyMappingLookup.class, remap = false)
20+
public class FixParallelKeyMappingRegistrationMixin {
21+
22+
/**
23+
* @author screret
24+
* @reason Fix keybind registration in datagen.<br>
25+
* <p>
26+
* The map isn't thread safe and some mods register their keybinds in places they probably shouldn't.<br>
27+
* (IDK why it only crashes in datagen, though)
28+
*/
29+
@WrapOperation(method = "<clinit>",
30+
at = @At(value = "INVOKE",
31+
target = "Ljava/util/EnumMap;put(Ljava/lang/Enum;Ljava/lang/Object;)Ljava/lang/Object;"))
32+
private static <K extends Enum<K>, V> V gtceu$makeKeyMappingMapsConcurrent(EnumMap<K, V> instance, K key, V value,
33+
Operation<V> original) {
34+
// replace `value`, which is a non-threadsafe HashMap, with a ConcurrentHashMap
35+
return original.call(instance, key, new ConcurrentHashMap<InputConstants.Key, List<KeyMapping>>());
36+
}
37+
}

src/main/resources/gtceu.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"TagManagerMixin",
6464
"TagValueAccessor",
6565
"client.ItemEntityMixin",
66+
"dev.datagen.FixParallelKeyMappingRegistrationMixin",
6667
"dev.test.GameTestRegistryMixin",
6768
"emi.EmiRecipeFillerMixin",
6869
"emi.FillRecipePacketMixin",

0 commit comments

Comments
 (0)