166 lines
9.3 KiB
C#
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("--------------------------------------------------");
|
|
}
|
|
}
|
|
}
|