Mercurial > repos > IBBoard.ArmyBuilder.API
changeset 3:1a54f6afafe7
Re #84 and #85: Support Army Builder v2/v3 files
* Separate out the two versions of file
* Restructure file loader to load v2 files correctly
* Tidy up file extractor (still not working)
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 17 May 2009 18:40:36 +0000 |
parents | d5ba733cd289 |
children | d2f7826147eb |
files | ABFile.cs ABv2File.cs ABv3File.cs Extractors/ArmyBuilderFileExtractor.cs IBBoard.ArmyBuilder.API.csproj Loaders/ArmyBuilderABFileLoader.cs |
diffstat | 6 files changed, 268 insertions(+), 165 deletions(-) [+] |
line wrap: on
line diff
--- a/ABFile.cs Mon Apr 20 19:28:01 2009 +0000 +++ b/ABFile.cs Sun May 17 18:40:36 2009 +0000 @@ -15,19 +15,12 @@ /// A .ab file (Army Builder's main data definition file). .ab files contain details of the application requirements for a game system, /// details of the game system, and all of the data files for that game system (including race data). /// </summary> - public class ABFile + public abstract class ABFile { private FileInfo file; private string header = ""; - private string gameName = ""; - private string folderName = ""; - private string releaseMajor = ""; - private string releaseMinor = ""; - private string requiredMajorVersion = ""; - private string requiredMinorVersion = ""; - private string uniqueID = ""; - private string exporter = ""; private string comment = ""; + private int fileTablePosition = 0; private List<FileTableEntry> files; public ABFile(String filePath) : this(new FileInfo(filePath)) @@ -90,112 +83,6 @@ } } - public string GameName - { - get - { - return gameName; - } - set - { - gameName = value; - } - } - - public string FolderName - { - get - { - return folderName; - } - set - { - folderName = value; - } - } - - public string Release - { - get { return ReleaseMajor + "." + ReleaseMinor; } - } - - public string ReleaseMajor - { - get - { - return releaseMajor; - } - set - { - releaseMajor = value; - } - } - - public string ReleaseMinor - { - get - { - return releaseMinor; - } - set - { - releaseMinor = value; - } - } - - public string RequiredVersion - { - get { return RequiredMajorVersion + "." + RequiredMinorVersion; } - } - - public string RequiredMajorVersion - { - get - { - return requiredMajorVersion; - } - set - { - requiredMajorVersion = value; - } - } - - public string RequiredMinorVersion - { - get - { - return requiredMinorVersion; - } - set - { - requiredMinorVersion = value; - } - } - - public string UniqueID - { - get - { - return uniqueID; - } - set - { - uniqueID = value; - } - } - - public string Exporter - { - get - { - return exporter; - } - set - { - exporter = value; - } - } - public string Comment { get @@ -207,5 +94,17 @@ comment = value; } } + + public int FileTablePosition + { + get + { + return fileTablePosition; + } + set + { + fileTablePosition = value; + } + } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ABv2File.cs Sun May 17 18:40:36 2009 +0000 @@ -0,0 +1,21 @@ +// This file (ABv2File.cs) is a part of the IBBoard.ArmyBuilder.API project and is copyright 2009 IBBoard +// +// The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license. +// + +using System; +using System.IO; + +namespace IBBoard.ArmyBuilder.API +{ + public class ABv2File : ABFile + { + public ABv2File(String filePath) : base(new FileInfo(filePath)) + { + } + + public ABv2File(FileInfo file) : base(file) + { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ABv3File.cs Sun May 17 18:40:36 2009 +0000 @@ -0,0 +1,136 @@ +// This file (ABv3File.cs) is a part of the IBBoard.ArmyBuilder.API project and is copyright 2009 IBBoard +// +// The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license. +// + +using System; +using System.IO; + +namespace IBBoard.ArmyBuilder.API +{ + public class ABv3File : ABFile + { + private string gameName = ""; + private string folderName = ""; + private string releaseMajor = ""; + private string releaseMinor = ""; + private string requiredMajorVersion = ""; + private string requiredMinorVersion = ""; + private string uniqueID = ""; + private string exporter = ""; + + public ABv3File(String filePath) : base(new FileInfo(filePath)) + { + } + + public ABv3File(FileInfo file) : base(file) + { + } + + public string GameName + { + get + { + return gameName; + } + set + { + gameName = value; + } + } + + public string FolderName + { + get + { + return folderName; + } + set + { + folderName = value; + } + } + + public string Release + { + get { return ReleaseMajor + "." + ReleaseMinor; } + } + + public string ReleaseMajor + { + get + { + return releaseMajor; + } + set + { + releaseMajor = value; + } + } + + public string ReleaseMinor + { + get + { + return releaseMinor; + } + set + { + releaseMinor = value; + } + } + + public string RequiredVersion + { + get { return RequiredMajorVersion + "." + RequiredMinorVersion; } + } + + public string RequiredMajorVersion + { + get + { + return requiredMajorVersion; + } + set + { + requiredMajorVersion = value; + } + } + + public string RequiredMinorVersion + { + get + { + return requiredMinorVersion; + } + set + { + requiredMinorVersion = value; + } + } + + public string UniqueID + { + get + { + return uniqueID; + } + set + { + uniqueID = value; + } + } + + public string Exporter + { + get + { + return exporter; + } + set + { + exporter = value; + } + } + } +}
--- a/Extractors/ArmyBuilderFileExtractor.cs Mon Apr 20 19:28:01 2009 +0000 +++ b/Extractors/ArmyBuilderFileExtractor.cs Sun May 17 18:40:36 2009 +0000 @@ -5,8 +5,6 @@ using System; using System.IO; -//using ICSharpCode.SharpZipLib.BZip2; -//using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using IBBoard.ArmyBuilder.API; @@ -15,30 +13,26 @@ public class ArmyBuilderFileExtractor { public static byte[] GetFileEntryContent(FileTableEntry entry) - { - //BZip2InputStream zipped = null; - //GZipInputStream zipped = null; + { InflaterInputStream zipped = null; byte[] byteArr = new byte[entry.FileSize]; try { - byte [] compressed = GetFileEntryCompressedContent(entry); - MemoryStream ms = new MemoryStream(compressed, 0, compressed.Length); + byte[] compressed = GetFileEntryCompressedContent(entry); + MemoryStream ms = new MemoryStream(compressed); ms.Seek(0, SeekOrigin.Begin); - //zipped = new BZip2InputStream(ms); - //zipped = new GZipInputStream(ms); - zipped = new InflaterInputStream(ms); - + zipped = new InflaterInputStream(ms, new Inflater(true)); + int size = 0; - int offset = 0; + int pos = 0; do { - size = zipped.Read(byteArr, offset, byteArr.Length); - offset+= size; - } - while (size > 0); + size = zipped.Read(byteArr, pos, byteArr.Length); + pos+=size; + } + while (size > 0); } finally {
--- a/IBBoard.ArmyBuilder.API.csproj Mon Apr 20 19:28:01 2009 +0000 +++ b/IBBoard.ArmyBuilder.API.csproj Sun May 17 18:40:36 2009 +0000 @@ -40,6 +40,8 @@ <Compile Include="Extractors\ArmyBuilderFileExtractor.cs" /> <Compile Include="FileTableEntry.cs" /> <Compile Include="Loaders\ArmyBuilderABFileLoader.cs" /> + <Compile Include="ABv3File.cs" /> + <Compile Include="ABv2File.cs" /> </ItemGroup> <ItemGroup> <None Include="COPYING.GPL" />
--- a/Loaders/ArmyBuilderABFileLoader.cs Mon Apr 20 19:28:01 2009 +0000 +++ b/Loaders/ArmyBuilderABFileLoader.cs Sun May 17 18:40:36 2009 +0000 @@ -11,21 +11,99 @@ public class ArmyBuilderABFileLoader { private static byte HEADER_DELIMITER = 0x09; + private static byte HEADER_TYPE_DELIMITER = 0x3A; + private static byte TABLE_HEADER_OFFSET_FROM = 4; + private static byte FILE_TABLE_OFFSET_LENGTH = 2; public static ABFile LoadFile(FileInfo file) { - ABFile abFile = new ABFile(file); - LoadData(abFile); + ABFile abFile = ReadFileInfo(file); + ReadFileTable(abFile); + return abFile; + } + + private static ABFile ReadFileInfo(FileInfo file) + { + BinaryReaderBigEndian reader = new BinaryReaderBigEndian(file.OpenRead()); + ABFile abFile = null; + + try + { + abFile = ReadFileInfo(file, reader); + } + finally + { + reader.Close(); + } + + return abFile; + } + + private static ABFile ReadFileInfo(FileInfo file, BinaryReaderBigEndian reader) + { + int tableOffset = reader.ReadInt(); + reader.Move(tableOffset); + ushort fileTableOffset = reader.ReadUShort(); + string header = reader.ReadDelimitedString(HEADER_TYPE_DELIMITER); + + ABFile abFile = CreateFile(file, header); + ReadExtraHeaders(abFile, reader); + int fileTablePosition = TABLE_HEADER_OFFSET_FROM + tableOffset + FILE_TABLE_OFFSET_LENGTH + fileTableOffset; + abFile.FileTablePosition = fileTablePosition; + int readerPosition = (int)reader.Position; + + if (fileTablePosition > readerPosition) + { + abFile.Comment = reader.ReadString(fileTablePosition - readerPosition); + } + return abFile; } - - private static void LoadData(ABFile abFile) + + private static ABFile CreateFile(FileInfo file, string header) { + ABFile abFile = null; + header = header.Trim(); + + if ("LWDExport".Equals(header)) + { + abFile = new ABv3File(file); + } + else if ("ArmyBuilder".Equals(header)) + { + abFile = new ABv2File(file); + } + else + { + throw new InvalidDataException("Unsupported file table header: "+header); + } + + abFile.Header = header; + return abFile; + } + + private static void ReadExtraHeaders(ABFile abFile, BinaryReaderBigEndian reader) + { + if (abFile is ABv3File) + { + ABv3File ab3File = (ABv3File)abFile; + ab3File.GameName = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.FolderName = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.ReleaseMajor = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.ReleaseMinor = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.RequiredMajorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.RequiredMinorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.UniqueID = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.Exporter = reader.ReadDelimitedString(HEADER_DELIMITER); + } + } + + private static void ReadFileTable(ABFile abFile) + { BinaryReaderBigEndian reader = new BinaryReaderBigEndian(abFile.File.OpenRead()); try { - ReadFileInfo(abFile, reader); ReadFileTable(abFile, reader); } finally @@ -34,37 +112,10 @@ } } - private static void ReadFileInfo(ABFile abFile, BinaryReaderBigEndian reader) - { - int tableOffset = reader.ReadInt(); - reader.Move(tableOffset); - ushort fileTableOffset = reader.ReadUShort(); - abFile.Header = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.GameName = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.FolderName = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.ReleaseMajor = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.ReleaseMinor = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.RequiredMajorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.RequiredMinorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.UniqueID = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.Exporter = reader.ReadDelimitedString(HEADER_DELIMITER); - int bytesRead = CalculateFileInfoSize(abFile); - - if (fileTableOffset > bytesRead) - { - abFile.Comment = reader.ReadString(fileTableOffset - bytesRead); - } - } - - private static int CalculateFileInfoSize(ABFile file) - { - return file.Header.Length + file.GameName.Length + file.FolderName.Length + file.ReleaseMajor.Length + file.ReleaseMinor.Length + - file.RequiredMajorVersion.Length + file.RequiredMinorVersion.Length + file.UniqueID.Length + file.Exporter.Length + 9; - } - private static void ReadFileTable(ABFile abFile, BinaryReaderBigEndian reader) - { + { FileTableEntry entry = null; + reader.Seek(abFile.FileTablePosition); do {