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>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Blowfish.cs" />
|
<Compile Include="Blowfish.cs" />
|
||||||
<Compile Include="MixEntry.cs" />
|
<Compile Include="MixEntry.cs" />
|
||||||
|
<Compile Include="MixFile.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -57,5 +57,7 @@ namespace MixBrowser
|
|||||||
uint hash = HashFilename(s);
|
uint hash = HashFilename(s);
|
||||||
Names.Add(hash, 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream s = File.Open(fn, FileMode.Open, FileAccess.Read);
|
MixFile file = new MixFile(fn);
|
||||||
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));
|
|
||||||
|
|
||||||
if (File.Exists("files.txt"))
|
if (File.Exists("files.txt"))
|
||||||
foreach (string filename in File.ReadAllLines("files.txt"))
|
foreach (string filename in File.ReadAllLines("files.txt"))
|
||||||
@@ -90,15 +39,8 @@ namespace MixBrowser
|
|||||||
else
|
else
|
||||||
Console.WriteLine("-- files.txt doesnt exist --");
|
Console.WriteLine("-- files.txt doesnt exist --");
|
||||||
|
|
||||||
foreach (MixEntry e in index)
|
foreach (MixEntry e in file.Content)
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
|
||||||
enum MixFileFlags : uint
|
|
||||||
{
|
|
||||||
Checksum = 0x10000,
|
|
||||||
Encrypted = 0x20000,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user