From 835c9002abe65c4d56fc5047107f77d4413fa657 Mon Sep 17 00:00:00 2001
From: Li
Date: Mon, 9 Jan 2023 05:18:25 -0800
Subject: [PATCH] Add Weapon Factory Parsing pt.1
---
.gitignore | 2 +
LibW4M/Data/SaveDataEntry.cs | 32 ++++++
LibW4M/Data/WeaponFactory/WeaponEntry.cs | 135 +++++++++++++++++++++++
LibW4M/Data/WeaponFactory/WeaponType.cs | 16 +++
LibW4M/LibW4M.csproj | 13 +++
LibW4M/W4SaveFile.cs | 14 +++
LibXom/Data/XomCompressor.cs | 4 +-
LibXom/Data/XomFile.cs | 6 +-
LibXom/Streams/XomStreamReader.cs | 86 +++++++++++++++
LibXom/Streams/XomStreamWriter.cs | 103 +++++++++++++++++
LibXom/XomReader.cs | 106 +++++-------------
LibXom/XomWriter.cs | 135 ++++++-----------------
Worms4Editor.sln | 10 +-
Worms4Editor/Program.cs | 24 ++--
14 files changed, 488 insertions(+), 198 deletions(-)
create mode 100644 LibW4M/Data/SaveDataEntry.cs
create mode 100644 LibW4M/Data/WeaponFactory/WeaponEntry.cs
create mode 100644 LibW4M/Data/WeaponFactory/WeaponType.cs
create mode 100644 LibW4M/LibW4M.csproj
create mode 100644 LibW4M/W4SaveFile.cs
create mode 100644 LibXom/Streams/XomStreamReader.cs
create mode 100644 LibXom/Streams/XomStreamWriter.cs
diff --git a/.gitignore b/.gitignore
index b8d5662..3f9ba73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@ Worms4Editor/obj/*
Worms4Editor/bin/*
LibXom/obj/*
LibXom/bin/*
+LibW4M/obj/*
+LibW4M/bin/*
.vs/*
diff --git a/LibW4M/Data/SaveDataEntry.cs b/LibW4M/Data/SaveDataEntry.cs
new file mode 100644
index 0000000..92667e9
--- /dev/null
+++ b/LibW4M/Data/SaveDataEntry.cs
@@ -0,0 +1,32 @@
+using LibXom.Data;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibW4M.Data
+{
+ internal abstract class SaveDataEntry
+ {
+ internal Guid guid = Guid.NewGuid();
+ internal W4SaveFile fileBelongs;
+ internal XomContainer mainContainer;
+ internal string uuid
+ {
+ get
+ {
+ return guid.ToString();
+ }
+ }
+ public abstract void Delete();
+ public abstract void Load();
+ public abstract void Save();
+ public SaveDataEntry (W4SaveFile fileBelongs, XomContainer mainContainer)
+ {
+ this.fileBelongs = fileBelongs;
+ this.mainContainer = mainContainer;
+ this.Load();
+ }
+ }
+}
diff --git a/LibW4M/Data/WeaponFactory/WeaponEntry.cs b/LibW4M/Data/WeaponFactory/WeaponEntry.cs
new file mode 100644
index 0000000..a5e2653
--- /dev/null
+++ b/LibW4M/Data/WeaponFactory/WeaponEntry.cs
@@ -0,0 +1,135 @@
+using LibXom.Data;
+using LibXom.Streams;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibW4M.Data.WeaponFactory
+{
+ internal class WeaponEntry : SaveDataEntry
+ {
+
+ private int weaponNameId;
+ public string WeaponName
+ {
+ get
+ {
+ return this.fileBelongs.w4Save.GetStringById(this.weaponNameId).Value;
+ }
+ }
+
+ private int weaponType;
+ private WeaponType detonationType;
+
+ private bool homing;
+ private bool homingAvoidLand;
+ private bool effectedByWind;
+ private bool fireOnGround;
+ private bool poison;
+ private int retreatTime;
+
+ private float wormDamageRadius;
+ private float wormDamageMagnitude;
+ private float landDamageRadius;
+
+ private float projectileCollisionRadius;
+ private float push;
+ private int fuseTime;
+
+ private int[] graphicalResourceIds;
+ private int[] graphicalLocatorIds;
+
+ private int launchFX;
+ private int arielFX;
+ private int detonationFX;
+
+ private int payloadResourceId;
+ private int projectileLaunchType;
+ private bool projectilePowersUp;
+ private int projectileNumClusters;
+ private float projectileMaxPower;
+ private float clusterSpread;
+ private float clusterMaxSpeed;
+
+
+ private XomContainer[] dataContainers;
+
+ public WeaponEntry(W4SaveFile fileBelongs, XomContainer mainContainer) : base(fileBelongs, mainContainer)
+ {
+
+ }
+
+ public override void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Load()
+ {
+ int[] sWpFc = this.mainContainer.Decompress();
+ XomContainer top = this.fileBelongs.w4Save.GetContainerById(sWpFc[1]);
+ XomContainer btm = this.fileBelongs.w4Save.GetContainerById(sWpFc[1]);
+
+ // parse top
+ using(XomStreamReader reader = new XomStreamReader(new MemoryStream(top.GetData())))
+ {
+ this.weaponNameId = XomCompressor.DecompressInt(reader.ReadInt32());
+
+ reader.Skip(1);
+ this.detonationType = (WeaponType)reader.ReadInt32();
+
+ reader.Skip(1);
+
+ this.homing = (reader.ReadByte() == 0x01);
+ this.homingAvoidLand = (reader.ReadByte() == 0x01);
+
+ this.effectedByWind = (reader.ReadByte() == 0x01);
+ this.fireOnGround = (reader.ReadByte() == 0x01);
+ this.poison = (reader.ReadByte() == 0x01);
+ this.retreatTime = reader.ReadInt32();
+
+ this.wormDamageRadius = reader.ReadFloat();
+ this.wormDamageMagnitude = reader.ReadFloat();
+ this.landDamageRadius = reader.ReadFloat();
+ this.projectileCollisionRadius = reader.ReadFloat();
+ this.push = reader.ReadFloat();
+
+ this.fuseTime = reader.ReadInt32();
+
+ // read GraphicalResourceIds
+ int totalGraphicalResourceIds = reader.ReadCompressedInt();
+ this.graphicalResourceIds = new int[totalGraphicalResourceIds];
+ for (int i = 0; i < totalGraphicalResourceIds; i++) this.graphicalResourceIds[i] = reader.ReadCompressedInt();
+
+ // read GraphicalLocatorIds
+ int totalGraphicalLocatorIds = reader.ReadCompressedInt();
+ this.graphicalLocatorIds = new int[totalGraphicalLocatorIds];
+ for (int i = 0; i < totalGraphicalLocatorIds; i++) this.graphicalLocatorIds[i] = reader.ReadCompressedInt();
+
+
+ this.launchFX = reader.ReadCompressedInt();
+ this.arielFX = reader.ReadCompressedInt();
+ this.detonationFX = reader.ReadCompressedInt();
+
+ this.payloadResourceId = reader.ReadInt32();
+ this.projectileLaunchType = reader.ReadInt32();
+
+ this.projectilePowersUp = (reader.ReadByte() == 0x01);
+ this.projectileNumClusters = reader.ReadInt32();
+
+ this.projectileMaxPower = reader.ReadFloat();
+ this.clusterSpread = reader.ReadFloat();
+ this.clusterMaxSpeed = reader.ReadFloat();
+ }
+ // parse btm
+ }
+
+ public override void Save()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/LibW4M/Data/WeaponFactory/WeaponType.cs b/LibW4M/Data/WeaponFactory/WeaponType.cs
new file mode 100644
index 0000000..94042fa
--- /dev/null
+++ b/LibW4M/Data/WeaponFactory/WeaponType.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibW4M.Data.WeaponFactory
+{
+ public enum WeaponType : int
+ {
+ StopsMoving = 0,
+ Fuse = 1,
+ User = 2
+ }
+
+}
diff --git a/LibW4M/LibW4M.csproj b/LibW4M/LibW4M.csproj
new file mode 100644
index 0000000..0313e2f
--- /dev/null
+++ b/LibW4M/LibW4M.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/LibW4M/W4SaveFile.cs b/LibW4M/W4SaveFile.cs
new file mode 100644
index 0000000..13a4bbf
--- /dev/null
+++ b/LibW4M/W4SaveFile.cs
@@ -0,0 +1,14 @@
+using LibXom.Data;
+
+namespace LibW4M
+{
+ public class W4SaveFile
+ {
+
+ public XomFile w4Save;
+ public W4SaveFile(XomFile w4Save)
+ {
+ this.w4Save = w4Save;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LibXom/Data/XomCompressor.cs b/LibXom/Data/XomCompressor.cs
index f1fb11b..312f05f 100644
--- a/LibXom/Data/XomCompressor.cs
+++ b/LibXom/Data/XomCompressor.cs
@@ -21,7 +21,7 @@ namespace LibXom.Data
throw new XomException("Number is too large or too small.");
}
- internal static int readCompressedIntFromStream(MemoryStream ms)
+ public static int ReadCompressedIntFromStream(Stream ms)
{
byte[] buffer = new byte[4];
@@ -58,7 +58,7 @@ namespace LibXom.Data
{
while (inputStream.Position < inputStream.Length)
{
- int n = readCompressedIntFromStream(inputStream);
+ int n = ReadCompressedIntFromStream(inputStream);
decompressedData.Add(n);
}
diff --git a/LibXom/Data/XomFile.cs b/LibXom/Data/XomFile.cs
index 0d73dd9..dcc2b3c 100644
--- a/LibXom/Data/XomFile.cs
+++ b/LibXom/Data/XomFile.cs
@@ -44,11 +44,11 @@ namespace LibXom.Data
}
public XomString GetStringById(int stringId)
{
- return XomStrings[stringId];
+ return XomStrings[stringId - 1];
}
public XomContainer GetContainerById(int containerId)
{
- return XomContainers[containerId];
+ return XomContainers[containerId - 1];
}
public XomType GetTypeByName(string typeName)
{
@@ -60,7 +60,7 @@ namespace LibXom.Data
internal int calculateIdForXomFileComponent(string searchUuid, XomFileComponent[] components)
{
for (int i = 0; i < components.Length; i++)
- if (components[i].uuid.Equals(searchUuid, StringComparison.CurrentCultureIgnoreCase)) return i;
+ if (components[i].uuid.Equals(searchUuid, StringComparison.CurrentCultureIgnoreCase)) return i + 1;
throw new XomFileComponentNotFoundException("A XOM Components ID could not be found in the Component List.");
}
diff --git a/LibXom/Streams/XomStreamReader.cs b/LibXom/Streams/XomStreamReader.cs
new file mode 100644
index 0000000..8c4753a
--- /dev/null
+++ b/LibXom/Streams/XomStreamReader.cs
@@ -0,0 +1,86 @@
+using LibXom.Data;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibXom.Streams
+{
+ public class XomStreamReader : IDisposable
+ {
+ private Stream xStream;
+ public Stream BaseStream
+ {
+ get
+ {
+ return xStream;
+ }
+ }
+ public int ReadCompressedInt()
+ {
+ return XomCompressor.ReadCompressedIntFromStream(xStream);
+ }
+ public byte[] ReadBytes(int amt)
+ {
+ byte[] buffer = new byte[amt];
+ xStream.Read(buffer, 0, amt);
+ return buffer;
+ }
+ public byte ReadByte()
+ {
+ return Convert.ToByte(xStream.ReadByte());
+ }
+ public string ReadStrLen(int len)
+ {
+ byte[] buf = ReadBytes(len);
+
+ int rlen = 0;
+ for (rlen = 0; rlen < len; rlen++)
+ if (buf[rlen] == 0) break;
+
+ return Encoding.UTF8.GetString(buf, 0, rlen);
+ }
+ public string ReadCStr()
+ {
+ StringBuilder cstr = new StringBuilder();
+
+ while (true)
+ {
+ char c = (char)ReadByte();
+ if (c == 0) break;
+ cstr.Append(c);
+ }
+
+ return cstr.ToString();
+ }
+ public void Skip(int amt)
+ {
+ xStream.Seek(amt, SeekOrigin.Current);
+ }
+ public float ReadFloat()
+ {
+ return BitConverter.ToSingle(ReadBytes(0x4));
+ }
+ public int ReadInt32()
+ {
+ return BitConverter.ToInt32(ReadBytes(0x4));
+ }
+ public int ReadInt32BE()
+ {
+ byte[] buffer = ReadBytes(0x4);
+ buffer.Reverse();
+ return BitConverter.ToInt32(buffer);
+ }
+
+ public void Dispose()
+ {
+ this.xStream.Dispose();
+ }
+
+ public XomStreamReader(Stream xStream)
+ {
+ this.xStream = xStream;
+ }
+ }
+}
diff --git a/LibXom/Streams/XomStreamWriter.cs b/LibXom/Streams/XomStreamWriter.cs
new file mode 100644
index 0000000..9ae9d4f
--- /dev/null
+++ b/LibXom/Streams/XomStreamWriter.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibXom.Streams
+{
+ public class XomStreamWriter : IDisposable
+ {
+ private Stream xStream;
+ public Stream BaseStream
+ {
+ get
+ {
+ return xStream;
+ }
+ }
+ public void WriteByte(byte b)
+ {
+ xStream.WriteByte(b);
+ }
+ public int Pos()
+ {
+ return Convert.ToInt32(xStream.Position);
+ }
+ public void Rewind(int amt)
+ {
+ xStream.Seek(-amt, SeekOrigin.Current);
+ }
+ public void Skip(int amt)
+ {
+ int cpos = Pos();
+ int len = Convert.ToInt32(xStream.Length);
+ int remain = len - cpos;
+
+ if (amt > remain)
+ {
+ xStream.Seek(remain, SeekOrigin.Current);
+ amt -= remain;
+ WritePadding(0, amt);
+ }
+ else
+ {
+ xStream.Seek(amt, SeekOrigin.Current);
+ }
+ }
+ public void WritePadding(byte pad, int len)
+ {
+ byte[] buf = new byte[len];
+ if (pad != 0)
+ for (int i = 0; i < len; i++)
+ buf[i] = pad;
+ WriteBytes(buf);
+ }
+ public void WriteBytes(byte[] bytes)
+ {
+ xStream.Write(bytes, 0, bytes.Length);
+ }
+ public void WriteInt32(int value)
+ {
+ byte[] buffer = BitConverter.GetBytes(value);
+ WriteBytes(buffer);
+ }
+ public void WriteInt32BE(int value)
+ {
+ byte[] buffer = BitConverter.GetBytes(value);
+ buffer.Reverse();
+ WriteBytes(buffer);
+ }
+
+ public void WriteStrLen(string str, int len)
+ {
+ WriteStr(str);
+
+ int padLen = len - str.Length;
+ if (padLen > 0)
+ Skip(padLen);
+ }
+
+ public void WriteStr(string str)
+ {
+ byte[] buffer = Encoding.UTF8.GetBytes(str);
+ WriteBytes(buffer);
+ }
+
+ public void WriteCStr(string str)
+ {
+ WriteStr(str);
+ WriteByte(0);
+ }
+
+ public void Dispose()
+ {
+ this.xStream.Dispose();
+ }
+
+ public XomStreamWriter(Stream xStream)
+ {
+ this.xStream = xStream;
+ }
+ }
+}
diff --git a/LibXom/XomReader.cs b/LibXom/XomReader.cs
index 265d7c1..c7bbbcb 100644
--- a/LibXom/XomReader.cs
+++ b/LibXom/XomReader.cs
@@ -1,60 +1,14 @@
using LibXom.Blocks;
using LibXom.Data;
+using LibXom.Streams;
+using System.IO;
using System.Text;
namespace LibXom
{
public class XomReader
{
- private Stream xomStream;
- private byte[] readBytes(int amt)
- {
- byte[] buffer = new byte[amt];
- xomStream.Read(buffer, 0, amt);
- return buffer;
- }
- private byte readByte()
- {
- return Convert.ToByte(xomStream.ReadByte());
- }
- private string readStrLen(int len)
- {
- byte[] buf = readBytes(len);
-
- int rlen = 0;
- for (rlen = 0; rlen < len; rlen++)
- if (buf[rlen] == 0) break;
-
- return Encoding.UTF8.GetString(buf, 0, rlen);
- }
- private string readCStr()
- {
- StringBuilder cstr = new StringBuilder();
-
- while (true)
- {
- char c = (char)readByte();
- if (c == 0) break;
- cstr.Append(c);
- }
-
- return cstr.ToString();
- }
- private int readInt32BE()
- {
- byte[] buffer = readBytes(0x4);
- buffer.Reverse();
- return BitConverter.ToInt32(buffer);
- }
- private void skip(int amt)
- {
- xomStream.Seek(amt, SeekOrigin.Current);
- }
- private int readInt32()
- {
- return BitConverter.ToInt32(readBytes(0x4));
- }
-
+ private XomStreamReader xomStream;
public bool bufferEndsWith(List buffer, byte[] search)
{
int len = search.Length;
@@ -79,12 +33,12 @@ namespace LibXom
public CtnrBlock readCtnr()
{
List buffer = new List();
- while (xomStream.Position < xomStream.Length)
+ while (xomStream.BaseStream.Position < xomStream.BaseStream.Length)
{
- buffer.Add(readByte());
+ buffer.Add(xomStream.ReadByte());
if (bufferEndsWith(buffer, Encoding.UTF8.GetBytes("CTNR")))
{
- skip(-4);
+ xomStream.Skip(-4);
int i = buffer.Count - 1;
int endAt = i - 4;
for (; i != endAt; i--)
@@ -97,58 +51,58 @@ namespace LibXom
public MoikBlock readMoik()
{
- int version = readInt32BE();
- skip(0x10);
- int numTypes = readInt32();
- int numCtnr = readInt32();
- int numCtnr2 = readInt32();
- skip(0x1C);
+ int version = xomStream.ReadInt32BE();
+ xomStream.Skip(0x10);
+ int numTypes = xomStream.ReadInt32();
+ int numCtnr = xomStream.ReadInt32();
+ int numCtnr2 = xomStream.ReadInt32();
+ xomStream.Skip(0x1C);
return new MoikBlock(version, numCtnr, numTypes);
}
public TypeBlock readType()
{
- skip(0x4);
- int numCtnr = readInt32();
- skip(0x4);
- byte[] md5 = readBytes(0x10);
- string typeName = readStrLen(0x20);
+ xomStream.Skip(0x4);
+ int numCtnr = xomStream.ReadInt32();
+ xomStream.Skip(0x4);
+ byte[] md5 = xomStream.ReadBytes(0x10);
+ string typeName = xomStream.ReadStrLen(0x20);
return new TypeBlock(numCtnr, md5, typeName);
}
public SchmBlock readSchm()
{
- int unk0 = readInt32();
- int unk1 = readInt32();
- int unk2 = readInt32();
+ int unk0 = xomStream.ReadInt32();
+ int unk1 = xomStream.ReadInt32();
+ int unk2 = xomStream.ReadInt32();
return new SchmBlock(unk0, unk1, unk2);
}
public GuidBlock readGuid()
{
- int unk0 = readInt32();
- int unk1 = readInt32();
- int unk2 = readInt32();
+ int unk0 = xomStream.ReadInt32();
+ int unk1 = xomStream.ReadInt32();
+ int unk2 = xomStream.ReadInt32();
return new GuidBlock(unk0, unk1, unk2);
}
public StrsBlock readStrs()
{
- int numStrs = readInt32();
- int strsSz = readInt32();
+ int numStrs = xomStream.ReadInt32();
+ int strsSz = xomStream.ReadInt32();
int[] offsets = new int[numStrs];
string[] strings = new string[numStrs];
for (int i = 0; i < numStrs; i++)
{
- offsets[i] = readInt32();
+ offsets[i] = xomStream.ReadInt32();
}
for (int i = 0; i < numStrs; i++)
{
- strings[i] = readCStr();
+ strings[i] = xomStream.ReadCStr();
}
return new StrsBlock(numStrs, strsSz, offsets, strings); ;
}
public XomBlock? readBlock()
{
- string hdr = readStrLen(0x4);
+ string hdr = xomStream.ReadStrLen(0x4);
switch (hdr)
{
@@ -171,7 +125,7 @@ namespace LibXom
private XomBlock[] readAllBlocks()
{
List xomBlocks = new List();
- while (xomStream.Position < xomStream.Length)
+ while (xomStream.BaseStream.Position < xomStream.BaseStream.Length)
{
XomBlock? block = readBlock();
if (block == null) break;
@@ -200,7 +154,7 @@ namespace LibXom
}
internal XomReader(Stream xom)
{
- this.xomStream = xom;
+ this.xomStream = new XomStreamReader(xom);
}
}
}
diff --git a/LibXom/XomWriter.cs b/LibXom/XomWriter.cs
index f87b30c..542d72b 100644
--- a/LibXom/XomWriter.cs
+++ b/LibXom/XomWriter.cs
@@ -1,139 +1,66 @@
using LibXom.Blocks;
using LibXom.Data;
+using LibXom.Streams;
using System.Text;
namespace LibXom
{
public class XomWriter
{
- private Stream xomStream;
+ private XomStreamWriter xomStream;
private XomFile xomFile;
-
- private void writeByte(byte b)
- {
- xomStream.WriteByte(b);
- }
- private int pos()
- {
- return Convert.ToInt32(xomStream.Position);
- }
- private void rewind(int amt)
- {
- xomStream.Seek(-amt, SeekOrigin.Current);
- }
- private void skip(int amt)
- {
- int cpos = pos();
- int len = Convert.ToInt32(xomStream.Length);
- int remain = len - cpos;
-
- if(amt > remain)
- {
- xomStream.Seek(remain, SeekOrigin.Current);
- amt -= remain;
- writePadding(0, amt);
- }
- else
- {
- xomStream.Seek(amt, SeekOrigin.Current);
- }
- }
- private void writePadding(byte pad, int len)
- {
- byte[] buf = new byte[len];
- if(pad != 0)
- for(int i = 0; i < len; i++)
- buf[i] = pad;
- writeBytes(buf);
- }
- private void writeBytes(byte[] bytes)
- {
- xomStream.Write(bytes, 0, bytes.Length);
- }
- private void writeInt32(int value)
- {
- byte[] buffer = BitConverter.GetBytes(value);
- writeBytes(buffer);
- }
- private void writeInt32BE(int value)
- {
- byte[] buffer = BitConverter.GetBytes(value);
- buffer.Reverse();
- writeBytes(buffer);
- }
-
- private void writeStrLen(string str, int len)
- {
- writeStr(str);
-
- int padLen = (len - str.Length);
- if (padLen > 0)
- skip(padLen);
- }
-
- private void writeStr(string str)
- {
- byte[] buffer = Encoding.UTF8.GetBytes(str);
- writeBytes(buffer);
- }
-
- private void writeCStr(string str)
- {
- writeStr(str);
- writeByte(0);
- }
private void writeMoik(MoikBlock moikBlock)
{
- writeStr(moikBlock.Name);
- writeInt32BE(moikBlock.Version);
- skip(0x10);
- writeInt32(moikBlock.NumTypes);
- writeInt32(moikBlock.NumCtnr);
- writeInt32(moikBlock.NumCtnr);
- skip(0x1C);
+ xomStream.WriteStr(moikBlock.Name);
+ xomStream.WriteInt32BE(moikBlock.Version);
+ xomStream.Skip(0x10);
+ xomStream.WriteInt32(moikBlock.NumTypes);
+ xomStream.WriteInt32(moikBlock.NumCtnr);
+ xomStream.WriteInt32(moikBlock.NumCtnr);
+ xomStream.Skip(0x1C);
}
private void writeType(TypeBlock typeBlock)
{
- writeStr(typeBlock.Name);
- skip(0x4);
- writeInt32(typeBlock.NumCtnr);
- skip(0x4);
- writeBytes(typeBlock.Md5);
- writeStrLen(typeBlock.TypeName, 0x20);
+ xomStream.WriteStr(typeBlock.Name);
+ xomStream.Skip(0x4);
+ xomStream.WriteInt32(typeBlock.NumCtnr);
+ xomStream.Skip(0x4);
+ xomStream.WriteBytes(typeBlock.Md5);
+ xomStream.WriteStrLen(typeBlock.TypeName, 0x20);
}
private void writeGuid(GuidBlock guidBlock)
{
- writeStr(guidBlock.Name);
- writeInt32(guidBlock.Unk0);
- writeInt32(guidBlock.Unk1);
- writeInt32(guidBlock.Unk2);
+ xomStream.WriteStr(guidBlock.Name);
+ xomStream.WriteInt32(guidBlock.Unk0);
+ xomStream.WriteInt32(guidBlock.Unk1);
+ xomStream.WriteInt32(guidBlock.Unk2);
}
private void writeSchm(SchmBlock schmBlock)
{
- writeStr(schmBlock.Name);
- writeInt32(schmBlock.Unk0);
- writeInt32(schmBlock.Unk1);
- writeInt32(schmBlock.Unk2);
+ xomStream.WriteStr(schmBlock.Name);
+ xomStream.WriteInt32(schmBlock.Unk0);
+ xomStream.WriteInt32(schmBlock.Unk1);
+ xomStream.WriteInt32(schmBlock.Unk2);
}
private void writeStrs(StrsBlock strsBlock)
{
- writeStr(strsBlock.Name);
- writeInt32(strsBlock.NumStrs);
- writeInt32(strsBlock.StringsSectionSz);
+ xomStream.WriteStr(strsBlock.Name);
+ xomStream.WriteInt32(strsBlock.NumStrs);
+ xomStream.WriteInt32(strsBlock.StringsSectionSz);
foreach (int offset in strsBlock.OffsetList)
- writeInt32(offset);
+ xomStream.WriteInt32(offset);
foreach (string str in strsBlock.StringList)
- writeCStr(str);
+ xomStream.WriteCStr(str);
}
private void writeCtnr(CtnrBlock ctnrBlock)
{
- writeStr(ctnrBlock.Name);
- writeBytes(ctnrBlock.Data);
+ xomStream.WriteStr(ctnrBlock.Name);
+ xomStream.WriteBytes(ctnrBlock.Data);
}
private void writeBlocks(XomBlock[] blocks)
@@ -165,7 +92,7 @@ namespace LibXom
}
internal XomWriter(Stream xomStream, XomFile xomFile)
{
- this.xomStream = xomStream;
+ this.xomStream = new XomStreamWriter(xomStream);
this.xomFile = xomFile;
}
}
diff --git a/Worms4Editor.sln b/Worms4Editor.sln
index adba5bb..ff6473e 100644
--- a/Worms4Editor.sln
+++ b/Worms4Editor.sln
@@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33205.214
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Worms4Editor", "Worms4Editor\Worms4Editor.csproj", "{FBAA43A5-824F-4C9A-97BC-7B18A42413B9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worms4Editor", "Worms4Editor\Worms4Editor.csproj", "{FBAA43A5-824F-4C9A-97BC-7B18A42413B9}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibXom", "LibXom\LibXom.csproj", "{7B60E17C-780E-44D3-BF02-9F5712DD3AE2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibXom", "LibXom\LibXom.csproj", "{7B60E17C-780E-44D3-BF02-9F5712DD3AE2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibW4M", "LibW4M\LibW4M.csproj", "{ABA3728B-4745-4622-B140-A82C07AF4992}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
{7B60E17C-780E-44D3-BF02-9F5712DD3AE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B60E17C-780E-44D3-BF02-9F5712DD3AE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B60E17C-780E-44D3-BF02-9F5712DD3AE2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ABA3728B-4745-4622-B140-A82C07AF4992}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ABA3728B-4745-4622-B140-A82C07AF4992}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ABA3728B-4745-4622-B140-A82C07AF4992}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ABA3728B-4745-4622-B140-A82C07AF4992}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Worms4Editor/Program.cs b/Worms4Editor/Program.cs
index fd67c31..614d8f9 100644
--- a/Worms4Editor/Program.cs
+++ b/Worms4Editor/Program.cs
@@ -10,20 +10,22 @@ namespace Worms4Editor
{
static void Main(string[] args)
{
- XomFile xfile = XomReader.ReadXomFile(@"Original.xom");
- //XomFile ps2file = XomReader.ReadXomFile(@"ps2.xom");
-
- XomType type = xfile.GetTypeByName("StoredStatsCollective");
- XomContainer container = type.Containers.First();
- File.WriteAllBytes("StoredStatsCollective.bin", container.DecompressToBytes());
-
- for(int i = 0; i < xfile.XomStrings.Length; i++)
+ XomFile xfile = XomReader.ReadXomFile(@"SaveGame.xom");
+
+ foreach(XomType type in xfile.XomTypes)
{
- XomString str = xfile.XomStrings[i];
- Console.WriteLine(str.Id.ToString("X") + ": " + str.Value);
+ Console.WriteLine(type.Name);
+
+ if (Directory.Exists(type.Name)) Directory.Delete(type.Name, true);
+
+ Directory.CreateDirectory(type.Name);
+ foreach(XomContainer container in type.Containers)
+ {
+ string name = Path.Combine(type.Name, container.Id.ToString("X") + ".bin");
+ File.WriteAllBytes(name, container.GetData());
+ }
}
- XomWriter.WriteXom(xfile, @"Original2.xom");
}
}
}
\ No newline at end of file