Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
 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");
     }
 }
Exemple #6
0
        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());
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        private string PeekChunkType()
        {
            string ct = BinUtils.GetByteString(mCurrentPos, mData, 4);

            return(ct);
        }
Exemple #9
0
        private uint PeekNumber(uint location)
        {
            uint retVal = BinUtils.GetNumberAtLocation(location, mData);

            return(retVal);
        }
Exemple #10
0
 bool HasInfo()
 {
     return(BinUtils.BinCompare(INFO, mData, mCurrentPos));
 }
Exemple #11
0
 bool HasName()
 {
     return(BinUtils.BinCompare(NAME, mData, mCurrentPos));
 }
Exemple #12
0
        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;
                }
            }
        }