From 40e1f98a71830cb5f636898d634c1691de68c504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 20 Dec 2020 20:19:31 +0100 Subject: [PATCH] Cleaned up chunk init in computer, avoid potential NRE in netcode when being unloaded again very quickly. --- .../block/entity/ComputerTileEntity.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java b/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java index cfdbe73a..2954a5b0 100644 --- a/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java @@ -220,6 +220,10 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic return; } + if (chunk == null) { + chunk = world.getChunkAt(getPos()); + } + busController.scan(); setBusState(busController.getState()); if (busState != AbstractDeviceBusController.BusState.READY) { @@ -368,8 +372,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic ServerScheduler.scheduleOnUnload(world, onWorldUnloaded); busElement.initialize(); - virtualMachine.rtc.setWorld(requireNonNull(getWorld())); - ServerScheduler.schedule(() -> chunk = requireNonNull(getWorld()).getChunkAt(getPos())); + virtualMachine.rtc.setWorld(world); } @Override @@ -392,7 +395,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic busState = value; - Network.sendToClientsTrackingChunk(new ComputerBusStateMessage(this), chunk); + final ComputerBusStateMessage message = new ComputerBusStateMessage(this); + Network.sendToClientsTrackingChunk(message, chunk); } private void setRunState(final RunState value) { @@ -402,7 +406,12 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic runState = value; - Network.sendToClientsTrackingChunk(new ComputerRunStateMessage(this), chunk); + // This method can be called from disposal logic, so if we are disposed quickly enough + // chunk may not be initialized yet. Avoid resulting NRE in network logic. + if (chunk != null) { + final ComputerRunStateMessage message = new ComputerRunStateMessage(this); + Network.sendToClientsTrackingChunk(message, chunk); + } } private void stopRunnerAndResetVM() { @@ -519,8 +528,6 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic virtualMachine.vmAdapter.fireLifecycleEvent(VMDeviceLifecycleEventType.INITIALIZE); try { - // TODO Initialize devices that need it asynchronously. - loadProgramFile(Buildroot.getFirmware()); loadProgramFile(Buildroot.getLinuxImage(), 0x200000); } catch (final Throwable e) { @@ -561,8 +568,9 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic terminal.putOutput(output); output.flip(); - Network.sendToClientsTrackingChunk( - new TerminalBlockOutputMessage(ComputerTileEntity.this, output), chunk); + + final TerminalBlockOutputMessage message = new TerminalBlockOutputMessage(ComputerTileEntity.this, output); + Network.sendToClientsTrackingChunk(message, chunk); } } }