From bf83de08b2d5ce69bf0137e0094c5603d9fdf865 Mon Sep 17 00:00:00 2001 From: James Chung <60687097+jchung01@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:45:55 -0700 Subject: [PATCH] Add fix for leaking client TEs (#298) * Add fix for leaking client TEs * Remove client-side markDirty() call --- src/main/java/appeng/hooks/TickHandler.java | 14 ++++++++++++++ src/main/java/appeng/tile/AEBaseTile.java | 16 ++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/java/appeng/hooks/TickHandler.java b/src/main/java/appeng/hooks/TickHandler.java index 788e8906f..851f04b0b 100644 --- a/src/main/java/appeng/hooks/TickHandler.java +++ b/src/main/java/appeng/hooks/TickHandler.java @@ -32,6 +32,7 @@ import appeng.me.Grid; import appeng.tile.AEBaseTile; import appeng.util.IWorldCallable; import appeng.util.Platform; +import com.google.common.base.Preconditions; import com.google.common.base.Stopwatch; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Multimap; @@ -66,7 +67,20 @@ public class TickHandler { return this.cliPlayerColors; } + /** + * Add a server or world callback which gets called the next time the queue is ticked. + *
+ * Callbacks on the client are not support. + *
+ * Using null as world will queue it into the global {@link TickEvent.ServerTickEvent}, otherwise it will be ticked with the + * corresponding {@link TickEvent.WorldTickEvent}. + * + * @param w null or the specific {@link World} + * @param c the callback + */ public void addCallable(final World w, final IWorldCallable> c) { + Preconditions.checkArgument(w == null || !w.isRemote, "Can only register serverside callbacks"); + if (w == null) { this.serverQueue.add(c); } else { diff --git a/src/main/java/appeng/tile/AEBaseTile.java b/src/main/java/appeng/tile/AEBaseTile.java index 2696a34a0..16f03a9cf 100644 --- a/src/main/java/appeng/tile/AEBaseTile.java +++ b/src/main/java/appeng/tile/AEBaseTile.java @@ -434,12 +434,16 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, } public void saveChanges() { - if (this.world != null) { - this.world.markChunkDirty(this.pos, this); - if (!this.markDirtyQueued) { - TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick); - this.markDirtyQueued = true; - } + // Clientside should not need to save/markDirty() data + if (this.world == null || this.world.isRemote) { + return; + } + + // Serverside is only queued once per tick to avoid costly operations + this.world.markChunkDirty(this.pos, this); + if (!this.markDirtyQueued) { + TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick); + this.markDirtyQueued = true; } }