Rewrite monitor networking (#453)

This moves monitor networking into its own packet, rather than serialising
using NBT. This allows us to be more flexible with how monitors are
serialised.

We now compress terminal data using gzip. This reduces the packet size
of a max-sized-monitor from ~25kb to as little as 100b.

On my test set of images (what I would consider to be the extreme end of
the "reasonable" case), we have packets from 1.4kb bytes up to 12kb,
with a mean of 6kb. Even in the worst case, this is a 2x reduction in
packet size.

While this is a fantastic win for the common case, it is not abuse-proof.
One can create a terminal with high entropy (and so uncompressible). This
will still be close to the original packet size.

In order to prevent any other abuse, we also limit the amount of monitor
data a client can possibly receive to 1MB (configurable).
This commit is contained in:
Jonathan Coates
2020-05-20 08:44:44 +01:00
committed by GitHub
parent 161a5b4707
commit d50a08a549
18 changed files with 507 additions and 72 deletions
@@ -72,6 +72,7 @@ public final class Config
private static Property modemHighAltitudeRangeDuringStorm;
private static Property maxNotesPerTick;
private static Property monitorRenderer;
private static Property monitorBandwidth;
private static Property turtlesNeedFuel;
private static Property turtleFuelLimit;
@@ -276,10 +277,21 @@ public final class Config
"monitors have performance issues, you may wish to experiment with alternative renderers." );
monitorRenderer.setValidValues( MonitorRenderer.NAMES );
monitorBandwidth = config.get( CATEGORY_PERIPHERAL, "monitor_bandwidth", (int) ComputerCraft.monitorBandwidth );
monitorBandwidth.setComment( "The limit to how much monitor data can be sent *per tick*. Note:\n" +
" - Bandwidth is measured before compression, so the data sent to the client is smaller.\n" +
" - This ignores the number of players a packet is sent to. Updating a monitor for one player consumes " +
"the same bandwidth limit as sending to 20.\n" +
" - A full sized monitor sends ~25kb of data. So the default (1MB) allows for ~40 monitors to be updated " +
"in a single tick. \n" +
"Set to 0 to disable." );
monitorBandwidth.setValidValues( MonitorRenderer.NAMES );
monitorBandwidth.setMinValue( 0 );
setOrder(
CATEGORY_PERIPHERAL,
commandBlockEnabled, modemRange, modemHighAltitudeRange, modemRangeDuringStorm, modemHighAltitudeRangeDuringStorm, maxNotesPerTick,
monitorRenderer
monitorRenderer, monitorBandwidth
);
}
@@ -474,6 +486,7 @@ public final class Config
ComputerCraft.modem_rangeDuringStorm = Math.min( modemRangeDuringStorm.getInt(), MODEM_MAX_RANGE );
ComputerCraft.modem_highAltitudeRangeDuringStorm = Math.min( modemHighAltitudeRangeDuringStorm.getInt(), MODEM_MAX_RANGE );
ComputerCraft.monitorRenderer = MonitorRenderer.ofString( monitorRenderer.getString() );
ComputerCraft.monitorBandwidth = Math.max( 0, monitorBandwidth.getLong() );
// Turtles
ComputerCraft.turtlesNeedFuel = turtlesNeedFuel.getBoolean();