mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 01:21:57 -05:00
Use DeflateStream instead of GZipStream, add basic GZip header reader.
This commit is contained in:
parent
d49c90c917
commit
9e53f84b88
3 changed files with 124 additions and 12 deletions
|
@ -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
107
Network/GZipHeaderReader.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue