McTools/McDecryptor/Program.cs

257 lines
8.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Threading;
using McCrypt;
namespace McDecryptor
{
class Program
{
public struct ContentListing
{
public string Path;
public string Type;
public string Name;
public int Id;
}
public static string EscapeFilename(string filename)
{
return filename.Replace("/", "_").Replace("\\", "_").Replace(":", "_").Replace("?", "_").Replace("*", "_").Replace("<", "_").Replace(">", "_").Replace("|", "_").Replace("\"", "_");
}
static void CopyFile(string src, string dst)
{
using (FileStream fs = File.OpenRead(src))
{
using(FileStream wfd = File.OpenWrite(dst))
{
fs.CopyTo(wfd);
}
}
}
static void CopyDirectory(string sourcePath, string targetPath)
{
List<Thread> threads = new List<Thread>();
//Now Create all of the directories
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
{
Thread thrd = new Thread(() =>
{
Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));
});
thrd.Priority = ThreadPriority.Highest;
thrd.Start();
threads.Add(thrd);
}
foreach (Thread t in threads.ToArray())
t.Join();
threads.Clear();
//Copy all the files & Replaces any files with the same name
foreach (string newPath in Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories))
{
Thread thrd = new Thread(() =>
{
CopyFile(newPath, newPath.Replace(sourcePath, targetPath));
});
thrd.Priority = ThreadPriority.Highest;
thrd.Start();
threads.Add(thrd);
}
foreach (Thread t in threads.ToArray())
t.Join();
threads.Clear();
}
static void Main(string[] args)
{
Console.WriteLine("-- McDecryptor --");
Console.WriteLine("Reading Configuration File...");
Config.Init();
Directory.SetCurrentDirectory(Config.ApplicationDirectory);
Config.ReadConfig("McDecryptor.cfg");
Keys.KeyDbFile = Config.KeysDbPath;
if (File.Exists(Config.KeysDbPath))
{
Console.WriteLine("Parsing Key Database File...");
Keys.ReadKeysDb(Config.KeysDbPath);
}
if (File.Exists(Config.OptionsTxt))
{
Keys.ReadOptionsTxt(Config.OptionsTxt);
}
Console.WriteLine("Minecraft Folder: " + Config.MinecraftFolder);
if (Directory.Exists(Config.MinecraftFolder))
{
string[] entFiles = Directory.GetFiles(Config.LocalState, "*.ent", SearchOption.TopDirectoryOnly);
foreach (string entFile in entFiles)
{
Console.WriteLine("Reading Entitlement File: " + Path.GetFileName(entFile));
Keys.ReadEntitlementFile(entFile);
}
}
string[] entFilesWorkDir = Directory.GetFiles(Config.ApplicationDirectory, "*.ent", SearchOption.TopDirectoryOnly);
foreach (string entFile in entFilesWorkDir)
{
Console.WriteLine("Reading Entitlement File: " + Path.GetFileName(entFile));
Keys.ReadEntitlementFile(entFile);
}
List<ContentListing> premiumContents = new List<ContentListing>();
Console.WriteLine("\n\n");
Console.WriteLine("Select what to decrypt: ");
int total = 1;
foreach (string searchFolder in Config.SearchFolders)
{
foreach(string searchModule in Config.SearchModules)
{
string moduleFolder = Path.Combine(searchFolder, searchModule);
if (Directory.Exists(moduleFolder))
{
foreach (string moduleItem in Directory.GetDirectories(moduleFolder, "*", SearchOption.TopDirectoryOnly))
{
ContentListing cList = new ContentListing();
cList.Name = Manifest.ReadName(Path.Combine(moduleItem, "manifest.json"));
cList.Type = searchModule;
cList.Id = total;
cList.Path = moduleItem;
premiumContents.Add(cList);
Console.WriteLine(cList.Id.ToString() + ") (" + cList.Type + ") " + cList.Name);
total++;
}
}
}
}
Console.WriteLine("Select multiple (seperated by ',') or write \"ALL\"");
List<int> toDecrypt = new List<int>();
while (true)
{
Console.Write("Which do you want to decrypt? ");
try
{
string readText = Console.ReadLine();
if (readText.ToUpper() == "ALL")
{
for(int i = 0; i < total-1; i++)
toDecrypt.Add(i);
break;
}
string[] entries = readText.Split(',');
foreach(string entry in entries) {
int tdc = Convert.ToInt32(entry.Trim())-1;
if (tdc < 0 || tdc >= total)
continue;
toDecrypt.Add(tdc);
}
break;
}
catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
}
foreach (int decryptMe in toDecrypt.ToArray())
{
ContentListing cListing = premiumContents.ToArray()[decryptMe];
string outFolder = Path.Combine(Config.OutFolder, cListing.Type, EscapeFilename(cListing.Name));
int counter = 1;
string ogOutFolder = outFolder;
while (Directory.Exists(outFolder))
{
outFolder = ogOutFolder + "_" + counter.ToString();
counter++;
}
Console.WriteLine("Decrypting: " + cListing.Name);
Directory.CreateDirectory(outFolder);
CopyDirectory(cListing.Path, outFolder);
try
{
string levelDatFile = Path.Combine(outFolder, "level.dat");
string skinsJsonFile = Path.Combine(outFolder, "skins.json");
string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
Marketplace.DecryptContents(outFolder);
if (Config.CrackPacks)
{
if (File.Exists(oldSchoolZipe))
Marketplace.CrackZipe(oldSchoolZipe);
if (File.Exists(levelDatFile))
Marketplace.CrackLevelDat(levelDatFile);
if (File.Exists(skinsJsonFile))
Marketplace.CrackSkinsJson(skinsJsonFile);
}
if (Config.ZipPacks)
{
Console.WriteLine("Zipping: " + cListing.Name);
string ext = "";
if (File.Exists(levelDatFile))
ext += ".mctemplate";
else if (false)
ext += ".mcaddon";
else
ext += ".mcpack";
string fname = outFolder + ext;
if (File.Exists(fname))
File.Delete(fname);
ZipFile.CreateFromDirectory(outFolder, fname, CompressionLevel.NoCompression, false);
Directory.Delete(outFolder, true);
}
}
catch (Exception e)
{
Console.Error.WriteLine("Failed to decrypt: " + cListing.Name+ " "+e.Message);
Directory.Delete(outFolder, true);
}
}
Console.WriteLine("Finished.");
Console.ReadKey();
}
}
}