mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Optimise network reading - only need to move memory after all pending packets are processed, not after each field.
This commit is contained in:
parent
04ade22693
commit
d16ba9bfc6
@ -469,16 +469,15 @@ namespace ClassicalSharp {
|
|||||||
int count = reader.ReadUInt8() + 1;
|
int count = reader.ReadUInt8() + 1;
|
||||||
if( game.Map.IsNotLoaded ) {
|
if( game.Map.IsNotLoaded ) {
|
||||||
Utils.LogDebug( "Server tried to update a block while still sending us the map!" );
|
Utils.LogDebug( "Server tried to update a block while still sending us the map!" );
|
||||||
reader.Remove( bulkCount * (sizeof(int) + 1) );
|
reader.Skip( bulkCount * (sizeof(int) + 1) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int* indices = stackalloc int[bulkCount];
|
int* indices = stackalloc int[bulkCount];
|
||||||
for( int i = 0; i < count; i++ )
|
for( int i = 0; i < count; i++ )
|
||||||
indices[i] = ReadInt32( reader.buffer, i * 4 );
|
indices[i] = reader.ReadInt32();
|
||||||
|
|
||||||
for( int i = 0; i < count; i++ ) {
|
for( int i = 0; i < count; i++ ) {
|
||||||
byte block = reader.buffer[i + bulkCount * sizeof(int)];
|
byte block = reader.ReadUInt8();
|
||||||
Vector3I coords = game.Map.GetCoords( indices[i] );
|
Vector3I coords = game.Map.GetCoords( indices[i] );
|
||||||
|
|
||||||
if( coords.X < 0 ) {
|
if( coords.X < 0 ) {
|
||||||
@ -487,12 +486,6 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
game.UpdateBlock( coords.X, coords.Y, coords.Z, block );
|
game.UpdateBlock( coords.X, coords.Y, coords.Z, block );
|
||||||
}
|
}
|
||||||
reader.Remove( bulkCount * (sizeof(int) + 1) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ReadInt32( byte[] buffer, int offset ) {
|
|
||||||
return buffer[offset + 0] << 24 | buffer[offset + 1] << 16
|
|
||||||
| buffer[offset + 2] << 8 | buffer[offset + 3];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSetTextColor() {
|
void HandleSetTextColor() {
|
||||||
|
@ -124,6 +124,7 @@ namespace ClassicalSharp {
|
|||||||
HandleLevelInit();
|
HandleLevelInit();
|
||||||
int usedLength = reader.ReadInt16();
|
int usedLength = reader.ReadInt16();
|
||||||
gzippedMap.Position = 0;
|
gzippedMap.Position = 0;
|
||||||
|
gzippedMap.Offset = reader.index;
|
||||||
gzippedMap.SetLength( usedLength );
|
gzippedMap.SetLength( usedLength );
|
||||||
|
|
||||||
if( gzipHeader.done || gzipHeader.ReadHeader( gzippedMap ) ) {
|
if( gzipHeader.done || gzipHeader.ReadHeader( gzippedMap ) ) {
|
||||||
@ -140,7 +141,7 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.Remove( 1024 );
|
reader.Skip( 1024 );
|
||||||
byte progress = reader.ReadUInt8();
|
byte progress = reader.ReadUInt8();
|
||||||
game.MapEvents.RaiseMapLoading( progress );
|
game.MapEvents.RaiseMapLoading( progress );
|
||||||
}
|
}
|
||||||
|
@ -77,11 +77,11 @@ namespace ClassicalSharp {
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( reader.size > 0 ) {
|
while( (reader.size - reader.index) > 0 ) {
|
||||||
byte opcode = reader.buffer[0];
|
byte opcode = reader.buffer[reader.index];
|
||||||
// Workaround for older D3 servers which wrote one byte too many for HackControl packets.
|
// Workaround for older D3 servers which wrote one byte too many for HackControl packets.
|
||||||
if( opcode == 0xFF && lastOpcode == PacketId.CpeHackControl ) {
|
if( opcode == 0xFF && lastOpcode == PacketId.CpeHackControl ) {
|
||||||
reader.Remove( 1 );
|
reader.Skip( 1 );
|
||||||
game.LocalPlayer.jumpVel = 0.42f; // assume default jump height
|
game.LocalPlayer.jumpVel = 0.42f; // assume default jump height
|
||||||
game.LocalPlayer.serverJumpVel = game.LocalPlayer.jumpVel;
|
game.LocalPlayer.serverJumpVel = game.LocalPlayer.jumpVel;
|
||||||
continue;
|
continue;
|
||||||
@ -90,13 +90,14 @@ namespace ClassicalSharp {
|
|||||||
if( opcode >= maxHandledPacket ) {
|
if( opcode >= maxHandledPacket ) {
|
||||||
ErrorHandler.LogError( "NetworkProcessor.Tick",
|
ErrorHandler.LogError( "NetworkProcessor.Tick",
|
||||||
"received an invalid opcode of " + opcode );
|
"received an invalid opcode of " + opcode );
|
||||||
reader.Remove( 1 );
|
reader.Skip( 1 );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( reader.size < packetSizes[opcode] ) break;
|
if( (reader.size - reader.index) < packetSizes[opcode] ) break;
|
||||||
ReadPacket( opcode );
|
ReadPacket( opcode );
|
||||||
}
|
}
|
||||||
|
reader.RemoveRead();
|
||||||
|
|
||||||
Player player = game.LocalPlayer;
|
Player player = game.LocalPlayer;
|
||||||
if( receivedFirstPosition ) {
|
if( receivedFirstPosition ) {
|
||||||
@ -134,7 +135,7 @@ namespace ClassicalSharp {
|
|||||||
PacketId lastOpcode;
|
PacketId lastOpcode;
|
||||||
|
|
||||||
void ReadPacket( byte opcode ) {
|
void ReadPacket( byte opcode ) {
|
||||||
reader.Remove( 1 ); // remove opcode
|
reader.Skip( 1 ); // remove opcode
|
||||||
lastOpcode = (PacketId)opcode;
|
lastOpcode = (PacketId)opcode;
|
||||||
Action handler = handlers[opcode];
|
Action handler = handlers[opcode];
|
||||||
lastPacket = DateTime.UtcNow;
|
lastPacket = DateTime.UtcNow;
|
||||||
@ -145,7 +146,7 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkipPacketData( PacketId opcode ) {
|
void SkipPacketData( PacketId opcode ) {
|
||||||
reader.Remove( packetSizes[(byte)opcode] - 1 );
|
reader.Skip( packetSizes[(byte)opcode] - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
Action[] handlers;
|
Action[] handlers;
|
||||||
|
@ -8,23 +8,16 @@ namespace ClassicalSharp {
|
|||||||
internal class FixedBufferStream : Stream {
|
internal class FixedBufferStream : Stream {
|
||||||
|
|
||||||
public byte[] _buffer;
|
public byte[] _buffer;
|
||||||
int _position, _length;
|
int _position, _length;
|
||||||
|
public int Offset;
|
||||||
|
|
||||||
public override bool CanRead {
|
public override bool CanRead { get { return true; } }
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanSeek {
|
public override bool CanSeek { get { return false; } }
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanWrite {
|
public override bool CanWrite { get { return false; } }
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Length {
|
public override long Length { get { return _length; } }
|
||||||
get { return _length; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Position {
|
public override long Position {
|
||||||
get { return _position; }
|
get { return _position; }
|
||||||
@ -35,22 +28,23 @@ namespace ClassicalSharp {
|
|||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flush() {
|
public override void Flush() { }
|
||||||
}
|
|
||||||
|
|
||||||
public override int Read( byte[] buffer, int offset, int count ) {
|
public override int Read( byte[] buffer, int offset, int count ) {
|
||||||
int numBytes = _length - _position;
|
int numBytes = _length - _position;
|
||||||
if( numBytes > count ) numBytes = count;
|
if( numBytes > count ) numBytes = count;
|
||||||
if( numBytes <= 0 ) return 0;
|
if( numBytes <= 0 ) return 0;
|
||||||
|
|
||||||
Buffer.BlockCopy( _buffer, _position, buffer, offset, numBytes );
|
Buffer.BlockCopy( _buffer, Offset + _position, buffer, offset, numBytes );
|
||||||
_position += numBytes;
|
_position += numBytes;
|
||||||
return numBytes;
|
return numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int ReadByte() {
|
public override int ReadByte() {
|
||||||
if( _position >= _length ) return -1;
|
if( _position >= _length ) return -1;
|
||||||
return _buffer[_position++];
|
byte value = _buffer[Offset + _position];
|
||||||
|
_position++;
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override long Seek( long offset, SeekOrigin origin ) {
|
public override long Seek( long offset, SeekOrigin origin ) {
|
||||||
|
@ -6,7 +6,7 @@ namespace ClassicalSharp {
|
|||||||
internal class NetReader {
|
internal class NetReader {
|
||||||
|
|
||||||
public byte[] buffer = new byte[4096 * 5];
|
public byte[] buffer = new byte[4096 * 5];
|
||||||
public int size = 0;
|
public int index = 0, size = 0;
|
||||||
public NetworkStream Stream;
|
public NetworkStream Stream;
|
||||||
|
|
||||||
public NetReader( NetworkStream stream ) {
|
public NetReader( NetworkStream stream ) {
|
||||||
@ -21,52 +21,59 @@ namespace ClassicalSharp {
|
|||||||
size += received;
|
size += received;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove( int byteCount ) {
|
public void Skip( int byteCount ) {
|
||||||
size -= byteCount;
|
index += byteCount;
|
||||||
Buffer.BlockCopy( buffer, byteCount, buffer, 0, size );
|
}
|
||||||
|
|
||||||
|
public void RemoveProcessed() {
|
||||||
|
size -= index;
|
||||||
|
if( size > 0 ) // only copy left over bytes
|
||||||
|
Buffer.BlockCopy( buffer, index, buffer, 0, size );
|
||||||
|
index = 0;
|
||||||
// We don't need to zero the old bytes, since they will be overwritten when ReadData() is called.
|
// We don't need to zero the old bytes, since they will be overwritten when ReadData() is called.
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReadInt32() {
|
public int ReadInt32() {
|
||||||
int value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
|
int value = buffer[index] << 24 | buffer[index + 1] << 16 |
|
||||||
Remove( 4 );
|
buffer[index + 2] << 8 | buffer[index + 3];
|
||||||
|
index += 4;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short ReadInt16() {
|
public short ReadInt16() {
|
||||||
short value = (short)( buffer[0] << 8 | buffer[1] );
|
short value = (short)(buffer[index] << 8 | buffer[index + 1]);
|
||||||
Remove( 2 );
|
index += 2;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sbyte ReadInt8() {
|
public sbyte ReadInt8() {
|
||||||
sbyte value = (sbyte)buffer[0];
|
sbyte value = (sbyte)buffer[index];
|
||||||
Remove( 1 );
|
index++;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte ReadUInt8() {
|
public byte ReadUInt8() {
|
||||||
byte value = buffer[0];
|
byte value = buffer[index];
|
||||||
Remove( 1 );
|
index++;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ReadBytes( int length ) {
|
public byte[] ReadBytes( int length ) {
|
||||||
byte[] data = new byte[length];
|
byte[] data = new byte[length];
|
||||||
Buffer.BlockCopy( buffer, 0, data, 0, length );
|
Buffer.BlockCopy( buffer, index, data, 0, length );
|
||||||
Remove( length );
|
index += length;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReadCp437String() {
|
public string ReadCp437String() {
|
||||||
int length = GetString( buffer, false );
|
int length = GetString( false );
|
||||||
Remove( 64 );
|
index += 64;
|
||||||
return new String( characters, 0, length );
|
return new String( characters, 0, length );
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReadAsciiString() {
|
public string ReadAsciiString() {
|
||||||
int length = GetString( buffer, true );
|
int length = GetString( true );
|
||||||
Remove( 64 );
|
index += 64;
|
||||||
return new String( characters, 0, length );
|
return new String( characters, 0, length );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +82,8 @@ namespace ClassicalSharp {
|
|||||||
return ReadCp437String();
|
return ReadCp437String();
|
||||||
|
|
||||||
messageType = (byte)MessageType.Normal;
|
messageType = (byte)MessageType.Normal;
|
||||||
int length = GetString( buffer, false );
|
int length = GetString( false );
|
||||||
Remove( 64 );
|
index += 64;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
if( length >= womDetail.Length && IsWomDetailString() ) {
|
if( length >= womDetail.Length && IsWomDetailString() ) {
|
||||||
@ -97,10 +104,10 @@ namespace ClassicalSharp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetString( byte[] data, bool ascii ) {
|
int GetString( bool ascii ) {
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for( int i = 63; i >= 0; i-- ) {
|
for( int i = 63; i >= 0; i-- ) {
|
||||||
byte code = data[i];
|
byte code = buffer[index + i];
|
||||||
if( length == 0 && !( code == 0 || code == 0x20 ) )
|
if( length == 0 && !( code == 0 || code == 0x20 ) )
|
||||||
length = i + 1;
|
length = i + 1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user