private string ReadNameHash() { string retVal = null; if (BinUtils.BinCompare(NAME, mData, mCurrentPos)) { ConsumeBytes(4); uint nameLen = BinUtils.GetNumberAtLocation(mCurrentPos, mData); ConsumeBytes(4); uint nameHash = BinUtils.GetNumberAtLocation(mCurrentPos, mData); ConsumeBytes(4); retVal = String.Format("0x{0:x}", nameHash); } return(retVal); }
public byte[] GetBodyData() { byte[] BodyBytes = { 0x42, 0x4f, 0x44, 0x59 }; long loc = BinUtils.GetLocationOfGivenBytes(0, BodyBytes, Data, 80); if (loc > -1) { uint bodyLen = BinUtils.GetNumberAtLocation(loc + 4, Data); long bodyStart = loc + 8; long bodyEnd = loc + 8 + bodyLen; byte[] bodyData = new byte[bodyLen]; Array.Copy(Data, bodyStart, bodyData, 0, bodyLen); return(bodyData); } return(null); }
/// <summary> /// Places the string with the given hashid into the stringbuilder passed in. /// String ids can be present multiple times. This will return the last occurance /// of the string. /// </summary> /// <param name="hashId"></param> /// <param name="sb">string will be added to the builder</param> /// <returns>The location of the string id, -1 if not found </returns> public int GetString(UInt32 hashId, StringBuilder sb) { int stringLoc = (int)BodyStart; int occurance = 0; int target_occurance = 1; if (mStringSet2 != null && mStringSet2.ContainsKey(hashId)) { target_occurance++; } UInt32 currentHash = 0; while (true) { currentHash = BinUtils.GetNumberAtLocation(stringLoc, mData); if (currentHash == hashId) { occurance++; if (occurance == target_occurance) { break; } } stringLoc = NextStringLoc(stringLoc); if (stringLoc + 10 > mData.Count) { return(-1); } } UInt16 sz = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData); int byteStart = stringLoc + 6; int byteEnd = stringLoc + sz - 1; char current = '\0'; for (int i = byteStart; i < byteEnd; i += 2) { current = (char)BinUtils.Get2ByteNumberAtLocation(i, mData); if (current != '\0') { sb.Append(current); } } return(stringLoc); }
/// <summary> /// Returns the path to the extraction folder /// </summary> /// <returns></returns> public string ExtractContents() { mCurrentPos = 0; //mPlanFileCount = 0; string retVal = CreateExtractDir(); //read file header if (!BinUtils.BinCompare(UCFB, mData, mCurrentPos)) { Program.MessageUser("ERROR! This is not a UCF file: " + FileName); return(null); } //ConsumeBytes(4); // advance past ucfb header uint bytesLeftInFile = InitializeRead(); if (mData.Length - (mCurrentPos + bytesLeftInFile) != 0) { Program.MessageUser("WARNING! ucfb length data kinda sketchy: " + FileName); } mManifest.Clear(); try { while (RipChunk(true) != null) { ; } } catch (System.IndexOutOfRangeException) { } WriteManifest(); if (FileName.EndsWith(".lvl")) { string reqFileName = FileName.Replace(".lvl", ".req"); int lastSlash = reqFileName.LastIndexOf("\\"); reqFileName = reqFileName.Substring(lastSlash + 1); reqFileName = retVal + reqFileName; string req = ReqMaker.GetReq(retVal); File.WriteAllText(reqFileName, req); } return(retVal); }
private void RenameItem(Chunk c, String newName) { if (newName != null) { if (newName.Length == c.Name.Length) { int start = (int)BinUtils.GetLocationOfGivenBytes(c.Start, ASCIIEncoding.ASCII.GetBytes(c.Name), mUcfbFileHelper.Data, 80); for (int i = 0; i < c.Name.Length; i++) { mUcfbFileHelper.Data[start + i] = (byte)newName[i]; } } else { Console.WriteLine("It is unsupported to change the length of the item's name."); } } else { Console.WriteLine("Error! Cannot set item name to null"); } }
public string GetAllStrings() { /*bool debug = true; * UInt16 prevSz = 0; * int prevLoc = 0; debug stuff*/ mStringSet = new Dictionary <uint, string>(2000); mStringSet2 = new Dictionary <uint, string>(200); StringBuilder cur = new StringBuilder(80); StringBuilder sb = new StringBuilder(50 * 3200); int stringLoc = (int)BodyStart; UInt32 currentHash = 0; UInt16 sz = 0; int byteStart = 0; int byteEnd = 0; char current = '\0'; string stringId = ""; while ((currentHash = BinUtils.GetNumberAtLocation(stringLoc, mData)) > 0) { stringId = HashHelper.GetStringFromHash(currentHash); if (stringId == null) { stringId = String.Format("0x{0:x6}", currentHash); } sb.Append(stringId); sb.Append("=\""); sz = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData); //Console.WriteLine("GetAllStrings: Size={0}", sz); byteStart = stringLoc + 6; byteEnd = stringLoc + sz - 1; current = '\0'; for (int i = byteStart; i < byteEnd; i += 2) { current = (char)BinUtils.Get2ByteNumberAtLocation(i, mData); if (current == '"') { sb.Append("\\\""); // escape the quote cur.Append("\\\""); } else if (current == '\\') { sb.Append("\\\\"); // escape the escape! cur.Append("\\\\"); } else if (current != '\0') { sb.Append(current); cur.Append(current); } } if (currentHash != 0xffffffff) { if (mStringSet.ContainsKey(currentHash)) { if (!mStringSet2.ContainsKey(currentHash)) { mStringSet2.Add(currentHash, cur.ToString()); } else { Console.WriteLine("Sorry, not showing 3+ instances of string 0x{0:x}:'{1}'", currentHash, cur.ToString()); } //Console.WriteLine("Error! key 0x{0:x} ({1}) already exists as: {2}", currentHash, stringId, mStringSet[currentHash]); //Console.WriteLine("Cannot add {0}:{1}",stringId, cur.ToString() ); } else { mStringSet.Add(currentHash, cur.ToString()); } } /*if (debug && cur.Length == 0) * Console.WriteLine("MT, sz:0x{0:x2} pos:0x{1:x6} prevSz:0x{2:x2} prevPos:0x{3:x6}", sz, stringLoc, prevSz, prevLoc); * prevLoc = stringLoc; // TODO remove these 2 after debugging * prevSz = sz; */ cur.Length = 0; // clear sb.Append("\"\n"); stringLoc = NextStringLoc(stringLoc); if (stringLoc + 10 > mData.Count) // for a string you need minimum 4 bytes for the hash, 2 for size and 4 for nulls { break; } } //Console.WriteLine("mStringSet2.Count:{0}",mStringSet2.Count); return(sb.ToString()); }
private string PeekName(uint location, string chunkType) { string name = ""; if (chunkType == "plan") { string lvlName = GetLvlFileName(); return(lvlName.Replace(".lvl", "")); } long loc = 0; if (chunkType == "lvl_") { uint hash = BinUtils.GetNumberAtLocation(location + 8, mData); string str = HashHelper.GetStringFromHash(hash); if (str != null) { name = str; } else { name = "0x" + hash.ToString("X"); } } if (chunkType == "entc") { loc = BinUtils.GetLocationOfGivenBytes(location, ASCIIEncoding.ASCII.GetBytes("TYPE"), mData, 80); } else { loc = BinUtils.GetLocationOfGivenBytes(location, ASCIIEncoding.ASCII.GetBytes("NAME"), mData, 80); } if (loc > -1) { int nameLen = mData[(int)loc + 4] - 1; // -1 for null byte if (loc > 0) { name = Encoding.ASCII.GetString(mData, (int)loc + 8, (int)nameLen); int zeroTest = name.IndexOf('\0'); if (zeroTest > -1) { name = name.Substring(0, zeroTest); } } List <string> hexNameTypes = new List <string> { "mcfg", "sanm", "fx__" }; if (nameLen == 3 && (hexNameTypes.IndexOf(chunkType) > -1 || HasBadCharacters(name)))//sf__ { uint hash = BinUtils.GetNumberAtLocation(loc + 8, mData); string str = HashHelper.GetStringFromHash(hash); if (str != null) { name = str; } else { name = String.Format("0x{0:X}", hash); } } } return(name); }
private string PeekChunkType() { string ct = BinUtils.GetByteString(mCurrentPos, mData, 4); return(ct); }
private uint PeekNumber(uint location) { uint retVal = BinUtils.GetNumberAtLocation(location, mData); return(retVal); }
bool HasInfo() { return(BinUtils.BinCompare(INFO, mData, mCurrentPos)); }
bool HasName() { return(BinUtils.BinCompare(NAME, mData, mCurrentPos)); }
public static void Main(string[] args) { LoadSettings(); if (args.Length == 0) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } else { try { ProcessArgs(args); } catch (Exception) { Console.Error.WriteLine("Error! Check arguments!"); return; } string[] files_ = GetFiles(files); switch (operation) { case OperationMode.ShowHelp: PrintHelp(); break; case OperationMode.Extract: if (input_lvl != null) { UcfbHelper helper = new UcfbHelper(); helper.FileName = input_lvl; helper.ExtractContents(); } else { Console.WriteLine("Error! Must specify input file"); } break; case OperationMode.Add: if (output_lvl == null) { output_lvl = input_lvl; } if (input_lvl != null) { UcfbHelper helper = new UcfbHelper(); helper.FileName = input_lvl; foreach (string f in files_) { string fileName = Munger.EnsureMungedFile(f, platform); helper.AddItemToEnd(fileName); } helper.SaveData(output_lvl); } else { Console.WriteLine("Error! Must specify input file"); } break; case OperationMode.Replace: if (output_lvl == null) { output_lvl = input_lvl; } if (input_lvl != null) { ReplaceItem_WithForm(input_lvl, output_lvl, files_); } else { Console.WriteLine("Error! Must specify input file"); } break; case OperationMode.Rename: if (input_lvl == null) { Console.WriteLine("Rename Error: no input file specified"); return; } if (old_name != null && new_name != null && old_name.Length == new_name.Length) { UcfbHelper helper = new UcfbHelper(); helper.FileName = input_lvl; helper.InitializeRead(); Chunk c = null; while ((c = helper.RipChunk(false)) != null) { if (c.Name == old_name) { break; } } if (c != null) { int start = (int)BinUtils.GetLocationOfGivenBytes(c.Start, ASCIIEncoding.ASCII.GetBytes(c.Name), helper.Data, 80); for (int i = 0; i < c.Name.Length; i++) { helper.Data[start + i] = (byte)new_name[i]; } helper.SaveData(output_lvl); Console.WriteLine("Changed {0} to {1}, saved to {2}", old_name, new_name, output_lvl); } else { Console.WriteLine("Coould not find '{0}'. No action taken", old_name); } } else { Console.WriteLine("Rename Error: old name and new name must be specified and be equal length"); } break; case OperationMode.ListContents: UcfbHelper listHelper = new UcfbHelper(); listHelper.FileName = input_lvl; listHelper.InitializeRead(); Chunk cur = null; while ((cur = listHelper.RipChunk(false)) != null) { Console.WriteLine("{0}.{1}", cur.Name, cur.Type); } break; case OperationMode.MergeCore: List <string> theFiles = new List <string>(Directory.GetFiles( merge_strings_search_dir, "core.lvl", SearchOption.AllDirectories)); //english,spanigh,italian,french,german,japanese,uk_english theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "english.txt", SearchOption.AllDirectories)); theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "spanish.txt", SearchOption.AllDirectories)); theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "italian.txt", SearchOption.AllDirectories)); theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "french.txt", SearchOption.AllDirectories)); theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "german.txt", SearchOption.AllDirectories)); theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "japanese.txt", SearchOption.AllDirectories)); theFiles.AddRange(Directory.GetFiles(merge_strings_search_dir, "uk_english.txt", SearchOption.AllDirectories)); CoreMerge.MergeLoc(input_lvl, output_lvl, theFiles); break; case OperationMode.PS2_BF1AddonScript: // This code operates as expected; but currently the PS2 crashes when reading the generated .lvl . string[] neededFiles = new String[] { ".\\bin\\luac_4.exe", ".\\bin\\BF1_LevelPack.exe", ".\\bin\\BF1_ScriptMunge.exe" }; foreach (string nf in neededFiles) { if (!File.Exists(nf)) { MessageBox.Show("Required files for operation:\r\n" + String.Join("\r\n", neededFiles), "Error, missing required files"); return; } } StringBuilder builder = new StringBuilder(); builder.Append("print('PROCESS_ADDONS_PS2_BF1 start', 'debug')\r\n"); //string debugFile = "DEBUG\\DEBUG.lvl"; //if (File.Exists(debugFile)) //{ // builder.Append(" ReadDataFile('addon\\debug\\debug.lvl'); \r\n"); // builder.Append(" ScriptCB_DoFile('debug'); \r\n"); //} string current = ""; for (int i = 0; i < 1000; i++) { current = string.Format("{0:D3}\\ADDON{0:D3}.lvl", i); if (File.Exists(current)) { builder.Append(String.Format(" ReadDataFile('addon\\{0:D3}\\addon{0:D3}.lvl'); \r\n", i)); builder.Append(String.Format(" ScriptCB_DoFile('addon{0:D3}'); \r\n", i)); } } builder.Append("print('PROCESS_ADDONS_PS2_BF1 end', 'debug')"); // copy to 'PROCESS_ADDONS_PS2_BF1.LUA' String ps2LuaFileName = "PROCESS_ADDONS_PS2_BF1.LUA"; File.WriteAllText(Path.GetFullPath(ps2LuaFileName), builder.ToString()); // create the lvl with the 'CreateLvlForm' CreateLvlForm lvlMaker = new CreateLvlForm(); lvlMaker.OverrideScriptMunge = Path.GetFullPath("bin\\BF1_ScriptMunge.exe"); lvlMaker.OverrideLevelPack = Path.GetFullPath("bin\\BF1_LevelPack.exe"); File.Copy("bin\\luac_4.exe", ".\\luac.exe", true); // ensure lua4 for BF1 lvlMaker.AddItem(ps2LuaFileName); try { lvlMaker.CreateLvl(".\\", "PROCESS_ADDONS_PS2_BF1.LVL", "PS2", true); RemoveLogFiles(); } catch (Exception lvlExc) { Console.WriteLine("Error Creating PROCESS_ADDONS_PS2_BF1.LVL!" + lvlExc.Message); } finally { File.Delete(".\\luac.exe"); lvlMaker.Dispose(); } break; } } }