Add Weapon Factory Parsing pt.1

This commit is contained in:
Li 2023-01-09 05:18:25 -08:00
parent 0247b45335
commit 835c9002ab
14 changed files with 488 additions and 198 deletions

2
.gitignore vendored
View File

@ -2,4 +2,6 @@ Worms4Editor/obj/*
Worms4Editor/bin/*
LibXom/obj/*
LibXom/bin/*
LibW4M/obj/*
LibW4M/bin/*
.vs/*

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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
}
}

13
LibW4M/LibW4M.csproj Normal file
View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LibXom\LibXom.csproj" />
</ItemGroup>
</Project>

14
LibW4M/W4SaveFile.cs Normal file
View File

@ -0,0 +1,14 @@
using LibXom.Data;
namespace LibW4M
{
public class W4SaveFile
{
public XomFile w4Save;
public W4SaveFile(XomFile w4Save)
{
this.w4Save = w4Save;
}
}
}

View File

@ -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);
}

View File

@ -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.");
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<byte> buffer, byte[] search)
{
int len = search.Length;
@ -79,12 +33,12 @@ namespace LibXom
public CtnrBlock readCtnr()
{
List<byte> buffer = new List<byte>();
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<XomBlock> xomBlocks = new List<XomBlock>();
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);
}
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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");
}
}
}