mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 01:26:50 -04:00
Add simple .zip reader (For reading texture packs), partially addresses #44.
This commit is contained in:
parent
4c73ceb7a6
commit
b6655d54d0
@ -159,11 +159,12 @@
|
||||
<Compile Include="Selections\SelectionManager.cs" />
|
||||
<Compile Include="Singleplayer\Commands.cs" />
|
||||
<Compile Include="Singleplayer\Server.cs" />
|
||||
<Compile Include="TexturePack\TerrainAtlas1D.cs" />
|
||||
<Compile Include="TexturePack\TerrainAtlas2D.cs" />
|
||||
<Compile Include="TexturePack\ZipExtractor.cs" />
|
||||
<Compile Include="Utils\Camera.cs" />
|
||||
<Compile Include="Utils\FastBitmap.cs" />
|
||||
<Compile Include="Utils\FastColour.cs" />
|
||||
<Compile Include="Utils\TerrainAtlas1D.cs" />
|
||||
<Compile Include="Utils\TerrainAtlas2D.cs" />
|
||||
<Compile Include="Utils\TextureRectangle.cs" />
|
||||
<Compile Include="Utils\StringBuffer.cs" />
|
||||
<Compile Include="Utils\Utils.cs" />
|
||||
@ -190,6 +191,7 @@
|
||||
<Folder Include="Game" />
|
||||
<Folder Include="Model" />
|
||||
<Folder Include="Network\Utils" />
|
||||
<Folder Include="TexturePack" />
|
||||
<Folder Include="Singleplayer" />
|
||||
<Folder Include="Utils" />
|
||||
<Folder Include="Physics" />
|
||||
|
70
ClassicalSharp/TexturePack/ZipExtractor.cs
Normal file
70
ClassicalSharp/TexturePack/ZipExtractor.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
|
||||
namespace ClassicalSharp.TexturePack {
|
||||
|
||||
public sealed class ZipExtractor {
|
||||
|
||||
static Encoding enc = Encoding.ASCII;
|
||||
public void Extract( Stream stream ) {
|
||||
|
||||
BinaryReader reader = new BinaryReader( stream );
|
||||
while( true ) {
|
||||
uint sig = reader.ReadUInt32();
|
||||
if( sig == 0x04034b50 ) { // local file header
|
||||
ReadLocalFileHeader( reader );
|
||||
} else if( sig == 0x02014b50 ) { // central directory header
|
||||
break;
|
||||
} else {
|
||||
throw new NotSupportedException( "Unsupported signature: " + sig.ToString( "X8" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadLocalFileHeader( BinaryReader reader ) {
|
||||
ushort versionNeeded = reader.ReadUInt16();
|
||||
ushort flags = reader.ReadUInt16();
|
||||
ushort compressionMethod = reader.ReadUInt16();
|
||||
reader.ReadUInt32(); // last modified
|
||||
reader.ReadUInt32(); // CRC 32
|
||||
int compressedSize = reader.ReadInt32();
|
||||
int uncompressedSize = reader.ReadInt32();
|
||||
ushort fileNameLen = reader.ReadUInt16();
|
||||
ushort extraFieldLen = reader.ReadUInt16();
|
||||
string fileName = enc.GetString( reader.ReadBytes( fileNameLen ) );
|
||||
reader.ReadBytes( extraFieldLen );
|
||||
|
||||
if( versionNeeded > 20 )
|
||||
Utils.LogWarning( "May not be able to properly extract a .zip enty with a version later than 2.0" );
|
||||
|
||||
byte[] data = DecompressEntry( reader, compressionMethod, compressedSize, uncompressedSize );
|
||||
if( data != null )
|
||||
HandleZipEntry( fileName, data );
|
||||
}
|
||||
|
||||
byte[] DecompressEntry( BinaryReader reader, ushort compressionMethod, int compressedSize, int uncompressedSize ) {
|
||||
if( compressionMethod == 0 ) { // Store/Raw
|
||||
return reader.ReadBytes( uncompressedSize );
|
||||
} else if( compressionMethod == 8 ) { // Deflate
|
||||
byte[] data = new byte[uncompressedSize];
|
||||
int index = 0, read = 0;
|
||||
DeflateStream deflater = new DeflateStream( reader.BaseStream, CompressionMode.Decompress );
|
||||
while( index < uncompressedSize &&
|
||||
( read = deflater.Read( data, index, data.Length - index ) ) > 0 ) {
|
||||
index += read;
|
||||
}
|
||||
return data;
|
||||
} else {
|
||||
Utils.LogWarning( "Unsupported .zip entry compression method: " + compressionMethod );
|
||||
reader.ReadBytes( compressedSize );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleZipEntry( string filename, byte[] data ) {
|
||||
Console.WriteLine( filename );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user