Ejemplo n.º 1
0
        /// <summary>
        /// 文件导出
        /// </summary>
        /// <param name="fileInfo"></param>
        private void ExportFile(FilePosInfo fileInfo)
        {
            FileStream fs = null;

            try
            {
                fs = File.Open(fileInfo.File, FileMode.Open);
                fs.Seek(fileInfo.FilePos, SeekOrigin.Begin);

                byte[] subFile = new byte[fileInfo.FileSize];
                fs.Read(subFile, 0, subFile.Length);

                File.WriteAllBytes(this.baseFolder + @"\" + fileInfo.SubName, subFile);
                fs.Close();
                fs = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 添加Afs文件
        /// </summary>
        /// <param name="afsFile"></param>
        private void AddAfsFile(string afsFile)
        {
            byte[] byAfs        = File.ReadAllBytes(afsFile);
            int    subFileCount = (byAfs[7] << 24) | (byAfs[6] << 16) | (byAfs[5] << 8) | byAfs[4];
            int    entryPos     = 8;
            int    nameEntryPos = entryPos + subFileCount * 8;

            nameEntryPos = (byAfs[nameEntryPos + 3] << 24) | (byAfs[nameEntryPos + 2] << 16) | (byAfs[nameEntryPos + 1] << 8) | byAfs[nameEntryPos];

            for (int i = 0; i < subFileCount; i++)
            {
                FilePosInfo fileInfo = new FilePosInfo(afsFile);
                fileInfo.FilePos  = (byAfs[entryPos + i * 8 + 3] << 24) | (byAfs[entryPos + i * 8 + 2] << 16) | (byAfs[entryPos + i * 8 + 1] << 8) | byAfs[entryPos + i * 8];
                fileInfo.FileSize = (byAfs[entryPos + i * 8 + 7] << 24) | (byAfs[entryPos + i * 8 + 6] << 16) | (byAfs[entryPos + i * 8 + 5] << 8) | byAfs[entryPos + i * 8 + 4];
                fileInfo.SubName  = Util.GetFileNameFromStringTable(byAfs, nameEntryPos + i * 0x30);
                fileInfo.SubIndex = i.ToString();
                if (string.IsNullOrEmpty(fileInfo.SubName.Trim()))
                {
                    fileInfo.SubName = Util.GetShortName(afsFile) + "_" + i.ToString().PadLeft(2, '0');
                }

                this.textFiles.Add(fileInfo);
                this.lstAsfFiles.Items.Add(fileInfo.SubName.PadRight(40, ' ') + " " + fileInfo.FilePos.ToString("x") + "--" + (fileInfo.FilePos + fileInfo.FileSize).ToString("x"));
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 重新设置带Entry信息的翻译后的数据
        /// </summary>
        /// <param name="currentFileInfo">当前选择的文件</param>
        /// <param name="byData">当前选择的文件的字节数据</param>
        /// <param name="cnBytes">翻译后的字节数据</param>
        /// <returns>带Entry信息的翻译后的数据</returns>
        protected override byte[] ResetCnDataWithEnrty(FilePosInfo currentFileInfo, byte[] byData, List <byte> cnBytes)
        {
            // 带Entry的文本,先保存修改后的各个Entry
            int entryLen = currentFileInfo.TextEntrys.Count * 2;

            byte[] byCnData = new byte[entryLen + 2 + cnBytes.Count];
            int    idx      = 0;

            for (int i = 0; i < currentFileInfo.TextEntrys.Count; i += 2)
            {
                int startPos = currentFileInfo.TextEntrys[i] / 2;
                int lenInfo  = currentFileInfo.TextEntrys[i + 1] / 2;

                byCnData[idx * 4]     = (byte)((startPos >> 8) & 0xFF);
                byCnData[idx * 4 + 1] = (byte)(startPos & 0xFF);

                byCnData[idx * 4 + 2] = (byte)((lenInfo >> 8) & 0xFF);
                byCnData[idx * 4 + 3] = (byte)(lenInfo & 0xFF);

                idx++;
            }

            // 再保存文本数据
            byCnData[entryLen]     = 0x80;
            byCnData[entryLen + 1] = 0;
            Array.Copy(cnBytes.ToArray(), 0, byCnData, entryLen + 2, cnBytes.Count);

            return(byCnData);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 重新设置Entry位置信息
        /// </summary>
        /// <param name="currentFileInfo">当前选择的文件</param>
        /// <param name="cnTxtLen">当前行中文文本字节长度</param>
        /// <param name="prevEntryPos">前一个Entry位置信息</param>
        /// <returns>当前Entry位置信息</returns>
        protected override int ResetLastEntryPosInfo(FilePosInfo currentFileInfo, int cnTxtLen, int prevEntryPos)
        {
            // 保存文本的长度
            currentFileInfo.TextEntrys.Add(cnTxtLen);

            return(prevEntryPos + cnTxtLen);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 初始化文本开始位置
        /// </summary>
        private void InitStartPos(string folder)
        {
            this.fileList.Items.Clear();
            this.textFiles.Clear();

            // 添加sysmes.ald文本
            FilePosInfo posInfo = new FilePosInfo(folder + @"\sysmes.ald");

            posInfo.TextStart = 0;
            posInfo.TextEnd   = 0xdc4;

            this.textFiles.Add(posInfo);
            this.fileList.Items.Add("sysmes.ald" + " 0x0--0xdc4");

            posInfo           = new FilePosInfo(folder + @"\sysmes.ald");
            posInfo.TextStart = 0xdc4;
            posInfo.SubIndex  = "_1";
            if (this.isNgc)
            {
                posInfo.TextEnd = 0x52f0;
            }
            else
            {
                posInfo.TextEnd = 0x4ab8;
            }

            this.textFiles.Add(posInfo);
            this.fileList.Items.Add("sysmes.ald" + " 0xdc4--0x" + posInfo.TextEnd.ToString("x"));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 根据配置文件,取得所有需要Copy的文件
        /// </summary>
        /// <param name="ngcFolder"></param>
        /// <returns></returns>
        private List <FilePosInfo> GetNeedCopyFiles(string ngcFolder, bool isComBinFile)
        {
            List <FilePosInfo> needCopyFiles = new List <FilePosInfo>();
            string             configFile;

            if (isComBinFile)
            {
                configFile = ngcFolder + @"\BinAddr.txt";
            }
            else
            {
                configFile = ngcFolder + @"\TextAddr.txt";
            }

            if (File.Exists(configFile))
            {
                string[] files = File.ReadAllLines(configFile);
                for (int i = 0; i < files.Length; i += 2)
                {
                    FilePosInfo fileInfo = new FilePosInfo(files[i], files[i + 1].Split(' '));
                    needCopyFiles.Add(fileInfo);
                }
            }

            return(needCopyFiles);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 文件变更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileList_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 设置文本
            FilePosInfo filePosInfo = this.textFiles[this.fileList.SelectedIndex];

            this.txtJp.Text = this.ChangeFile(filePosInfo.File, filePosInfo.TextStart, filePosInfo.TextEnd, this.jpFontCharPage);
            this.txtCn.Text = this.ChangeFile(filePosInfo.File + "_cn", filePosInfo.TextStart, filePosInfo.TextEnd, this.cnFontCharPage);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// 对象比较
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 private int PosInfoCompare(FilePosInfo a, FilePosInfo b)
 {
     if (a.IsFolder || b.IsFolder)
     {
         return(0);
     }
     else
     {
         return(a.FilePos - b.FilePos);
     }
 }
Ejemplo n.º 9
0
 /// <summary>
 /// 开始解码文本
 /// </summary>
 /// <param name="currentFileInfo">当前选择的文件</param>
 /// <param name="isCnTxt">是否是中文</param>
 /// <returns>解码的文本</returns>
 protected override string DecodeText(FilePosInfo currentFileInfo, bool isCnTxt)
 {
     if (isCnTxt)
     {
         return(this.DecodeText(File.ReadAllBytes(this.cnFile), currentFileInfo));
     }
     else
     {
         return(this.DecodeText(File.ReadAllBytes(currentFileInfo.File), currentFileInfo));
     }
 }
Ejemplo n.º 10
0
        /// <summary>
        /// 写入Ngc补丁(文件大小、格式可以不固定)
        /// </summary>
        /// <param name="jpFiInfosForSort"></param>
        /// <param name="jpFiInfos"></param>
        /// <param name="allCnFiles"></param>
        /// <param name="cnFs"></param>
        /// <param name="jpFs"></param>
        /// <returns></returns>
        private int WriteNgcTypeA(List <FilePosInfo> jpFiInfosForSort, List <FilePosInfo> jpFiInfos, List <FilePosInfo> allCnFiles,
                                  BufferedStream cnFs, BufferedStream jpFs)
        {
            int copyFile = 0;
            int copyLen  = 0;

            foreach (FilePosInfo jpFiInfo in jpFiInfosForSort)
            {
                // 更新进度条
                this.ProcessBarStep();

                // 如果是目录,不做任何处理
                if (jpFiInfo.IsFolder)
                {
                    continue;
                }

                // 查找原始文件对应的中文文件
                FilePosInfo cnFiInfo = allCnFiles.FirstOrDefault <FilePosInfo>(cnFile => cnFile.File.EndsWith(jpFiInfo.File, StringComparison.OrdinalIgnoreCase));
                if (cnFiInfo == null)
                {
                    // 如果没有找到中文文件,写入原始的文件
                    jpFs.Seek(jpFiInfo.FilePos, SeekOrigin.Begin);
                    cnFs.Seek(jpFiInfo.TextStart, SeekOrigin.Begin);
                    this.FileStreamCopy(cnFs, jpFs, jpFiInfo.FileSize);
                }
                else
                {
                    cnFs.Seek(jpFiInfo.TextStart, SeekOrigin.Begin);
                    copyLen = this.FileStreamCopy(cnFs, cnFiInfo.File);
                    copyFile++;

                    if (copyLen != jpFiInfo.FileSize)
                    {
                        jpFiInfo.TextEnd = copyLen;

                        if (cnFiInfo.File.ToLower().IndexOf("start.dol") >= 0)
                        {
                            throw new Exception("Start.dol是重要系统文件,大小不能变化!");
                        }

                        // 文件大小变化,改变这个文件以后的所有文件的位置信息
                        int diffSize = Util.ResetPos(copyLen - jpFiInfo.FileSize, RAW_SIZE);
                        this.ResetAllPos(jpFiInfos, jpFiInfo.FilePos, diffSize);
                    }
                }
            }

            return(copyFile);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 开始解码
        /// </summary>
        /// <param name="byData"></param>
        /// <param name="startPos"></param>
        private string DecodeText(byte[] byData, FilePosInfo filePosInfo, string[] fontChar)
        {
            StringBuilder sb       = new StringBuilder();
            int           txtStart = filePosInfo.TextStart + 2;

            for (int j = filePosInfo.EntryPos; j < filePosInfo.TextStart; j += 4)
            {
                int startPos = txtStart + Util.GetOffset(byData, j, j + 1) * 2;
                int endPos   = startPos + Util.GetOffset(byData, j + 2, j + 3) * 2;
                sb.Append(this.DecodeText(byData, fontChar, startPos, endPos));
            }

            return(sb.ToString());
        }
Ejemplo n.º 12
0
 /// <summary>
 /// 开始解码
 /// </summary>
 /// <param name="byData"></param>
 /// <param name="filePosInfo"></param>
 private string DecodeText(byte[] byData, FilePosInfo filePosInfo)
 {
     if (filePosInfo.File.EndsWith(".dol", StringComparison.OrdinalIgnoreCase))
     {
         Encoding encoding = Encoding.GetEncoding("Shift-jis");
         byte[]   byTemp   = new byte[filePosInfo.TextEnd - filePosInfo.TextStart];
         Array.Copy(byData, filePosInfo.TextStart, byTemp, 0, byTemp.Length);
         return(this.ResetText(Util.EncodeByteArray(byTemp, encoding))
                .Replace("^0^^0^^0^^0^", "^0 0 0 0^\n")
                .Replace("^0^^0^", "^0 0^\n"));
     }
     else
     {
         return(this.ResetText(this.DecodeSkpText(byData, filePosInfo)));
     }
 }
Ejemplo n.º 13
0
        /// <summary>
        /// 设置文本位置信息
        /// </summary>
        /// <param name="fiInfo"></param>
        private bool SetTextPosInfo(FilePosInfo fiInfo)
        {
            byte[] byData = File.ReadAllBytes(fiInfo.File);
            //fiInfo.TextEnd = Util.GetOffset(byData, 0x8, 0xB);

            //for (int i = 0x20; i < byData.Length; i += 2)
            //{
            //    //if (byData[i] == 0x20 && byData[i + 1] == 0xF1 && byData[i + 2] == 0x20 && byData[i + 3] == 0xFF)
            //    //{
            //    //    fiInfo.EntryPos = i + 4;
            //    //    fiInfo.TextStart = fiInfo.EntryPos + Util.GetOffset(byData, fiInfo.EntryPos, fiInfo.EntryPos + 3);
            //    //    return true;
            //    //}
            //    if (byData[i] == 0x20 && byData[i + 1] == 0xFF && byData[i + 2] == 0x0 && byData[i + 3] == 0x0
            //        && (byData[i + 4] != 0x0 || byData[i + 5] != 0x0))
            //    {
            //        fiInfo.EntryPos = i + 2;
            //        fiInfo.TextStart = fiInfo.EntryPos + Util.GetOffset(byData, fiInfo.EntryPos, fiInfo.EntryPos + 3);
            //        return true;
            //    }
            //}

            int txtStartPos = Util.GetOffset(byData, 0x1C, 0x1F);
            int txtEndPos   = Util.GetOffset(byData, 0x20, 0x23);

            if (txtStartPos == 0 || txtEndPos == 0 || txtStartPos >= txtEndPos)
            {
                return(false);
            }

            fiInfo.TextEnd = txtEndPos;
            for (int i = txtStartPos; i < txtEndPos; i++)
            {
                if (byData[i] == 0x20 && (byData[i + 1] == 0xFF || byData[i + 1] == 0x03) && byData[i + 2] == 0x0 && byData[i + 3] == 0x0 &&
                    (byData[i + 4] != 0x0 || byData[i + 5] != 0x0) && byData[i + 6] == 0x0 && byData[i + 7] == 0x0)
                {
                    fiInfo.EntryPos  = i + 2;
                    fiInfo.TextStart = fiInfo.EntryPos + Util.GetOffset(byData, fiInfo.EntryPos, fiInfo.EntryPos + 3);
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// 导入文件
        /// </summary>
        /// <param name="fileInfo"></param>
        private void ImportFile(FilePosInfo fileInfo)
        {
            FileStream fs = null;

            try
            {
                string impFile = this.baseFolder + @"\" + fileInfo.SubName;
                if (!File.Exists(impFile))
                {
                    throw new Exception("没有找到导入的文件!");
                }

                byte[] subFile = File.ReadAllBytes(impFile);
                if (subFile.Length > fileInfo.FileSize)
                {
                    throw new Exception("导入的文件容量大于原始文件!");
                }
                else if (impFile.ToLower().IndexOf(fileInfo.SubName.ToLower()) == -1)
                {
                    throw new Exception("导入的文件名和原始文件名不一致");
                }

                fs = File.Open(fileInfo.File, FileMode.Open);
                fs.Seek(fileInfo.FilePos, SeekOrigin.Begin);

                fs.Write(subFile, 0, subFile.Length);
                fs.Close();
                fs = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// 开始解码
        /// </summary>
        /// <param name="byData"></param>
        /// <param name="filePosInfo"></param>
        private string DecodeSkpText(byte[] byData, FilePosInfo filePosInfo)
        {
            StringBuilder sb       = new StringBuilder();
            int           txtStart = filePosInfo.TextStart;
            Encoding      encoding = Encoding.GetEncoding("Shift-jis");

            byte[] byTemp = null;

            try
            {
                for (int j = filePosInfo.EntryPos + 4; j < filePosInfo.TextStart; j += 4)
                {
                    int startPos = txtStart;
                    int endPos   = filePosInfo.EntryPos + Util.GetOffset(byData, j, j + 3);
                    txtStart = endPos;

                    byTemp = new byte[endPos - startPos];
                    Array.Copy(byData, startPos, byTemp, 0, byTemp.Length);
                    sb.Append(Util.EncodeByteArray(byTemp, encoding));

                    sb.Append("\n");
                }

                if (filePosInfo.TextEnd > txtStart)
                {
                    byTemp = new byte[filePosInfo.TextEnd - txtStart];
                    Array.Copy(byData, txtStart, byTemp, 0, byTemp.Length);
                    sb.Append(Util.EncodeByteArray(byTemp, encoding));
                }
            }
            catch
            {
                return("发生错误:\n" + filePosInfo.EntryPos.ToString("x") + " " + filePosInfo.TextStart.ToString("x"));
            }

            return(sb.ToString());
        }
Ejemplo n.º 16
0
        /// <summary>
        /// 导入所有的图片
        /// </summary>
        private void ImportAllImg(params object[] param)
        {
            List <FilePosInfo> fileNameInfo =
                Util.GetAllFiles(this.baseFolder).Where(p => !p.IsFolder &&
                                                        p.File.EndsWith(".png", StringComparison.OrdinalIgnoreCase)
                                                        ).ToList();

            if (fileNameInfo.Count == 0)
            {
                MessageBox.Show("没有发现能导入的文件,请重新检查选择的目录,或导入的文件是否是[fileName_XX.png]的格式");
                return;
            }

            this.currentImgEditor.rotateFlipType = (RotateFlipType)param[0];

            // 统计信息
            List <string> impFiles    = new List <string>();
            int           impImgCount = 0;

            // 显示进度条
            this.ResetProcessBar(fileNameInfo.Count);

            for (int i = 0; i < fileNameInfo.Count; i++)
            {
                FilePosInfo fileInfo = fileNameInfo[i];

                // 取得要导入的文件名
                string[] names        = Util.GetShortName(fileInfo.File).Replace(".png", string.Empty).Split('_');
                string   impShortName = names[0];
                int      impFileIndex = Convert.ToInt16(names[1]);

                // 查找导入文件的位置
                int    oldFileIndex    = -1;
                int    oldFileSubIndex = 0;
                string itemText        = string.Empty;
                this.Invoke((MethodInvoker) delegate()
                {
                    for (int j = 0; j < this.lstImg.Items.Count; j++)
                    {
                        itemText = this.lstImg.Items[j].ToString();
                        if (itemText.IndexOf(impShortName) >= 0)
                        {
                            if (oldFileSubIndex == impFileIndex)
                            {
                                oldFileIndex = j;
                                break;
                            }
                            else
                            {
                                oldFileSubIndex++;
                            }
                        }
                    }
                });


                if (oldFileIndex != -1)
                {
                    // 保存当前文件名
                    impImgCount++;
                    if (!impFiles.Contains(impShortName))
                    {
                        impFiles.Add(impShortName);
                    }

                    this.Invoke((MethodInvoker) delegate()
                    {
                        this.lstImg.SelectedIndex = oldFileIndex;
                    });

                    Image[] oldImg = this.currentImgEditor.ImageDecode(this.ImgFiles[oldFileIndex], itemText);
                    if (oldImg.Length == 1)
                    {
                        this.ImgFiles[oldFileIndex] =
                            this.currentImgEditor.ImportImg(fileInfo.File, oldImg[0], this.ImgFiles[oldFileIndex], itemText);
                    }
                    else
                    {
                        int gridImgIndex = Convert.ToInt16(names[2]);
                        this.currentImgEditor.imageIndex = gridImgIndex;
                        this.ImgFiles[oldFileIndex]      =
                            this.currentImgEditor.ImportImg(fileInfo.File, oldImg[gridImgIndex], this.ImgFiles[oldFileIndex], itemText);
                    }

                    this.ImgChangeInfo[oldFileIndex] = true;
                }

                // 更新进度条
                this.ProcessBarStep();
            }

            // 隐藏进度条
            this.CloseProcessBar();

            StringBuilder sb = new StringBuilder();

            sb.Append("所有图片导入完成!\n");
            sb.Append("总共:" + fileNameInfo.Count + " 张图片\n");
            sb.Append("其中:" + impImgCount + " 张图片,导入到了:" + impFiles.Count + " 个文件中\n");
            MessageBox.Show(sb.ToString());

            // 切换最新图片
            this.Invoke((MethodInvoker) delegate()
            {
                this.lstImg_SelectedIndexChanged(this.lstImg, new EventArgs());
            });
        }
Ejemplo n.º 17
0
        /// <summary>
        /// 写入Ngc补丁(文件大小、格式固定)
        /// </summary>
        /// <param name="jpFiInfosForSort"></param>
        /// <param name="jpFiInfos"></param>
        /// <param name="allCnFiles"></param>
        /// <param name="cnFs"></param>
        /// <param name="jpFs"></param>
        /// <returns></returns>
        private int WriteNgcTypeB(List <FilePosInfo> jpFiInfosForSort, List <FilePosInfo> jpFiInfos, List <FilePosInfo> allCnFiles,
                                  BufferedStream cnFs, BufferedStream jpFs)
        {
            int copyLen  = 0;
            int copyFile = 0;

            for (int i = 0; i < jpFiInfosForSort.Count; i++)
            {
                FilePosInfo jpFiInfo = jpFiInfosForSort[i];

                // 更新进度条
                this.ProcessBarStep();

                // 调整位置
                jpFs.Seek(jpFiInfo.FilePos, SeekOrigin.Begin);
                cnFs.Seek(jpFiInfo.TextStart, SeekOrigin.Begin);

                if (i < jpFiInfosForSort.Count - 1)
                {
                    copyLen = jpFiInfosForSort[i + 1].TextStart - jpFiInfo.TextStart;
                }
                else
                {
                    copyLen = NGC_ISO_LEN - jpFiInfo.TextStart;
                }

                // 写入原始的文件
                this.FileStreamCopy(cnFs, jpFs, copyLen);

                // 查找原始文件对应的中文文件
                FilePosInfo cnFiInfo = allCnFiles.FirstOrDefault <FilePosInfo>(cnFile => cnFile.File.EndsWith(jpFiInfo.File, StringComparison.OrdinalIgnoreCase));
                if (cnFiInfo != null)
                {
                    cnFs.Seek(jpFiInfo.TextStart, SeekOrigin.Begin);
                    copyLen = this.FileStreamCopy(cnFs, cnFiInfo.File);
                    copyFile++;

                    if (copyLen > jpFiInfo.FileSize)
                    {
                        string errInfo = cnFiInfo.File + "\r\n" + "补丁文件Size超过原来的文件,无法保持一致\r\n"
                                         + "请去掉【保持内部文件大小、位置一致】的选项";
                        throw new Exception(errInfo);
                    }
                    else if (copyLen < jpFiInfo.FileSize)
                    {
                        if (cnFiInfo.File.ToLower().IndexOf("start.dol") >= 0)
                        {
                            throw new Exception("Start.dol是重要系统文件,大小不能变化!");
                        }

                        // 补丁文件小于原文件,补0
                        int emptyLen = jpFiInfo.FileSize - copyLen;
                        while (emptyLen-- > 0)
                        {
                            cnFs.WriteByte(0);
                        }
                    }
                }
            }

            return(copyFile);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// 开始打包(重新组织每个文件大小,位置)
        /// </summary>
        private void PatchNgc(params object[] param)
        {
            string jpIsoFile     = (string)param[0];
            string cnPatchFolder = (string)param[1];
            bool   isReSize      = (bool)param[2];

            // 改变标题,按钮状态
            string oldTitle = this.Text;

            this.SetWinStatus(false, this.Text + " 打补丁中,请稍等......");

            // 开始打补丁
            List <FilePosInfo> jpFiInfos                  = new List <FilePosInfo>();
            List <FilePosInfo> jpFiInfosForSort           = new List <FilePosInfo>();
            List <KeyValuePair <string, int> > folderInfo = new List <KeyValuePair <string, int> >();
            BufferedStream jpFs      = null;
            BufferedStream cnFs      = null;
            FileStream     jpReader  = null;
            FileStream     cnWriter  = null;
            string         cnIsoFile = string.Empty;
            // 设置第一个文件开始位置(默认最大,挨个比较取最小的)
            int firstFilePos = NGC_ISO_LEN;
            // 当前目录
            string currentFolder = "root";

            try
            {
                // 将文件中的数据,读取到byData中
                jpReader = File.OpenRead(jpIsoFile);
                jpFs     = new BufferedStream(jpReader, COPY_BLOCK);

                // 读取Dol位置信息
                jpFs.Seek(0x420, SeekOrigin.Begin);
                byte[] byData = new byte[4];
                jpFs.Read(byData, 0, byData.Length);
                int dolOffset = Util.GetOffset(byData, 0, 3);

                // 读取FST位置信息
                jpFs.Seek(0x424, SeekOrigin.Begin);
                byData = new byte[4];
                jpFs.Read(byData, 0, byData.Length);
                int fstOffset = Util.GetOffset(byData, 0, 3);

                jpFs.Seek(0x4, SeekOrigin.Current);
                jpFs.Read(byData, 0, byData.Length);
                int fstSize = Util.GetOffset(byData, 0, 3);

                jpFs.Seek(0x4, SeekOrigin.Current);
                jpFs.Read(byData, 0, byData.Length);
                int maxFstSize = Util.GetOffset(byData, 0, 3);

                jpFs.Seek(0x4, SeekOrigin.Current);
                jpFs.Read(byData, 0, byData.Length);
                int userPos = Util.GetOffset(byData, 0, 3);

                jpFs.Seek(0x4, SeekOrigin.Current);
                jpFs.Read(byData, 0, byData.Length);
                int userLen = Util.GetOffset(byData, 0, 3);

                // 读取FST信息
                jpFs.Seek(fstOffset, SeekOrigin.Begin);
                byte[] fstData = new byte[fstSize];
                jpFs.Read(fstData, 0, fstData.Length);

                // 设置Dol信息
                FilePosInfo fileInfo = new FilePosInfo("Start.dol", false, fstOffset - dolOffset);
                fileInfo.FilePos   = dolOffset;
                fileInfo.FileSize  = fstOffset - dolOffset;
                fileInfo.TextStart = fileInfo.FilePos;
                fileInfo.TextEnd   = fileInfo.FileSize;
                jpFiInfos.Add(fileInfo);
                jpFiInfosForSort.Add(fileInfo);

                // 循环读取文件信息
                int    fstNum      = Util.GetOffset(fstData, 0x8, 0xB);
                byte[] fileNameTab = new byte[fstSize - fstNum * 0xc];
                Array.Copy(fstData, fstNum * 0xc, fileNameTab, 0, fileNameTab.Length);
                int fileNameOffset = Util.GetOffset(fstData, 0x1, 0x3);

                String      rootName = Util.GetFileNameFromStringTable(fileNameTab, fileNameOffset);
                FilePosInfo rootFile = new FilePosInfo("root", true, 0);
                rootFile.FileSize = fstNum;
                folderInfo.Add(new KeyValuePair <string, int>("root", fstNum));
                jpFiInfos.Add(rootFile);

                // 循环读取文件信息
                for (int i = 1; i < fstNum; i++)
                {
                    int fstTabOffset = i * 0xc;
                    fileNameOffset = Util.GetOffset(fstData, fstTabOffset + 0x1, fstTabOffset + 0x3);
                    String name     = Util.GetFileNameFromStringTable(fileNameTab, fileNameOffset);
                    bool   isFolder = fstData[fstTabOffset] == 1;
                    int    filePos  = Util.GetOffset(fstData, fstTabOffset + 0x4, fstTabOffset + 0x7);
                    int    fileSize = Util.GetOffset(fstData, fstTabOffset + 0x8, fstTabOffset + 0xB);
                    fileInfo           = new FilePosInfo(name, isFolder, fileSize);
                    fileInfo.FilePos   = filePos;
                    fileInfo.FileSize  = fileSize;
                    fileInfo.TextStart = filePos;
                    fileInfo.TextEnd   = fileSize;


                    // 重新设置当前的目录及文件名
                    if (isFolder)
                    {
                        currentFolder = jpFiInfos[filePos + 1].File + @"\" + name;
                        fileInfo.File = currentFolder;
                        folderInfo.Add(new KeyValuePair <string, int>(currentFolder, fileSize));
                    }
                    else
                    {
                        fileInfo.File = this.GetCurrentFolder(folderInfo, i) + fileInfo.File;

                        if (filePos < firstFilePos)
                        {
                            firstFilePos = filePos;
                        }
                        jpFiInfosForSort.Add(fileInfo);
                    }

                    jpFiInfos.Add(fileInfo);
                }

                // 将地址信息List重新排序
                jpFiInfosForSort.Sort(this.PosInfoCompare);

                // 为了防止文件过大,超过容量,尽量减少firstFilePos
                if (isReSize)
                {
                    int startFilePos = Util.ResetPos(userPos + userLen, RAW_SIZE);
                    if (startFilePos < firstFilePos)
                    {
                        int diffSize = Util.ResetPos(startFilePos - firstFilePos, RAW_SIZE);
                        this.ResetAllPos(jpFiInfos, firstFilePos, diffSize);

                        firstFilePos = startFilePos;
                    }
                }

                // 重新设置原始文件路径,去掉里面的[root],因为中文补丁文件中,可能没有这个路径
                jpFiInfosForSort.ForEach(p => p.File = p.File.Replace(@"root\", ""));

                // 读取所有补丁文件信息
                Util.IsGetAllFile = true;
                List <FilePosInfo> allCnFiles = Util.GetAllFiles(cnPatchFolder).Where(p => !p.IsFolder).ToList();
                Util.IsGetAllFile = false;

                // 重新生成中文Iso文件
                string isoShortName = Util.GetShortNameWithoutType(jpIsoFile);
                cnIsoFile = jpIsoFile.Replace(isoShortName + ".", isoShortName + "_CN.");

                if (File.Exists(cnIsoFile))
                {
                    File.Delete(cnIsoFile);
                }

                cnWriter = File.Open(cnIsoFile, FileMode.CreateNew);
                cnFs     = new BufferedStream(cnWriter, COPY_BLOCK);
                cnFs.SetLength(NGC_ISO_LEN);

                // Copy第一个文件之前的数据信息
                jpFs.Seek(0, SeekOrigin.Begin);
                cnFs.Seek(0, SeekOrigin.Begin);
                this.FileStreamCopy(cnFs, jpFs, firstFilePos);

                // 显示进度条
                this.ResetProcessBar(jpFiInfos.Count);

                // 循环所有的原始文件,替换成相应中文文件,写入中文Iso
                int copyFile = 0;
                if (isReSize)
                {
                    copyFile = WriteNgcTypeA(jpFiInfosForSort, jpFiInfos, allCnFiles, cnFs, jpFs);
                }
                else
                {
                    copyFile = WriteNgcTypeB(jpFiInfosForSort, jpFiInfos, allCnFiles, cnFs, jpFs);
                }

                // 写入文件的位置信息
                // 只有在改变了单个文件大小,位置的情况下才写入
                if (isReSize)
                {
                    for (int i = 1; i < fstNum; i++)
                    {
                        int         fstTabOffset = i * 0xc;
                        FilePosInfo filePosInfo  = jpFiInfos[i + 1];

                        fstData[fstTabOffset + 0x4] = (byte)((filePosInfo.TextStart >> 24) & 0xFF);
                        fstData[fstTabOffset + 0x5] = (byte)((filePosInfo.TextStart >> 16) & 0xFF);
                        fstData[fstTabOffset + 0x6] = (byte)((filePosInfo.TextStart >> 8) & 0xFF);
                        fstData[fstTabOffset + 0x7] = (byte)(filePosInfo.TextStart & 0xFF);

                        fstData[fstTabOffset + 0x8] = (byte)((filePosInfo.TextEnd >> 24) & 0xFF);
                        fstData[fstTabOffset + 0x9] = (byte)((filePosInfo.TextEnd >> 16) & 0xFF);
                        fstData[fstTabOffset + 0xA] = (byte)((filePosInfo.TextEnd >> 8) & 0xFF);
                        fstData[fstTabOffset + 0xB] = (byte)(filePosInfo.TextEnd & 0xFF);
                    }
                    cnFs.Seek(fstOffset, SeekOrigin.Begin);
                    cnFs.Write(fstData, 0, fstData.Length);
                }

                // 隐藏进度条
                this.CloseProcessBar();

                MessageBox.Show("打汉化补丁完成!\n一共成功导入了:" + copyFile + " 个文件");
            }
            finally
            {
                if (jpFs != null)
                {
                    jpFs.Close();
                }

                if (cnFs != null)
                {
                    cnFs.Close();
                }

                if (jpReader != null)
                {
                    jpReader.Close();
                }

                if (cnWriter != null)
                {
                    cnWriter.Close();
                }

                // 恢复按钮状态
                this.SetWinStatus(true, oldTitle);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// 生成新的Afs文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreateAfs_Click(object sender, EventArgs e)
        {
            string             afsFiles  = @"E:\游戏汉化\NgcBioCv\BioCvNgcCn\A\root\rdx_lnkA";
            List <FilePosInfo> fileInfos = Util.GetAllFiles(afsFiles).Where(p => !p.IsFolder && p.File.EndsWith(".rdx@", StringComparison.OrdinalIgnoreCase)).ToList();

            string oldAfsFile = @"E:\游戏汉化\NgcBioCv\BioCvNgcJp\A\root\rdx_lnk1.afs";

            byte[] byOldAfs     = File.ReadAllBytes(oldAfsFile);
            int    subFileCount = (byOldAfs[7] << 24) | (byOldAfs[6] << 16) | (byOldAfs[5] << 8) | byOldAfs[4];
            int    entryPos     = 8;
            int    nameEntryPos = entryPos + subFileCount * 8;

            nameEntryPos = (byOldAfs[nameEntryPos + 3] << 24) | (byOldAfs[nameEntryPos + 2] << 16) | (byOldAfs[nameEntryPos + 1] << 8) | byOldAfs[nameEntryPos];

            List <FilePosInfo> oldFiles = new List <FilePosInfo>();
            int firstPos = 0;

            for (int i = 0; i < subFileCount + 1; i++)
            {
                FilePosInfo fileInfo = new FilePosInfo(oldAfsFile);
                fileInfo.FilePos  = (byOldAfs[entryPos + i * 8 + 3] << 24) | (byOldAfs[entryPos + i * 8 + 2] << 16) | (byOldAfs[entryPos + i * 8 + 1] << 8) | byOldAfs[entryPos + i * 8];
                fileInfo.FileSize = (byOldAfs[entryPos + i * 8 + 7] << 24) | (byOldAfs[entryPos + i * 8 + 6] << 16) | (byOldAfs[entryPos + i * 8 + 5] << 8) | byOldAfs[entryPos + i * 8 + 4];

                oldFiles.Add(fileInfo);

                if (i == 0)
                {
                    firstPos = fileInfo.FilePos;
                }
            }

            if ((oldFiles.Count - fileInfos.Count) != 1)
            {
                return;
            }

            List <byte[]> newFileBy = new List <byte[]>();

            for (int i = 0; i < oldFiles.Count - 1; i++)
            {
                FilePosInfo oldItem = oldFiles[i];
                FilePosInfo newItem = fileInfos[i];

                byte[] cnFile = File.ReadAllBytes(newItem.File);
                newFileBy.Add(cnFile);
                int newSize  = cnFile.Length;
                int sizeDiff = newSize - oldItem.FileSize;

                if (sizeDiff != 0)
                {
                    for (int j = i + 1; j < oldFiles.Count; j++)
                    {
                        FilePosInfo resetItem = oldFiles[j];
                        resetItem.FilePos += sizeDiff;

                        // 开始位置特殊处理,必须是2048的倍数
                        int chkDiffLen = resetItem.FilePos % 2048;
                        if (chkDiffLen > 0)
                        {
                            resetItem.FilePos += (2048 - chkDiffLen);
                        }
                    }
                }

                oldItem.FileSize = newSize;
            }

            FilePosInfo lastItem = oldFiles[oldFiles.Count - 1];

            byte[] byNewAfs = new byte[lastItem.FilePos + lastItem.FileSize];
            Array.Copy(byOldAfs, 0, byNewAfs, 0, 8);

            for (int i = 0; i < oldFiles.Count; i++)
            {
                FilePosInfo oldItem = oldFiles[i];
                byNewAfs[entryPos + i * 8]     = (byte)(oldItem.FilePos & 0xFF);
                byNewAfs[entryPos + i * 8 + 1] = (byte)((oldItem.FilePos >> 8) & 0xFF);
                byNewAfs[entryPos + i * 8 + 2] = (byte)((oldItem.FilePos >> 16) & 0xFF);
                byNewAfs[entryPos + i * 8 + 3] = (byte)((oldItem.FilePos >> 24) & 0xFF);

                byNewAfs[entryPos + i * 8 + 4] = (byte)(oldItem.FileSize & 0xFF);
                byNewAfs[entryPos + i * 8 + 5] = (byte)((oldItem.FileSize >> 8) & 0xFF);
                byNewAfs[entryPos + i * 8 + 6] = (byte)((oldItem.FileSize >> 16) & 0xFF);
                byNewAfs[entryPos + i * 8 + 7] = (byte)((oldItem.FileSize >> 24) & 0xFF);

                if (i < oldFiles.Count - 1)
                {
                    FilePosInfo newItem = fileInfos[i];
                    Array.Copy(newFileBy[i], 0, byNewAfs, oldItem.FilePos, newFileBy[i].Length);
                }
                else
                {
                    Array.Copy(byOldAfs, nameEntryPos, byNewAfs, lastItem.FilePos, lastItem.FileSize);
                }
            }

            File.WriteAllBytes(oldAfsFile.Replace("BioCvNgcJp", "BioCvNgcCn"), byNewAfs);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// 导出文本
        /// </summary>
        private void ExoprtText()
        {
            Microsoft.Office.Interop.Excel.Application xApp   = null;
            Microsoft.Office.Interop.Excel.Workbook    xBook  = null;
            Microsoft.Office.Interop.Excel.Worksheet   xSheet = null;

            // 设定保存的文件名
            string fileName = @"E:\My\Hanhua\testFile\bioCv\BioCvTextNgc.xls";

            //string fileName = @"D:\game\iso\wii\生化危机维罗妮卡汉化\Bio0Text_" + this.exportName + ".xls";

            // 先删除原来的文件
            File.Delete(fileName);

            // 显示进度条
            this.ResetProcessBar(this.fileList.Items.Count);

            try
            {
                // 创建Application对象
                xApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
                //xApp.Visible = true;

                // 追加一个WorkBook
                xBook = xApp.Workbooks.Add(Missing.Value);

                for (int j = 0; j < this.fileList.Items.Count; j++)
                {
                    // 追加一个Sheet
                    FilePosInfo filePosInfo = this.textFiles[j];

                    // 更新当前文本
                    this.fileList.SelectedIndex = j;

                    // 取得日文、中文文本
                    string jpText = this.txtJp.Text;
                    string cnText = this.txtCn.Text;

                    string sheetName     = Util.GetShortFileName(filePosInfo.File);
                    int    sameNameCount = 0;
                    for (int i = 0; i < j; i++)
                    {
                        if (Util.GetShortFileName(this.textFiles[i].File).IndexOf(sheetName) >= 0)
                        {
                            sameNameCount++;
                        }
                    }

                    xSheet      = (Microsoft.Office.Interop.Excel.Worksheet)xBook.Sheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
                    xSheet.Name = sheetName + (sameNameCount > 0 ? "_" + sameNameCount.ToString().PadLeft(2, '0') : string.Empty);

                    // 将每行文本保存到Sheet中
                    string[] jpTexts = jpText.Split('\n');
                    string[] cnTexts = cnText.Split('\n');

                    for (int i = 0; i < jpTexts.Length; i++)
                    {
                        // 写入日文文本
                        Microsoft.Office.Interop.Excel.Range rngJp = xSheet.get_Range("A" + (i + 1), Missing.Value);
                        rngJp.Value2 = jpTexts[i];
                    }
                    for (int i = 0; i < cnTexts.Length; i++)
                    {
                        // 写入中文文本
                        Microsoft.Office.Interop.Excel.Range rngCn = xSheet.get_Range("G" + (i + 1), Missing.Value);
                        rngCn.Value2 = cnTexts[i];
                    }

                    // 更新进度条
                    this.ProcessBarStep();
                }

                // 保存
                xSheet.SaveAs(
                    fileName,
                    Missing.Value, Missing.Value, Missing.Value, Missing.Value,
                    Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

                // 隐藏进度条
                this.CloseProcessBar();

                // 显示保存完成信息
                MessageBox.Show("导出完成!");
            }
            catch (Exception me)
            {
                MessageBox.Show(this.baseFile + "\n" + me.Message);
            }
            finally
            {
                // 隐藏进度条
                this.CloseProcessBar();

                // 清空各种对象
                xSheet = null;
                xBook  = null;
                if (xApp != null)
                {
                    xApp.Quit();
                    xApp = null;
                }
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// 开始复制文本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCopy_Click(object sender, EventArgs e)
        {
            if (!this.CheckFath(this.txtJpFolder) ||
                !this.CheckFath(this.txtCnFolder) ||
                !this.CheckFath(this.txtNgcFolder))
            {
                return;
            }

            // 根据配置文件,取得所有需要Copy的文件
            List <FilePosInfo> needCopyFiles    = this.GetNeedCopyFiles(this.txtNgcFolder.Text, false);
            List <FilePosInfo> needCopyBinFiles = this.GetNeedCopyFiles(this.txtNgcFolder.Text, true);

            if (needCopyFiles.Count == 0 || needCopyBinFiles.Count == 0)
            {
                MessageBox.Show("路径错误,没有找到需要Copy的文件!");
                return;
            }

            StringBuilder notExistFiles  = new StringBuilder();
            StringBuilder saveFaileFiles = new StringBuilder();

            this.fileCheckInfo.Clear();

            // 显示进度条
            this.ResetProcessBar(needCopyFiles.Count + needCopyBinFiles.Count);

            try
            {
                // 开始循环所有的日文bin文件
                for (int i = 0; i < needCopyBinFiles.Count; i++)
                {
                    FilePosInfo fileInfo = needCopyBinFiles[i];

                    // 取得各个文件名
                    string fileName = @"\" + fileInfo.File.Replace("_1", string.Empty).Replace("_2", string.Empty).Replace("_3", string.Empty).Replace("_4", string.Empty).Replace("_5", string.Empty);
                    string jpFile   = this.txtJpFolder.Text + @"\BIN" + fileName + ".bin";
                    string cnFile   = this.txtCnFolder.Text + @"\BIN" + fileName + ".bin";
                    string ngcFile  = this.txtNgcFolder.Text + @"\root\&&systemdata\start_cn.dol";

                    if (File.Exists(jpFile) &&
                        File.Exists(cnFile))
                    {
                        // 取得文本数据
                        int    startPos = Convert.ToInt32(fileInfo.PosInfo[0], 16);
                        int    endPos   = Convert.ToInt32(fileInfo.PosInfo[1], 16);
                        byte[] byJpData = new byte[endPos - startPos];
                        byte[] byCnData = new byte[byJpData.Length];
                        this.GetTextData(jpFile, cnFile, fileInfo.PosInfo, byJpData, byCnData);

                        // 保存文本数据
                        this.SaveTextData(ngcFile, byJpData, byCnData, notExistFiles, saveFaileFiles, fileInfo.File);
                    }

                    // 更新进度条
                    this.ProcessBarStep();
                }

                // 开始循环所有的日文rdt文件
                //for (int i = 1; i <= 7; i++)
                //{
                //    List<FilePosInfo> copyFiles = needCopyFiles.Where(p => p.File.IndexOf("r" + i) != -1).ToList();
                //    foreach (FilePosInfo fileInfo in copyFiles)
                //    {
                //        // 取得各个文件名
                //        string fileName = @"\" + fileInfo.File.Replace("_1", string.Empty).Replace("_2", string.Empty);
                //        string jpFile = this.txtJpFolder.Text + @"\STAGE" + i + fileName + ".ard";
                //        string cnFile = this.txtCnFolder.Text + @"\STAGE" + i + fileName + ".ard";
                //        string ngcFile1 = this.txtNgcFolder.Text + @"\root\bio19\data_j\rdt" + fileName + ".rdt";
                //        string ngcFile2 = this.txtNgcFolder.Text + @"\root\bio19\data_aj\rdt" + fileName + ".rdt";

                //        if (File.Exists(jpFile)
                //            && File.Exists(cnFile))
                //        {
                //            // 取得文本数据
                //            int startPos = Convert.ToInt32(fileInfo.PosInfo[0], 16);
                //            int endPos = Convert.ToInt32(fileInfo.PosInfo[1], 16);
                //            byte[] byJpData = new byte[endPos - startPos];
                //            byte[] byCnData = new byte[byJpData.Length];
                //            this.GetTextData(jpFile, cnFile, fileInfo.PosInfo, byJpData, byCnData);

                //            // 保存文本数据
                //            this.SaveTextData(ngcFile1, byJpData, byCnData, notExistFiles, saveFaileFiles, fileInfo.File);
                //            this.SaveTextData(ngcFile2, byJpData, byCnData, notExistFiles, saveFaileFiles, fileInfo.File);
                //        }

                //        // 更新进度条
                //        this.ProcessBarStep();
                //    }
                //}

                // 隐藏进度条
                this.CloseProcessBar();
            }
            catch (Exception me)
            {
                MessageBox.Show(this.baseFile + "\n" + me.Message);
            }
            finally
            {
                // 隐藏进度条
                this.CloseProcessBar();
            }

            // 显示结果
            if (notExistFiles.Length == 0 && saveFaileFiles.Length == 0)
            {
                MessageBox.Show("完全Copy成功!");
            }
            else
            {
                MessageBox.Show("不存在的文件:\n" + notExistFiles.ToString() + "\n" + "错误的文件:\n" + saveFaileFiles.ToString());
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// 选择文件变更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lstAsfFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            FilePosInfo fileInfo = this.textFiles[this.lstAsfFiles.SelectedIndex];

            this.baseFile = fileInfo.File;
        }