Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import io.github.opencubicchunks.cubicchunks.core.server.PlayerCubeMap;
import io.github.opencubicchunks.cubicchunks.core.server.SpawnCubes;
import io.github.opencubicchunks.cubicchunks.core.server.VanillaNetworkHandler;
import io.github.opencubicchunks.cubicchunks.core.util.CompatHandler;
import io.github.opencubicchunks.cubicchunks.core.util.world.CubeSplitTickList;
import io.github.opencubicchunks.cubicchunks.core.util.world.CubeSplitTickSet;
import io.github.opencubicchunks.cubicchunks.core.world.CubeWorldEntitySpawner;
Expand Down Expand Up @@ -117,8 +118,6 @@ public abstract class MixinWorldServer extends MixinWorld implements ICubicWorld

@Shadow protected abstract void playerCheckLight();

@Shadow public abstract boolean spawnEntity(Entity entityIn);

@Shadow public abstract boolean addWeatherEffect(Entity entityIn);

@Shadow @Mutable @Final private Set<NextTickListEntry> pendingTickListEntriesHashSet;
Expand Down Expand Up @@ -368,7 +367,7 @@ private void tickColumn(boolean raining, boolean thundering, Chunk chunk) {
skeletonHorse.setTrap(true);
skeletonHorse.setGrowingAge(0);
skeletonHorse.setPosition((double) strikePos.getX(), (double) strikePos.getY(), (double) strikePos.getZ());
this.spawnEntity(skeletonHorse);
CompatHandler.spawnEntity(skeletonHorse, (WorldServer) (Object) this);
this.addWeatherEffect(new EntityLightningBolt((World) (Object) this,
(double) strikePos.getX(), (double) strikePos.getY(), (double) strikePos.getZ(), true));
} else {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
*/
package io.github.opencubicchunks.cubicchunks.core.util;

import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -43,7 +43,9 @@
import io.github.opencubicchunks.cubicchunks.core.asm.mixin.ICubicWorldInternal;
import io.github.opencubicchunks.cubicchunks.core.asm.mixin.fixes.common.fakeheight.IASMEventHandler;
import io.github.opencubicchunks.cubicchunks.core.asm.mixin.fixes.common.fakeheight.IEventBus;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.common.MinecraftForge;
Expand All @@ -56,6 +58,7 @@
import net.minecraftforge.fml.common.eventhandler.EventBus;
import net.minecraftforge.fml.common.eventhandler.IEventListener;
import net.minecraftforge.fml.common.eventhandler.ListenerList;
import org.bukkit.event.entity.CreatureSpawnEvent;

public class CompatHandler {

Expand Down Expand Up @@ -290,4 +293,24 @@ private static <T> IEventListener[] getFakeEventListeners(ListenerList listenerL

return newList.toArray(new IEventListener[0]);
}

/*
* Hybrid servers do have this method in World class, but not in WorldServer.
*/
public static boolean spawnEntity(Entity entity, WorldServer world) {
if (PlatformCompatUtils.isHybridEnv() && MH_WorldServer_Bukkit_addEntity != null) {
try {
return (boolean) MH_WorldServer_Bukkit_addEntity.invokeExact(world, entity, CreatureSpawnEvent.SpawnReason.DEFAULT);
} catch (Throwable th) {
CubicChunks.LOGGER.error("Failed to call WorldServer.addEntity", th);
return false;
}
}
return world.spawnEntity(entity);
}

// MethodHandle for WorldServer#addEntity(Entity, CreatureSpawnEvent.SpawnReason) method in CraftBukkit
private static final MethodHandle MH_WorldServer_Bukkit_addEntity = ReflectionUtil.methodHandle(true, WorldServer.class, "addEntity",
Entity.class,
ReflectionUtil.getClass("org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,22 @@ public class PlatformCompatUtils {
private PlatformCompatUtils() {
}

private static final boolean isHybridEnv = isClassLoaded("org.bukkit.Bukkit");
private static final boolean isHybridEnv = isClassExists("org.bukkit.Bukkit");

public static boolean isClassLoaded(String name) {
public static boolean isClassLoaded(String className) {
try {
Class.forName(name);
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

public static boolean isClassExists(String className) {
String classPath = className.replace('.', '/') + ".class";
return Thread.currentThread().getContextClassLoader().getResource(classPath) != null;
}

public static boolean isHybridEnv() {
return isHybridEnv;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

@ParametersAreNonnullByDefault
Expand Down Expand Up @@ -65,4 +67,36 @@ public static MethodHandle constructHandle(Class<?> owner, Class<?>... args) {
throw new Error(e);
}
}

/**
* Returns a method handle for a method of a class.
*
* @param suppressException if true, returns null if the method is not found instead of throwing error
* @param owner the class
* @param name the method name
* @param args the method arguments
* @return the method handle, or null if not found and suppressException is true
*/
@CheckForNull
public static MethodHandle methodHandle(boolean suppressException, Class<?> owner, String name, Class<?>... args) {
for (Class<?> clazz : args) {
if (clazz == null) return null;
}
try {
return MethodHandles.lookup().unreflect(owner.getDeclaredMethod(name, args));
} catch (Exception e) {
if (suppressException) return null;
//if it happens - either something has gone horribly wrong or the JVM is blocking access
throw new Error(e);
}
}

@Nullable
public static Class<?> getClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
return null;
}
}
}
3 changes: 1 addition & 2 deletions src/main/resources/cubicchunks.mixins.core.bukkit.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"server": [
"common.MixinWorld_HeightLimits_Bukkit_Sided",
"common.MixinPlayerList_Bukkit_Sided",
"common.MixinChunk_Cubes_Bukkit_Sided",
"common.MixinWorldServer_Bukkit"
"common.MixinChunk_Cubes_Bukkit_Sided"
]
}
1 change: 1 addition & 0 deletions src/main/resources/cubicchunks.mixins.core.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"common.MixinWorldEntitySpawner",
"common.MixinWorldInfo",
"common.MixinWorldProvider",
"common.MixinWorldServer",
"common.MixinWorldSettings",
"common.vanillaclient.ICPacketPlayer",
"common.vanillaclient.ICPacketPlayerDigging",
Expand Down
1 change: 0 additions & 1 deletion src/main/resources/cubicchunks.mixins.core.vanilla.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"mixins": [
"common.MixinChunk_Cubes_Vanilla_Sided",
"common.MixinWorld_HeightLimits_Vanilla_Sided",
"common.MixinWorldServer",
"common.MixinPlayerList_Vanilla_Sided"
],
"client": [],
Expand Down
Loading