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