ITS WORKING!!! --some noob
git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1054 993157c7-ee19-0410-b2c4-bb4e9862e678
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -36,6 +37,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Blowfish.cs" />
|
||||
<Compile Include="MixEntry.cs" />
|
||||
<Compile Include="MixFile.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -57,5 +57,7 @@ namespace MixBrowser
|
||||
uint hash = HashFilename(s);
|
||||
Names.Add(hash, s);
|
||||
}
|
||||
|
||||
public const int Size = 12;
|
||||
}
|
||||
}
|
||||
|
||||
146
MixBrowser/MixFile.cs
Normal file
146
MixBrowser/MixFile.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace MixBrowser
|
||||
{
|
||||
class MixFile
|
||||
{
|
||||
readonly string filename;
|
||||
readonly List<MixEntry> index;
|
||||
readonly bool isRmix, isEncrypted;
|
||||
|
||||
public ICollection<MixEntry> Content
|
||||
{
|
||||
get { return index.AsReadOnly(); }
|
||||
}
|
||||
|
||||
public MixFile(string filename)
|
||||
{
|
||||
this.filename = filename;
|
||||
using (Stream s = File.OpenRead(filename))
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(s);
|
||||
uint signature = reader.ReadUInt32();
|
||||
|
||||
isRmix = 0 == (signature & ~(uint)(MixFileFlags.Checksum | MixFileFlags.Encrypted));
|
||||
|
||||
if (isRmix)
|
||||
{
|
||||
isEncrypted = 0 != (signature & (uint)MixFileFlags.Encrypted);
|
||||
index = ParseRaHeader(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
isEncrypted = false;
|
||||
s.Seek(0, SeekOrigin.Begin);
|
||||
index = ParseTdHeader(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<MixEntry> ParseRaHeader(Stream s)
|
||||
{
|
||||
if (!isEncrypted)
|
||||
return ParseTdHeader(s);
|
||||
|
||||
long headerStart = 84;
|
||||
BinaryReader reader = new BinaryReader(s);
|
||||
byte[] keyblock = reader.ReadBytes(80);
|
||||
byte[] blowfishKey = MixDecrypt.MixDecrypt.BlowfishKey(keyblock);
|
||||
|
||||
uint[] h = ReadUints(reader, 2);
|
||||
|
||||
Blowfish fish = new Blowfish(blowfishKey);
|
||||
uint[] decrypted = fish.Decrypt(h);
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter writer = new BinaryWriter(ms);
|
||||
foreach (uint t in decrypted)
|
||||
writer.Write(t);
|
||||
writer.Flush();
|
||||
|
||||
ms.Position = 0;
|
||||
BinaryReader reader2 = new BinaryReader(ms);
|
||||
|
||||
ushort numFiles = reader.ReadUInt16();
|
||||
uint datasize = reader.ReadUInt32();
|
||||
|
||||
Console.WriteLine("{0} files, {1} kb", numFiles, datasize >> 10);
|
||||
|
||||
s.Position = headerStart;
|
||||
reader = new BinaryReader(s);
|
||||
|
||||
h = ReadUints(reader, 2 + numFiles * MixEntry.Size / 4);
|
||||
decrypted = fish.Decrypt(h);
|
||||
|
||||
ms = new MemoryStream();
|
||||
writer = new BinaryWriter(ms);
|
||||
foreach (uint t in decrypted)
|
||||
writer.Write(t);
|
||||
writer.Flush();
|
||||
|
||||
ms.Position = 0;
|
||||
|
||||
return ParseTdHeader(ms);
|
||||
}
|
||||
|
||||
uint[] ReadUints(BinaryReader r, int count)
|
||||
{
|
||||
uint[] ret = new uint[count];
|
||||
for (int i = 0; i < ret.Length; i++)
|
||||
ret[i] = r.ReadUInt32();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
List<MixEntry> ParseTdHeader(Stream s)
|
||||
{
|
||||
List<MixEntry> items = new List<MixEntry>();
|
||||
|
||||
BinaryReader reader = new BinaryReader(s);
|
||||
ushort numFiles = reader.ReadUInt16();
|
||||
uint dataSize = reader.ReadUInt32();
|
||||
|
||||
for (int i = 0; i < numFiles; i++)
|
||||
items.Add(new MixEntry(reader));
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public Stream GetContent(uint hash)
|
||||
{
|
||||
foreach( MixEntry e in index )
|
||||
if (e.Hash == hash)
|
||||
{
|
||||
using (Stream s = File.OpenRead(filename))
|
||||
{
|
||||
s.Seek(2 + 4 + (isRmix ? 4 : 0), SeekOrigin.Begin);
|
||||
if (isEncrypted)
|
||||
s.Seek(80, SeekOrigin.Current);
|
||||
|
||||
s.Seek(index.Count * MixEntry.Size + e.Offset, SeekOrigin.Current);
|
||||
byte[] data = new byte[ e.Length ];
|
||||
s.Read( data, 0, (int)e.Length );
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
}
|
||||
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
public Stream GetContent(string filename)
|
||||
{
|
||||
return GetContent(MixEntry.HashFilename(filename));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum MixFileFlags : uint
|
||||
{
|
||||
Checksum = 0x10000,
|
||||
Encrypted = 0x20000,
|
||||
}
|
||||
}
|
||||
@@ -31,58 +31,7 @@ namespace MixBrowser
|
||||
return;
|
||||
}
|
||||
|
||||
Stream s = File.Open(fn, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader reader = new BinaryReader(s);
|
||||
|
||||
uint signature = reader.ReadUInt32();
|
||||
|
||||
if (0 == (signature & ~(uint)(MixFileFlags.Checksum | MixFileFlags.Encrypted)))
|
||||
{
|
||||
Console.WriteLine("{0} - Red Alert MIX", Path.GetFileName(fn));
|
||||
if (0 != (signature & (uint)MixFileFlags.Checksum))
|
||||
Console.WriteLine("Checksum: YES");
|
||||
if (0 != (signature & (uint)MixFileFlags.Encrypted))
|
||||
{
|
||||
Console.WriteLine("Encrypted: YES");
|
||||
|
||||
//get the blowfish key
|
||||
byte[] bfkey = MixDecrypt.MixDecrypt.BlowfishKey(reader.ReadBytes(80));
|
||||
|
||||
Blowfish fish = new Blowfish(bfkey);
|
||||
|
||||
uint[] data = { reader.ReadUInt32(), reader.ReadUInt32() };
|
||||
uint[] decrypted = fish.Decrypt(data);
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter w = new BinaryWriter(ms);
|
||||
foreach (uint u in decrypted)
|
||||
w.Write(u);
|
||||
w.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
BinaryReader reader2 = new BinaryReader(ms);
|
||||
|
||||
ushort numfiles2 = reader2.ReadUInt16();
|
||||
uint datasize2 = reader2.ReadUInt32();
|
||||
|
||||
Console.WriteLine("{0} files - {1} KB", numfiles2, datasize2 >> 10);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
Console.WriteLine("{0} - Tiberian Dawn MIX", Path.GetFileName(fn) );
|
||||
|
||||
s.Seek(0, SeekOrigin.Begin);
|
||||
reader = new BinaryReader(s);
|
||||
|
||||
ushort numfiles = reader.ReadUInt16();
|
||||
uint datasize = reader.ReadUInt32();
|
||||
Console.WriteLine("{0} files - {1} KB", numfiles, datasize >> 10);
|
||||
|
||||
List<MixEntry> index = new List<MixEntry>();
|
||||
for (ushort i = 0; i < numfiles; i++)
|
||||
index.Add(new MixEntry(reader));
|
||||
MixFile file = new MixFile(fn);
|
||||
|
||||
if (File.Exists("files.txt"))
|
||||
foreach (string filename in File.ReadAllLines("files.txt"))
|
||||
@@ -90,15 +39,8 @@ namespace MixBrowser
|
||||
else
|
||||
Console.WriteLine("-- files.txt doesnt exist --");
|
||||
|
||||
foreach (MixEntry e in index)
|
||||
foreach (MixEntry e in file.Content)
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum MixFileFlags : uint
|
||||
{
|
||||
Checksum = 0x10000,
|
||||
Encrypted = 0x20000,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user