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.mod.ArclightMod;
|
||||
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 net.minecraft.block.Block;
|
||||
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 javax.annotation.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(World.class)
|
||||
@ -193,6 +196,14 @@ public abstract class WorldMixin implements WorldBridge {
|
||||
|
||||
public CraftWorld getWorld() {
|
||||
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) {
|
||||
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