Example #1
0
        private int GetChunkCount(string filename)
        {
            if (!File.Exists(filename))
            {
                throw new FileNotFoundException("指定されたmcaファイルが見つかりません。");
            }

            using (RegionFileAccess.RegionFile rf = new RegionFileAccess.RegionFile(filename))
            {
                rf.LoadFile();

                int chunkNum = 0;
                for (int i = 0; i < rf.ChunkData.Count; i++)
                {
                    // 未使用チャンクはnullになってる
                    if (null != rf.ChunkData[i])
                    {
                        chunkNum++;
                    }

                    if (i % 32 == 0)
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                }
                return(chunkNum);
            }
        }
Example #2
0
        private void chunkConvertWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // 出力先ディレクトリチェック
            if (Directory.Exists(outputPath.Text))
            {
                DialogResult result = MessageBox.Show("出力先ディレクトリを上書きします。", "確認", MessageBoxButtons.OKCancel);

                if (result != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
            }
            else
            {
                Directory.CreateDirectory(outputPath.Text);
            }

            // 総チャンク数をプログレスバーの最大値にセット
            if (chunkConvertProgressBar.InvokeRequired)
            {
                chunkConvertProgressBar.Invoke((Action)(() =>
                {
                    chunkConvertProgressBar.Maximum = int.Parse(chunkCount.Text);

                    inputPath.Enabled = false;
                    inputRef.Enabled = false;

                    outputPath.Enabled = false;
                    outputRef.Enabled = false;

                    startFix.Visible = false;
                    chunkConvertProgressBar.Visible = true;
                }));
            }

            // level.datのPlayerデータを書き換え
            FixPlayerSackData(inputPath.Text + "\\level.dat",
                              InputToOutputPath(inputPath.Text + "\\level.dat"),
                              "//Data/Player/Inventory");


            // Playerフォルダの個別データを書き換え
            Directory.CreateDirectory(outputPath.Text + "\\players");
            foreach (string playerFile in Directory.GetFiles(inputPath.Text + "\\players", "*.dat"))
            {
                FixPlayerSackData(playerFile,
                                  InputToOutputPath(playerFile),
                                  "//Inventory");
            }


            // 処理済みチャンク数
            int fixChunkNum = 0;

            // 袋のID
            int itemSackId = int.Parse(itemSackID.Text);

            foreach (string regionDir in Directory.GetDirectories(inputPath.Text, "region"))
            {
                // 出力先regionフォルダの作成
                Directory.CreateDirectory(InputToOutputPath(regionDir));

                foreach (string mcaFile in Directory.GetFiles(regionDir, "*.mca"))
                {
                    using (RegionFileAccess.RegionFile rf = new RegionFileAccess.RegionFile(mcaFile))
                    {
                        rf.LoadFile();

                        for (int i = 0; i < rf.ChunkData.Count; i++)
                        {
                            if (null != rf.ChunkData[i])
                            {
                                fNbt.NbtCompound nbtRoot = rf.ChunkData[i].GetRootNBT();

#if DEBUG
                                using (StreamWriter sw = new StreamWriter(InputToOutputPath(mcaFile) + "_nbt_" + i + ".txt", false, Encoding.UTF8)) {
                                    sw.Write(nbtRoot.ToString());
                                }
#endif

                                // TileEntities差し替え
                                fNbt.NbtList tileEntities = fNbt.NbtQuery.Get <fNbt.NbtList>(nbtRoot, "//Level/TileEntities");
                                foreach (fNbt.NbtCompound tileEntity in tileEntities)
                                {
                                    fNbt.NbtList items;
                                    if (tileEntity.TryGet <fNbt.NbtList>("Items", out items))
                                    {
                                        foreach (fNbt.NbtCompound item in items)
                                        {
                                            FixItemSackData(item, itemSackId);
                                        }
                                    }
                                }

                                // Entities差し替え
                                fNbt.NbtList entities = fNbt.NbtQuery.Get <fNbt.NbtList>(nbtRoot, "//Level/Entities");
                                foreach (fNbt.NbtCompound entity in entities)
                                {
                                    fNbt.NbtList items;
                                    // チェストトロッコ等のインベントリ
                                    if (entity.TryGet <fNbt.NbtList>("Items", out items))
                                    {
                                        foreach (fNbt.NbtCompound item in items)
                                        {
                                            FixItemSackData(item, itemSackId);
                                        }
                                    }

                                    fNbt.NbtCompound tag;
                                    // ドロップアイテム
                                    if (entity.TryGet <fNbt.NbtCompound>("Item", out tag))
                                    {
                                        FixItemSackData(tag, itemSackId);
                                    }
                                }

                                // チャンクデータ更新
                                rf.ChunkData[i].SetRootNbt(nbtRoot);

                                chunkConvertWorker.ReportProgress(++fixChunkNum);
                            }

                            if (i % 16 == 0)
                            {
                                System.Threading.Thread.Sleep(2);
                            }
                        }

                        rf.SaveFile(InputToOutputPath(mcaFile));
                    }
                }
            }
        }