From 76053cb400b55a11669ef56deea6f44f1bc26bed Mon Sep 17 00:00:00 2001
From: lastbattle <4586194+lastbattle@users.noreply.github.com>
Date: Sat, 1 Jan 2022 15:17:21 +0800
Subject: [PATCH] [WzLib] Refractoring
---
.../MapleCryptoLib/MapleCryptoConstants.cs | 2 ++
MapleLib/WzLib/Util/WzBinaryReader.cs | 4 ++--
MapleLib/WzLib/Util/WzBinaryWriter.cs | 23 +++++++++++++++----
MapleLib/WzLib/Util/WzTool.cs | 2 +-
MapleLib/WzLib/WzDirectory.cs | 9 ++++----
MapleLib/WzLib/WzFile.cs | 16 ++++++-------
MapleLib/WzLib/WzImage.cs | 5 ++--
MapleLib/WzLib/WzImageProperty.cs | 4 ++--
.../WzLib/WzProperties/WzBinaryProperty.cs | 2 +-
.../WzLib/WzProperties/WzCanvasProperty.cs | 4 ++--
.../WzLib/WzProperties/WzConvexProperty.cs | 8 ++++---
.../WzLib/WzProperties/WzStringProperty.cs | 2 +-
MapleLib/WzLib/WzProperties/WzSubProperty.cs | 4 ++--
MapleLib/WzLib/WzProperties/WzUOLProperty.cs | 4 ++--
.../WzLib/WzProperties/WzVectorProperty.cs | 4 ++--
MapleLib/WzSettings.cs | 3 ---
16 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/MapleLib/MapleCryptoLib/MapleCryptoConstants.cs b/MapleLib/MapleCryptoLib/MapleCryptoConstants.cs
index fe280570..48f0d8bd 100644
--- a/MapleLib/MapleCryptoLib/MapleCryptoConstants.cs
+++ b/MapleLib/MapleCryptoLib/MapleCryptoConstants.cs
@@ -86,11 +86,13 @@ public static bool IsDefaultMapleStoryUserKey()
};
///
+ /// ?s_BasicKey@CAESCipher@@2PAEA
/// IV used to create the WzKey for GMS
///
public static byte[] WZ_GMSIV = new byte[4] { 0x4D, 0x23, 0xC7, 0x2B };
///
+ /// ?s_BasicKey@CAESCipher@@2PAEA
/// IV used to create the WzKey for the latest version of GMS, MSEA, or KMS
///
public static byte[] WZ_MSEAIV = new byte[4] { 0xB9, 0x7D, 0x63, 0xE9 };
diff --git a/MapleLib/WzLib/Util/WzBinaryReader.cs b/MapleLib/WzLib/Util/WzBinaryReader.cs
index b5ebaae6..3c8f5471 100644
--- a/MapleLib/WzLib/Util/WzBinaryReader.cs
+++ b/MapleLib/WzLib/Util/WzBinaryReader.cs
@@ -204,10 +204,10 @@ public string ReadStringBlock(uint offset)
switch (ReadByte())
{
case 0:
- case 0x73:
+ case WzImage.WzImageHeaderByte_WithoutOffset:
return ReadString();
case 1:
- case 0x1B:
+ case WzImage.WzImageHeaderByte_WithOffset:
return ReadStringAtOffset(offset + ReadInt32());
default:
return "";
diff --git a/MapleLib/WzLib/Util/WzBinaryWriter.cs b/MapleLib/WzLib/Util/WzBinaryWriter.cs
index 46cae7f9..ec05a719 100644
--- a/MapleLib/WzLib/Util/WzBinaryWriter.cs
+++ b/MapleLib/WzLib/Util/WzBinaryWriter.cs
@@ -15,9 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
along with this program. If not, see .*/
using System.Collections;
-using System.Collections.Generic;
using System.IO;
-using System.Text;
using MapleLib.MapleCryptoLib;
namespace MapleLib.WzLib.Util
@@ -29,7 +27,7 @@ public class WzBinaryWriter : BinaryWriter
{
#region Properties
public WzMutableKey WzKey { get; set; }
- public uint Hash { get; set; }
+ public uint Hash { get; }
public Hashtable StringCache { get; set; }
public WzHeader Header { get; set; }
public bool LeaveOpen { get; internal set; }
@@ -37,7 +35,15 @@ public class WzBinaryWriter : BinaryWriter
#region Constructors
public WzBinaryWriter(Stream output, byte[] WzIv)
- : this(output, WzIv, false) { }
+ : this(output, WzIv, false)
+ {
+ this.Hash = 0;
+ }
+
+ public WzBinaryWriter(Stream output, byte[] WzIv, uint Hash)
+ : this(output, WzIv, false) {
+ this.Hash = Hash;
+ }
public WzBinaryWriter(Stream output, byte[] WzIv, bool leaveOpen)
: base(output)
@@ -49,6 +55,12 @@ public WzBinaryWriter(Stream output, byte[] WzIv, bool leaveOpen)
#endregion
#region Methods
+ ///
+ /// ?InternalSerializeString@@YAHPAGPAUIWzArchive@@EE@Z
+ ///
+ ///
+ ///
+ ///
public void WriteStringValue(string s, int withoutOffset, int withOffset)
{
if (s.Length > 4 && StringCache.ContainsKey(s))
@@ -102,6 +114,7 @@ public override void Write(string value)
if (value[i] > sbyte.MaxValue)
{
unicode = true;
+ break;
}
}
@@ -224,7 +237,7 @@ public void WriteOffset(uint value)
{
uint encOffset = (uint)BaseStream.Position;
encOffset = (encOffset - Header.FStart) ^ 0xFFFFFFFF;
- encOffset *= Hash;
+ encOffset *= Hash; // could this be removed?
encOffset -= MapleCryptoConstants.WZ_OffsetConstant;
encOffset = RotateLeft(encOffset, (byte)(encOffset & 0x1F));
uint writeOffset = encOffset ^ (value - (Header.FStart * 2));
diff --git a/MapleLib/WzLib/Util/WzTool.cs b/MapleLib/WzLib/Util/WzTool.cs
index 35552896..baeacd26 100644
--- a/MapleLib/WzLib/Util/WzTool.cs
+++ b/MapleLib/WzLib/Util/WzTool.cs
@@ -249,7 +249,7 @@ public static bool IsDataWzHotfixFile(string path)
{
byte firstByte = reader.ReadByte();
- result = firstByte == WzImage.WzImageHeaderByte; // check the first byte. It should be 0x73 that represends a WzImage
+ result = firstByte == WzImage.WzImageHeaderByte_WithoutOffset; // check the first byte. It should be 0x73 that represends a WzImage
}
return result;
diff --git a/MapleLib/WzLib/WzDirectory.cs b/MapleLib/WzLib/WzDirectory.cs
index 9454fca3..e98a077b 100644
--- a/MapleLib/WzLib/WzDirectory.cs
+++ b/MapleLib/WzLib/WzDirectory.cs
@@ -232,7 +232,7 @@ internal void ParseDirectory(bool lazyParse = false)
reader.BaseStream.Position = rememberPos;
fsize = reader.ReadCompressedInt();
checksum = reader.ReadCompressedInt();
- offset = reader.ReadOffset();
+ offset = reader.ReadOffset(); // IWzArchive::Getposition(pArchive)
if (type == 3)
{
@@ -263,14 +263,15 @@ internal void ParseDirectory(bool lazyParse = false)
}
}
- // Offsets are calculated manually
- if (this.wzFile != null && this.wzFile.b64BitClient) // This only applies for 64-bit client based WZ files.
+ // Offsets are calculated manually as a work-around, until I've figured out how
+ // the new offsets are calculated for 64-bit based WZ file..
+ if (this.wzFile != null && this.wzFile.b64BitClient)
{
long startOffset = reader.BaseStream.Position;
foreach (WzImage image in WzImages)
{
image.Offset = (uint)startOffset;
- startOffset += image.BlockSize; // TODO: Test saving the wz after it is changed. This may break
+ startOffset += image.BlockSize;
}
}
diff --git a/MapleLib/WzLib/WzFile.cs b/MapleLib/WzLib/WzFile.cs
index 4fcea5d6..b0b513c1 100644
--- a/MapleLib/WzLib/WzFile.cs
+++ b/MapleLib/WzLib/WzFile.cs
@@ -224,10 +224,12 @@ internal WzFileParseStatus ParseMainWzDirectory(bool lazyParse = false)
this.Header.Ident = reader.ReadString(4);
this.Header.FSize = reader.ReadUInt64();
this.Header.FStart = reader.ReadUInt32();
- this.Header.Copyright = reader.ReadString((int)(Header.FStart - 17U));
+ //this.Header.Copyright = reader.ReadNullTerminatedString();
+ this.Header.Copyright = reader.ReadString((int)(Header.FStart - 17U));
byte unk1 = reader.ReadByte();
byte[] unk2 = reader.ReadBytes((int)(Header.FStart - (ulong)reader.BaseStream.Position));
+
reader.Header = this.Header;
this.wzVersionHeader = 0;
@@ -258,8 +260,8 @@ internal WzFileParseStatus ParseMainWzDirectory(bool lazyParse = false)
if (!this.b64BitClient)
{
this.versionHash = CheckAndGetVersionHash(wzVersionHeader, mapleStoryPatchVersion);
+ reader.Hash = this.versionHash;
}
- reader.Hash = this.versionHash;
WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this);
directory.ParseDirectory();
this.wzDir = directory;
@@ -276,9 +278,9 @@ private bool TryDecodeWithWZVersionNumber(WzBinaryReader reader, int useWzVersio
this.versionHash = CheckAndGetVersionHash(useWzVersionHeader, mapleStoryPatchVersion);
if (this.versionHash == 0) // ugly hack, but that's the only way if the version number isnt known (nexon stores this in the .exe)
return false;
+ reader.Hash = this.versionHash;
}
- reader.Hash = this.versionHash;
long fallbackOffsetPosition = reader.BaseStream.Position; // save position to rollback to, if should parsing fail from here
WzDirectory testDirectory;
try
@@ -309,8 +311,8 @@ private bool TryDecodeWithWZVersionNumber(WzBinaryReader reader, int useWzVersio
switch (checkByte)
{
- case 0x73:
- case 0x1b:
+ case WzImage.WzImageHeaderByte_WithoutOffset: // 0x73
+ case WzImage.WzImageHeaderByte_WithOffset:
{
WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this);
directory.ParseDirectory(lazyParse);
@@ -511,10 +513,8 @@ public void SaveToDisk(string path, bool? bSaveAs64BitWzFile, WzMapleVersion sav
WzTool.StringCache.Clear();
- using (WzBinaryWriter wzWriter = new WzBinaryWriter(File.Create(path), WzIv))
+ using (WzBinaryWriter wzWriter = new WzBinaryWriter(File.Create(path), WzIv, versionHash))
{
- wzWriter.Hash = versionHash;
-
uint totalLen = wzDir.GetImgOffsets(wzDir.GetOffsets(Header.FStart + 2));
Header.FSize = totalLen - Header.FStart;
for (int i = 0; i < 4; i++)
diff --git a/MapleLib/WzLib/WzImage.cs b/MapleLib/WzLib/WzImage.cs
index 27d250af..1ea0a9cd 100644
--- a/MapleLib/WzLib/WzImage.cs
+++ b/MapleLib/WzLib/WzImage.cs
@@ -31,7 +31,8 @@ public class WzImage : WzObject, IPropertyContainer
{
//TODO: nest wzproperties in a wzsubproperty inside of WzImage
- public const int WzImageHeaderByte = 0x73;
+ public const int WzImageHeaderByte_WithoutOffset = 0x73;
+ public const int WzImageHeaderByte_WithOffset = 0x1B;
#region Fields
internal bool parsed = false;
@@ -355,7 +356,7 @@ public bool ParseImage(bool forceReadFromData = false)
}
return false; // unhandled for now, if it isnt an .lua image
}
- case WzImageHeaderByte:
+ case WzImageHeaderByte_WithoutOffset:
{
string prop = reader.ReadString();
ushort val = reader.ReadUInt16();
diff --git a/MapleLib/WzLib/WzImageProperty.cs b/MapleLib/WzLib/WzImageProperty.cs
index d688dfd5..babf06a1 100644
--- a/MapleLib/WzLib/WzImageProperty.cs
+++ b/MapleLib/WzLib/WzImageProperty.cs
@@ -193,10 +193,10 @@ internal static WzExtended ParseExtendedProp(WzBinaryReader reader, uint offset,
switch (reader.ReadByte())
{
case 0x01:
- case 0x1B:
+ case WzImage.WzImageHeaderByte_WithOffset:
return ExtractMore(reader, offset, endOfBlock, name, reader.ReadStringAtOffset(offset + reader.ReadInt32()), parent, imgParent);
case 0x00:
- case 0x73:
+ case WzImage.WzImageHeaderByte_WithoutOffset:
return ExtractMore(reader, offset, endOfBlock, name, "", parent, imgParent);
default:
throw new System.Exception("Invalid byte read at ParseExtendedProp");
diff --git a/MapleLib/WzLib/WzProperties/WzBinaryProperty.cs b/MapleLib/WzLib/WzProperties/WzBinaryProperty.cs
index 60a71de4..1de0a7d1 100644
--- a/MapleLib/WzLib/WzProperties/WzBinaryProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzBinaryProperty.cs
@@ -93,7 +93,7 @@ public override void SetValue(object value)
public override void WriteValue(WzBinaryWriter writer)
{
byte[] data = GetBytes(false);
- writer.WriteStringValue("Sound_DX8", 0x73, 0x1B);
+ writer.WriteStringValue("Sound_DX8", WzImage.WzImageHeaderByte_WithoutOffset, WzImage.WzImageHeaderByte_WithOffset);
writer.Write((byte)0);
writer.WriteCompressedInt(data.Length);
writer.WriteCompressedInt(len_ms);
diff --git a/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs b/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs
index 54fd16a5..26590ff4 100644
--- a/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs
@@ -162,9 +162,9 @@ public override WzImageProperty GetFromPath(string path)
}
return ret;
}
- public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
+ public override void WriteValue(WzBinaryWriter writer)
{
- writer.WriteStringValue("Canvas", 0x73, 0x1B);
+ writer.WriteStringValue("Canvas", WzImage.WzImageHeaderByte_WithoutOffset, WzImage.WzImageHeaderByte_WithOffset);
writer.Write((byte)0);
if (properties.Count > 0) // subproperty in the canvas
{
diff --git a/MapleLib/WzLib/WzProperties/WzConvexProperty.cs b/MapleLib/WzLib/WzProperties/WzConvexProperty.cs
index 2d46ec03..687739ee 100644
--- a/MapleLib/WzLib/WzProperties/WzConvexProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzConvexProperty.cs
@@ -130,11 +130,13 @@ public override WzImageProperty GetFromPath(string path)
}
return ret;
}
- public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
+ public override void WriteValue(WzBinaryWriter writer)
{
List extendedProps = new List(properties.Count);
- foreach (WzImageProperty prop in properties) if (prop is WzExtended) extendedProps.Add((WzExtended)prop);
- writer.WriteStringValue("Shape2D#Convex2D", 0x73, 0x1B);
+ foreach (WzImageProperty prop in properties)
+ if (prop is WzExtended)
+ extendedProps.Add((WzExtended)prop);
+ writer.WriteStringValue("Shape2D#Convex2D", WzImage.WzImageHeaderByte_WithoutOffset, WzImage.WzImageHeaderByte_WithOffset);
writer.WriteCompressedInt(extendedProps.Count);
foreach (WzImageProperty imgProperty in properties)
diff --git a/MapleLib/WzLib/WzProperties/WzStringProperty.cs b/MapleLib/WzLib/WzProperties/WzStringProperty.cs
index 7643cd48..7b21ff66 100644
--- a/MapleLib/WzLib/WzProperties/WzStringProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzStringProperty.cs
@@ -59,7 +59,7 @@ public override WzImageProperty DeepClone()
/// The name of the property
///
public override string Name { get { return name; } set { name = value; } }
- public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
+ public override void WriteValue(WzBinaryWriter writer)
{
writer.Write((byte)8);
writer.WriteStringValue(Value, 0, 1);
diff --git a/MapleLib/WzLib/WzProperties/WzSubProperty.cs b/MapleLib/WzLib/WzProperties/WzSubProperty.cs
index 1a187f25..4232c2c9 100644
--- a/MapleLib/WzLib/WzProperties/WzSubProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzSubProperty.cs
@@ -130,7 +130,7 @@ public override WzImageProperty GetFromPath(string path)
}
return ret;
}
- public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
+ public override void WriteValue(WzBinaryWriter writer)
{
bool bIsLuaProperty = false;
if (properties.Count == 1 && properties[0] is WzLuaProperty)
@@ -138,7 +138,7 @@ public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
bIsLuaProperty = true;
}
if (!bIsLuaProperty)
- writer.WriteStringValue("Property", 0x73, 0x1B);
+ writer.WriteStringValue("Property", WzImage.WzImageHeaderByte_WithoutOffset, WzImage.WzImageHeaderByte_WithOffset);
WzImageProperty.WritePropertyList(writer, properties);
}
diff --git a/MapleLib/WzLib/WzProperties/WzUOLProperty.cs b/MapleLib/WzLib/WzProperties/WzUOLProperty.cs
index 6c299d45..633c8dfc 100644
--- a/MapleLib/WzLib/WzProperties/WzUOLProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzUOLProperty.cs
@@ -105,9 +105,9 @@ public override WzImageProperty GetFromPath(string path)
///
public override WzPropertyType PropertyType { get { return WzPropertyType.UOL; } }
- public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
+ public override void WriteValue(WzBinaryWriter writer)
{
- writer.WriteStringValue("UOL", 0x73, 0x1B);
+ writer.WriteStringValue("UOL", WzImage.WzImageHeaderByte_WithoutOffset, WzImage.WzImageHeaderByte_WithOffset);
writer.Write((byte)0);
writer.WriteStringValue(Value, 0, 1);
}
diff --git a/MapleLib/WzLib/WzProperties/WzVectorProperty.cs b/MapleLib/WzLib/WzProperties/WzVectorProperty.cs
index c6a1eefd..2cf8120d 100644
--- a/MapleLib/WzLib/WzProperties/WzVectorProperty.cs
+++ b/MapleLib/WzLib/WzProperties/WzVectorProperty.cs
@@ -69,9 +69,9 @@ public override WzImageProperty DeepClone()
/// The WzPropertyType of the property
///
public override WzPropertyType PropertyType { get { return WzPropertyType.Vector; } }
- public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer)
+ public override void WriteValue(WzBinaryWriter writer)
{
- writer.WriteStringValue("Shape2D#Vector2D", 0x73, 0x1B);
+ writer.WriteStringValue("Shape2D#Vector2D", WzImage.WzImageHeaderByte_WithoutOffset, WzImage.WzImageHeaderByte_WithOffset);
writer.WriteCompressedInt(X.Value);
writer.WriteCompressedInt(Y.Value);
}
diff --git a/MapleLib/WzSettings.cs b/MapleLib/WzSettings.cs
index 027c3ae2..6af643d9 100644
--- a/MapleLib/WzSettings.cs
+++ b/MapleLib/WzSettings.cs
@@ -15,9 +15,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
along with this program. If not, see .*/
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using MapleLib.WzLib.WzProperties;
using System.Reflection;
using MapleLib.WzLib.WzStructure;