Use DeflateStream instead of GZipStream, add basic GZip header reader.

This commit is contained in:
UnknownShadow200 2015-05-31 06:48:06 +10:00
parent d49c90c917
commit 9e53f84b88
3 changed files with 124 additions and 12 deletions

View file

@ -127,6 +127,7 @@
<Compile Include="Network\Enums.cs" />
<Compile Include="Network\FastNetReader.cs" />
<Compile Include="Network\FixedBufferStream.cs" />
<Compile Include="Network\GZipHeaderReader.cs" />
<Compile Include="Network\NetworkProcessor.cs" />
<Compile Include="Network\AsyncDownloader.cs" />
<Compile Include="Network\WomConfigHandler.cs" />

107
Network/GZipHeaderReader.cs Normal file
View file

@ -0,0 +1,107 @@
using System;
using System.IO;
namespace ClassicalSharp {
internal class GZipHeaderReader {
enum State {
Header1,
Header2,
CompressionMethod,
Flags,
LastModifiedTime,
CompressionFlags,
OperatingSystem,
HeaderChecksum,
Done,
}
State state = State.Header1;
public bool done;
int flags;
int partsRead;
public bool ReadHeader( Stream s ) {
switch( state ) {
case State.Header1:
if( !ReadAndCheckHeaderByte( s, 0x1F ) )
return false;
goto case State.Header2;
case State.Header2:
if( !ReadAndCheckHeaderByte( s, 0x8B ) )
return false;
goto case State.CompressionMethod;
case State.CompressionMethod:
if( !ReadAndCheckHeaderByte( s, 0x08 ) )
return false;
goto case State.Flags;
case State.Flags:
if( !ReadHeaderByte( s, out flags ) )
return false;
if( flags >= 0x04 ) // We don't support extra, comment, or original name fields
throw new NotSupportedException( "Unsupported gzip flags: " + flags );
goto case State.LastModifiedTime;
case State.LastModifiedTime:
for( ; partsRead < 4; partsRead++ ) {
int part = s.ReadByte();
if( part == -1 )
return false;
}
partsRead = 0;
state = State.CompressionFlags;
goto case State.CompressionFlags;
case State.CompressionFlags:
int comFlags;
if( !ReadHeaderByte( s, out comFlags ) )
return false;
goto case State.OperatingSystem;
case State.OperatingSystem:
int os;
if( !ReadHeaderByte( s, out os ) )
return false;
goto case State.HeaderChecksum;
case State.HeaderChecksum:
if( ( flags & 0x02 ) != 0 ) {
for( ; partsRead < 2; partsRead++ ) {
int part = s.ReadByte();
if( part == -1 )
return false;
}
}
partsRead = 0;
state = State.Done;
done = true;
return true;
}
return true;
}
bool ReadAndCheckHeaderByte( Stream s, byte expected ) {
int value;
if( !ReadHeaderByte( s, out value ) )
return false;
if( value != expected )
throw new InvalidDataException( "Unepxected constant in GZip header. (" + expected + "-" + value + ")" );
return true;
}
bool ReadHeaderByte( Stream s, out int value ) {
value = s.ReadByte();
if( value == -1 )
return false;
state++;
return true;
}
}
}

View file

@ -120,7 +120,7 @@ namespace ClassicalSharp {
"EmoteFix", "ClickDistance", "HeldBlock", "BlockPermissions",
"SelectionCuboid", "MessageTypes", "CustomBlocks", "EnvColors",
"HackControl", "EnvMapAppearance", "ExtPlayerList", "ChangeModel",
"EnvWeatherType",
"EnvWeatherType",
};
@ -236,7 +236,8 @@ namespace ClassicalSharp {
FastNetReader reader;
int cpeServerExtensionsCount;
DateTime receiveStart;
GZipStream gzipStream;
DeflateStream gzipStream;
GZipHeaderReader gzipHeader;
int mapSizeIndex;
byte[] mapSize = new byte[4];
byte[] map;
@ -286,7 +287,8 @@ namespace ClassicalSharp {
sendWomId = true;
}
receivedFirstPosition = false;
gzipStream = new GZipStream( gzippedMap, CompressionMode.Decompress );
gzipHeader = new GZipHeaderReader();
gzipStream = new DeflateStream( gzippedMap, CompressionMode.Decompress );
mapSizeIndex = 0;
mapIndex = 0;
receiveStart = DateTime.UtcNow;
@ -298,16 +300,18 @@ namespace ClassicalSharp {
gzippedMap.Position = 0;
gzippedMap.SetLength( usedLength );
if( mapSizeIndex < 4 ) {
mapSizeIndex += gzipStream.Read( mapSize, 0, 4 - mapSizeIndex );
}
if( mapSizeIndex == 4 ) {
if( map == null ) {
int size = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
map = new byte[size];
if( gzipHeader.done || gzipHeader.ReadHeader( gzippedMap ) ) {
if( mapSizeIndex < 4 ) {
mapSizeIndex += gzipStream.Read( mapSize, 0, 4 - mapSizeIndex );
}
if( mapSizeIndex == 4 ) {
if( map == null ) {
int size = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
map = new byte[size];
}
mapIndex += gzipStream.Read( map, mapIndex, map.Length - mapIndex );
}
mapIndex += gzipStream.Read( map, mapIndex, map.Length - mapIndex );
}
reader.Remove( 1024 );
byte progress = reader.ReadUInt8();