Implement Decompress function fully.
This commit is contained in:
parent
b271d97983
commit
b3b07228a9
|
@ -1,4 +1,5 @@
|
||||||
Worms4Editor/obj/*
|
Worms4Editor/obj/*
|
||||||
Worms4Editor/bin/*
|
Worms4Editor/bin/*
|
||||||
LibXom/obj/*
|
LibXom/obj/*
|
||||||
LibXom/bin/*
|
LibXom/bin/*
|
||||||
|
.vs/*
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace LibXom.Data
|
||||||
|
|
||||||
return DecompressInt(BitConverter.ToInt32(buffer));
|
return DecompressInt(BitConverter.ToInt32(buffer));
|
||||||
}
|
}
|
||||||
public static int[] Decompress(byte[] input)
|
internal static int[] decompressBuffer(byte[] input)
|
||||||
{
|
{
|
||||||
List<int> decompressedData = new List<int>();
|
List<int> decompressedData = new List<int>();
|
||||||
|
|
||||||
|
@ -48,50 +48,21 @@ namespace LibXom.Data
|
||||||
if (unum <= 0xFFFFFFFF) return 4;
|
if (unum <= 0xFFFFFFFF) return 4;
|
||||||
throw new XomException("Number is too large or too small.");
|
throw new XomException("Number is too large or too small.");
|
||||||
}
|
}
|
||||||
private static int decompressInt16(int compressedInt)
|
private static int pow(int val, int pow)
|
||||||
{
|
{
|
||||||
int mul = (compressedInt >> 8);
|
return Convert.ToInt32(Math.Pow(val, pow));
|
||||||
int add = (compressedInt & 0xFF);
|
|
||||||
|
|
||||||
return (mul * 0x80) + (add % 0x80);
|
|
||||||
}
|
}
|
||||||
private static int decompressInt24(int compressedInt)
|
// TODO: Write the inverse of this; "CompressInt()"
|
||||||
{
|
|
||||||
int mul = (compressedInt >> 8) & 0xFF;
|
|
||||||
int mul2 = (compressedInt >> 16);
|
|
||||||
|
|
||||||
int add = (compressedInt & 0xFF);
|
|
||||||
|
|
||||||
return ((mul2 * 0x80) * mul) + (add % 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int decompressInt32(int compressedInt)
|
|
||||||
{
|
|
||||||
int mul = (compressedInt >> 8) & 0xFF;
|
|
||||||
int mul2 = (compressedInt >> 16) & 0xFF;
|
|
||||||
int mul3 = (compressedInt >> 24);
|
|
||||||
|
|
||||||
int add = (compressedInt & 0xFF);
|
|
||||||
|
|
||||||
return (((mul3 * 0x80) * mul2 * 0x80) * mul * 0x80) + (add % 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int DecompressInt(int compressedInt)
|
public static int DecompressInt(int compressedInt)
|
||||||
{
|
{
|
||||||
switch (getNumberByteCount(compressedInt))
|
int b1 = (compressedInt & 0xFF);
|
||||||
{
|
int b2 = (compressedInt >> 8) & 0xFF;
|
||||||
case 1:
|
int b3 = (compressedInt >> 16) & 0xFF;
|
||||||
return compressedInt;
|
int b4 = (compressedInt >> 24) & 0xFF;
|
||||||
case 2:
|
|
||||||
return decompressInt16(compressedInt);
|
return (b4 * pow(0x80, 3)) + ((b3 % 0x80) * pow(0x80, 0x2)) + ((b2 % 0x80) * pow(0x80, 1)) + (b1 % 0x80);
|
||||||
case 3:
|
|
||||||
return decompressInt24(compressedInt);
|
|
||||||
case 4:
|
|
||||||
return decompressInt32(compressedInt);
|
|
||||||
default:
|
|
||||||
throw new XomException("Number is too large or too small.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int NextCompressedInterger(int compressedInt)
|
public static int NextCompressedInterger(int compressedInt)
|
||||||
{
|
{
|
||||||
// Some parts of XOM follow a particular pattern,
|
// Some parts of XOM follow a particular pattern,
|
||||||
|
|
|
@ -26,25 +26,40 @@ namespace LibXom.Data
|
||||||
return this.fileBelongs.calculateIdForXomFileComponent(this.uuid, fileBelongs.XomContainers);
|
return this.fileBelongs.calculateIdForXomFileComponent(this.uuid, fileBelongs.XomContainers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public byte[] Data
|
public byte[] GetData()
|
||||||
{
|
{
|
||||||
get
|
return data;
|
||||||
|
}
|
||||||
|
public void SetData(byte[] data)
|
||||||
|
{
|
||||||
|
this.Type.ReplaceContainerData(this, data);
|
||||||
|
}
|
||||||
|
private byte[] intArrayToByteArray(int[] intArray)
|
||||||
|
{
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
return data;
|
foreach (int i in intArray)
|
||||||
}
|
{
|
||||||
set
|
byte[] buf = BitConverter.GetBytes(i);
|
||||||
{
|
ms.Write(buf, 0, buf.Length);
|
||||||
this.Type.ReplaceContainerData(this, value);
|
}
|
||||||
|
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
return ms.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] Decompress()
|
public int[] Decompress()
|
||||||
{
|
{
|
||||||
byte[] compressedData = new byte[Data.Length - 3];
|
byte[] compressedData = new byte[data.Length - 3];
|
||||||
Array.ConstrainedCopy(Data, 3, compressedData, 0, compressedData.Length);
|
Array.ConstrainedCopy(data, 3, compressedData, 0, compressedData.Length);
|
||||||
return XomCompressor.Decompress(compressedData);
|
return XomCompressor.decompressBuffer(compressedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] DecompressToBytes()
|
||||||
|
{
|
||||||
|
return intArrayToByteArray(this.Decompress());
|
||||||
|
}
|
||||||
internal XomContainer(XomFile fromFile, string fromType, byte[] data)
|
internal XomContainer(XomFile fromFile, string fromType, byte[] data)
|
||||||
{
|
{
|
||||||
fileBelongs = fromFile;
|
fileBelongs = fromFile;
|
||||||
|
|
|
@ -42,12 +42,13 @@ namespace LibXom.Data
|
||||||
return xomContainers.ToArray();
|
return xomContainers.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public XomString GetStringById(int stringId)
|
||||||
|
{
|
||||||
|
return XomStrings[stringId];
|
||||||
|
}
|
||||||
public XomContainer GetContainerById(int containerId)
|
public XomContainer GetContainerById(int containerId)
|
||||||
{
|
{
|
||||||
foreach(XomContainer container in XomContainers)
|
return XomContainers[containerId];
|
||||||
if (container.Id.Equals(containerId)) return container;
|
|
||||||
throw new XomContainerNotFoundException("No container with id " + containerId + " was found.");
|
|
||||||
}
|
}
|
||||||
public XomType GetTypeByName(string typeName)
|
public XomType GetTypeByName(string typeName)
|
||||||
{
|
{
|
||||||
|
@ -58,13 +59,10 @@ namespace LibXom.Data
|
||||||
}
|
}
|
||||||
internal int calculateIdForXomFileComponent(string searchUuid, XomFileComponent[] components)
|
internal int calculateIdForXomFileComponent(string searchUuid, XomFileComponent[] components)
|
||||||
{
|
{
|
||||||
int id = 0;
|
for (int i = 0; i < components.Length; i++)
|
||||||
foreach(XomFileComponent component in components)
|
if (components[i].uuid.Equals(searchUuid, StringComparison.CurrentCultureIgnoreCase)) return i;
|
||||||
{
|
|
||||||
if (component.uuid.Equals(searchUuid, StringComparison.InvariantCultureIgnoreCase)) return id;
|
throw new XomFileComponentNotFoundException("A XOM Components ID could not be found in the Component List.");
|
||||||
id = XomCompressor.NextCompressedInterger(id);
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
internal XomFile(XomBlock[] xomBlocks)
|
internal XomFile(XomBlock[] xomBlocks)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using LibXom.Blocks;
|
using LibXom.Blocks;
|
||||||
using LibXom.Data;
|
using LibXom.Data;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Worms4Editor
|
namespace Worms4Editor
|
||||||
{
|
{
|
||||||
|
@ -9,28 +10,25 @@ namespace Worms4Editor
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine(XomCompressor.DecompressInt(32767).ToString("X"));
|
/* int id = 0;
|
||||||
Console.WriteLine(XomCompressor.DecompressInt(98432).ToString("X"));
|
for (int i = 0; i < 0x7FFFFF; i++) {
|
||||||
Console.WriteLine(XomCompressor.DecompressInt(98433).ToString("X"));
|
|
||||||
Console.WriteLine(XomCompressor.DecompressInt(8388607).ToString("X"));
|
|
||||||
int id = 0;
|
|
||||||
for (int i = 0; i < 0x9000; i++) {
|
|
||||||
int d = XomCompressor.DecompressInt(id);
|
int d = XomCompressor.DecompressInt(id);
|
||||||
if (d != i) Console.WriteLine("FAIL; " + i.ToString("X") + " id " + id.ToString("X") + " d " + d.ToString("X"));
|
if (d != i) Console.WriteLine("FAIL; " + i.ToString("X") + " id " + id.ToString("X") + " d " + d.ToString("X"));
|
||||||
else Console.WriteLine("PASS; " + i.ToString("X") + " id " + id.ToString("X") + " d " + d.ToString("X"));
|
else Console.WriteLine("PASS; " + i.ToString("X") + " id " + id.ToString("X") + " d " + d.ToString("X"));
|
||||||
id = XomCompressor.NextCompressedInterger(id);
|
id = XomCompressor.NextCompressedInterger(id);
|
||||||
}
|
} */
|
||||||
XomFile xfile = XomReader.ReadXomFile(@"SaveGame.xom");
|
XomFile xfile = XomReader.ReadXomFile(@"Original.xom");
|
||||||
XomFile ps2file = XomReader.ReadXomFile(@"ps2.xom");
|
//XomFile ps2file = XomReader.ReadXomFile(@"ps2.xom");
|
||||||
|
|
||||||
XomType type = xfile.GetTypeByName("StoredStatsCollective");
|
XomType type = xfile.GetTypeByName("StoredStatsCollective");
|
||||||
File.WriteAllBytes("StoredStatsCollective.bin", type.Containers.First().Data);
|
XomContainer container = type.Containers.First();
|
||||||
|
File.WriteAllBytes("StoredStatsCollective.bin", container.DecompressToBytes());
|
||||||
|
|
||||||
/*foreach(int d in data)
|
for(int i = 0; i < xfile.XomStrings.Length; i++)
|
||||||
{
|
{
|
||||||
Console.WriteLine(d + ": "+ BitConverter.ToString(ps2file.GetContainerById(d).Data).Replace("-", " "));
|
XomString str = xfile.XomStrings[i];
|
||||||
}*/
|
Console.WriteLine(str.Id.ToString("X") + ": " + str.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue