Do not initialize a new world for wrapped worlds (#125)
This commit is contained in:
parent
3b0e2bd9bf
commit
793fddc227
@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.world.WorldBridge;
|
|||||||
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
|
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
|
||||||
import io.izzel.arclight.common.mod.ArclightMod;
|
import io.izzel.arclight.common.mod.ArclightMod;
|
||||||
import io.izzel.arclight.common.mod.server.ArclightServer;
|
import io.izzel.arclight.common.mod.server.ArclightServer;
|
||||||
|
import io.izzel.arclight.common.mod.server.world.WrappedWorlds;
|
||||||
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
@ -43,6 +44,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Mixin(World.class)
|
@Mixin(World.class)
|
||||||
@ -193,6 +196,14 @@ public abstract class WorldMixin implements WorldBridge {
|
|||||||
|
|
||||||
public CraftWorld getWorld() {
|
public CraftWorld getWorld() {
|
||||||
if (this.world == null) {
|
if (this.world == null) {
|
||||||
|
Optional<Field> delegate = WrappedWorlds.getDelegate(this.getClass());
|
||||||
|
if (delegate.isPresent()) {
|
||||||
|
try {
|
||||||
|
return ((WorldBridge) delegate.get().get(this)).bridge$getWorld();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (generator == null) {
|
if (generator == null) {
|
||||||
generator = getServer().getGenerator(((IServerWorldInfo) this.getWorldInfo()).getWorldName());
|
generator = getServer().getGenerator(((IServerWorldInfo) this.getWorldInfo()).getWorldName());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
package io.izzel.arclight.common.mod.server.world;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.mod.ArclightMod;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class WrappedWorlds {
|
||||||
|
|
||||||
|
private static final HashSet<Class<?>> RESULT = new HashSet<>();
|
||||||
|
private static final HashMap<Class<?>, Field> FIELD = new HashMap<>();
|
||||||
|
|
||||||
|
public static Optional<Field> getDelegate(Class<?> cl) {
|
||||||
|
if (cl.equals(ServerWorld.class)) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else {
|
||||||
|
return getOrCreate(cl, key -> {
|
||||||
|
for (Field f : cl.getDeclaredFields()) {
|
||||||
|
if (World.class.isAssignableFrom(f.getType())) {
|
||||||
|
ArclightMod.LOGGER.debug("{} delegates to field {}", cl, f.getName());
|
||||||
|
f.setAccessible(true);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Optional<Field> delegate = getDelegate(cl);
|
||||||
|
if (delegate.isPresent()) {
|
||||||
|
return delegate.get();
|
||||||
|
} else {
|
||||||
|
ArclightMod.LOGGER.debug("{} delegates to nothing", cl);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Optional<Field> getOrCreate(Class<?> cl, Function<Class<?>, Field> function) {
|
||||||
|
Field field = FIELD.get(cl);
|
||||||
|
if (field != null) {
|
||||||
|
return Optional.of(field);
|
||||||
|
} else if (RESULT.contains(cl)) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else {
|
||||||
|
Field delegate = function.apply(cl);
|
||||||
|
RESULT.add(cl);
|
||||||
|
if (delegate != null) {
|
||||||
|
FIELD.put(cl, delegate);
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(delegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user