Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: DHeir on Jul 7th, 2012  |  syntax: C#  |  size: 12.88 KB  |  hits: 14  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Text.RegularExpressions;
  7. using System.Diagnostics;
  8.  
  9. namespace Minecraft360Util
  10. {
  11.     static class Constants
  12.     {
  13.         public const bool ThankYou = false;
  14.         public const string Minecraft = "Minecraft.exe";
  15.         public const string File = "savegame.dat";
  16.         public const string FileDec = "savegame.dec";
  17.         // ASCII strings in Hex
  18.         public const string Health = "Health"; // 4865616C7468
  19.         public const string Inventory = "Inventory"; // 496E76656E746F7279
  20.         public const string Slot = "Slot"; // 536C6F74
  21.         public const string id = "id"; // 6964
  22.         public const string Damage = "Damage"; // 44616D616765
  23.         public const string Count = "Count"; // 436F756E74
  24.         public const string Rotation = "Rotation"; // 526F746174696F6E
  25.         // 04 53 6C 6F 74 00 02 00 02 69 64 01 66 02 00 06 44 61 6D 61 67 65 00 00 01 00 05 43 6F 75 6E 74 01 00 01 00
  26.         // 4  S  l  o  t  0  2  0  2  i  d  01 66 02 00 06 D  a  m  a  g  e  0  0  1  0  5  C  o  u  n  t  1  0  1  0
  27.     }
  28.  
  29.     class Program
  30.     {
  31.         static void Main(string[] args)
  32.         {
  33.             // Here we utilize minecraft.exe to decompress our savegame.dat file that is stored in xbox con file.
  34.             string path = Directory.GetCurrentDirectory();
  35.             ProcessStartInfo startInfo = new ProcessStartInfo();
  36.             startInfo.FileName = Path.GetFullPath(Constants.Minecraft);
  37.             startInfo.Arguments = "-d " + "\"" + path + "\\" + Constants.File + "\"" + " " + "\"" + path + "\\" + Constants.FileDec + "\"";
  38.             startInfo.WindowStyle = ProcessWindowStyle.Hidden;
  39.             startInfo.UseShellExecute = false;
  40.             startInfo.RedirectStandardOutput = true;
  41.             startInfo.RedirectStandardError = true;
  42.             try
  43.             {
  44.                 using (Process process = Process.Start(startInfo))
  45.                 {
  46.                     using (StreamReader reader = process.StandardOutput)
  47.                     {
  48.                         string result = reader.ReadToEnd();
  49.                         Console.Write(result);
  50.                     }
  51.                 }
  52.             }
  53.             catch
  54.             {
  55.                 Console.WriteLine("An unknown error occured!");
  56.             }
  57.             // End of decompressing savegame.dat
  58.  
  59.             // start work on decompressed game save.
  60.             byte[] file = File.ReadAllBytes(Constants.FileDec);
  61.             using (MemoryStream memory = new MemoryStream(file))
  62.             {
  63.                 using (BinaryReader reader = new BinaryReader(memory))
  64.                 {
  65.                     reader.BaseStream.Position = file.Length - 16;
  66.                     byte[] chunkSize = reader.ReadBytes(4);
  67.                     byte[] chunkEnd = reader.ReadBytes(4);
  68.                     string chunkSizeString = BitConverter.ToString(chunkSize).Replace("-", "");
  69.                     string chunkEndString = BitConverter.ToString(chunkEnd).Replace("-", "");
  70.                     int chunkSizeInt = Int32.Parse(chunkSizeString, System.Globalization.NumberStyles.HexNumber);
  71.                     int chunkEndInt = Int32.Parse(chunkEndString, System.Globalization.NumberStyles.HexNumber);
  72.                     int chunkStartInt = chunkEndInt - chunkSizeInt;
  73.                     reader.BaseStream.Position = chunkStartInt;
  74.                     byte[] chunk = new byte[chunkSizeInt];
  75.                     chunk = reader.ReadBytes(chunkSizeInt);
  76.                     //int inventoryInChunk = IndexOf(chunk, Encoding.ASCII.GetBytes(Constants.Inventory)) - 1;
  77.                     //int rotationInChunk = IndexOf(chunk, Encoding.ASCII.GetBytes(Constants.Rotation)) - 2;
  78.                     int inventoryInChunk = ByteSearch(chunk, Encoding.ASCII.GetBytes(Constants.Inventory), 0) - 1;
  79.                     int rotationInChunk = ByteSearch(chunk, Encoding.ASCII.GetBytes(Constants.Rotation), 0) - 2;
  80.                     byte[] newChunk = new byte[chunk.Length - (inventoryInChunk + (chunk.Length - rotationInChunk))];
  81.                     Buffer.BlockCopy(chunk, inventoryInChunk, newChunk, 0, newChunk.Length);
  82.                     // This will be the offset from beginning of file where we want to overwrite with new data.
  83.                     //  New Variable     What we have as previous start offset  +   how many bytes in the string "Inventory" is.
  84.                     //int inventorySizeInChunk = byte array index 14 ( 15 bytes in from beginning of file )
  85.                     int newWriteOffset = chunkStartInt + inventoryInChunk;
  86.  
  87.                     // Push data to console.
  88.                     Console.WriteLine();
  89.                     Console.WriteLine("XBOX 360 Minecraft Toolkit. - Credit to \"fairchild\"\nfor his minecraft save compression toolkit.");
  90.                     Console.WriteLine();
  91.                     Console.WriteLine("Size of file: {0}", file.Length);
  92.                     Console.WriteLine("Chunk Start Offset: {0} Int: {1}", chunkStartInt.ToString("X8"), chunkStartInt);
  93.                     Console.WriteLine("Chunk End Offset:   {0} Int: {1}", chunkEndString, chunkEndInt);
  94.                     Console.WriteLine("Chunk Size:         {0} Int: {1}", chunkSizeString, chunkSizeInt);
  95.                     //Console.WriteLine("Read Size:                   Int: {0}", chunk.Length);
  96.                     Console.WriteLine("Inv offset number of bytes:  Int: {0}",inventoryInChunk);
  97.                     Console.WriteLine("Trimmed bytes from array.    Int: {0}", inventoryInChunk + (chunk.Length - rotationInChunk));
  98.                     Console.WriteLine("New overwrite offset         Int: {0}", newWriteOffset);
  99.                     Console.WriteLine();
  100.                     //int slotInChunk = IndexOf(newChunk, Encoding.ASCII.GetBytes(Constants.Slot));
  101.                     //Console.WriteLine("Slot: {0}", slotInChunk);
  102.                     //int idInChunk = IndexOf(newChunk, Encoding.ASCII.GetBytes(Constants.id));
  103.                     //Console.WriteLine("id: {0}", idInChunk);
  104.                     //int damageInChunk = IndexOf(newChunk, Encoding.ASCII.GetBytes(Constants.Damage));
  105.                     //Console.WriteLine("Damage: {0}", damageInChunk);
  106.                     //int countInChunk = IndexOf(newChunk, Encoding.ASCII.GetBytes(Constants.Count));
  107.                     //Console.WriteLine("Count: {0}", countInChunk);
  108.                     Console.WriteLine("Dumping byte array... Press any key to continue.");
  109.                     Console.ReadKey();
  110.  
  111.                     if (Constants.ThankYou == true)
  112.                     {
  113.                         for (int i = 0; i < 3; i++)
  114.                         {
  115.                             Console.Clear();
  116.                             Console.ForegroundColor = ConsoleColor.Red;
  117.                             Console.WriteLine("Thank you fairchild!");
  118.                             System.Threading.Thread.Sleep(250);
  119.                             Console.SetCursorPosition(0, 0);
  120.                             Console.ForegroundColor = ConsoleColor.Yellow;
  121.                             Console.WriteLine("Thank you fairchild!");
  122.                             System.Threading.Thread.Sleep(250);
  123.                             Console.SetCursorPosition(0, 0);
  124.                             Console.ForegroundColor = ConsoleColor.Green;
  125.                             Console.WriteLine("Thank you fairchild!");
  126.                             System.Threading.Thread.Sleep(250);
  127.                             Console.SetCursorPosition(0, 0);
  128.                         }
  129.                     }
  130.                     Console.Clear();
  131.                     Console.ResetColor();
  132.  
  133.                     Console.ForegroundColor = ConsoleColor.Green;
  134.                     Console.WriteLine("Byte[]:");
  135.                     Console.Write("  1. ");
  136.                     Console.ResetColor();
  137.                     for (int i = 1; i < newChunk.Length + 1; i++)
  138.                     {
  139.                         Console.Write(newChunk[i - 1].ToString("X2"));
  140.  
  141.                         if (i % 8 == 0) // Evenly divisable by 8
  142.                         {
  143.                             Console.WriteLine();
  144.                         }
  145.  
  146.                         if (i % 8 == 0) // Evenly divisable by 8
  147.                         {
  148.                             if (i > newChunk.Length - 1)
  149.                             {
  150.                                 break;
  151.                             }
  152.                             Console.ForegroundColor = ConsoleColor.Green;
  153.                             // This is 8 bytes * 10.
  154.                             // or lines 1 - 9, to be padded.
  155.                             if (i < (8 * 9))
  156.                             {
  157.                                 Console.Write("  {0}. ", (i / 8) + 1);
  158.                             }
  159.                             // This is 8 bytes * 10 less than 8 * 100.
  160.                             // or lines 10 - 99, to be padded.
  161.                             if ((i >= (8 * 9)) & (i < (8 * 99)))
  162.                             {
  163.                                 Console.Write(" {0}. ", (i / 8) + 1);
  164.                             }
  165.                             // This is 8 bytes * 100
  166.                             // or lines over 100, to not be padded.
  167.                             if (i >= (8 * 99))
  168.                             {
  169.                                 Console.Write("{0}. ", (i / 8) + 1);
  170.                             }
  171.                             Console.ResetColor();
  172.                         }
  173.  
  174.                         if ((i % 4 == 0) & !(i % 8 == 0)) // Evenly divisable by 4 and not 8, avoid duplicate spacing.
  175.                         {
  176.                             Console.Write(" ");
  177.                         }
  178.                     }
  179.  
  180.                     // Lets hold the console window open.
  181.                     Console.ReadKey();
  182.                 }
  183.             }
  184.         }
  185.  
  186.         // Taken from http://boncode.blogspot.com/2011/02/net-c-find-pattern-in-byte-array.html
  187.         private static int ByteSearch(byte[] searchIn, byte[] searchBytes, int start)
  188.         {
  189.             int found = -1;
  190.             bool matched = false;
  191.             //only look at this if we have a populated search array and search bytes with a sensible start
  192.             if (searchIn.Length > 0 && searchBytes.Length > 0 && start <= (searchIn.Length - searchBytes.Length) && searchIn.Length >= searchBytes.Length)
  193.             {
  194.                 //iterate through the array to be searched
  195.                 for (int i = start; i <= searchIn.Length - searchBytes.Length; i++)
  196.                 {
  197.                     //if the start bytes match we will start comparing all other bytes
  198.                     if (searchIn[i] == searchBytes[0])
  199.                     {
  200.                         if (searchIn.Length > 1)
  201.                         {
  202.                             //multiple bytes to be searched we have to compare byte by byte
  203.                             matched = true;
  204.                             for (int y = 1; y <= searchBytes.Length - 1; y++)
  205.                             {
  206.                                 if (searchIn[i + y] != searchBytes[y])
  207.                                 {
  208.                                     matched = false;
  209.                                     break;
  210.                                 }
  211.                             }
  212.                             //everything matched up
  213.                             if (matched)
  214.                             {
  215.                                 found = i;
  216.                                 break;
  217.                             }
  218.  
  219.                         }
  220.                         else
  221.                         {
  222.                             //search byte is only one bit nothing else to do
  223.                             found = i;
  224.                             break; //stop the loop
  225.                         }
  226.  
  227.                     }
  228.                 }
  229.  
  230.             }
  231.             return found;
  232.         }
  233.  
  234.         // Old code for byte searching, not sure how to make this loop through the file. Shamelessley stolen from the internet, forgot the source.
  235.         //public static int IndexOf(byte[] arrayToSearchThrough, byte[] patternToFind)
  236.         //{
  237.         //    if (patternToFind.Length > arrayToSearchThrough.Length)
  238.         //        return -1;
  239.         //    for (int i = 0; i < arrayToSearchThrough.Length - patternToFind.Length; i++)
  240.         //    {
  241.         //        bool found = true;
  242.         //        for (int j = 0; j < patternToFind.Length; j++)
  243.         //        {
  244.         //            if (arrayToSearchThrough[i + j] != patternToFind[j])
  245.         //            {
  246.         //                found = false;
  247.         //                break;
  248.         //            }
  249.         //        }
  250.         //        if (found)
  251.         //        {
  252.         //            return i;
  253.         //        }
  254.         //    }
  255.         //    return -1;
  256.         //}
  257.     }
  258. }