magellan/Lucidiot.Magellan.Extract/Program.cs

166 lines
9.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using Lucidiot.Raima;
namespace Lucidiot.Magellan.Extract {
class Program {
static int Main(string[] args) {
if (args.Length < 1) {
Console.WriteLine("Usage: thing.exe <MGI/IMI file> [<MGI/IMI file> ...]");
return 1;
}
foreach (string arg in args) {
DumpMGI(arg);
}
return 0;
}
static void DumpMGI(string MGIPath) {
Console.WriteLine("Magellan Map archive contents - {0}", MGIPath);
MapArchiveEntry[] entries;
try {
entries = MapArchive.ReadHeader(MGIPath);
} catch (Exception e) {
ConsoleColor current = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.ToString());
Console.ForegroundColor = current;
Console.WriteLine();
Console.WriteLine("--------------------------------------------------");
return;
}
List<MapArchiveEntry> databases = new List<MapArchiveEntry>();
foreach (MapArchiveEntry entry in entries) {
Console.WriteLine("{0,-16} {1} bytes starting at offset {2}", entry.FullName, entry.Length, entry.Offset);
if (entry.Extension.ToLowerInvariant() == "dbd") {
Console.WriteLine(" Looks like a Raima database, will attempt to dump its schema below.");
databases.Add(entry);
}
}
Console.WriteLine();
Console.WriteLine("--------------------------------------------------");
foreach (MapArchiveEntry db in databases) {
DumpDatabase(MGIPath, db.FullName);
}
}
static void DumpDatabase(string MGIPath, string fileName) {
Console.WriteLine("Raima Database Manager Embedded V3.00 Database Schema Dump");
Console.WriteLine("Database {0} in archive {1}", fileName, MGIPath);
DatabaseSchema ds;
try {
ds = DatabaseSchema.Load(fileName, new MapArchiveStorage(MGIPath));
} catch (Exception e) {
ConsoleColor current = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.ToString());
Console.ForegroundColor = current;
Console.WriteLine();
Console.WriteLine("--------------------------------------------------");
return;
}
Console.WriteLine("PageSize: {0}", ds.PageSize);
Console.WriteLine("--- FILE ENTRIES ---------------------------------");
for (int i = 0; i < ds.FileEntries.Count; i++) {
FileEntry entry = ds.FileEntries[i];
Console.WriteLine(" #{0}: {1}", i, entry.Name);
Console.WriteLine(" {0}, {1}", entry.Type, entry.Status);
Console.WriteLine(" Descriptor {0}, page size {1}", entry.Descriptor, entry.PageSize);
Console.WriteLine(" {0} record slots of size {1}", entry.Slots, entry.SlotSize);
if ((entry.Options & FileEntryOptions.Compressed) == FileEntryOptions.Compressed)
Console.WriteLine(" Compressed");
if ((entry.Options & FileEntryOptions.Local) == FileEntryOptions.Local)
Console.WriteLine(" Local");
if ((entry.Options & FileEntryOptions.Static) == FileEntryOptions.Static)
Console.WriteLine(" Static");
}
if (ds.FileEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--- RECORD ENTRIES -------------------------------");
for (int i = 0; i < ds.RecordEntries.Count; i++) {
RecordEntry entry = ds.RecordEntries[i];
Console.WriteLine(" #{0}: Record from file #{1}", i, entry.FileEntryIndex);
Console.WriteLine(" {0} field entries starting at #{1}", entry.FieldEntryCount, entry.FirstFieldEntryIndex);
if ((entry.Options & RecordEntryOptions.Timestamped) == RecordEntryOptions.Timestamped)
Console.WriteLine(" Timestamped");
if ((entry.Options & RecordEntryOptions.Local) == RecordEntryOptions.Local)
Console.WriteLine(" Local");
if ((entry.Options & RecordEntryOptions.Static) == RecordEntryOptions.Static)
Console.WriteLine(" Static");
if ((entry.Options & RecordEntryOptions.ContainsCompoundKey) == RecordEntryOptions.ContainsCompoundKey)
Console.WriteLine(" Contains a compound key");
}
if (ds.RecordEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--- FIELD ENTRIES --------------------------------");
for (int i = 0; i < ds.FieldEntries.Count; i++) {
FieldEntry entry = ds.FieldEntries[i];
Console.WriteLine(" #{0}: Field from record #{1}", i, entry.RecordEntryIndex);
Console.WriteLine(" Type: {0}[{1},{2},{3}]", entry.Type, entry.Dimension1, entry.Dimension2, entry.Dimension3);
if (entry.Type == FieldType.CompoundKey) {
Console.WriteLine(" First field of the compound key: #{0}", entry.Offset);
Console.WriteLine(" Length: {0}", entry.Length);
} else
Console.WriteLine(" Found in rows at offset {0}, length {1}", entry.Offset, entry.Length);
Console.WriteLine(" B-Tree index: {0}", entry.KeyType == FieldKeyType.None ? "No" : "Yes" + (entry.KeyType == FieldKeyType.Unique ? ", with unique constraint" : ""));
if (entry.KeyType != FieldKeyType.None)
Console.WriteLine(" Key file #{0}, key number #{1}", entry.KeyFileIndex, entry.KeyNumber);
if ((entry.Options & FieldEntryOptions.Unsigned) == FieldEntryOptions.Unsigned)
Console.WriteLine(" Type is unsigned");
if ((entry.Options & FieldEntryOptions.Optional) == FieldEntryOptions.Optional)
Console.WriteLine(" Optional");
if ((entry.Options & FieldEntryOptions.StructField) == FieldEntryOptions.StructField)
Console.WriteLine(" Part of a previously listed GroupedField");
if ((entry.Options & FieldEntryOptions.CompoundKeyMember) == FieldEntryOptions.CompoundKeyMember)
Console.WriteLine(" Part of a compound key");
if ((entry.Options & FieldEntryOptions.SortField) == FieldEntryOptions.SortField)
Console.WriteLine(" Part of a sort entry");
}
if (ds.FieldEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--- SET ENTRIES ----------------------------------");
for (int i = 0; i < ds.SetEntries.Count; i++) {
SetEntry entry = ds.SetEntries[i];
Console.WriteLine(" #{0}: Set from record #{1}", i, entry.RecordEntryIndex);
Console.WriteLine(" {0} member entries starting at #{1}", entry.MemberCount, entry.FirstMemberEntryIndex);
Console.WriteLine(" Offset: {0}", entry.Offset);
Console.WriteLine(" Ordering: {0}", entry.Ordering);
if ((entry.Options & SetEntryOptions.Timestamped) == SetEntryOptions.Timestamped)
Console.WriteLine(" Timestamped");
}
if (ds.SetEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--- MEMBER ENTRIES -------------------------------");
for (int i = 0; i < ds.MemberEntries.Count; i++) {
MemberEntry entry = ds.MemberEntries[i];
Console.WriteLine(" #{0}: member entry from record #{1}", i, entry.RecordIndex);
Console.WriteLine(" Offset: ", entry.Offset);
Console.WriteLine(" {0} sort entries starting at #{1}", entry.SortEntryCount, entry.FirstSortEntryIndex);
}
if (ds.MemberEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--- SORT ENTRIES ---------------------------------");
for (int i = 0; i < ds.SortEntries.Count; i++) {
SortEntry entry = ds.SortEntries[i];
Console.WriteLine(" #{0}: set #{1} - field #{2}", i, entry.SetIndex, entry.FieldIndex);
}
if (ds.SortEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--- KEY ENTRIES ----------------------------------");
if (ds.KeyEntries.Count < 1)
Console.WriteLine(" No entries found.");
Console.WriteLine();
Console.WriteLine("--------------------------------------------------");
}
}
}