From 1b5a10591b018febe5a73750d24d549b97fafd99 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 20 Nov 2022 20:39:52 -0600 Subject: [PATCH] Add IDhApiWorldProxy --- .../java/com/seibel/lod/api/DhApiMain.java | 16 ++- .../interfaces/world/IDhApiLevelWrapper.java | 2 +- .../interfaces/world/IDhApiWorldProxy.java | 62 +++++++++ .../java/com/seibel/lod/core/Initializer.java | 4 +- .../lod/core/world/AbstractDhWorld.java | 8 ++ .../lod/core/world/DhApiWorldProxy.java | 126 ++++++++++++++++++ 6 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiWorldProxy.java create mode 100644 core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java diff --git a/api/src/main/java/com/seibel/lod/api/DhApiMain.java b/api/src/main/java/com/seibel/lod/api/DhApiMain.java index 941696fbd..a2aa5502e 100644 --- a/api/src/main/java/com/seibel/lod/api/DhApiMain.java +++ b/api/src/main/java/com/seibel/lod/api/DhApiMain.java @@ -3,6 +3,7 @@ package com.seibel.lod.api; import com.seibel.lod.api.interfaces.config.IDhApiConfig; import com.seibel.lod.api.interfaces.override.IDhApiOverrideable; import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGeneratorOverrideRegister; +import com.seibel.lod.api.interfaces.world.IDhApiWorldProxy; import com.seibel.lod.api.methods.override.DhApiWorldGeneratorOverrideRegister; import com.seibel.lod.core.DependencyInjection.DhApiEventInjector; import com.seibel.lod.core.DependencyInjection.OverrideInjector; @@ -24,7 +25,7 @@ import com.seibel.lod.core.interfaces.dependencyInjection.IOverrideInjector; * the concrete object we replaced, there would be issues. * * @author James Seibel - * @version 2022-11-12 + * @version 2022-11-20 */ public class DhApiMain { @@ -52,6 +53,19 @@ public class DhApiMain */ public static IDhApiTerrainDataRepo terrainRepo = null; + /** + * WARNING: will be null until after DH initializes for the first time.

+ * + * Use a {@link com.seibel.lod.api.methods.events.abstractEvents.DhApiAfterDhInitEvent DhApiAfterDhInitEvent} + * along with the {@link DhApiMain#events ApiCoreInjectors.events} to be notified when this can + * be safely used.

+ * + * Used to interact with Distant Horizons' currently loaded world and + * get levels to use with the {@link DhApiMain#terrainRepo}. + */ + public static IDhApiWorldProxy worldProxy = null; + + // always available // diff --git a/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java b/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java index d0ed8ea6c..a0669f23e 100644 --- a/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java +++ b/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java @@ -43,7 +43,7 @@ public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper /** * Returns the lowest possible block position for the level.
- * For MC versions before 1.19 this will return 0. + * For MC versions before 1.18 this will return 0. */ default int getMinHeight() { return 0; } diff --git a/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiWorldProxy.java b/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiWorldProxy.java new file mode 100644 index 000000000..7724ea203 --- /dev/null +++ b/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiWorldProxy.java @@ -0,0 +1,62 @@ +/* + * This file is part of the Distant Horizons mod (formerly the LOD Mod), + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2022 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.lod.api.interfaces.world; + +import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper; + +/** + * Used to interact with Distant Horizons current world. + * + * @author James Seibel + * @version 2022-11-20 + */ +public interface IDhApiWorldProxy +{ + /** Returns true if a world is loaded. */ + boolean worldLoaded(); + + + /** + * In singleplayer this will return the level the player is currently in.
+ * In multiplayer this will return null. + * + * @throws IllegalStateException if no world is loaded + */ + IDhApiLevelWrapper getSinglePlayerLevel() throws IllegalStateException; + + /** @throws IllegalStateException if no world is loaded */ + Iterable getAllLoadedLevelWrappers() throws IllegalStateException; + + /** + * In the case of servers running multiverse there may be multiple levels for the same dimensionType. + * + * @throws IllegalStateException if no world is loaded + */ + Iterable getAllLoadedLevelsForDimensionType(IDhApiDimensionTypeWrapper dimensionTypeWrapper) throws IllegalStateException; + + /** + * Returns any dimensions that have names containing the given string (case-insensitive).
+ * In the case of servers running multiverse there may be multiple levels for the same dimensionType. + * + * @throws IllegalStateException if no world is loaded + */ + Iterable getAllLoadedLevelsWithDimensionNameLike(String dimensionName) throws IllegalStateException; + +} diff --git a/core/src/main/java/com/seibel/lod/core/Initializer.java b/core/src/main/java/com/seibel/lod/core/Initializer.java index 7790d6c9a..bfa188fe2 100644 --- a/core/src/main/java/com/seibel/lod/core/Initializer.java +++ b/core/src/main/java/com/seibel/lod/core/Initializer.java @@ -7,12 +7,13 @@ import com.seibel.lod.core.datatype.full.FullDataLoader; import com.seibel.lod.core.datatype.full.SparseDataLoader; import com.seibel.lod.api.DhApiMain; import com.seibel.lod.core.datatype.full.SpottyDataLoader; +import com.seibel.lod.core.world.DhApiWorldProxy; /** * Handles first time Core setup. * * @author Leetom - * @version 2022-11-12 + * @version 2022-11-20 */ public class Initializer { @@ -26,6 +27,7 @@ public class Initializer // link Core's config to the API DhApiMain.configs = DhApiConfig.INSTANCE; DhApiMain.terrainRepo = DhApiTerrainDataRepo.INSTANCE; + DhApiMain.worldProxy = DhApiWorldProxy.INSTANCE; } } diff --git a/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java b/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java index 8c94d8f36..e5667a92c 100644 --- a/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java @@ -1,13 +1,21 @@ package com.seibel.lod.core.world; +import com.seibel.lod.api.interfaces.world.IDhApiDimensionTypeWrapper; +import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper; +import com.seibel.lod.api.interfaces.world.IDhApiWorldProxy; import com.seibel.lod.core.level.IDhLevel; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.Logger; import java.io.Closeable; +import java.util.ArrayList; import java.util.concurrent.CompletableFuture; +/** + * Represents an entire world (aka server) and + * contains every level in that world. + */ public abstract class AbstractDhWorld implements Closeable { protected static final Logger LOGGER = DhLoggerBuilder.getLogger(); diff --git a/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java b/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java new file mode 100644 index 000000000..cf3526303 --- /dev/null +++ b/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java @@ -0,0 +1,126 @@ +package com.seibel.lod.core.world; + +import com.seibel.lod.api.interfaces.world.IDhApiDimensionTypeWrapper; +import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper; +import com.seibel.lod.api.interfaces.world.IDhApiWorldProxy; +import com.seibel.lod.core.api.internal.SharedApi; +import com.seibel.lod.core.dependencyInjection.SingletonInjector; +import com.seibel.lod.core.level.IDhLevel; +import com.seibel.lod.core.logging.DhLoggerBuilder; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; +import org.apache.logging.log4j.Logger; + +import java.io.Closeable; +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; + +/** + * Used to interact with the currently loaded world. + * This is separate from the world itself to prevent issues + * with API implementors referencing said world when it needs + * to be loaded/unloaded. + * + * @author James Seibel + * @version 2022-11-20 + */ +public class DhApiWorldProxy implements IDhApiWorldProxy +{ + public static DhApiWorldProxy INSTANCE = new DhApiWorldProxy(); + + private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + private static final String NO_WORLD_EXCEPTION_STRING = "No world loaded"; + + + + private DhApiWorldProxy() { } + + + + @Override + public boolean worldLoaded() { return SharedApi.currentWorld != null; } + + @Override + public IDhApiLevelWrapper getSinglePlayerLevel() + { + if (SharedApi.currentWorld == null) + { + throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); + } + + + if (!SharedApi.MC.isDedicatedServer()) + { + return MC.getWrappedClientWorld(); + } + else + { + return null; + } + } + + + @Override + public Iterable getAllLoadedLevelWrappers() + { + if (SharedApi.currentWorld == null) + { + throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); + } + + + ArrayList returnList = new ArrayList<>(); + for (IDhLevel dhLevel : SharedApi.currentWorld.getAllLoadedLevels()) + { + returnList.add(dhLevel.getLevelWrapper()); + } + return returnList; + } + + @Override + public Iterable getAllLoadedLevelsForDimensionType(IDhApiDimensionTypeWrapper dimensionTypeWrapper) + { + if (SharedApi.currentWorld == null) + { + throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); + } + + + ArrayList returnList = new ArrayList<>(); + for (IDhLevel dhLevel : SharedApi.currentWorld.getAllLoadedLevels()) + { + ILevelWrapper levelWrapper = dhLevel.getLevelWrapper(); + if (levelWrapper.getDimensionType().equals(dimensionTypeWrapper)) + { + returnList.add(levelWrapper); + } + } + return returnList; + } + + @Override + public Iterable getAllLoadedLevelsWithDimensionNameLike(String dimensionName) + { + if (SharedApi.currentWorld == null) + { + throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); + } + + + String soughtDimName = dimensionName.toLowerCase(); + + ArrayList returnList = new ArrayList<>(); + for (IDhLevel dhLevel : SharedApi.currentWorld.getAllLoadedLevels()) + { + ILevelWrapper levelWrapper = dhLevel.getLevelWrapper(); + String levelDimName = levelWrapper.getDimensionType().getDimensionName().toLowerCase(); + if (levelDimName.contains(soughtDimName)) + { + returnList.add(levelWrapper); + } + } + + return returnList; + } + +}