From 0247b45335f28e12942a16b0313229e3a4e2df7b Mon Sep 17 00:00:00 2001
From: Li
Date: Sun, 8 Jan 2023 22:28:17 -0800
Subject: [PATCH] Fix saving
---
LibXom/Data/XomFile.cs | 52 ++++++++++++++++++++++++++++++++++++----
LibXom/Data/XomString.cs | 11 +--------
LibXom/XomWriter.cs | 12 +++++++++-
Worms4Editor/Program.cs | 3 ++-
4 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/LibXom/Data/XomFile.cs b/LibXom/Data/XomFile.cs
index 2d452ca..0d73dd9 100644
--- a/LibXom/Data/XomFile.cs
+++ b/LibXom/Data/XomFile.cs
@@ -64,6 +64,52 @@ namespace LibXom.Data
throw new XomFileComponentNotFoundException("A XOM Components ID could not be found in the Component List.");
}
+
+ internal XomBlock[] generateBlocks()
+ {
+ XomContainer[] containers = this.XomContainers;
+ XomType[] types = this.XomTypes;
+ XomString[] strings = XomStrings;
+
+ List blocks = new List();
+ // add MOIK block
+ blocks.Add(new MoikBlock(this.version, containers.Length, types.Length));
+ // add type blocks
+ foreach (XomType type in types) blocks.Add(new TypeBlock(type.Containers.Length, type.Md5, type.Name));
+
+ // Add guid and schm block
+ blocks.Add(new GuidBlock(0, 0, 0));
+ blocks.Add(new SchmBlock(unk0, 0, 0));
+
+
+ // Create a list of all strings and the offset they would appear in the strs block.
+ Dictionary stringOffsets = new Dictionary();
+ int loc = 0;
+ XomString[] stringsSorted = strings.OrderBy(o => o.Value, StringComparer.Ordinal).ToArray();
+ string[] stringLst = new string[stringsSorted.Length];
+ for (int i = 0; i < stringsSorted.Length; i++)
+ {
+ XomString str = stringsSorted[i];
+ stringLst[i] = str.Value;
+ stringOffsets.Add(str.Value, loc);
+ loc += str.Value.Length + 1; // str length, + \0 for terminator.
+ }
+
+ // now create the strs block
+ int[] offsetLst = new int[strings.Length];
+ for(int i = 0; i < strings.Length; i++)
+ {
+ XomString str = strings[i];
+ offsetLst[i] = stringOffsets[str.Value];
+ }
+ blocks.Add(new StrsBlock(strings.Length, loc, offsetLst, stringLst));
+
+ // Add containers
+ foreach (XomContainer container in containers) blocks.Add(new CtnrBlock(container.GetData()));
+
+ return blocks.ToArray();
+ }
+
internal XomFile(XomBlock[] xomBlocks)
{
MoikBlock? moikBlock = XomBlockHandler.GetBlockByName(xomBlocks, "MOIK") as MoikBlock;
@@ -101,11 +147,7 @@ namespace LibXom.Data
{
int offset = stringBlock.OffsetList[i];
string value = stringOffsets[offset];
- // Were storing the offset here so that i can figure out how to best order the values again
- // when reconstructing the value (eg make it as close to the actual game)
- // ideally this wouldnt be needed.
- // TODO: Figure out how strings are ordered, so i can ditch the offset variable.
- xomStrings.Add(new XomString(this, offset, value));
+ xomStrings.Add(new XomString(this, value));
}
diff --git a/LibXom/Data/XomString.cs b/LibXom/Data/XomString.cs
index e841dbe..49c86dc 100644
--- a/LibXom/Data/XomString.cs
+++ b/LibXom/Data/XomString.cs
@@ -9,7 +9,6 @@ namespace LibXom.Data
{
public class XomString : XomFileComponent
{
- private int offset;
private string value;
public override int Id
@@ -19,13 +18,6 @@ namespace LibXom.Data
return this.fileBelongs.calculateIdForXomFileComponent(this.uuid, fileBelongs.XomStrings);
}
}
- public int Offset
- {
- get
- {
- return offset;
- }
- }
public string Value
{
get
@@ -33,10 +25,9 @@ namespace LibXom.Data
return value;
}
}
- internal XomString(XomFile fromFile, int offset, string value)
+ internal XomString(XomFile fromFile, string value)
{
this.fileBelongs = fromFile;
- this.offset = offset;
this.value = value;
}
}
diff --git a/LibXom/XomWriter.cs b/LibXom/XomWriter.cs
index d32371d..f87b30c 100644
--- a/LibXom/XomWriter.cs
+++ b/LibXom/XomWriter.cs
@@ -150,8 +150,18 @@ namespace LibXom
}
}
- public void WriteXom()
+ public static void WriteXom(XomFile xfile, string filename)
{
+ using(FileStream fs = File.OpenWrite(filename))
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ XomWriter writer = new XomWriter(ms, xfile);
+ writer.writeBlocks(writer.xomFile.generateBlocks());
+ ms.Seek(0, SeekOrigin.Begin);
+ ms.CopyTo(fs);
+ }
+ }
}
internal XomWriter(Stream xomStream, XomFile xomFile)
{
diff --git a/Worms4Editor/Program.cs b/Worms4Editor/Program.cs
index 67f4abc..fd67c31 100644
--- a/Worms4Editor/Program.cs
+++ b/Worms4Editor/Program.cs
@@ -10,7 +10,6 @@ namespace Worms4Editor
{
static void Main(string[] args)
{
- int id = 0;
XomFile xfile = XomReader.ReadXomFile(@"Original.xom");
//XomFile ps2file = XomReader.ReadXomFile(@"ps2.xom");
@@ -23,6 +22,8 @@ namespace Worms4Editor
XomString str = xfile.XomStrings[i];
Console.WriteLine(str.Id.ToString("X") + ": " + str.Value);
}
+
+ XomWriter.WriteXom(xfile, @"Original2.xom");
}
}
}
\ No newline at end of file