2016-06-11 15:29:45 +10:00
|
|
|
|
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
|
|
|
using System;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using ClassicalSharp.GraphicsAPI;
|
|
|
|
|
using ClassicalSharp.Model;
|
2016-09-11 12:45:23 +10:00
|
|
|
|
using ClassicalSharp.Network;
|
2016-07-13 22:48:28 +10:00
|
|
|
|
#if ANDROID
|
|
|
|
|
using Android.Graphics;
|
|
|
|
|
#endif
|
2016-07-14 11:29:54 +10:00
|
|
|
|
using PathIO = System.IO.Path; // Android.Graphics.Path clash otherwise
|
2016-06-11 15:29:45 +10:00
|
|
|
|
|
|
|
|
|
namespace ClassicalSharp.TexturePack {
|
|
|
|
|
|
|
|
|
|
/// <summary> Extracts resources from a .zip texture pack. </summary>
|
|
|
|
|
public sealed class TexturePackExtractor {
|
|
|
|
|
|
|
|
|
|
public const string Dir = "texpacks";
|
|
|
|
|
Game game;
|
|
|
|
|
public void Extract( string path, Game game ) {
|
2016-09-11 11:58:59 +10:00
|
|
|
|
path = PathIO.Combine( Dir, path );
|
|
|
|
|
path = PathIO.Combine( Program.AppDirectory, path );
|
|
|
|
|
using( Stream fs = File.OpenRead( path ) )
|
2016-06-11 15:29:45 +10:00
|
|
|
|
Extract( fs, game );
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-11 11:58:59 +10:00
|
|
|
|
public void Extract( Stream stream, Game game ) {
|
2016-06-11 15:29:45 +10:00
|
|
|
|
this.game = game;
|
|
|
|
|
game.Events.RaiseTexturePackChanged();
|
|
|
|
|
ZipReader reader = new ZipReader();
|
|
|
|
|
|
|
|
|
|
reader.ShouldProcessZipEntry = (f) => true;
|
|
|
|
|
reader.ProcessZipEntry = ProcessZipEntry;
|
|
|
|
|
reader.Extract( stream );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProcessZipEntry( string filename, byte[] data, ZipEntry entry ) {
|
|
|
|
|
// Ignore directories: convert x/name to name and x\name to name.
|
2016-08-15 20:00:57 +10:00
|
|
|
|
string name = Utils.ToLower( filename );
|
2016-06-11 15:29:45 +10:00
|
|
|
|
int i = name.LastIndexOf( '\\' );
|
|
|
|
|
if( i >= 0 ) name = name.Substring( i + 1, name.Length - 1 - i );
|
|
|
|
|
i = name.LastIndexOf( '/' );
|
|
|
|
|
if( i >= 0 ) name = name.Substring( i + 1, name.Length - 1 - i );
|
|
|
|
|
game.Events.RaiseTextureChanged( name, data );
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-11 12:45:23 +10:00
|
|
|
|
|
|
|
|
|
internal static void ExtractTerrainPng( Game game, DownloadedItem item ) {
|
|
|
|
|
if( item.Data != null ) {
|
|
|
|
|
Bitmap bmp = (Bitmap)item.Data;
|
|
|
|
|
game.World.TextureUrl = item.Url;
|
|
|
|
|
game.Events.RaiseTexturePackChanged();
|
|
|
|
|
|
|
|
|
|
if( !Platform.Is32Bpp( bmp ) ) {
|
|
|
|
|
Utils.LogDebug( "Converting terrain atlas to 32bpp image" );
|
|
|
|
|
game.Drawer2D.ConvertTo32Bpp( ref bmp );
|
|
|
|
|
}
|
|
|
|
|
if( !game.ChangeTerrainAtlas( bmp, null ) ) { bmp.Dispose(); return; }
|
|
|
|
|
|
|
|
|
|
TextureCache.Add( item.Url, bmp );
|
|
|
|
|
TextureCache.AddETag( item.Url, item.ETag, game.ETags );
|
|
|
|
|
TextureCache.AdddLastModified( item.Url, item.LastModified, game.LastModified );
|
|
|
|
|
} else {
|
|
|
|
|
FileStream data = TextureCache.GetStream( item.Url );
|
|
|
|
|
if( data == null ) { // e.g. 404 errors
|
|
|
|
|
ExtractDefault( game );
|
|
|
|
|
} else if( item.Url != game.World.TextureUrl ) {
|
|
|
|
|
Bitmap bmp = GetBitmap( data );
|
|
|
|
|
if( bmp == null ) { data.Dispose(); return; }
|
|
|
|
|
|
|
|
|
|
game.World.TextureUrl = item.Url;
|
|
|
|
|
game.Events.RaiseTexturePackChanged();
|
|
|
|
|
if( game.ChangeTerrainAtlas( bmp, data ) ) return;
|
|
|
|
|
|
|
|
|
|
bmp.Dispose();
|
|
|
|
|
data.Dispose();
|
|
|
|
|
} else {
|
|
|
|
|
data.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void ExtractTexturePack( Game game, DownloadedItem item ) {
|
|
|
|
|
if( item.Data != null ) {
|
|
|
|
|
game.World.TextureUrl = item.Url;
|
|
|
|
|
byte[] data = (byte[])item.Data;
|
|
|
|
|
TexturePackExtractor extractor = new TexturePackExtractor();
|
|
|
|
|
using( Stream ms = new MemoryStream( data ) ) {
|
|
|
|
|
extractor.Extract( ms, game );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TextureCache.Add( item.Url, data );
|
|
|
|
|
TextureCache.AddETag( item.Url, item.ETag, game.ETags );
|
|
|
|
|
TextureCache.AdddLastModified( item.Url, item.LastModified, game.LastModified );
|
|
|
|
|
} else {
|
|
|
|
|
FileStream data = TextureCache.GetStream( item.Url );
|
|
|
|
|
if( data == null ) { // e.g. 404 errors
|
|
|
|
|
ExtractDefault( game );
|
|
|
|
|
} else if( item.Url != game.World.TextureUrl ) {
|
|
|
|
|
game.World.TextureUrl = item.Url;
|
|
|
|
|
TexturePackExtractor extractor = new TexturePackExtractor();
|
|
|
|
|
extractor.Extract( data, game );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal static void ExtractDefault( Game game ) {
|
|
|
|
|
TexturePackExtractor extractor = new TexturePackExtractor();
|
|
|
|
|
extractor.Extract( game.DefaultTexturePack, game );
|
|
|
|
|
game.World.TextureUrl = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Bitmap GetBitmap( FileStream fs ) {
|
|
|
|
|
try {
|
|
|
|
|
return Platform.ReadBmp( fs );
|
|
|
|
|
} catch( ArgumentException ex ) {
|
|
|
|
|
ErrorHandler.LogError( "Cache.GetBitmap", ex );
|
|
|
|
|
return null;
|
|
|
|
|
} catch( IOException ex ) {
|
|
|
|
|
ErrorHandler.LogError( "Cache.GetBitmap", ex );
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-06-11 15:29:45 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|