Skip to content

Commit

Permalink
Fix classloading order issue (#51)
Browse files Browse the repository at this point in the history
Apotheosis dramatically changed the classloading order, thus when ArclightConstants is load before TicketType, TicketType reads a null when getting ArclightConstants.PLUGIN.

Also removed other cyclic references like this. Close #51
  • Loading branch information
IzzelAliz committed Sep 20, 2020
1 parent c6c8379 commit 7b763dd
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 31 deletions.
12 changes: 12 additions & 0 deletions arclight-api/src/main/java/io/izzel/arclight/api/Unsafe.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ public class Unsafe {
}
}

public static <T> T getStatic(Class<?> cl, String name) {
try {
Unsafe.ensureClassInitialized(cl);
Field field = cl.getDeclaredField(name);
Object materialByNameBase = Unsafe.staticFieldBase(field);
long materialByNameOffset = Unsafe.staticFieldOffset(field);
return (T) Unsafe.getObject(materialByNameBase, materialByNameOffset);
} catch (Exception e) {
return null;
}
}

public static MethodHandles.Lookup lookup() {
return lookup;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import org.bukkit.plugin.Plugin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import io.izzel.arclight.common.mod.ArclightConstants;

import java.util.Comparator;

@Mixin(TicketType.class)
public abstract class TicketTypeMixin implements TicketTypeBridge {

private static final TicketType<Unit> PLUGIN = ArclightConstants.PLUGIN;
private static final TicketType<Plugin> PLUGIN_TICKET = ArclightConstants.PLUGIN_TICKET;
private static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0);
private static final TicketType<Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", Comparator.comparing(it -> it.getClass().getName()));

@Override @Accessor(value = "lifespan")
public abstract void bridge$setLifespan(long lifespan);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.izzel.arclight.common.mixin.core.world.storage.loot;

import io.izzel.arclight.common.mod.ArclightConstants;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.storage.loot.LootParameter;
import net.minecraft.world.storage.loot.LootParameters;
import org.spongepowered.asm.mixin.Mixin;

@Mixin(LootParameters.class)
public class LootParametersMixin {

private static final LootParameter<Integer> LOOTING_MOD = ArclightConstants.LOOTING_MOD;
private static final LootParameter<Integer> LOOTING_MOD = new LootParameter<>(new ResourceLocation("bukkit:looting_mod"));;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@

import com.google.common.collect.ImmutableList;
import io.izzel.arclight.api.EnumHelper;
import net.minecraft.util.ResourceLocation;
import io.izzel.arclight.api.Unsafe;
import net.minecraft.util.Unit;
import net.minecraft.world.server.TicketType;
import net.minecraft.world.storage.loot.LootParameter;
import net.minecraft.world.storage.loot.LootParameters;
import org.bukkit.TreeType;
import org.bukkit.plugin.Plugin;

import java.util.Comparator;

public class ArclightConstants {

public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0);
public static final TicketType<Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", Comparator.comparing(it -> it.getClass().getName()));
public static final TicketType<Unit> PLUGIN = Unsafe.getStatic(TicketType.class, "PLUGIN");
public static final TicketType<Plugin> PLUGIN_TICKET = Unsafe.getStatic(TicketType.class, "PLUGIN_TICKET");

public static final TreeType MOD = EnumHelper.addEnum(TreeType.class, "MOD", ImmutableList.of(), ImmutableList.of());

public static final LootParameter<Integer> LOOTING_MOD = new LootParameter<>(new ResourceLocation("bukkit:looting_mod"));
public static final LootParameter<Integer> LOOTING_MOD = Unsafe.getStatic(LootParameters.class, "LOOTING_MOD");

/**
* Arclight marker magic value for non-used custom dimension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@
import java.util.Map;
import java.util.Set;

@SuppressWarnings({"unchecked", "ConstantConditions"})
@SuppressWarnings({"ConstantConditions"})
public class BukkitRegistry {

private static final List<Class<?>> MAT_CTOR = ImmutableList.of(int.class);
private static final List<Class<?>> ENTITY_CTOR = ImmutableList.of(String.class, Class.class, int.class);
private static final List<Class<?>> ENV_CTOR = ImmutableList.of(int.class);
private static final Map<String, Material> BY_NAME = getStatic(Material.class, "BY_NAME");
private static final Map<Block, Material> BLOCK_MATERIAL = getStatic(CraftMagicNumbers.class, "BLOCK_MATERIAL");
private static final Map<Item, Material> ITEM_MATERIAL = getStatic(CraftMagicNumbers.class, "ITEM_MATERIAL");
private static final Map<Material, Item> MATERIAL_ITEM = getStatic(CraftMagicNumbers.class, "MATERIAL_ITEM");
private static final Map<Material, Block> MATERIAL_BLOCK = getStatic(CraftMagicNumbers.class, "MATERIAL_BLOCK");
private static final Map<String, EntityType> ENTITY_NAME_MAP = getStatic(EntityType.class, "NAME_MAP");
private static final Map<Integer, World.Environment> ENVIRONMENT_MAP = getStatic(World.Environment.class, "lookup");
private static final Map<String, Material> BY_NAME = Unsafe.getStatic(Material.class, "BY_NAME");
private static final Map<Block, Material> BLOCK_MATERIAL = Unsafe.getStatic(CraftMagicNumbers.class, "BLOCK_MATERIAL");
private static final Map<Item, Material> ITEM_MATERIAL = Unsafe.getStatic(CraftMagicNumbers.class, "ITEM_MATERIAL");
private static final Map<Material, Item> MATERIAL_ITEM = Unsafe.getStatic(CraftMagicNumbers.class, "MATERIAL_ITEM");
private static final Map<Material, Block> MATERIAL_BLOCK = Unsafe.getStatic(CraftMagicNumbers.class, "MATERIAL_BLOCK");
private static final Map<String, EntityType> ENTITY_NAME_MAP = Unsafe.getStatic(EntityType.class, "NAME_MAP");
private static final Map<Integer, World.Environment> ENVIRONMENT_MAP = Unsafe.getStatic(World.Environment.class, "lookup");

public static void registerAll() {
CrashReportExtender.registerCrashCallable("Arclight", () -> new CraftCrashReport().call().toString());
Expand Down Expand Up @@ -255,18 +255,6 @@ private static EntityPropertySpec entitySpec(ResourceLocation location) {
return ArclightConfig.spec().getCompat().getEntity(location.toString()).orElse(EntityPropertySpec.EMPTY);
}

private static <T> T getStatic(Class<?> cl, String name) {
try {
Unsafe.ensureClassInitialized(cl);
Field field = cl.getDeclaredField(name);
Object materialByNameBase = Unsafe.staticFieldBase(field);
long materialByNameOffset = Unsafe.staticFieldOffset(field);
return (T) Unsafe.getObject(materialByNameBase, materialByNameOffset);
} catch (Exception e) {
return null;
}
}

private static void putStatic(Class<?> cl, String name, Object o) {
try {
Unsafe.ensureClassInitialized(cl);
Expand Down

0 comments on commit 7b763dd

Please sign in to comment.