private void setEgvCharsSlotColor() { Program.SlotTable<int> slotCount = new Program.SlotTable<int>(0); for (int i = 0; i < dgvChars.Rows.Count; i++) { slotCount[dlcData.Chars[i]]++; } //Program.SlotTable<bool> NotComIniSlotTable = GetNotComIniSlotTable(); Program.SlotTable<bool> UsableSlotTable = GetUsableSlotTable(); Program.SlotTable<string> ComIniSlotCommentTable = GetComIniSlotCommentTable(); Program.SlotTable<bool> NotComIniSlotTable = new Program.SlotTable<bool>(true); for (int i = 0; i < ComIniSlotCommentTable.Count(); i++) { for (int j = 0; j < ComIniSlotCommentTable[i].Length; j++) { var ComIniSlotComment = ComIniSlotCommentTable[i, j]; NotComIniSlotTable[i, j] = (ComIniSlotCommentTable[i, j] == ""); } } for (int i = 0; i < dgvChars.Rows.Count; i++) { dgvChars.Rows[i].Cells[1].Style.BackColor = getSlotBackColor(slotCount, NotComIniSlotTable, UsableSlotTable, dlcData.Chars[i]); dgvChars.Rows[i].Cells[1].Style.SelectionBackColor = getSlotSelectionBackColor(slotCount, NotComIniSlotTable, UsableSlotTable, dlcData.Chars[i]); /* switch (slotCount[dlcData.Chars[i]]) { case default(int): // = 0 dgvChars.Rows[i].Cells[1].Style.BackColor = System.Drawing.Color.Red; dgvChars.Rows[i].Cells[1].Style.SelectionBackColor = System.Drawing.Color.Red; //dgvChars.Rows[i].Cells[1].Style.SelectionForeColor = System.Drawing.Color.Black; break; case 1: if (!NotComIniSlotTable[dlcData.Chars[i]]) { dgvChars[1, i].Style.BackColor = System.Drawing.Color.PaleTurquoise; dgvChars[1, i].Style.SelectionBackColor = System.Drawing.Color.DarkBlue; //dgvChars[1, i].Style.SelectionForeColor = System.Drawing.Color.Black; } else if(!UsableSlotTable[dlcData.Chars[i]]) { dgvChars[1, i].Style.BackColor = System.Drawing.Color.Orange; dgvChars[1, i].Style.SelectionBackColor = System.Drawing.Color.Chocolate; //dgvChars[1, i].Style.BackColor = System.Drawing.Color.Red; } else { dgvChars[1, i].Style.BackColor = System.Drawing.Color.Empty; dgvChars[1, i].Style.SelectionBackColor = System.Drawing.Color.Empty; //dgvChars[1, i].Style.SelectionForeColor = System.Drawing.Color.Empty; } break; default: dgvChars[1, i].Style.BackColor = System.Drawing.Color.LightGray; dgvChars[1, i].Style.SelectionBackColor = System.Drawing.Color.DimGray; //dgvChars[1, i].Style.SelectionForeColor = System.Drawing.Color.Empty; break; } */ } }
private void SaveDLC(bool Compression, bool Instant) { List<string[]> FassingFolderList = null; #if !DEBUG try #endif { if(Instant && GetGameShortcut() =="" && GetGameExe() == "") { var e = new FileNotFoundException(null, "game.exe"); MessageBox.Show(e.Message, Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error); tbSavePath_TextChanged(null, null);//念のため return; } Program.SlotTable<string> ComIniSlotCommentTable = GetComIniSlotCommentTable(); var NotthingComIni = true; for(var i = 0; i < dlcData.Chars.Count; i++) { if (ComIniSlotCommentTable[dlcData.Chars[i]] != "") { NotthingComIni = false; break; } } if(!NotthingComIni) { throw new Exception(Program.dicLanguage["CharaCommonKillInstant"]); } if (dgvChars.Rows.Count == 0) { throw new Exception(Program.dicLanguage["AddCharacter"]); } string dlcName = ""; if (newDlc) { bool direxists = false; try { if (tbSavePath.Text != string.Empty) { direxists = Directory.Exists(Path.GetDirectoryName(tbSavePath.Text)); } } catch { } if (!direxists) { var pt = LoadIniString("InitialDirectory", "BCM"); // ここも BMC で。 if (pt != "") saveFileDialog.InitialDirectory = GetOwnOFolderrExistingParent((Path.GetDirectoryName(pt))); // ただし親を見る。 saveFileDialog.FileName = Path.GetFileName(openFileDialog.FileName); if (saveFileDialog.ShowDialog() == DialogResult.OK) { System.Text.RegularExpressions.Regex regex_doa = new System.Text.RegularExpressions.Regex(@"^(.*\\([^\\]+))\\\2\.bcm$", System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (regex_doa.IsMatch(saveFileDialog.FileName)) { tbSavePath.Text = regex_doa.Replace(saveFileDialog.FileName, "$1"); SaveIniString("InitialDirectory", "BCM", Path.GetDirectoryName(saveFileDialog.FileName)); } else { tbSavePath.Text = saveFileDialog.FileName; SaveIniString("InitialDirectory", "BCM", saveFileDialog.FileName); } } else { throw new Exception(Program.dicLanguage["SetDestinationToSave"]); } } if (!DirectoryIsPureDLC(tbSavePath.Text)) { MessageBox.Show(Program.dicLanguage["NotPureDLCFolder"], Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error); tbSavePath_TextChanged(null, null);//念のため return; } dlcName = Path.GetFileNameWithoutExtension(tbSavePath.Text); // 保存用の dlcData 変数 DLCData dlcData4Save = new DLCData(); dlcData4Save.SavePath = dlcData.SavePath; dlcData4Save.BcmVer = dlcData.BcmVer; dlcData4Save.skipRead = dlcData.skipRead; // 問題のもの以外をコピー Program.SlotTable<int> slotCount = new Program.SlotTable<int>(0); for (int i = 0; i < dgvChars.Rows.Count; i++) { slotCount[dlcData.Chars[i]]++; } for (int i = 0; i < dlcData.Chars.Count; i++) { if (CheckCharFile(dlcData.Chars[i]) && slotCount[dlcData.Chars[i]] == 1 && dlcData.Chars[i].AddTexsCount <= getAvailableTextsCount(dlcData.Chars[i])) { dlcData4Save.Chars.Add(dlcData.Chars[i]); } } if (dlcData4Save.Chars.Count > 0) { bool comp = Compression;// cbComp.Checked; if (Instant) { FassingFolderList = new List<string[]>(); // 今から保存しようとしているフォルダが存在していれば if (Directory.Exists(tbSavePath.Text)) { var src = tbSavePath.Text; var back = GetBackupPath(src); Directory.Move(src, back); FassingFolderList.Add(new string[2] { src, back }); //BackupOriginal = true; } // 既存の DLC で邪魔になるものを排除 var sot = GetSlotOwnerPathAndDLCData(); var Path2DLC = new Dictionary<string, DLCData>(); for(var i = 0; i < dlcData.Chars.Count; i++) { var tpl = sot[dlcData.Chars[i]]; if (tpl != null) { var jamapath = tpl.Item1; var dlcd = tpl.Item2; var idx = tpl.Item3; dlcd.Chars.RemoveAt(idx); Path2DLC[jamapath] = dlcd; // 以前の DLCData が上書きされるように見えるが、DLCdata の参照は全て同じなので問題ない。 } } foreach(var jamapath in Path2DLC.Keys) { var src = Path.GetDirectoryName(jamapath); var back = GetBackupPath(src); FassingFolderList.Add(new string[2] { src, back }); Directory.Move(src, back); var KaridlcName = Path.GetFileNameWithoutExtension(src); } } // DLC Tool 1.1 より if (!Program.SaveDLC(dlcData4Save, tbSavePath.Text, dlcName, comp)) { tbSavePath_TextChanged(null, null);//念のため return; } string message; if (dlcData4Save.Chars.Count == dlcData.Chars.Count) { message = Program.dicLanguage["SavedDLC"]; } else { message = Program.dicLanguage["SavedPartialDLC"]; } string path = tbSavePath.Text + @"\" + Path.GetFileName(tbListPath.Text) + ".lst"; if (cbSaveListInDLC.Enabled && cbSaveListInDLC.Checked && !Instant) { string name; try { name = Path.GetFileName(tbListPath.Text); } catch { name = ""; } bool GoodName = (name != "" && name.IndexOfAny(Path.GetInvalidFileNameChars()) < 0); if (GoodName) { dlcData.SavePath = tbSavePath.Text; Program.SaveState(dlcData, path); //dlcData4Save とどっちか迷うところだけど、バックアップ機能を兼ねると思えばオリジナルのほうで良いのでは。 } } else if (cbSaveListInDLC.Enabled && !cbSaveListInDLC.Checked) { // ファイルが存在していてそれがユーザーが保存したもので無ければ消す try { if (path != tbListPath.Text + ".lst" && File.Exists(path)) { File.Delete(path); } } catch { } } // ショートカットを探す System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\\DLC\\\d+$"); string shortcut = GetGameShortcut(); // ゲームそのものを探す string DOA5EXE = ""; if (shortcut == "") { DOA5EXE = GetGameExe(); } if (shortcut == "" && DOA5EXE == "") { if (!Instant) { MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { throw new FileNotFoundException(null, "game.exe"); // ファイルの復元はエラー後に行われる } } else { if (!Instant) { if (MessageBox.Show(message + "\n\n" + Program.dicLanguage["DoYouStartDOA5"], "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { if (shortcut != "") { OpenWithShortcut(shortcut, "", false); } else { // 念のためカレントディレクトリを動かしておく string sCD = System.Environment.CurrentDirectory; System.Environment.CurrentDirectory = Path.GetDirectoryName(DOA5EXE); ;//System.IO.Path.GetDirectoryName(fileName); System.Diagnostics.Process.Start("\"" + DOA5EXE + "\""); System.Environment.CurrentDirectory = sCD; } } } else { System.Diagnostics.Process DOAProcess = null; Enabled = false; // ゲーム起動 DateTime startTime = DateTime.Now; if (shortcut != "") { OpenWithShortcut(shortcut, "", false); } else { // 念のためカレントディレクトリを動かしておく string sCD = Environment.CurrentDirectory; Environment.CurrentDirectory = Path.GetDirectoryName(DOA5EXE); ;//System.IO.Path.GetDirectoryName(fileName); System.Diagnostics.Process.Start("\"" + DOA5EXE + "\""); // コイツの戻り値は使えない模様(一度直ぐに閉じる) Environment.CurrentDirectory = sCD; } // スクリプト経由で起動する場合、ゲームの起動を動的に補足する var foundAtLeastOne = false; if (DOAProcess == null) { var step = 0.1; // 秒 var seekingTime = 10; // 秒 double tFromFirstFound = 0; for (double t = 0; t < seekingTime; t += step) { //ローカルコンピュータ上で実行されているすべてのプロセスを取得 System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses(); //配列から1つずつ取り出す foreach (System.Diagnostics.Process p in ps) { Application.DoEvents(); try { if (p.ProcessName == "game" && Path.GetFileName(p.MainModule.FileName) == "game.exe" /*&& p.StartTime >= startTime*/) { DOAProcess = p; } } catch { } if (DOAProcess != null) { foundAtLeastOne = true; break; } } if(foundAtLeastOne && DOAProcess == null) { tFromFirstFound = double.PositiveInfinity; } // 起動後一度すぐに閉じるので、 // 2秒ほどは待つ if (tFromFirstFound < 2) { DOAProcess = null; System.Threading.Thread.Sleep((int)(step * 1000 + 0.5)); if (foundAtLeastOne) tFromFirstFound += step; continue; } else if (DOAProcess != null) { break; } System.Threading.Thread.Sleep((int)(step * 1000 + 0.5)); if (foundAtLeastOne) tFromFirstFound += step; } } if (DOAProcess == null && !foundAtLeastOne) { Enabled = true; throw new Exception("Dead or alive process is not found."); } else if(DOAProcess != null) { // プロセスが終了するのを待つ while (!DOAProcess.WaitForExit((int)(10))) { Application.DoEvents(); } } var DLCDir = tbSavePath.Text; var DLCName = Path.GetFileName(DLCDir); File.Delete(DLCDir + @"\data\" + DLCName + ".bin"); File.Delete(DLCDir + @"\data\" + DLCName + ".blp"); File.Delete(DLCDir + @"\data\" + DLCName + ".lnk"); Directory.Delete(DLCDir + @"\data"); File.Delete(DLCDir + @"\" + DLCName + ".bcm"); Directory.Delete(DLCDir); for (var i = 0; i < FassingFolderList.Count; i++) { Directory.Move(FassingFolderList[i][1], FassingFolderList[i][0]); } Enabled = true; this.TopMost = true; Activate(); this.TopMost = false; } } } else { throw new Exception(Program.dicLanguage["NotSavedDLC"]); } } else { bool direxists = false; try { if (tbSavePath.Text != string.Empty) { direxists = Directory.Exists(tbSavePath.Text); } } catch { } if (!direxists || dlcData.skipRead > 0) { if (dlcData.skipRead > 0) { MessageBox.Show(Program.dicLanguage["OverwritingKillsSkipedItem"], Program.dicLanguage["Notice"], MessageBoxButtons.OK, MessageBoxIcon.Warning); } var pt = GetOwnOFolderrExistingParent(LoadIniString("InitialDirectory", "BCM")); if (pt != "") saveFileDialogBCM.InitialDirectory = pt; saveFileDialogBCM.FileName = Path.GetFileName(openFileDialogBCM.FileName); if (saveFileDialogBCM.ShowDialog() == DialogResult.OK) { SaveIniString("InitialDirectory", "BCM", Path.GetDirectoryName(saveFileDialogBCM.FileName)); tbSavePath.Text = saveFileDialogBCM.FileName; } else { throw new Exception(Program.dicLanguage["SetDestinationToSave"]); } } if (!DirectoryIsPureDLC(Path.GetDirectoryName(tbSavePath.Text))) { MessageBox.Show(Program.dicLanguage["NotPureDLCFolder"], Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error); tbSavePath_TextChanged(null, null);//念のため return; } dlcName = Path.GetFileNameWithoutExtension(tbSavePath.Text); Program.SaveBCM(dlcData, tbSavePath.Text, dlcName); MessageBox.Show(Program.dicLanguage["SavedBCM"], "Info", MessageBoxButtons.OK, MessageBoxIcon.Information); } } #if !DEBUG catch (Exception ex) { if (FassingFolderList != null) { for (var i = 0; i < FassingFolderList.Count; i++) { try { Directory.Move(FassingFolderList[i][1], FassingFolderList[i][0]); } catch { } } } Enabled = true; // 必須 if (ex is OverflowException) { MessageBox.Show(Program.dicLanguage["DecreaseDLCNum"], Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show(ex.Message, Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endif tbSavePath_TextChanged(null, null);//これは念のためじゃなくて必須 }
/* // common, initial 情報を完全にファイルで管理する更新にともなって使われなくなる。 private Program.SlotTable<bool> GetNotComIniSlotTable() // Dictionary とかを使ったほうがいいのだろうけどどうせここは計算時間の主要項じゃないし。 { Program.SlotTable<bool> NotComIniSlotTable = new Program.SlotTable<bool>(true); // chara_common, chara_initial は直に書く。その方が楽だしトラブルも減りそうだし何より高速になる。 NotComIniSlotTable[0, 0] = NotComIniSlotTable[0, 1] = NotComIniSlotTable[0, 2] = false; // ザック NotComIniSlotTable[1, 3] = NotComIniSlotTable[1, 5] = NotComIniSlotTable[1, 8] = false; // ティナ NotComIniSlotTable[2, 1] = NotComIniSlotTable[2, 2] = false; // ジャン・リー NotComIniSlotTable[3, 1] = NotComIniSlotTable[3, 2] = NotComIniSlotTable[3, 3] = false; // アイン NotComIniSlotTable[4, 1] = NotComIniSlotTable[4, 2] = NotComIniSlotTable[4, 3] = false; // リュウ・ハヤブサ NotComIniSlotTable[5, 3] = NotComIniSlotTable[5, 4] = NotComIniSlotTable[5, 5] = NotComIniSlotTable[5, 6] = false; // かすみ NotComIniSlotTable[6, 1] = NotComIniSlotTable[6, 2] = false; // ゲン・フー NotComIniSlotTable[7, 3] = NotComIniSlotTable[7, 5] = NotComIniSlotTable[7, 8] = false; // エレナ NotComIniSlotTable[8, 0] = NotComIniSlotTable[8, 1] = NotComIniSlotTable[8, 2] = NotComIniSlotTable[8, 3] = false; // レオン NotComIniSlotTable[9, 0] = NotComIniSlotTable[9, 1] = NotComIniSlotTable[9, 2] = false; // バース NotComIniSlotTable[10, 3] = NotComIniSlotTable[10, 5] = NotComIniSlotTable[10, 6] = false; // こころ NotComIniSlotTable[11, 1] = NotComIniSlotTable[11, 2] = false; // ハヤテ NotComIniSlotTable[12, 3] = NotComIniSlotTable[12, 5] = NotComIniSlotTable[12, 8] = false; // レイファン NotComIniSlotTable[13, 3] = NotComIniSlotTable[13, 4] = NotComIniSlotTable[13, 5] = NotComIniSlotTable[13, 6] = false; // あやね NotComIniSlotTable[14, 0] = NotComIniSlotTable[14, 1] = NotComIniSlotTable[14, 2] = false; // エリオット NotComIniSlotTable[15, 3] = NotComIniSlotTable[15, 5] = NotComIniSlotTable[15, 8] = false; // リサ // Alpha-152 NotComIniSlotTable[19, 1] = NotComIniSlotTable[19, 2] = false; // ブラッド・ウォン NotComIniSlotTable[20, 3] = NotComIniSlotTable[20, 5] = NotComIniSlotTable[20, 6] = false; // クリスティ NotComIniSlotTable[21, 3] = NotComIniSlotTable[21, 5] = NotComIniSlotTable[21, 6] = false; // ヒトミ NotComIniSlotTable[24, 0] = NotComIniSlotTable[24, 1] = NotComIniSlotTable[24, 2] = false; // バイマン NotComIniSlotTable[29, 0] = NotComIniSlotTable[29, 1] = NotComIniSlotTable[29, 2] = false; // リグ NotComIniSlotTable[30, 3] = NotComIniSlotTable[30, 5] = NotComIniSlotTable[30, 6] = false; // ミラ NotComIniSlotTable[31, 1] = NotComIniSlotTable[31, 2] = false; // アキラ NotComIniSlotTable[32, 1] = NotComIniSlotTable[32, 2] = false; // サラ NotComIniSlotTable[33, 1] = NotComIniSlotTable[33, 2] = false; // パイ・チェン NotComIniSlotTable[39, 3] = NotComIniSlotTable[39, 4] = NotComIniSlotTable[39, 5] = NotComIniSlotTable[39, 6] = NotComIniSlotTable[39, 7] = NotComIniSlotTable[39, 8] = NotComIniSlotTable[39, 10] = false; // 紅葉 NotComIniSlotTable[40, 3] = NotComIniSlotTable[40, 5] = NotComIniSlotTable[40, 6] = NotComIniSlotTable[40, 7] = false; // レイチェル NotComIniSlotTable[41, 1] = NotComIniSlotTable[41, 2] = NotComIniSlotTable[41, 3] = false; // ジャッキー // マリー・ローズ // PHASE-4 // 女天狗 // ほのか // 雷道 return NotComIniSlotTable; } */ private Program.SlotTable<bool> GetUsableSlotTable() { Program.SlotTable<bool> UsableSlotTable = new Program.SlotTable<bool>(true); // 想定される書式のパスが指定されているか string SavePath = tbSavePath.Text; string ParentPath; if (System.Text.RegularExpressions.Regex.IsMatch(SavePath, @"\\\d+$")) { ParentPath = Path.GetDirectoryName(SavePath); } else { return UsableSlotTable; } // 兄弟 DLC をすべて調べる //System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\\(\d+)([^\\]*)$"); // 1234 - DLC Name\1234.bcm を許す記述 System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\\(\d+)$"); // 1234 - DLC Name\1234.bcm を許さない記述 string[] brothers = Directory.GetDirectories(ParentPath); for (int i = 0; i < brothers.Length; i++) { if (brothers[i] != SavePath && regex.IsMatch(brothers[i])) { //string brotherBCM = regex.Replace(brothers[i], @"\$1$2\$1.bcm"); // 1234 - DLC Name\1234.bcm を許す記述 string brotherBCM = regex.Replace(brothers[i], @"\$1\$1.bcm"); // 1234 - DLC Name\1234.bcm を許さない記述 DLCData dlcData2; //MessageBox.Show(brotherBCM); try { dlcData2 = Program.OpenBCM_超原始的修正(brotherBCM); } catch { continue; } //MessageBox.Show(brothers[i] + "\n" + dlcData2.Chars.Count.ToString()); for (int j = 0; j < dlcData2.Chars.Count; j++) { UsableSlotTable[dlcData2.Chars[j]] = false; } } } return UsableSlotTable; }
//private Program.SlotTable<string> GetSlotOwnerTable(bool BCMPathMode) private object GetSlotOwnerInfo(int Mode) { object SlotOwnerInfo = null; switch (Mode) { case 0: //GetSlotOwnerTable SlotOwnerInfo = new Program.SlotTable<string>(""); break; case 1: //GetSlotOwnerPathAndDLCData SlotOwnerInfo = new Program.SlotTable<Tuple<string, DLCData,int>>(null/*new Tuple<string, DLCData,int>("", null,0)*/); break; } //Program.SlotTable<string> SlotOwnerTable = new Program.SlotTable<string>(""); // 想定される書式のパスが指定されているか string SavePath = tbSavePath.Text; string ParentPath; if (System.Text.RegularExpressions.Regex.IsMatch(SavePath, @"\\\d+$")) { ParentPath = Path.GetDirectoryName(SavePath); } else { return SlotOwnerInfo; } // 兄弟 DLC を取得 string[] brothers; try { brothers = Directory.GetDirectories(ParentPath); } catch { return SlotOwnerInfo; } // Lists フォルダを読んでおく string[] listpaths = null; try { listpaths = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), @"Lists")); } catch { } System.Collections.Generic.List<DLCData> LCands0 = null; System.Collections.Generic.List<string> LCandPaths0 = null; if (listpaths != null) { LCands0 = new System.Collections.Generic.List<DLCData>(); LCandPaths0 = new System.Collections.Generic.List<string>(); System.Text.RegularExpressions.Regex checkComIni = new System.Text.RegularExpressions.Regex(@"default(?:\.[^\\]*)?\.[lr]st$", System.Text.RegularExpressions.RegexOptions.IgnoreCase); for (int k = 0; k < listpaths.Length; k++) { if (!checkComIni.IsMatch(Path.GetFileName(listpaths[k]))) { try { // 順序を逆転させないこと! LCands0.Add(Program.OpenState(listpaths[k], false)); LCandPaths0.Add(listpaths[k]); } catch { } } } } // 兄弟 DLC をすべて調べる //System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\\(\d+)([^\\]*)$"); // 1234 - DLC Name\1234.bcm を許す記述 System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\\(\d+)$"); // 1234 - DLC Name\1234.bcm を許さない記述 for (int i = 0; i < brothers.Length; i++) { var LCands = new System.Collections.Generic.List<DLCData>(); System.Collections.Generic.List<string> LCandPaths = new System.Collections.Generic.List<string>(); if (LCands0 != null && LCandPaths0 != null) { LCands.AddRange(LCands0); LCandPaths.AddRange(LCandPaths0); } //MessageBox.Show(((brothers[i] != SavePath) + ", " + ( regex.IsMatch(brothers[i])))); if (brothers[i] != SavePath && regex.IsMatch(brothers[i])) { //string brotherBCM = regex.Replace(brothers[i], @"\$1$2\$1.bcm"); // 1234 - DLC Name\1234.bcm を許す記述 string brotherBCM = regex.Replace(brothers[i], @"\$1\$1.bcm"); // 1234 - DLC Name\1234.bcm を許さない記述 DLCData dlcData2; //MessageBox.Show(brotherBCM); try { dlcData2 = Program.OpenBCM_超原始的修正(brotherBCM); } catch { continue; } //MessageBox.Show(brothers[i] + "\n" + dlcData2.Chars.Count.ToString()); for (int j = 0; j < dlcData2.Chars.Count; j++) { string name; string listpath = ""; string[] lsts = Directory.GetFiles(brothers[i], "*.lst"); string[] rsts = Directory.GetFiles(brothers[i], "*.rst"); //新しい配列を作る string[] lists = new string[lsts.Length + rsts.Length]; //マージする配列のデータをコピーする Array.Copy(lsts, lists, lsts.Length); Array.Copy(rsts, 0, lists, lsts.Length, rsts.Length); //MessageBox.Show(lists.Length.ToString()); if (lists.Length <= 0) { name = Path.GetFileName(brothers[i]); } else { var last = File.GetLastWriteTime(lists[0]); name = Path.GetFileNameWithoutExtension(lists[0]); for (int k = 1; k < lists.Length; k++) { var last2 = File.GetLastWriteTime(lists[k]); if (last2 > last) { last = last2; listpath = lists[k]; name = Path.GetFileNameWithoutExtension(listpath); } } } // Lists フォルダから name と listpath を作る DLCData listdata = null; if (listpath == "" && listpaths != null) { // break のためだけの while 文 bool found; while (true) { // パスがドンピシャのものを探す found = false; for (int k = 0; k < LCands.Count; k++) { if (LCands[k].SavePath == brothers[i]) { found = true; break; } } if (found) { for (int k = 0; k < LCands.Count; k++) { if (LCands[k].SavePath != brothers[i]) { LCands.RemoveAt(k); LCandPaths.RemoveAt(k); k--; } } break; } // リストファイルの path のファイル名が brothers[i] のプレフィックスに一致するものを探す // 同時に最大一致文字数を取得 int maxlength = 0; found = false; for (int k = 0; k < LCands.Count; k++) { string listpathfilename = Path.GetFileName(LCands[k].SavePath); string br = Path.GetFileName(brothers[i]); //MessageBox.Show(brothers[i] + ", \n" + Path.GetFileName(LCands[k].SavePath) + "\n" + maxlength); if (listpathfilename.Length > maxlength && listpathfilename == br.Substring(0, Math.Min(listpathfilename.Length, br.Length))) { //MessageBox.Show(brothers[i] + ", \n" + Path.GetFileName(LCands[k].SavePath) + "\n" + k); found = true; maxlength = listpathfilename.Length; //break; } } if (found) { for (int k = 0; k < LCands.Count; k++) { string listpathfilename = Path.GetFileName(LCands[k].SavePath); string br = Path.GetFileName(brothers[i]); //MessageBox.Show(listpathfilename + "\n" + br + "\n" + k.ToString() + "\n" + LCandPaths[k]); if (!(listpathfilename.Length == maxlength && listpathfilename == br.Substring(0, Math.Min(listpathfilename.Length, br.Length)))) { LCands.RemoveAt(k); LCandPaths.RemoveAt(k); k--; } } break; } break; } // もし何かしら見つかっていたらその中で更新日時が最も新しい物を設定 if (found && LCands.Count > 0) { listpath = LCandPaths[0]; name = Path.GetFileNameWithoutExtension(listpath); listdata = LCands[0]; var last = File.GetLastWriteTime(listpath); for (int k = 1; k < LCands.Count; k++) { var last2 = File.GetLastWriteTime(LCandPaths[k]); if (last2 > last) { listpath = LCandPaths[k]; name = Path.GetFileNameWithoutExtension(listpath); listdata = LCands[k]; last = last2; } } } } // リストファイル内のコメントから設定する if (listpath != "") { if (listdata == null) { listdata = Program.OpenState(listpath, false); } for (int k = 0; k < listdata.Chars.Count; k++) { if (dlcData2.Chars[j].CostumeSlot == listdata.Chars[k].CostumeSlot && dlcData2.Chars[j].ID == listdata.Chars[k].ID && listdata.Chars[k].Comment != "") { name = listdata.Chars[k].Comment; while (name.Substring(name.Length - 1) == ",") { name = name.Substring(0, name.Length - 1); } break; } } } switch(Mode) { case 0: var SlotOwnerTable = ((Program.SlotTable<string>)SlotOwnerInfo); if (SlotOwnerTable[dlcData2.Chars[j]] == "") { SlotOwnerTable[dlcData2.Chars[j]] = name; } else { SlotOwnerTable[dlcData2.Chars[j]] += ", " + name; } break; case 1: var SlotOwnerPathAndDLCData= (Program.SlotTable<Tuple<string, DLCData,int>>)SlotOwnerInfo; SlotOwnerPathAndDLCData[dlcData2.Chars[j]] = new Tuple<string, DLCData,int>(brotherBCM,dlcData2,j); break; } /* if (BCMPathMode) { SlotOwnerTable[dlcData2.Chars[j]] = brotherBCM; } else { if (SlotOwnerTable[dlcData2.Chars[j]] == "") { SlotOwnerTable[dlcData2.Chars[j]] = name; } else { SlotOwnerTable[dlcData2.Chars[j]] += ", " + name; } } */ } } } return SlotOwnerInfo; }
// よく考えると全キャラ分取得するのは無駄な気もするが、 // ボトルネックはおそらくファイル読み込みであって、 // その部分はキャラを限定してもほとんど速くならないと思うから // このままでいいことにしよう。 private Program.SlotTable<string> GetComIniSlotCommentTable() { //Program.SlotTable<string> ComIniSlotCommentTable = new Program.SlotTable<string>("common,initial"); Program.SlotTable < string > ComIniSlotCommentTable = new Program.SlotTable<string>(""); // Lists フォルダを読んでおく(GetSlotOwnerTable のほぼコピー) string[] listpaths = null; try { listpaths = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), @"Lists")); } catch { return ComIniSlotCommentTable; // この関数ではリスト以外に情報源がない } System.Collections.Generic.List<DLCData> LCands = null; System.Collections.Generic.List<string> LCandPaths = null; if (listpaths != null) { LCands = new System.Collections.Generic.List<DLCData>(); LCandPaths = new System.Collections.Generic.List<string>(); //System.Text.RegularExpressions.Regex checkComIni = new System.Text.RegularExpressions.Regex(@"chara_common|chara_initial"); System.Text.RegularExpressions.Regex checkComIni = new System.Text.RegularExpressions.Regex(@"default(?:\.[^\\]*)?\.[lr]st$", System.Text.RegularExpressions.RegexOptions.IgnoreCase); for (int k = 0; k < listpaths.Length; k++) { //MessageBox.Show(Path.GetFileName(listpaths[k]) + ", " + checkComIni.IsMatch(Path.GetFileName(listpaths[k]))); if (checkComIni.IsMatch(Path.GetFileName(listpaths[k]))) // ここも違う { try { // 順序を逆転させないこと! LCands.Add(Program.OpenState(listpaths[k], false)); LCandPaths.Add(listpaths[k]); } catch { } } } } // リストが何もなかったら何も出来ない if (LCandPaths.Count == 0) { return ComIniSlotCommentTable; } // listpaths 更新日時降順にバブルソート for (int i = 0; i < LCandPaths.Count; i++) { for (int j = 1; j < LCands.Count - i; j++) { if (File.GetLastWriteTime(LCandPaths[j - 1]) < File.GetLastWriteTime(LCandPaths[j])) { var temp = LCandPaths[j]; LCandPaths[j] = LCandPaths[j - 1]; LCandPaths[j - 1] = temp; var temp2 = LCands[j]; LCands[j] = LCands[j - 1]; LCands[j - 1] = temp2; } } } // 先頭の listdata のみを用いる DLCData listdata = LCands[0]; string defaultTitle = Path.GetFileNameWithoutExtension(LCandPaths[0]); if (defaultTitle.Length >= "default.".Length) { defaultTitle = defaultTitle.Substring("default.".Length); } else { defaultTitle = "common,initial"; } //MessageBox.Show(defaultTitle); for (int i = 0; i < listdata.Chars.Count; i++) { if (ComIniSlotCommentTable[listdata.Chars[i]] == "common/initial" && listdata.Chars[i].Comment != "") { string name = listdata.Chars[i].Comment; while (name.Substring(name.Length - 1) == ",") { name = name.Substring(0, name.Length - 1); } ComIniSlotCommentTable[listdata.Chars[i]] = name; } else { ComIniSlotCommentTable[listdata.Chars[i]] = defaultTitle; } } return ComIniSlotCommentTable; }
private void dgvChars_MouseDown(object sender, MouseEventArgs e) { // マウスの左ボタンが押されている場合 var eb = e.Button; if (eb == MouseButtons.Left) { // MouseDownイベント発生時の (x,y)座標を取得 DataGridView.HitTestInfo hit = dgvChars.HitTest(e.X, e.Y); if (hit.RowIndex < 0) { // クリックした場所がコメントじゃないカラムヘッダだった場合、その列が移動できないようにする // マウス UP イベントで解除 if (hit.Type == DataGridViewHitTestType.ColumnHeader && hit.ColumnIndex < 3) { dgvChars.AllowUserToOrderColumns = false; return; } return; } // コントロールキーが押されていたらどこをクリックしたかによらずその行の選択をトグルする // シフトキーが押されていたらカレントからガバッと選択する if ((Control.ModifierKeys & Keys.Control) == Keys.Control /*|| (Control.ModifierKeys & Keys.Shift) == Keys.Shift*/) { //MessageBox.Show("a"); // しかしここで変更してもその後クリックが発生して意味がなくなるので // ここでは単にその後の動作のキャンセルにとどまる // ・・・そしてそうしたらそれだけで勝手にできるようになった。 dgvChars_MouseDown_dontSelectOne = true; return; //dgvChars.Rows[hit.RowIndex].Selected = true; //!dgvChars.Rows[hit.RowIndex].Selected; //MessageBox.Show("1"); } if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { //MessageBox.Show(dgvChars.CurrentCell.Value.ToString()); dgvChars_MouseDown_dontSelectOne = true; dgvChars_MouseDown_LeftShiftPreClickedIndex = dgvChars.CurrentCell.RowIndex; dragStartIndexes = GetSelectedCharsIndexesArray(); return; } // 該当行を選択状態にする←これをするとクリックイベントが起きなくなる? if (!dgvChars.Rows[hit.RowIndex].Selected) dgvChars.ClearSelection(); dgvChars.Rows[hit.RowIndex].Selected = true; // そうでなくて、更にそれがスロットのところで newDLC ならスロットメニューを表示 if (newDlc && hit.ColumnIndex == 1) { var r = dgvChars.GetCellDisplayRectangle(1, hit.RowIndex, false); cmsSlot.Items.Clear(); // 選択キャラ Character Char = dlcData.Chars[hit.RowIndex]; byte tempCostumeSlot = Char.CostumeSlot; byte bound = Program.NumOfSlots[Char.ID]; Program.SlotTable<int> slotCount = new Program.SlotTable<int>(0); for (int i = 0; i < dgvChars.Rows.Count; i++) { // 自分以外の情報は今は不要 if (dlcData.Chars[i].ID == Char.ID) { slotCount[dlcData.Chars[i]]++; } } // 自分自身は数えられているはずだという前提がここではほとんど成立しないので for (byte i = 0; i < Program.NumOfSlots[Char.ID]; i++) { if (i != tempCostumeSlot) { Char.CostumeSlot = i; slotCount[Char]++; } } // common, initial を exe に埋め込んでいたときの記述 /* Program.SlotTable<bool> NotComIniSlotTable = GetNotComIniSlotTable(); Program.SlotTable<string> ComIniSlotCommentTable = GetComIniSlotCommentTable(); Program.SlotTable<string> SlotOwnerTable = GetSlotOwnerTable(); Program.SlotTable<bool> UsableSlotTable = GetNotComIniSlotTable(); */ Program.SlotTable<string> ComIniSlotCommentTable = GetComIniSlotCommentTable(); Program.SlotTable<bool> NotComIniSlotTable = new Program.SlotTable<bool>(true); for (int i = 0; i < ComIniSlotCommentTable.Count(); i++) { for (int j = 0; j < ComIniSlotCommentTable[i].Length; j++) { var ComIniSlotComment = ComIniSlotCommentTable[i, j]; NotComIniSlotTable[i, j] = (ComIniSlotCommentTable[i, j] == ""); } } Program.SlotTable<string> SlotOwnerTable = GetSlotOwnerTable(); Program.SlotTable<bool> UsableSlotTable = new Program.SlotTable<bool>(true); for (int i = 0; i < UsableSlotTable.Count(); i++) { for (int j = 0; j < UsableSlotTable[i].Length; j++) { UsableSlotTable[i, j] = (SlotOwnerTable[i, j] == ""); } } for (byte i = 0; i < bound; i++) { Char.CostumeSlot = i; if (UsableSlotTable[Char] && NotComIniSlotTable[Char]) { cmsSlot.Items.Add(i.ToString()); } else if (NotComIniSlotTable[Char]) { cmsSlot.Items.Add(i.ToString() + " (" + SlotOwnerTable[Char] + ")"); } else if (UsableSlotTable[Char]) { cmsSlot.Items.Add(i.ToString() + " (" + ComIniSlotCommentTable[Char] + ")"); } else { cmsSlot.Items.Add(i.ToString() + " ((" + ComIniSlotCommentTable[Char] + ", " + SlotOwnerTable[Char] + ")"); } cmsSlot.Items[i].BackColor = getSlotBackColor(slotCount, NotComIniSlotTable, UsableSlotTable, Char); cmsSlot.Items[i].Click += ChangeSlot; } // 直ぐに元に戻す Char.CostumeSlot = tempCostumeSlot; // 矢印を頭につける //cmsSlot.Items[tempCostumeSlot].Text = "▶" + cmsSlot.Items[tempCostumeSlot].Text; // フォント変更(と言うか下線付加) if (tempCostumeSlot < cmsSlot.Items.Count) // 何らかの理由で現在のスロット番号が有効範囲の外にあると false { //現在のフォントを覚えておく var oldFont = cmsSlot.Items[tempCostumeSlot].Font; //現在のフォントにBoldを付加したフォントを作成する //なおBoldを取り消す場合は、「oldFont.Style & ~FontStyle.Bold」とする var newFont = new System.Drawing.Font(oldFont, oldFont.Style | System.Drawing.FontStyle.Underline | System.Drawing.FontStyle.Bold); //Boldを付加したフォントを設定する cmsSlot.Items[tempCostumeSlot].Font = newFont; //前のフォントを解放する oldFont.Dispose(); } System.Drawing.Point location = dgvChars.PointToScreen(r.Location); //MessageBox.Show("a"); cmsSlot.Show(location); //cmsSlot.Items.Clear(); } else // それも違ってたら手動ソート開始 { mouseDownPoint = new System.Drawing.Point(e.X, e.Y); dragStartIndexes = GetSelectedCharsIndexesArray(); dgvChars_MouseDown_SortDirectionList = new SortOrder[dgvChars.Columns.Count]; for (int i = 0; i < dgvChars.Columns.Count; i++) { dgvChars_MouseDown_SortDirectionList[i] = dgvChars.Columns[i].HeaderCell.SortGlyphDirection; } } } else { mouseDownPoint = System.Drawing.Point.Empty; // 右クリック if (eb == MouseButtons.Right && btnCharsAdd.Enabled) { if (dragPrevIndexes != null) { slideChar(dragPrevIndexes, dragStartIndexes); // 擬似選択状態を本当の選択状態にコピー for (int i = 0; i < dgvChars.Rows.Count; i++) { dgvChars.Rows[i].Selected = (Array.IndexOf(dragPrevIndexes, i) >= 0); } dragPrevIndexes = dragStartIndexes = null; dragHoldRelIndex = -1; this.Cursor = Cursors.Default; // 選択表示を普通の方法に戻す for (int i = 0; i < dgvChars.Rows.Count; i++) { var row = dgvChars.Rows[i]; for (int j = 0; j < row.Cells.Count; j++) { var stl = row.Cells[j].Style; stl.SelectionBackColor = System.Drawing.Color.Empty; stl.SelectionForeColor = System.Drawing.Color.Empty; stl.BackColor = System.Drawing.Color.Empty; stl.ForeColor = System.Drawing.Color.Empty; } } // キーの下をカレントに DataGridView.HitTestInfo hitc = dgvChars.HitTest(e.X, e.Y); if (hitc.Type == DataGridViewHitTestType.Cell) { dgvChars.CurrentCell = dgvChars.Rows[hitc.RowIndex].Cells[hitc.ColumnIndex]; } // コイツを復活させる。 dgvChars_SelectionChanged_RepairingSelection = false; // 色を再描画 setEgvCharsSlotColor(); //MessageBox.Show("2"); setEgvCharsNameColor(); setEgvCharsTextsColor(); //MessageBox.Show("1"); dgvChars.Focus(); dgvChars_MouseDown_dontSelectOne = true; if (dgvChars_MouseDown_SortDirectionList != null) { for (int i = 0; i < dgvChars.Columns.Count; i++) { dgvChars.Columns[i].HeaderCell.SortGlyphDirection = dgvChars_MouseDown_SortDirectionList[i]; } dgvChars_MouseDown_SortDirectionList = null; } return; } // MouseDownイベント発生時の (x,y)座標を取得 DataGridView.HitTestInfo hit = dgvChars.HitTest(e.X, e.Y); int index = hit.RowIndex; if (index < 0) { // カラムヘッダの右クリック時は何もしない if (hit.Type == DataGridViewHitTestType.ColumnHeader) { return; } index = dgvChars.Rows.Count - 1; } // 編集状態で、なおかつそこをクリックした場合は何もしない var cc = dgvChars.CurrentCell; if (dgvChars.IsCurrentCellInEditMode && hit.ColumnIndex == cc.ColumnIndex && hit.RowIndex == cc.RowIndex) { return; } // 間違っでもこれはやらないように //mouseDownPoint = new System.Drawing.Point(e.X, e.Y); ; // 該当行を選択状態にする if (index >= 0) { // 1.3.1 の修正において、ここで選択前のインデックスを忘れるとマズイことが分かったので覚えておく if (dgvChars.SelectedRows.Count == 1) { dgvChars_MouseDown_LastSelectedCharIndex = dgvChars.SelectedRows[0].Index; } else { dgvChars_MouseDown_LastSelectedCharIndex = -1; } dgvChars.ClearSelection(); dgvChars.Rows[index].Selected = true; } clikedForm = "dgvChars"; contextMenuStrip.Items.Add(Program.dicLanguage["DeleteD"]); contextMenuStrip.Items[contextMenuStrip.Items.Count - 1].Click += btnCharsDelete_Click; contextMenuStrip.Show(Cursor.Position.X, Cursor.Position.Y); contextMenuStrip.Closed += DeleteLastCMSItem; //cmsAddDeleteChars.Show(Cursor.Position.X, Cursor.Position.Y); } } }