From e26195169fe63b9dde31eddeb927f9fb98acb20c Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 22 Jun 2022 13:29:28 -0700 Subject: [PATCH] Closing the blinds - Prevent LightUpdater from interacting with invalid levels. - Bump version - 0.6.3 --- gradle.properties | 2 +- .../flywheel/light/DummyLightUpdater.java | 50 +++++++++++++++++++ .../jozufozu/flywheel/light/LightUpdated.java | 32 ++++++++++++ .../jozufozu/flywheel/light/LightUpdater.java | 15 ++++-- .../jozufozu/flywheel/util/WorldAttached.java | 2 +- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/light/DummyLightUpdater.java create mode 100644 src/main/java/com/jozufozu/flywheel/light/LightUpdated.java diff --git a/gradle.properties b/gradle.properties index 7989201c7..45c6f4660 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.6.2 +mod_version = 0.6.3 mc_update_version = 1.18 minecraft_version = 1.18.2 forge_version = 40.0.15 diff --git a/src/main/java/com/jozufozu/flywheel/light/DummyLightUpdater.java b/src/main/java/com/jozufozu/flywheel/light/DummyLightUpdater.java new file mode 100644 index 000000000..0cb04f944 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/DummyLightUpdater.java @@ -0,0 +1,50 @@ +package com.jozufozu.flywheel.light; + +import java.util.stream.Stream; + +import com.jozufozu.flywheel.util.box.ImmutableBox; + +import net.minecraft.world.level.LightLayer; + +public class DummyLightUpdater extends LightUpdater { + public static final DummyLightUpdater INSTANCE = new DummyLightUpdater(); + + private DummyLightUpdater() { + super(null); + } + + @Override + public void tick() { + // noop + } + + @Override + public void addListener(LightListener listener) { + // noop + } + + @Override + public void removeListener(LightListener listener) { + // noop + } + + @Override + public void onLightUpdate(LightLayer type, long sectionPos) { + // noop + } + + @Override + public void onLightPacket(int chunkX, int chunkZ) { + // noop + } + + @Override + public Stream getAllBoxes() { + return Stream.empty(); + } + + @Override + public boolean isEmpty() { + return true; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/light/LightUpdated.java b/src/main/java/com/jozufozu/flywheel/light/LightUpdated.java new file mode 100644 index 000000000..4173ef2a8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/LightUpdated.java @@ -0,0 +1,32 @@ +package com.jozufozu.flywheel.light; + +import net.minecraft.client.Minecraft; +import net.minecraft.world.level.LevelAccessor; + +/** + * Marker interface for custom/fake levels to indicate that LightUpdater should bother interacting with it.

+ * + * Implement this if your custom level has light updates at all. If so, be sure to call + * {@link com.jozufozu.flywheel.util.WorldAttached#invalidateWorld} when your level in unloaded. + */ +public interface LightUpdated extends LevelAccessor { + + /** + * @return {@code true} if this level is passing light updates into LightUpdater. + */ + default boolean receivesLightUpdates() { + return true; + } + + static boolean receivesLightUpdates(LevelAccessor level) { + // The client level is guaranteed to receive updates. + if (Minecraft.getInstance().level == level) { + return true; + } + // Custom/fake levels need to indicate that LightUpdater has meaning. + if (level instanceof LightUpdated c) { + return c.receivesLightUpdates(); + } + return false; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java index c1b3b4f54..4958fd682 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java @@ -20,14 +20,23 @@ import net.minecraft.world.level.LightLayer; /** * Keeps track of what chunks/sections each listener is in, so we can update exactly what needs to be updated. + * + * @apiNote Custom/fake levels (that are {@code != Minecraft.getInstance.level}) need to implement + * {@link LightUpdated} for LightUpdater to work with them. */ public class LightUpdater { - private static final WorldAttached light = new WorldAttached<>(LightUpdater::new); + private static final WorldAttached LEVELS = new WorldAttached<>(LightUpdater::new); private final ParallelTaskEngine taskEngine; - public static LightUpdater get(LevelAccessor world) { - return light.get(world); + public static LightUpdater get(LevelAccessor level) { + if (LightUpdated.receivesLightUpdates(level)) { + // The level is valid, add it to the map. + return LEVELS.get(level); + } else { + // Fake light updater for a fake level. + return DummyLightUpdater.INSTANCE; + } } private final LightProvider provider; diff --git a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java index 408b54e51..45b989f2f 100644 --- a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java +++ b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java @@ -28,7 +28,7 @@ public class WorldAttached { } public static void invalidateWorld(LevelAccessor world) { - Iterator>> i = allMaps.iterator(); + var i = allMaps.iterator(); while (i.hasNext()) { Map map = i.next() .get();