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:
chrisf
2007-06-19 10:24:14 +00:00
parent b59ba43934
commit 711a99a022
4 changed files with 152 additions and 60 deletions

View File

@@ -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>

View File

@@ -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
View 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,
}
}

View File

@@ -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,
}
}