mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-12 03:00:30 +00:00
Defer sending monitor updates until tick end
We send monitor updates when a player starts watching a chunk. However, the block/tile data has not been sent when this event is fired, and so the packet is entirely ignored. Instead, we now queue a "send this" task, which is then dispatched on the next tick end. I have memories of this working on 1.12, so either something changed in an update or I'm a complete idiot. Both are possible. Fixes #687
This commit is contained in:
parent
763bab80fa
commit
1544749282
@ -9,6 +9,7 @@ import dan200.computercraft.ComputerCraft;
|
|||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import dan200.computercraft.shared.network.client.MonitorClientMessage;
|
import dan200.computercraft.shared.network.client.MonitorClientMessage;
|
||||||
import dan200.computercraft.shared.network.client.TerminalState;
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
@ -28,6 +29,7 @@ import java.util.Queue;
|
|||||||
public final class MonitorWatcher
|
public final class MonitorWatcher
|
||||||
{
|
{
|
||||||
private static final Queue<TileMonitor> watching = new ArrayDeque<>();
|
private static final Queue<TileMonitor> watching = new ArrayDeque<>();
|
||||||
|
private static final Queue<PlayerUpdate> playerUpdates = new ArrayDeque<>();
|
||||||
|
|
||||||
private MonitorWatcher()
|
private MonitorWatcher()
|
||||||
{
|
{
|
||||||
@ -58,10 +60,8 @@ public final class MonitorWatcher
|
|||||||
ServerMonitor serverMonitor = getMonitor( monitor );
|
ServerMonitor serverMonitor = getMonitor( monitor );
|
||||||
if( serverMonitor == null || monitor.enqueued ) continue;
|
if( serverMonitor == null || monitor.enqueued ) continue;
|
||||||
|
|
||||||
// We use the cached terminal state if available - this is guaranteed to
|
// The chunk hasn't been sent to the client yet, so we can't send an update. Do it on tick end.
|
||||||
TerminalState state = monitor.cached;
|
playerUpdates.add( new PlayerUpdate( event.getPlayer(), monitor ) );
|
||||||
if( state == null ) state = monitor.cached = serverMonitor.write();
|
|
||||||
NetworkHandler.sendToPlayer( event.getPlayer(), new MonitorClientMessage( monitor.getBlockPos(), state ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +70,23 @@ public final class MonitorWatcher
|
|||||||
{
|
{
|
||||||
if( event.phase != TickEvent.Phase.END ) return;
|
if( event.phase != TickEvent.Phase.END ) return;
|
||||||
|
|
||||||
|
PlayerUpdate playerUpdate;
|
||||||
|
while( (playerUpdate = playerUpdates.poll()) != null )
|
||||||
|
{
|
||||||
|
TileMonitor tile = playerUpdate.monitor;
|
||||||
|
if( tile.enqueued || tile.isRemoved() ) continue;
|
||||||
|
|
||||||
|
ServerMonitor monitor = getMonitor( tile );
|
||||||
|
if( monitor == null ) continue;
|
||||||
|
|
||||||
|
// Some basic sanity checks to the player. It's possible they're no longer within range, but that's harder
|
||||||
|
// to track efficiently.
|
||||||
|
ServerPlayerEntity player = playerUpdate.player;
|
||||||
|
if( !player.isAlive() || player.getLevel() != tile.getLevel() ) continue;
|
||||||
|
|
||||||
|
NetworkHandler.sendToPlayer( playerUpdate.player, new MonitorClientMessage( tile.getBlockPos(), getState( tile, monitor ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
long limit = ComputerCraft.monitorBandwidth;
|
long limit = ComputerCraft.monitorBandwidth;
|
||||||
boolean obeyLimit = limit > 0;
|
boolean obeyLimit = limit > 0;
|
||||||
|
|
||||||
@ -90,7 +107,7 @@ public final class MonitorWatcher
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalState state = tile.cached = monitor.write();
|
TerminalState state = getState( tile, monitor );
|
||||||
NetworkHandler.sendToAllTracking( new MonitorClientMessage( pos, state ), chunk );
|
NetworkHandler.sendToAllTracking( new MonitorClientMessage( pos, state ), chunk );
|
||||||
|
|
||||||
limit -= state.size();
|
limit -= state.size();
|
||||||
@ -101,4 +118,23 @@ public final class MonitorWatcher
|
|||||||
{
|
{
|
||||||
return !monitor.isRemoved() && monitor.getXIndex() == 0 && monitor.getYIndex() == 0 ? monitor.getCachedServerMonitor() : null;
|
return !monitor.isRemoved() && monitor.getXIndex() == 0 && monitor.getYIndex() == 0 ? monitor.getCachedServerMonitor() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TerminalState getState( TileMonitor tile, ServerMonitor monitor )
|
||||||
|
{
|
||||||
|
TerminalState state = tile.cached;
|
||||||
|
if( state == null ) state = tile.cached = monitor.write();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class PlayerUpdate
|
||||||
|
{
|
||||||
|
final ServerPlayerEntity player;
|
||||||
|
final TileMonitor monitor;
|
||||||
|
|
||||||
|
private PlayerUpdate( ServerPlayerEntity player, TileMonitor monitor )
|
||||||
|
{
|
||||||
|
this.player = player;
|
||||||
|
this.monitor = monitor;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user