Skip to content

Commit

Permalink
[WzLib] Improve the write speed of wz when saving
Browse files Browse the repository at this point in the history
- the .wz file is re-opened each time it is trying to dump a new directory or image.
  • Loading branch information
eaxvac committed Jul 12, 2020
1 parent a9f2ea6 commit 6093ec6
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 71 deletions.
13 changes: 3 additions & 10 deletions HaCreator/GUI/Repack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace HaCreator.GUI
{
public partial class Repack : Form
{
List<WzFile> toRepack = new List<WzFile>();
private readonly List<WzFile> toRepack = new List<WzFile>();

public Repack()
{
Expand Down Expand Up @@ -103,7 +103,7 @@ private void ChangeRepackState(string state)
/// <param name="bSaveFileInHaCreatorDirectory"></param>
private void FinishSuccess(bool bSaveFileInHaCreatorDirectory)
{
MessageBox.Show("Repacked successfully. " + (!bSaveFileInHaCreatorDirectory ? "press OK to restart." : "Please replace the files in HaCreator\\Output."));
MessageBox.Show("Repacked successfully. " + (!bSaveFileInHaCreatorDirectory ? "Please replace the files under the MapleStory directory." : "Please replace the files in HaCreator\\Output."));

if (!bSaveFileInHaCreatorDirectory)
{
Expand Down Expand Up @@ -247,14 +247,7 @@ private void RepackerThread()

if (!bSaveFileInHaCreatorDirectory) // only replace the original file if its saving in the maplestory folder
{
string buPath = Path.Combine(orgBackupDir, Path.GetFileName(orgFile));
// Try to backup to /Originals/ First, if there is already a file there, we are not original, so just backup to /Backup/
if (File.Exists(buPath))
{
buPath = Path.Combine(backupDir, Path.GetFileName(orgFile));
}
File.Move(orgFile, buPath);
File.Move(tmpFile, orgFile);
File.Move(tmpFile, orgFile + "_NewCreated.wz");
}
}
catch (Exception e)
Expand Down
4 changes: 2 additions & 2 deletions MapleLib/WzLib/Spine/WzSpineAnimationItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ public void LoadResources(GraphicsDevice graphicsDevice)
}

bool pma;
if (wzSpineAtlasPropertyNode.parent is WzImageProperty)
pma = ((WzImageProperty)wzSpineAtlasPropertyNode.parent)["PMA"].ReadValue(0) > 0;
if (wzSpineAtlasPropertyNode.parent is WzImageProperty imgProperty)
pma = imgProperty["PMA"].ReadValue(0) > 0;
else
pma = ((WzImage)wzSpineAtlasPropertyNode.parent)["PMA"].ReadValue(0) > 0;

Expand Down
7 changes: 3 additions & 4 deletions MapleLib/WzLib/Spine/WzSpineAtlasLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,10 @@ private static bool TryLoadSkeletonJsonOrBinary(WzImageProperty atlasNode, Atlas
// try read binary based
foreach (WzImageProperty property in childProperties)
{
if (property is WzBinaryProperty)
// should be called binaryproperty actually
if (property is WzBinaryProperty soundProp)
{
WzBinaryProperty soundProp = (WzBinaryProperty)property; // should be called binaryproperty actually

using (MemoryStream ms = new MemoryStream(soundProp.GetBytes(false)))
using (MemoryStream ms = new MemoryStream(soundProp.GetBytes(false)))
{
SkeletonBinary skeletonBinary = new SkeletonBinary(atlas);
data = skeletonBinary.ReadSkeletonData(ms);
Expand Down
12 changes: 6 additions & 6 deletions MapleLib/WzLib/Spine/WzSpineTextureLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,22 @@ public void Load(AtlasPage page, string path)
WzCanvasProperty canvasProperty = null;

WzImageProperty imageChild = (WzImageProperty)ParentNode[path];
if (imageChild is WzUOLProperty)
if (imageChild is WzUOLProperty uolProperty)
{
WzObject uolLink = ((WzUOLProperty)imageChild).LinkValue;
WzObject uolLink = uolProperty.LinkValue;

if (uolLink is WzCanvasProperty)
if (uolLink is WzCanvasProperty uolPropertyLink)
{
canvasProperty = (WzCanvasProperty)uolLink;
canvasProperty = uolPropertyLink;
}
else
{
// other unimplemented prop?
}
}
else if (imageChild is WzCanvasProperty)
else if (imageChild is WzCanvasProperty property)
{
canvasProperty = (WzCanvasProperty)imageChild;
canvasProperty = property;
}

if (canvasProperty != null)
Expand Down
2 changes: 1 addition & 1 deletion MapleLib/WzLib/Util/WzBinaryWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void WriteStringValue(string s, int withoutOffset, int withOffset)

public void WriteWzObjectValue(string s, byte type)
{
string storeName = type + "_" + s;
string storeName = string.Format("{0}_{1}", type, s);
if (s.Length > 4 && StringCache.ContainsKey(storeName))
{
Write((byte)2);
Expand Down
76 changes: 40 additions & 36 deletions MapleLib/WzLib/WzDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,10 @@ internal void SaveImages(BinaryWriter wzWriter, FileStream fs)
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <param name="useIv">The IV to use while generating the data file. If null, it'll use the WzDirectory default</param>
/// <param name="prevOpenedStream">The previously opened file stream</param>
/// <returns></returns>
internal int GenerateDataFile(string fileName, byte[] useIv)
internal int GenerateDataFile(byte[] useIv, FileStream prevOpenedStream)
{
bool useCustomIv = useIv != null; // whole shit gonna be re-written if its a custom IV specified

Expand All @@ -330,63 +330,67 @@ internal int GenerateDataFile(string fileName, byte[] useIv)
size = WzTool.GetCompressedIntLength(entryCount);
offsetSize = WzTool.GetCompressedIntLength(entryCount);

using (FileStream fileWrite = new FileStream(fileName, FileMode.Append, FileAccess.Write))
foreach (WzImage img in images)
{
foreach (WzImage img in images)
if (useCustomIv || img.bIsImageChanged)
{
if (useCustomIv || img.bIsImageChanged)
using (MemoryStream memStream = new MemoryStream())
{
using (MemoryStream memStream = new MemoryStream())
using (WzBinaryWriter imgWriter = new WzBinaryWriter(memStream, useCustomIv ? useIv : this.WzIv))
{
using (WzBinaryWriter imgWriter = new WzBinaryWriter(memStream, useCustomIv ? useIv : this.WzIv))
{
img.SaveImage(imgWriter, useCustomIv);
img.SaveImage(imgWriter, useCustomIv);

img.CalculateAndSetImageChecksum(memStream.ToArray()); // checksum
img.CalculateAndSetImageChecksum(memStream.ToArray()); // checksum

img.tempFileStart = fileWrite.Position;
fileWrite.Write(memStream.ToArray(), 0, (int)memStream.Length);
img.tempFileEnd = fileWrite.Position;
}
img.tempFileStart = prevOpenedStream.Position;
prevOpenedStream.Write(memStream.ToArray(), 0, (int)memStream.Length);
img.tempFileEnd = prevOpenedStream.Position;
}
}
else
{
img.tempFileStart = img.offset;
img.tempFileEnd = img.offset + img.size;
}
img.UnparseImage();

int nameLen = WzTool.GetWzObjectValueLength(img.name, 4);
size += nameLen;
int imgLen = img.size;
size += WzTool.GetCompressedIntLength(imgLen);
size += imgLen;
size += WzTool.GetCompressedIntLength(img.Checksum);
size += 4;
offsetSize += nameLen;
offsetSize += WzTool.GetCompressedIntLength(imgLen);
offsetSize += WzTool.GetCompressedIntLength(img.Checksum);
offsetSize += 4;

// otherwise Item.wz (300MB) probably uses > 4GB
GC.Collect();
}
else
{
img.tempFileStart = img.offset;
img.tempFileEnd = img.offset + img.size;
}
img.UnparseImage();

int nameLen = WzTool.GetWzObjectValueLength(img.name, 4);
size += nameLen;
int imgLen = img.size;
size += WzTool.GetCompressedIntLength(imgLen);
size += imgLen;
size += WzTool.GetCompressedIntLength(img.Checksum);
size += 4;
offsetSize += nameLen;
offsetSize += WzTool.GetCompressedIntLength(imgLen);
offsetSize += WzTool.GetCompressedIntLength(img.Checksum);
offsetSize += 4;

// otherwise Item.wz (300MB) probably uses > 4GB
if (useCustomIv) // when using custom IV, or changing IVs, all images have to be re-read and re-written..
{
GC.Collect(); // GC slows down writing of maps in HaCreator
GC.WaitForPendingFinalizers();
}

//Debug.WriteLine("Writing image :" + img.FullPath);
}

foreach (WzDirectory dir in subDirs)
{
int nameLen = WzTool.GetWzObjectValueLength(dir.name, 3);
size += nameLen;
size += dir.GenerateDataFile(fileName, useIv);
size += dir.GenerateDataFile(useIv, prevOpenedStream);
size += WzTool.GetCompressedIntLength(dir.size);
size += WzTool.GetCompressedIntLength(dir.Checksum);
size += 4;
offsetSize += nameLen;
offsetSize += WzTool.GetCompressedIntLength(dir.size);
offsetSize += WzTool.GetCompressedIntLength(dir.Checksum);
offsetSize += 4;

//Debug.WriteLine("Writing dir :" + dir.FullPath);
}
return size;
}
Expand Down
5 changes: 4 additions & 1 deletion MapleLib/WzLib/WzFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,10 @@ public void SaveToDisk(string path, WzMapleVersion savingToPreferredWzVer = WzMa

string tempFile = Path.GetFileNameWithoutExtension(path) + ".TEMP";
File.Create(tempFile).Close();
wzDir.GenerateDataFile(tempFile, bIsWzIvSimilar ? null : WzIv);
using (FileStream fs = new FileStream(tempFile, FileMode.Append, FileAccess.Write))
{
wzDir.GenerateDataFile(bIsWzIvSimilar ? null : WzIv, fs);
}

WzTool.StringCache.Clear();
uint totalLen = wzDir.GetImgOffsets(wzDir.GetOffsets(Header.FStart + 2));
Expand Down
14 changes: 3 additions & 11 deletions MapleLib/WzLib/WzProperties/WzBinaryProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

namespace MapleLib.WzLib.WzProperties
{
public enum WzSoundPropertyType
public enum WzBinaryPropertyType
{
Binary,
Raw, // could be anything..
MP3,
WAV,
}
Expand Down Expand Up @@ -166,14 +166,6 @@ public WzBinaryProperty(string name, WzBinaryReader reader, bool parseNow)
reader.BaseStream.Position += soundDataLen;
}

/*public WzSoundProperty(string name)
{
this.name = name;
this.len_ms = 0;
this.header = null;
this.mp3bytes = null;
}*/

/// <summary>
/// Creates a WzSoundProperty with the specified name and data from another WzSoundProperty Object
/// </summary>
Expand Down Expand Up @@ -246,7 +238,7 @@ public WzBinaryProperty(string name, string file)
this.mp3bytes = File.ReadAllBytes(file);
}

public static bool memcmp(byte[] a, byte[] b, int n)
public static bool Memcmp(byte[] a, byte[] b, int n)
{
for (int i = 0; i < n; i++)
{
Expand Down

0 comments on commit 6093ec6

Please sign in to comment.