/// <summary> /// Creates an entry that only exists in memory. /// </summary> public RAFFileListEntry(RAFArchive raf, string rafPath, UInt32 offsetDatFile, UInt32 fileSize, UInt32 nameStringTableIndex) { inMemory = true; this.raf = raf; this.fileName = rafPath; this.fileOffset = offsetDatFile; this.fileSize = fileSize; this.stringTableIndex = nameStringTableIndex; }
//(string rafPath, UInt32 offset, UInt32 fileSize, UInt32 nameStringTableIndex) public RAFFileListEntry(RAFArchive raf, ref byte[] directoryFileContent, UInt32 offsetDirectoryEntry) { this.raf = raf; this.directoryFileContent = directoryFileContent; this.offsetEntry = offsetDirectoryEntry; this.fileOffset = BitConverter.ToUInt32(directoryFileContent, (int)offsetEntry + 4);; this.fileSize = BitConverter.ToUInt32(directoryFileContent, (int)offsetEntry + 8); this.stringTableIndex = BitConverter.ToUInt32(directoryFileContent, (int)offsetEntry + 12); this.fileName = null; // this.raf.GetDirectoryFile().GetStringTable()[this.stringTableIndex]; }
public RAFManagerCleanWizard(RAFArchive[] archives) { InitializeComponent(); //By default, it's fully highlighted - this unfocuses it, basically introductionTextbox.Select(introductionTextbox.Text.Length, 0); this.archives = archives; ManageGUI(); }
//(string rafPath, UInt32 offset, UInt32 fileSize, UInt32 nameStringTableIndex) public RAFFileListEntry(RAFArchive raf, ref byte[] directoryFileContent, UInt32 offsetDirectoryEntry) { this.raf = raf; this.directoryFileContent = directoryFileContent; this.offsetEntry = offsetDirectoryEntry; this.fileOffset = BitConverter.ToUInt32(directoryFileContent, (int)offsetEntry + 4); ; this.fileSize = BitConverter.ToUInt32(directoryFileContent, (int)offsetEntry + 8); this.stringTableIndex = BitConverter.ToUInt32(directoryFileContent, (int)offsetEntry + 12); this.fileName = null; // this.raf.GetDirectoryFile().GetStringTable()[this.stringTableIndex]; }
public RAFFileList(RAFArchive raf, byte[] directoryFileContent, UInt32 offsetFileListHeader) { this.content = directoryFileContent; this.offsetFileListHeader = offsetFileListHeader; //The file list starts with a uint stating how many files we have fileListCount = BitConverter.ToUInt32(content.SubArray((Int32)offsetFileListHeader, 4), 0); //After the file list count, we have the actual data. UInt32 offsetEntriesStart = offsetFileListHeader + 4; this.fileEntries = new List<RAFFileListEntry>(); for (UInt32 currentOffset = offsetEntriesStart; currentOffset < offsetEntriesStart + 16 * fileListCount; currentOffset += 16) { this.fileEntries.Add(new RAFFileListEntry(raf, ref directoryFileContent, currentOffset)); } }
public RAFDirectoryFile(RAFArchive raf, string location) { this.raf = raf; content = System.IO.File.ReadAllBytes(location); magic = BitConverter.ToUInt32(content.SubArray(0, 4), 0); version = BitConverter.ToUInt32(content.SubArray(4, 4), 0); mgrIndex = BitConverter.ToUInt32(content.SubArray(8, 4), 0); offsetFileList = BitConverter.ToUInt32(content.SubArray(12, 4), 0); offsetStringTable = BitConverter.ToUInt32(content.SubArray(16, 4), 0); //UINT32 is casted to INT32. This should be fine, since i doubt that the RAF will become //a size of 2^31-1 in bytes. fileList = new RAFFileList(raf, content, offsetFileList); //Now we load our string table stringTable = new RAFStringTable(raf, content, offsetStringTable); }
public RAFFileList(RAFArchive raf, byte[] directoryFileContent, UInt32 offsetFileListHeader) { this.content = directoryFileContent; this.offsetFileListHeader = offsetFileListHeader; //The file list starts with a uint stating how many files we have fileListCount = BitConverter.ToUInt32(content.SubArray((Int32)offsetFileListHeader, 4), 0); //After the file list count, we have the actual data. UInt32 offsetEntriesStart = offsetFileListHeader + 4; this.fileEntries = new List <RAFFileListEntry>(); for (UInt32 currentOffset = offsetEntriesStart; currentOffset < offsetEntriesStart + 16 * fileListCount; currentOffset += 16) { this.fileEntries.Add(new RAFFileListEntry(raf, ref directoryFileContent, currentOffset)); } }
public RAFStringTable(RAFArchive raf, byte[] directoryFileContent, UInt32 offsetTable) { this.raf = raf; this.directoryFileContent = directoryFileContent; //Console.WriteLine("String Table Offset: " + offsetTable.ToString("x")); UInt32 sizeOfData = BitConverter.ToUInt32(directoryFileContent, (int)offsetTable); UInt32 stringCount = BitConverter.ToUInt32(directoryFileContent, (int)offsetTable+4); //Load strings in memory for (UInt32 i = 0; i < stringCount; i++) { UInt32 entryOffset = offsetTable + 8 + i * 8; //+8 because of table header { size, count } //Above value points to the actual entry UInt32 entryValueOffset = BitConverter.ToUInt32(directoryFileContent, (int)entryOffset); UInt32 entryValueSize = BitConverter.ToUInt32(directoryFileContent, (int)entryOffset + 4); //-1 seems necessary. I'd assume some null padding ends strings... byte[] stringBytes = directoryFileContent.SubArray((int)(entryValueOffset + offsetTable), (int)entryValueSize - 1); strings.Add(Encoding.ASCII.GetString(stringBytes)); } }
public RAFStringTable(RAFArchive raf, byte[] directoryFileContent, UInt32 offsetTable) { this.raf = raf; this.directoryFileContent = directoryFileContent; //Console.WriteLine("String Table Offset: " + offsetTable.ToString("x")); UInt32 sizeOfData = BitConverter.ToUInt32(directoryFileContent, (int)offsetTable); UInt32 stringCount = BitConverter.ToUInt32(directoryFileContent, (int)offsetTable + 4); //Load strings in memory for (UInt32 i = 0; i < stringCount; i++) { UInt32 entryOffset = offsetTable + 8 + i * 8; //+8 because of table header { size, count } //Above value points to the actual entry UInt32 entryValueOffset = BitConverter.ToUInt32(directoryFileContent, (int)entryOffset); UInt32 entryValueSize = BitConverter.ToUInt32(directoryFileContent, (int)entryOffset + 4); //-1 seems necessary. I'd assume some null padding ends strings... byte[] stringBytes = directoryFileContent.SubArray((int)(entryValueOffset + offsetTable), (int)entryValueSize - 1); strings.Add(Encoding.ASCII.GetString(stringBytes)); } }
/// <summary> /// Dumps the content of the first .raf/.raf.dat archive seen in the given directory. /// Outputs to the given ostream /// </summary> public static bool Dump(string directory, StreamWriter ostream) { #region output_usage_header ostream.WriteLine("Experimental RAF Dumper by ItzWarty @ ItzWarty.com April 28 2011 10:00pm pst"); ostream.WriteLine("RAF dogcumentation @ bit.ly/mSyYrR "); ostream.WriteLine("USAGE: RAF_DUMP (Or just double click executable)"); ostream.WriteLine("Precondition: RAF_DUMP is sitting next to a Riot Archive File."); ostream.WriteLine("Postcondition: 'dump' folder created. RAF extracted into folder."); #endregion //string dumpDir = @"C:\Riot Games\League of Legends\RADS\projects\lol_game_client\filearchives\0.0.0.28\dump\"; //We write the file containing "name hash" next to our program. string hashesFile = Environment.CurrentDirectory + "\\hashes.txt"; string hashesLog = ""; //We write to this file saying what we don't compress string notcompressedsFile = Environment.CurrentDirectory + "\\nocompress.txt"; string notcompressedsLog = ""; string dumpDir = Environment.CurrentDirectory + "\\dump\\"; String[] filesInDir = Directory.GetFiles(Environment.CurrentDirectory); String rafName = ""; foreach (String fileName in filesInDir) { if (fileName.Split("\\").Last().EndsWith(".raf", StringComparison.InvariantCultureIgnoreCase)) { rafName = fileName; } } if (rafName == "") { ostream.WriteLine("Couldn't find RAF file!!"); //ostream.WriteLine("This executable must be in the same folder as a *.raf and *.raf.dat file!"); //ostream.WriteLine("Exiting... Press a key (or two) to exit"); //ostream.ReadKey(); return false; } ostream.WriteLine("Found RAF: " + rafName); RAFArchive raf = new RAFArchive(rafName); FileStream fStream = raf.GetDataFileContentStream(); //DeflateStream dfStream = new DeflateStream(fStream, CompressionMode.Decompress); //int loggingOffset = 10; //No longer applicable since we aren't logging to system.out console directly List<RAFFileListEntry> files = raf.GetDirectoryFile().GetFileList().GetFileEntries(); foreach (RAFFileListEntry entry in files) { //ostream.SetCursorPosition(0, 7); ostream.WriteLine("Dumping: " + entry.FileName.Split("\\").Last() + " ".Repeat(40)); //ostream.SetCursorPosition(0, 8); ostream.WriteLine(" Data File Offset: $" + entry.FileOffset.ToString("x") + "; Size:" + entry.FileSize + " ($" + entry.FileSize.ToString("x") + ")" + " ".Repeat(40)); //Console.SetCursorPosition(0, 7); //Console.WriteLine(" Expected FileName Checksum: $" + entry.StringNameHash.ToString("x") + "; Calculated:" + Adler32(entry.GetFileName).ToString("x")/*entry.GetFileName.GetHashCode().ToString("x")*/ + " ".Repeat(40)); //Console.WriteLine(" To: " + dumpDir + entry.GetFileName+";;"); hashesLog += entry.FileName + "|||" + entry.StringNameHash + "\n"; //zlib.ad byte[] buffer = new byte[entry.FileSize]; fStream.Seek(entry.FileOffset, SeekOrigin.Begin); fStream.Read(buffer, 0, (int)entry.FileSize); PrepareDirectory((dumpDir + entry.FileName).Replace("/", "\\")); try { MemoryStream mStream = new MemoryStream(buffer); zlib.ZInputStream zinput = new zlib.ZInputStream(mStream); List<byte> dBuffer = new List<byte>(); //decompressed buffer, arraylist to my knowledge... int data = 0; while ((data = zinput.Read()) != -1) dBuffer.Add((byte)data); //ComponentAce.Compression.Libs.zlib.ZStream a = new ComponentAce.Compression.Libs.zlib.ZStream(); File.WriteAllBytes((dumpDir + entry.FileName).Replace("/", "\\"), dBuffer.ToArray()); } catch { notcompressedsLog += entry.FileName.ToLower() + "\n"; //Console.SetCursorPosition(2, loggingOffset++); ostream.Write("UNABLE TO DECOMPRESS FILE, WRITING DEFLATED FILE:"); //Console.SetCursorPosition(4, loggingOffset++); ostream.Write(" " + entry.FileName); File.WriteAllBytes((dumpDir + entry.FileName).Replace("/", "\\"), buffer.ToArray()); } } //Console.SetCursorPosition(0, 0); ostream.WriteLine("Write hashes and nocompress file"); File.WriteAllText(hashesFile, hashesLog); File.WriteAllText(notcompressedsFile, notcompressedsLog); ostream.WriteLine("DONE!" + " ".Repeat(30)); //fStream.Close(); return true; //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); }
/// <summary> /// Loads the RAF Archives /// </summary> public void LoadRAFArchives() { ArchiveFSOs = new List<RAFInMemoryFileSystemObject>(); Archives = new List<RAFArchive>(); TreeView temp = new TreeView(); //temp.TreeViewNodeSorter = new RAFFSOTreeNodeSorter(); string[] archivePaths = Directory.GetDirectories(fileArchivesPath); for (int i = 0; i < archivePaths.Length; i++) { string archiveName = archivePaths[i].Replace(fileArchivesPath, "").Replace("/", ""); gui.LogToLoader("Load Archive - " + archiveName + " [0%]"); //Title("Loading RAF File - " + archiveName); //Log("Loading RAF Archive Folder: " + archiveName); RAFArchive raf = null; RAFInMemoryFileSystemObject archiveRoot = new RAFInMemoryFileSystemObject(null, RAFFSOType.ARCHIVE, archiveName); temp.Nodes.Add(archiveRoot); ArchiveFSOs.Add(archiveRoot); #if !DEBUG try { #endif //Load raf file table and add to our list of archives Archives.Add( raf = new RAFArchive( Directory.GetFiles(archivePaths[i], "*.raf")[0] ) ); //Enumerate entries and add to our tree... in the future this should become sorted List<RAFFileListEntry> entries = raf.GetDirectoryFile().GetFileList().GetFileEntries(); for (int j = 0; j < entries.Count; j++) { // Console.WriteLine(entries[j].StringNameHash.ToString("x").PadLeft(8, '0').ToUpper()); if (j % 1000 == 1000) gui.SetLastLoaderLine("Load Archive - " + archiveName + " [" + (j * 100 / entries.Count) + "%]"); //Title("Loading RAF Files - " + archiveName +" - " + j+"/"+entries.Count); RAFInMemoryFileSystemObject node = archiveRoot.AddToTree(RAFFSOType.FILE, entries[j].FileName); } //Log(entries.Count.ToString() + " Files"); #if !DEBUG } catch (Exception exception) { Log("FAILED:\r\n" + exception.Message + "\r\n"); } #endif //Add to our tree displayer //Title("Sorting nodes... this might take a while"); if (archiveRoot.Nodes.Count == 0) { MessageBox.Show("Another instance of RAF Manager is likely already open.\r\n" + "If not, then another application has not released control over the \r\n" + "RAF Archives. RAF Manager will continue to run, but some features \r\n" + "may not work properly. Usually a restart of the application will \r\n" + "fix this. If you have issues, post a reply on the forum thread, \r\n" + "whose link can be found under the 'About' menu header."); } } }
private void BeginMinifyArchive(RAFArchive archive) { bw.RunWorkerAsync(archive); }
void MainForm_Load(object sender, EventArgs e) { MainWindowLoading loader = new MainWindowLoading(); loader.Show(); loader.Log("Begin Check For Updates"); CheckForUpdates(); loader.Log("Find Archives Folder"); SetArchivesRoot(); loader.Log("Begin Loading RAF Archives"); consoleLogTB.Text = "www.ItzWarty.com Riot Archive File Packer/Unpacker " + ApplicationInformation.BuildTime; rafContentView.TreeViewNodeSorter = new RAFFSOTreeNodeSorter(); //Enumerate RAF files string[] archivePaths = Directory.GetDirectories(archivesRoot); #region load_raf_archives for (int i = 0; i < archivePaths.Length; i++) { string archiveName = archivePaths[i].Replace(archivesRoot, "").Replace("/", ""); loader.Log("Load Archive - " + archiveName +" [0%]"); //Title("Loading RAF File - " + archiveName); //Log("Loading RAF Archive Folder: " + archiveName); RAFArchive raf = null; RAFInMemoryFileSystemObject archiveRoot = new RAFInMemoryFileSystemObject(null, RAFFSOType.ARCHIVE, archiveName); rafContentView.Nodes.Add(archiveRoot); #if !DEBUG try { #endif //Load raf file table and add to our list of archives rafArchives.Add(archiveName, raf = new RAFArchive( Directory.GetFiles(archivePaths[i], "*.raf")[0] ) ); //Enumerate entries and add to our tree... in the future this should become sorted List<RAFFileListEntry> entries = raf.GetDirectoryFile().GetFileList().GetFileEntries(); for (int j = 0; j < entries.Count; j++) { // Console.WriteLine(entries[j].StringNameHash.ToString("x").PadLeft(8, '0').ToUpper()); if (j % 1000 == 0) loader.Log("Load Archive - " + archiveName + " [" + (j * 100 / entries.Count) + "%]"); //Title("Loading RAF Files - " + archiveName +" - " + j+"/"+entries.Count); RAFInMemoryFileSystemObject node = archiveRoot.AddToTree(RAFFSOType.FILE, entries[j].FileName); } //Log(entries.Count.ToString() + " Files"); #if !DEBUG } catch (Exception exception) { Log("FAILED:\r\n" + exception.Message + "\r\n"); } #endif //Add to our tree displayer //Title("Sorting nodes... this might take a while"); if (archiveRoot.Nodes.Count == 0) { MessageBox.Show("Another instance of RAF Manager is likely already open.\r\n" + "If not, then another application has not released control over the \r\n" + "RAF Archives. RAF Manager will continue to run, but some features \r\n" + "may not work properly. Usually a restart of the application will \r\n" + "fix this. If you have issues, post a reply on the forum thread, \r\n" + "whose link can be found under the 'About' menu header."); } } #endregion try { while (loader.Visible) //Hack - i have no idea why this is necessary sometimes... probs race condition somewhere { loader.Hide(); Application.DoEvents(); } }catch{} lock (consoleLogTB) { Log(""); Log("A simple guide for using RAF Manager can be located at About->Simple Guide."); Log(""); if (File.Exists(".laststate.rmproj")) { Log("Open last state"); OpenProject(".laststate.rmproj"); } } }
/// <summary> /// Dumps the content of the first .raf/.raf.dat archive seen in the given directory. /// Outputs to the given ostream /// </summary> public static bool Dump(string directory, StreamWriter ostream) { #region output_usage_header ostream.WriteLine("Experimental RAF Dumper by ItzWarty @ ItzWarty.com April 28 2011 10:00pm pst"); ostream.WriteLine("RAF dogcumentation @ bit.ly/mSyYrR "); ostream.WriteLine("USAGE: RAF_DUMP (Or just double click executable)"); ostream.WriteLine("Precondition: RAF_DUMP is sitting next to a Riot Archive File."); ostream.WriteLine("Postcondition: 'dump' folder created. RAF extracted into folder."); #endregion //string dumpDir = @"C:\Riot Games\League of Legends\RADS\projects\lol_game_client\filearchives\0.0.0.28\dump\"; //We write the file containing "name hash" next to our program. string hashesFile = Environment.CurrentDirectory + "\\hashes.txt"; string hashesLog = ""; //We write to this file saying what we don't compress string notcompressedsFile = Environment.CurrentDirectory + "\\nocompress.txt"; string notcompressedsLog = ""; string dumpDir = Environment.CurrentDirectory + "\\dump\\"; String[] filesInDir = Directory.GetFiles(Environment.CurrentDirectory); String rafName = ""; foreach (String fileName in filesInDir) { if (fileName.Split("\\").Last().EndsWith(".raf", StringComparison.InvariantCultureIgnoreCase)) { rafName = fileName; } } if (rafName == "") { ostream.WriteLine("Couldn't find RAF file!!"); //ostream.WriteLine("This executable must be in the same folder as a *.raf and *.raf.dat file!"); //ostream.WriteLine("Exiting... Press a key (or two) to exit"); //ostream.ReadKey(); return(false); } ostream.WriteLine("Found RAF: " + rafName); RAFArchive raf = new RAFArchive(rafName); FileStream fStream = raf.GetDataFileContentStream(); //DeflateStream dfStream = new DeflateStream(fStream, CompressionMode.Decompress); //int loggingOffset = 10; //No longer applicable since we aren't logging to system.out console directly List <RAFFileListEntry> files = raf.GetDirectoryFile().GetFileList().GetFileEntries(); foreach (RAFFileListEntry entry in files) { //ostream.SetCursorPosition(0, 7); ostream.WriteLine("Dumping: " + entry.FileName.Split("\\").Last() + " ".Repeat(40)); //ostream.SetCursorPosition(0, 8); ostream.WriteLine(" Data File Offset: $" + entry.FileOffset.ToString("x") + "; Size:" + entry.FileSize + " ($" + entry.FileSize.ToString("x") + ")" + " ".Repeat(40)); //Console.SetCursorPosition(0, 7); //Console.WriteLine(" Expected FileName Checksum: $" + entry.StringNameHash.ToString("x") + "; Calculated:" + Adler32(entry.GetFileName).ToString("x")/*entry.GetFileName.GetHashCode().ToString("x")*/ + " ".Repeat(40)); //Console.WriteLine(" To: " + dumpDir + entry.GetFileName+";;"); hashesLog += entry.FileName + "|||" + entry.StringNameHash + "\n"; //zlib.ad byte[] buffer = new byte[entry.FileSize]; fStream.Seek(entry.FileOffset, SeekOrigin.Begin); fStream.Read(buffer, 0, (int)entry.FileSize); PrepareDirectory((dumpDir + entry.FileName).Replace("/", "\\")); try { MemoryStream mStream = new MemoryStream(buffer); zlib.ZInputStream zinput = new zlib.ZInputStream(mStream); List <byte> dBuffer = new List <byte>(); //decompressed buffer, arraylist to my knowledge... int data = 0; while ((data = zinput.Read()) != -1) { dBuffer.Add((byte)data); } //ComponentAce.Compression.Libs.zlib.ZStream a = new ComponentAce.Compression.Libs.zlib.ZStream(); File.WriteAllBytes((dumpDir + entry.FileName).Replace("/", "\\"), dBuffer.ToArray()); } catch { notcompressedsLog += entry.FileName.ToLower() + "\n"; //Console.SetCursorPosition(2, loggingOffset++); ostream.Write("UNABLE TO DECOMPRESS FILE, WRITING DEFLATED FILE:"); //Console.SetCursorPosition(4, loggingOffset++); ostream.Write(" " + entry.FileName); File.WriteAllBytes((dumpDir + entry.FileName).Replace("/", "\\"), buffer.ToArray()); } } //Console.SetCursorPosition(0, 0); ostream.WriteLine("Write hashes and nocompress file"); File.WriteAllText(hashesFile, hashesLog); File.WriteAllText(notcompressedsFile, notcompressedsLog); ostream.WriteLine("DONE!" + " ".Repeat(30)); //fStream.Close(); return(true); //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); }