mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-19 12:35:52 -04:00
Implement partial default.zip updates.
This commit is contained in:
parent
babf253b59
commit
619fd5ded4
@ -49,11 +49,10 @@ namespace ClassicalSharp.TexturePack {
|
||||
}
|
||||
|
||||
/// <summary> Sets the atlas bitmap that animation frames are contained within. </summary>
|
||||
public void SetAtlas( Bitmap bmp ) {
|
||||
void SetAtlas( Bitmap bmp ) {
|
||||
if( !FastBitmap.CheckFormat( bmp.PixelFormat ) )
|
||||
game.Drawer2D.ConvertTo32Bpp( ref bmp );
|
||||
|
||||
Clear();
|
||||
this.animBmp = bmp;
|
||||
animsBuffer = new FastBitmap( bmp, true, true );
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace Launcher {
|
||||
failed = true;
|
||||
|
||||
if( fetcher.Done ) {
|
||||
if( !fetcher.defaultZipExists ) {
|
||||
if( ResourceList.Files.Count > 0 ) {
|
||||
ResourcePatcher patcher = new ResourcePatcher( fetcher );
|
||||
patcher.Run();
|
||||
}
|
||||
|
@ -17,16 +17,36 @@ namespace Launcher {
|
||||
|
||||
string texDir = Path.Combine( Program.AppDirectory, "texpacks" );
|
||||
string zipPath = Path.Combine( texDir, "default.zip" );
|
||||
defaultZipExists = File.Exists( zipPath );
|
||||
if( defaultZipExists )
|
||||
CheckClassicGuiPng( zipPath );
|
||||
if( !defaultZipExists ) {
|
||||
// classic.jar + 1.6.2.jar + terrain-patch.png + gui.png
|
||||
DownloadSize += (291 + 4621 + 7 + 21) / 1024f;
|
||||
ResourcesCount += 4;
|
||||
AllResourcesExist = false;
|
||||
}
|
||||
bool defaultZipExists = File.Exists( zipPath );
|
||||
if( File.Exists( zipPath ) )
|
||||
CheckDefaultZip( zipPath );
|
||||
|
||||
CheckTexturePack();
|
||||
CheckMusic( audioPath );
|
||||
CheckSounds();
|
||||
}
|
||||
|
||||
void CheckTexturePack() {
|
||||
ushort flags = 0;
|
||||
foreach( var entry in ResourceList.Files )
|
||||
flags |= entry.Value;
|
||||
if( flags != 0 ) AllResourcesExist = false;
|
||||
|
||||
if( (flags & ResourceList.cMask) != 0 ) {
|
||||
DownloadSize += 291/1024f; ResourcesCount++;
|
||||
}
|
||||
if( (flags & ResourceList.mMask) != 0 ) {
|
||||
DownloadSize += 4621/1024f; ResourcesCount++;
|
||||
}
|
||||
if( (flags & ResourceList.tMask) != 0 ) {
|
||||
DownloadSize += 7/1024f; ResourcesCount++;
|
||||
}
|
||||
if( (flags & ResourceList.gMask) != 0 ) {
|
||||
DownloadSize += 21/1024f; ResourcesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMusic( string audioPath ) {
|
||||
string[] files = ResourceList.MusicFiles;
|
||||
for( int i = 0; i < files.Length; i++ ) {
|
||||
string file = Path.Combine( audioPath, files[i] + ".ogg" );
|
||||
@ -37,7 +57,9 @@ namespace Launcher {
|
||||
AllResourcesExist = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CheckSounds() {
|
||||
if( !DigSoundsExist ) {
|
||||
ResourcesCount += ResourceList.DigSounds.Length;
|
||||
DownloadSize += 173 / 1024f;
|
||||
@ -52,22 +74,20 @@ namespace Launcher {
|
||||
public float DownloadSize;
|
||||
public int ResourcesCount;
|
||||
internal bool[] musicExists = new bool[7];
|
||||
internal bool classicGuiPngExists, defaultZipExists;
|
||||
internal bool defaultZipExists;
|
||||
|
||||
void CheckClassicGuiPng( string path ) {
|
||||
void CheckDefaultZip( string path ) {
|
||||
ZipReader reader = new ZipReader();
|
||||
reader.ShouldProcessZipEntry = ShouldProcessZipEntry;
|
||||
reader.ProcessZipEntry = ProcessZipEntry;
|
||||
|
||||
using( Stream src = new FileStream( path, FileMode.Open, FileAccess.Read ) )
|
||||
reader.Extract( src );
|
||||
if( !classicGuiPngExists )
|
||||
defaultZipExists = false;
|
||||
}
|
||||
|
||||
bool ShouldProcessZipEntry( string filename ) {
|
||||
if( filename == "gui_classic.png" )
|
||||
classicGuiPngExists = true;
|
||||
bool ShouldProcessZipEntry( string filename ) {
|
||||
string name = ResourceList.GetFile( filename );
|
||||
ResourceList.Files.Remove( name );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using ClassicalSharp.Network;
|
||||
using ClassicalSharp.TexturePack;
|
||||
|
||||
namespace Launcher {
|
||||
|
||||
@ -23,6 +22,7 @@ namespace Launcher {
|
||||
const string musicUri = "http://s3.amazonaws.com/MinecraftResources/music/";
|
||||
const string newMusicUri = "http://s3.amazonaws.com/MinecraftResources/newmusic/";
|
||||
|
||||
ushort flags;
|
||||
public void DownloadItems( AsyncDownloader downloader, Action<string> setStatus ) {
|
||||
this.downloader = downloader;
|
||||
DownloadMusicFiles();
|
||||
@ -31,12 +31,18 @@ namespace Launcher {
|
||||
stepPatcher = new SoundPatcher( ResourceList.StepSounds, "step_", "classic jar" );
|
||||
stepPatcher.FetchFiles( stepSoundsUri, altStepSoundsUri, this, StepSoundsExist );
|
||||
|
||||
if( !defaultZipExists ) {
|
||||
flags = 0;
|
||||
foreach( var entry in ResourceList.Files )
|
||||
flags |= entry.Value;
|
||||
|
||||
if( (flags & ResourceList.cMask) != 0 )
|
||||
downloader.DownloadData( jarClassicUri, false, "classic_jar" );
|
||||
if( (flags & ResourceList.mMask) != 0 )
|
||||
downloader.DownloadData( jar162Uri, false, "162_jar" );
|
||||
downloader.DownloadData( pngTerrainPatchUri, false, "terrain_patch" );
|
||||
if( (flags & ResourceList.gMask) != 0 )
|
||||
downloader.DownloadData( pngGuiPatchUri, false, "gui_patch" );
|
||||
}
|
||||
if( (flags & ResourceList.tMask) != 0 )
|
||||
downloader.DownloadData( pngTerrainPatchUri, false, "terrain_patch" );
|
||||
SetFirstStatus( setStatus );
|
||||
}
|
||||
|
||||
@ -56,10 +62,7 @@ namespace Launcher {
|
||||
setStatus( MakeNext( ResourceList.MusicFiles[i] ) );
|
||||
return;
|
||||
}
|
||||
|
||||
string next = !DigSoundsExist ? "dig_cloth1" :
|
||||
(!StepSoundsExist ? "step_cloth1" : " classic jar");
|
||||
setStatus( MakeNext( next ) );
|
||||
setStatus( MakeNext( FirstItem() ) );
|
||||
}
|
||||
|
||||
|
||||
@ -74,25 +77,44 @@ namespace Launcher {
|
||||
if( !stepPatcher.CheckDownloaded( this, setStatus ) )
|
||||
return false;
|
||||
|
||||
if( !Download( "classic_jar", "classic jar",
|
||||
"1.6.2 jar", ref jarClassic, setStatus ) )
|
||||
if( !Download( "classic_jar", "classic jar", "1.6.2 jar", ref jarClassic, setStatus ) )
|
||||
return false;
|
||||
if( !Download( "162_jar", "1.6.2 jar",
|
||||
"terrain patch", ref jar162, setStatus ) )
|
||||
if( !Download( "162_jar", "1.6.2 jar", "terrain patch", ref jar162, setStatus ) )
|
||||
return false;
|
||||
if( !Download( "terrain_patch", "terrain.png patch",
|
||||
"gui", ref pngTerrainPatch, setStatus ) )
|
||||
if( !Download( "gui_patch", "gui.png patch", null, ref pngGuiPatch, setStatus ) )
|
||||
return false;
|
||||
if( !Download( "gui_patch", "gui.png patch",
|
||||
null, ref pngGuiPatch, setStatus ) )
|
||||
if( !Download( "terrain_patch", "terrain.png patch", "gui", ref pngTerrainPatch, setStatus ) )
|
||||
return false;
|
||||
|
||||
Done |= IsDone();
|
||||
return true;
|
||||
}
|
||||
|
||||
string FirstItem() {
|
||||
if( !DigSoundsExist ) return "dig_cloth1";
|
||||
if( !StepSoundsExist ) return "step_cloth1";
|
||||
|
||||
bool done = !defaultZipExists ? pngGuiPatch != null :
|
||||
stepPatcher.Done;
|
||||
if( done ) {
|
||||
Done = true;
|
||||
return true;
|
||||
}
|
||||
if( (flags & ResourceList.cMask) != 0 )
|
||||
return "classic jar";
|
||||
if( (flags & ResourceList.mMask) != 0 )
|
||||
return "1.6.2 jar";
|
||||
if( (flags & ResourceList.gMask) != 0 )
|
||||
return "gui.png patch";
|
||||
if( (flags & ResourceList.tMask) != 0 )
|
||||
return "terrain.png patch";
|
||||
return "(unknown)";
|
||||
}
|
||||
|
||||
bool IsDone() {
|
||||
if( flags == 0 ) return stepPatcher.Done;
|
||||
if( (flags & ResourceList.tMask) != 0 )
|
||||
return pngTerrainPatch != null;
|
||||
if( (flags & ResourceList.gMask) != 0 )
|
||||
return pngGuiPatch != null;
|
||||
if( (flags & ResourceList.mMask) != 0 )
|
||||
return jar162 != null;
|
||||
if( (flags & ResourceList.cMask) != 0 )
|
||||
return jarClassic != null;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -151,13 +173,11 @@ namespace Launcher {
|
||||
DownloadSize = checker.DownloadSize;
|
||||
ResourcesCount = checker.ResourcesCount;
|
||||
musicExists = checker.musicExists;
|
||||
defaultZipExists = checker.defaultZipExists;
|
||||
}
|
||||
|
||||
public bool AllResourcesExist, DigSoundsExist, StepSoundsExist;
|
||||
public float DownloadSize;
|
||||
public int ResourcesCount, CurrentResource;
|
||||
bool[] musicExists = new bool[7];
|
||||
internal bool defaultZipExists;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
@ -16,65 +17,116 @@ namespace Launcher {
|
||||
pngTerrainPatch = fetcher.pngTerrainPatch;
|
||||
pngGuiPatch = fetcher.pngGuiPatch;
|
||||
}
|
||||
ZipReader reader;
|
||||
ZipWriter writer;
|
||||
Bitmap animBitmap;
|
||||
List<string> existing = new List<string>();
|
||||
|
||||
byte[] jarClassic, jar162, pngTerrainPatch, pngGuiPatch;
|
||||
public void Run() {
|
||||
byte[] jarClassic, jar162, pngTerrainPatch, pngGuiPatch;
|
||||
public void Run() {
|
||||
reader = new ZipReader();
|
||||
reader.ShouldProcessZipEntry = ShouldProcessZipEntry_Classic;
|
||||
reader.ProcessZipEntry = ProcessZipEntry_Classic;
|
||||
string texDir = Path.Combine( Program.AppDirectory, "texpacks" );
|
||||
string path = Path.Combine( texDir, "default.zip" );
|
||||
ExtractExisting( path );
|
||||
|
||||
using( Stream srcClassic = new MemoryStream( jarClassic ),
|
||||
srcModern = new MemoryStream( jar162 ),
|
||||
dst = new FileStream( path, FileMode.Create, FileAccess.Write ) ) {
|
||||
using( Stream dst = new FileStream( path, FileMode.Create, FileAccess.Write ) ) {
|
||||
writer = new ZipWriter( dst );
|
||||
reader.Extract( srcClassic );
|
||||
writer.entries = new ZipEntry[100];
|
||||
for( int i = 0; i < entries.Count; i++ )
|
||||
writer.WriteZipEntry( entries[i], datas[i] );
|
||||
|
||||
// Grab animations and snow
|
||||
animBitmap = new Bitmap( 1024, 64, PixelFormat.Format32bppArgb );
|
||||
reader.ShouldProcessZipEntry = ShouldProcessZipEntry_Modern;
|
||||
reader.ProcessZipEntry = ProcessZipEntry_Modern;
|
||||
reader.Extract( srcModern );
|
||||
|
||||
writer.WriteNewImage( animBitmap, "animations.png" );
|
||||
writer.WriteNewString( animationsTxt, "animations.txt" );
|
||||
using( Bitmap guiBitmap = new Bitmap( new MemoryStream( pngGuiPatch ) ) ) {
|
||||
writer.WriteNewImage( guiBitmap, "gui.png" );
|
||||
ExtractClassic();
|
||||
ExtractModern();
|
||||
if( pngGuiPatch != null ) {
|
||||
using( Bitmap guiBitmap = new Bitmap( new MemoryStream( pngGuiPatch ) ) )
|
||||
writer.WriteNewImage( guiBitmap, "gui.png" );
|
||||
}
|
||||
animBitmap.Dispose();
|
||||
writer.WriteCentralDirectoryRecords();
|
||||
}
|
||||
}
|
||||
ZipReader reader;
|
||||
ZipWriter writer;
|
||||
Bitmap animBitmap;
|
||||
|
||||
|
||||
#region From default.zip
|
||||
|
||||
List<ZipEntry> entries = new List<ZipEntry>();
|
||||
List<byte[]> datas = new List<byte[]>();
|
||||
void ExtractExisting( string path ) {
|
||||
if( !File.Exists( path ) ) return;
|
||||
|
||||
using( Stream src = new FileStream( path, FileMode.Open, FileAccess.Read ) ) {
|
||||
reader.ShouldProcessZipEntry = (file) => true;
|
||||
reader.ProcessZipEntry = ExtractExisting;
|
||||
reader.Extract( src );
|
||||
}
|
||||
}
|
||||
|
||||
void ExtractExisting( string filename, byte[] data, ZipEntry entry ) {
|
||||
filename = ResourceList.GetFile( filename );
|
||||
entry.Filename = filename;
|
||||
existing.Add( filename );
|
||||
entries.Add( entry );
|
||||
datas.Add( data );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region From classic
|
||||
|
||||
void ExtractClassic() {
|
||||
if( jarClassic == null ) return;
|
||||
using( Stream src = new MemoryStream( jarClassic ) ) {
|
||||
reader.ShouldProcessZipEntry = ShouldProcessZipEntry_Classic;
|
||||
reader.ProcessZipEntry = ProcessZipEntry_Classic;
|
||||
reader.Extract( src );
|
||||
}
|
||||
}
|
||||
|
||||
bool ShouldProcessZipEntry_Classic( string filename ) {
|
||||
return filename.StartsWith( "gui" )
|
||||
return filename.StartsWith( "gui" )
|
||||
|| filename.StartsWith( "mob" ) || filename.IndexOf( '/' ) < 0;
|
||||
}
|
||||
|
||||
StringComparison comp = StringComparison.OrdinalIgnoreCase;
|
||||
void ProcessZipEntry_Classic( string filename, byte[] data, ZipEntry entry ) {
|
||||
if( writer.entries == null )
|
||||
writer.entries = new ZipEntry[reader.entries.Length];
|
||||
if( !filename.EndsWith( ".png", comp ) ) return;
|
||||
entry.Filename = ResourceList.GetFile( filename );
|
||||
|
||||
if( filename != "terrain.png" ) {
|
||||
int lastSlash = filename.LastIndexOf( '/' );
|
||||
if( lastSlash >= 0 )
|
||||
entry.Filename = filename.Substring( lastSlash + 1 );
|
||||
if( entry.Filename == "gui.png" )
|
||||
if( entry.Filename != "terrain.png" ) {
|
||||
if( entry.Filename == "gui.png" )
|
||||
entry.Filename = "gui_classic.png";
|
||||
writer.WriteZipEntry( entry, data );
|
||||
if( !existing.Contains( entry.Filename ) )
|
||||
writer.WriteZipEntry( entry, data );
|
||||
return;
|
||||
} else if( !existing.Contains( "terrain.png" ) ){
|
||||
using( Bitmap dstBitmap = new Bitmap( new MemoryStream( data ) ),
|
||||
maskBitmap = new Bitmap( new MemoryStream( pngTerrainPatch ) ) ) {
|
||||
PatchImage( dstBitmap, maskBitmap );
|
||||
writer.WriteNewImage( dstBitmap, "terrain.png" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region From Modern
|
||||
|
||||
void ExtractModern() {
|
||||
if( jar162 == null ) return;
|
||||
|
||||
using( Bitmap dstBitmap = new Bitmap( new MemoryStream( data ) ),
|
||||
maskBitmap = new Bitmap( new MemoryStream( pngTerrainPatch ) ) ) {
|
||||
PatchImage( dstBitmap, maskBitmap );
|
||||
writer.WriteNewImage( dstBitmap, "terrain.png" );
|
||||
using( Stream src = new MemoryStream( jar162 ) ) {
|
||||
// Grab animations and snow
|
||||
animBitmap = new Bitmap( 1024, 64, PixelFormat.Format32bppArgb );
|
||||
reader.ShouldProcessZipEntry = ShouldProcessZipEntry_Modern;
|
||||
reader.ProcessZipEntry = ProcessZipEntry_Modern;
|
||||
reader.Extract( src );
|
||||
|
||||
if( !existing.Contains( "animations.png" ) )
|
||||
writer.WriteNewImage( animBitmap, "animations.png" );
|
||||
if( !existing.Contains( "animations.txt" ) )
|
||||
writer.WriteNewString( animationsTxt, "animations.txt" );
|
||||
animBitmap.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,14 +140,15 @@ namespace Launcher {
|
||||
}
|
||||
|
||||
void ProcessZipEntry_Modern( string filename, byte[] data, ZipEntry entry ) {
|
||||
entry.Filename = ResourceList.GetFile( filename );
|
||||
switch( filename ) {
|
||||
case "assets/minecraft/textures/environment/snow.png":
|
||||
entry.Filename = "snow.png";
|
||||
writer.WriteZipEntry( entry, data );
|
||||
if( !existing.Contains( "snow.png" ) )
|
||||
writer.WriteZipEntry( entry, data );
|
||||
break;
|
||||
case "assets/minecraft/textures/entity/chicken.png":
|
||||
entry.Filename = "mob/chicken.png";
|
||||
writer.WriteZipEntry( entry, data );
|
||||
if( !existing.Contains( "chicken.png" ) )
|
||||
writer.WriteZipEntry( entry, data );
|
||||
break;
|
||||
case "assets/minecraft/textures/blocks/water_still.png":
|
||||
PatchDefault( data, 0 );
|
||||
@ -109,6 +162,8 @@ namespace Launcher {
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
unsafe void PatchImage( Bitmap dstBitmap, Bitmap maskBitmap ) {
|
||||
using( FastBitmap dst = new FastBitmap( dstBitmap, true, false ),
|
||||
src = new FastBitmap( maskBitmap, true, true ) ) {
|
||||
|
@ -1,28 +1,30 @@
|
||||
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using ClassicalSharp.TexturePack;
|
||||
|
||||
namespace Launcher {
|
||||
|
||||
public sealed class ResourceList {
|
||||
|
||||
// Nibbles: Classic jar, 1.6.2 jar, gui patch, terrain patch
|
||||
public const ushort cMask = 0xF000;
|
||||
public const ushort mMask = 0x0F00;
|
||||
public const ushort gMask = 0x00F0;
|
||||
public const ushort tMask = 0x000F;
|
||||
|
||||
public static Dictionary<string, ushort> Files = new Dictionary<string, ushort>() {
|
||||
// classic jar files
|
||||
{ "char.png", 0x1000 }, { "clouds.png", 0x1000 },
|
||||
{ "default.png", 0x1000 }, { "particles.png", 0x1000 },
|
||||
{ "rain.png", 0x1000 }, { "terrain.png", 0x1001 },
|
||||
{ "gui.png", 0x1000 }, { "icons.png", 0x1000 },
|
||||
{ "arrows.png", 0x1000 }, { "sign.png", 0x1000 },
|
||||
{ "creeper.png", 0x1000 }, { "pig.png", 0x1000 },
|
||||
{ "sheep.png", 0x1000 }, { "sheep_fur.png", 0x1000 },
|
||||
{ "skeleton.png", 0x1000 }, { "spider.png", 0x1000 },
|
||||
{ "zombie.png", 0x1000 },
|
||||
{ "char.png", cMask }, { "clouds.png", cMask },
|
||||
{ "default.png", cMask }, { "particles.png", cMask },
|
||||
{ "rain.png", cMask }, { "terrain.png", cMask | tMask },
|
||||
{ "gui_classic.png", cMask }, { "icons.png", cMask },
|
||||
//{ "arrows.png", cMask }, { "sign.png", cMask },
|
||||
{ "creeper.png", cMask }, { "pig.png", cMask },
|
||||
{ "sheep.png", cMask }, { "sheep_fur.png", cMask },
|
||||
{ "skeleton.png", cMask }, { "spider.png", cMask },
|
||||
{ "zombie.png", cMask },
|
||||
// Other files
|
||||
{ "snow.png", 0x0100 }, { "chicken.png", 0x0100 },
|
||||
{ "animations.png", 0x0100 }, { "gui_classic.png", 0x0010 },
|
||||
{ "snow.png", mMask }, { "chicken.png", mMask },
|
||||
{ "animations.png", mMask }, { "gui.png", gMask },
|
||||
};
|
||||
|
||||
public static string[] DigSounds = new [] { "Acloth1", "Acloth2", "Acloth3", "Acloth4", "Bglass1",
|
||||
@ -36,5 +38,15 @@ namespace Launcher {
|
||||
"Astone3", "Astone4", "Awood1", "Awood2", "Awood3", "Awood4" };
|
||||
|
||||
public static string[] MusicFiles = new [] { "calm1", "calm2", "calm3", "hal1", "hal2", "hal3", "hal4" };
|
||||
|
||||
public static string GetFile( string path ) {
|
||||
// Ignore directories: convert x/name to name and x\name to name.
|
||||
string name = path.ToLower();
|
||||
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 );
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user