From c1b89a2b9ac247816d712332853f4d0b99706d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= Date: Fri, 9 Jun 2023 22:42:33 +0800 Subject: [PATCH] Update Tools page --- Source/GrasscutterTools/App.config | 3 + Source/GrasscutterTools/Forms/FormMain.cs | 9 ++- .../Game/CutScene/CutSceneItem.cs | 21 +++++- .../Game/Dungeon/DungeonItem.cs | 32 +++++++++ Source/GrasscutterTools/Game/TextMapData.cs | 11 +++ .../GrasscutterTools/GrasscutterTools.csproj | 1 + .../Pages/PageTools.Designer.cs | 62 +++++++++++++++- Source/GrasscutterTools/Pages/PageTools.cs | 70 +++++++++++++++++++ .../Properties/Settings.Designer.cs | 12 ++++ .../Properties/Settings.settings | 3 + 10 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 Source/GrasscutterTools/Game/Dungeon/DungeonItem.cs diff --git a/Source/GrasscutterTools/App.config b/Source/GrasscutterTools/App.config index 23becb7..dbf4562 100644 --- a/Source/GrasscutterTools/App.config +++ b/Source/GrasscutterTools/App.config @@ -70,6 +70,9 @@ + + + \ No newline at end of file diff --git a/Source/GrasscutterTools/Forms/FormMain.cs b/Source/GrasscutterTools/Forms/FormMain.cs index f451967..93c272a 100644 --- a/Source/GrasscutterTools/Forms/FormMain.cs +++ b/Source/GrasscutterTools/Forms/FormMain.cs @@ -108,7 +108,9 @@ namespace GrasscutterTools.Forms CreatePage(); CreatePage(); CreatePage(); - //AddPageToGui(CreatePage("Tools")); +#if DEBUG + CreatePage(); +#endif TCMain.ResumeLayout(); Logger.I(TAG, "InitPages completed"); } @@ -137,6 +139,9 @@ namespace GrasscutterTools.Forms Resources.PageAchievementTitle, Resources.PageSetPropTitle, Resources.PageAboutTitle, +#if DEBUG + "Tools", +#endif }); } @@ -186,7 +191,7 @@ namespace GrasscutterTools.Forms tp.Controls.Add(page); return page; } - + private void ListPages_SelectedIndexChanged(object sender, EventArgs e) { TCMain.SelectedIndex = ListPages.SelectedIndex; diff --git a/Source/GrasscutterTools/Game/CutScene/CutSceneItem.cs b/Source/GrasscutterTools/Game/CutScene/CutSceneItem.cs index 901ef74..28bba74 100644 --- a/Source/GrasscutterTools/Game/CutScene/CutSceneItem.cs +++ b/Source/GrasscutterTools/Game/CutScene/CutSceneItem.cs @@ -1,4 +1,23 @@ -using Newtonsoft.Json; +/** + * Grasscutter Tools + * Copyright (C) 2023 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + **/ + +using Newtonsoft.Json; namespace GrasscutterTools.Game.CutScene { diff --git a/Source/GrasscutterTools/Game/Dungeon/DungeonItem.cs b/Source/GrasscutterTools/Game/Dungeon/DungeonItem.cs new file mode 100644 index 0000000..b7a5fed --- /dev/null +++ b/Source/GrasscutterTools/Game/Dungeon/DungeonItem.cs @@ -0,0 +1,32 @@ +/** + * Grasscutter Tools + * Copyright (C) 2023 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + **/ + +using Newtonsoft.Json; + +namespace GrasscutterTools.Game.Dungeon +{ + internal class DungeonItem + { + [JsonProperty("id")] + public int Id { get; set; } + + [JsonProperty("nameTextMapHash")] + public string NameTextMapHash { get; set; } + } +} diff --git a/Source/GrasscutterTools/Game/TextMapData.cs b/Source/GrasscutterTools/Game/TextMapData.cs index 82ac5db..6314500 100644 --- a/Source/GrasscutterTools/Game/TextMapData.cs +++ b/Source/GrasscutterTools/Game/TextMapData.cs @@ -17,6 +17,7 @@ * **/ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -31,9 +32,12 @@ namespace GrasscutterTools.Game { LoadManualTextMap(Path.Combine(resourcesDirPath, "ExcelBinOutput", "ManualTextMapConfigData.json")); LoadTextMaps(Path.Combine(resourcesDirPath, "TextMap")); + LoadTextMap(TextMapFilePaths[Array.IndexOf(TextMapFiles, "TextMapCHS")]); + DefaultTextMap = TextMap; } public Dictionary ManualTextMap; + public Dictionary DefaultTextMap; public Dictionary TextMap; public string[] TextMapFilePaths; public string[] TextMapFiles; @@ -81,5 +85,12 @@ namespace GrasscutterTools.Game } } } + + public string GetText(string textMapHash) + { + return TextMap.TryGetValue(textMapHash, out var text) ? text + : DefaultTextMap.TryGetValue(textMapHash, out text) ? text + : "???"; + } } } \ No newline at end of file diff --git a/Source/GrasscutterTools/GrasscutterTools.csproj b/Source/GrasscutterTools/GrasscutterTools.csproj index d1bb75b..a2263c6 100644 --- a/Source/GrasscutterTools/GrasscutterTools.csproj +++ b/Source/GrasscutterTools/GrasscutterTools.csproj @@ -140,6 +140,7 @@ + diff --git a/Source/GrasscutterTools/Pages/PageTools.Designer.cs b/Source/GrasscutterTools/Pages/PageTools.Designer.cs index 5bc91be..6cadf85 100644 --- a/Source/GrasscutterTools/Pages/PageTools.Designer.cs +++ b/Source/GrasscutterTools/Pages/PageTools.Designer.cs @@ -30,11 +30,16 @@ { this.BtnUpdateResources = new System.Windows.Forms.Button(); this.BtnConvertCutScene = new System.Windows.Forms.Button(); + this.LblProjectResRoot = new System.Windows.Forms.Label(); + this.TxtProjectResRoot = new System.Windows.Forms.TextBox(); + this.LblGcResRoot = new System.Windows.Forms.Label(); + this.TxtGcResRoot = new System.Windows.Forms.TextBox(); + this.BtnUpdateDungeon = new System.Windows.Forms.Button(); this.SuspendLayout(); // // BtnUpdateResources // - this.BtnUpdateResources.Location = new System.Drawing.Point(3, 3); + this.BtnUpdateResources.Location = new System.Drawing.Point(41, 195); this.BtnUpdateResources.Name = "BtnUpdateResources"; this.BtnUpdateResources.Size = new System.Drawing.Size(100, 30); this.BtnUpdateResources.TabIndex = 0; @@ -44,7 +49,7 @@ // // BtnConvertCutScene // - this.BtnConvertCutScene.Location = new System.Drawing.Point(109, 3); + this.BtnConvertCutScene.Location = new System.Drawing.Point(147, 195); this.BtnConvertCutScene.Name = "BtnConvertCutScene"; this.BtnConvertCutScene.Size = new System.Drawing.Size(150, 30); this.BtnConvertCutScene.TabIndex = 0; @@ -52,14 +57,62 @@ this.BtnConvertCutScene.UseVisualStyleBackColor = true; this.BtnConvertCutScene.Click += new System.EventHandler(this.BtnConvertCutScene_Click); // + // LblProjectResRoot + // + this.LblProjectResRoot.AutoSize = true; + this.LblProjectResRoot.Location = new System.Drawing.Point(38, 34); + this.LblProjectResRoot.Name = "LblProjectResRoot"; + this.LblProjectResRoot.Size = new System.Drawing.Size(141, 17); + this.LblProjectResRoot.TabIndex = 1; + this.LblProjectResRoot.Text = "项目 Resources/ 路径:"; + // + // TxtProjectResRoot + // + this.TxtProjectResRoot.Location = new System.Drawing.Point(185, 31); + this.TxtProjectResRoot.Name = "TxtProjectResRoot"; + this.TxtProjectResRoot.Size = new System.Drawing.Size(413, 23); + this.TxtProjectResRoot.TabIndex = 2; + // + // LblGcResRoot + // + this.LblGcResRoot.AutoSize = true; + this.LblGcResRoot.Location = new System.Drawing.Point(44, 63); + this.LblGcResRoot.Name = "LblGcResRoot"; + this.LblGcResRoot.Size = new System.Drawing.Size(135, 17); + this.LblGcResRoot.TabIndex = 3; + this.LblGcResRoot.Text = "GC_Resources/ 路径:"; + // + // TxtGcResRoot + // + this.TxtGcResRoot.Location = new System.Drawing.Point(185, 60); + this.TxtGcResRoot.Name = "TxtGcResRoot"; + this.TxtGcResRoot.Size = new System.Drawing.Size(413, 23); + this.TxtGcResRoot.TabIndex = 4; + // + // BtnUpdateDungeon + // + this.BtnUpdateDungeon.Location = new System.Drawing.Point(41, 100); + this.BtnUpdateDungeon.Name = "BtnUpdateDungeon"; + this.BtnUpdateDungeon.Size = new System.Drawing.Size(150, 30); + this.BtnUpdateDungeon.TabIndex = 0; + this.BtnUpdateDungeon.Text = "Update Dungeon"; + this.BtnUpdateDungeon.UseVisualStyleBackColor = true; + this.BtnUpdateDungeon.Click += new System.EventHandler(this.BtnUpdateDungeon_Click); + // // PageTools // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.TxtGcResRoot); + this.Controls.Add(this.LblGcResRoot); + this.Controls.Add(this.TxtProjectResRoot); + this.Controls.Add(this.LblProjectResRoot); + this.Controls.Add(this.BtnUpdateDungeon); this.Controls.Add(this.BtnConvertCutScene); this.Controls.Add(this.BtnUpdateResources); this.Name = "PageTools"; this.ResumeLayout(false); + this.PerformLayout(); } @@ -67,5 +120,10 @@ private System.Windows.Forms.Button BtnUpdateResources; private System.Windows.Forms.Button BtnConvertCutScene; + private System.Windows.Forms.Label LblProjectResRoot; + private System.Windows.Forms.TextBox TxtProjectResRoot; + private System.Windows.Forms.Label LblGcResRoot; + private System.Windows.Forms.TextBox TxtGcResRoot; + private System.Windows.Forms.Button BtnUpdateDungeon; } } diff --git a/Source/GrasscutterTools/Pages/PageTools.cs b/Source/GrasscutterTools/Pages/PageTools.cs index 5d8c38e..8b363fb 100644 --- a/Source/GrasscutterTools/Pages/PageTools.cs +++ b/Source/GrasscutterTools/Pages/PageTools.cs @@ -2,8 +2,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Windows.Forms; +using GrasscutterTools.Game; using GrasscutterTools.Game.CutScene; +using GrasscutterTools.Game.Dungeon; using GrasscutterTools.Properties; using Newtonsoft.Json; @@ -16,6 +19,12 @@ namespace GrasscutterTools.Pages InitializeComponent(); } + public override void OnLoad() + { + TxtGcResRoot.Text = Settings.Default.ResourcesDirPath; + TxtProjectResRoot.Text = Settings.Default.ProjectResourcePath; + } + private void BtnUpdateResources_Click(object sender, EventArgs e) { var src = new OpenFileDialog @@ -89,5 +98,66 @@ namespace GrasscutterTools.Pages MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } } + + private bool CheckInputPaths() + { + if (string.IsNullOrEmpty(TxtProjectResRoot.Text) || string.IsNullOrEmpty(TxtGcResRoot.Text)) + { + MessageBox.Show("请先填写资源目录路径!", Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + if (Directory.Exists(TxtProjectResRoot.Text) && Directory.Exists(TxtGcResRoot.Text)) + { + Settings.Default.ResourcesDirPath = TxtGcResRoot.Text; + Settings.Default.ProjectResourcePath = TxtProjectResRoot.Text; + return true; + } + else + { + MessageBox.Show("请填写正确的Res路径!", Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + } + + private TextMapData TextMapData; + + private void BtnUpdateDungeon_Click(object sender, EventArgs e) + { + try + { + if (!CheckInputPaths()) return; + + var json = File.ReadAllText( + Path.Combine(TxtGcResRoot.Text, "ExcelBinOutput", "DungeonExcelConfigData.json"), + Encoding.UTF8); + var dungeons = JsonConvert.DeserializeObject>(json); + + if (TextMapData == null) + TextMapData = new TextMapData(TxtGcResRoot.Text); + + UpdateDungeonsForLanguage(dungeons, "TextMapCHS", "zh-cn"); + UpdateDungeonsForLanguage(dungeons, "TextMapCHT", "zh-tw"); + UpdateDungeonsForLanguage(dungeons, "TextMapEN", "en-us"); + UpdateDungeonsForLanguage(dungeons, "TextMapRU", "ru-ru"); + MessageBox.Show("OK", Resources.Tips, MessageBoxButtons.OK); + } + catch (Exception ex) + { + MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void UpdateDungeonsForLanguage(IEnumerable dungeons, string textMap, string language) + { + var i = Array.IndexOf(TextMapData.TextMapFiles, textMap); + TextMapData.LoadTextMap(TextMapData.TextMapFilePaths[i]); + + var dungeonFilePath = Path.Combine(TxtProjectResRoot.Text, language, "Dungeon.txt"); + File.WriteAllLines( + dungeonFilePath, + dungeons.Select(it => $"{it.Id}:{TextMapData.GetText(it.NameTextMapHash)}"), + Encoding.UTF8); + } } } diff --git a/Source/GrasscutterTools/Properties/Settings.Designer.cs b/Source/GrasscutterTools/Properties/Settings.Designer.cs index 427b523..62fef4d 100644 --- a/Source/GrasscutterTools/Properties/Settings.Designer.cs +++ b/Source/GrasscutterTools/Properties/Settings.Designer.cs @@ -262,5 +262,17 @@ namespace GrasscutterTools.Properties { this["ActivityConfigJsonPath"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProjectResourcePath { + get { + return ((string)(this["ProjectResourcePath"])); + } + set { + this["ProjectResourcePath"] = value; + } + } } } diff --git a/Source/GrasscutterTools/Properties/Settings.settings b/Source/GrasscutterTools/Properties/Settings.settings index 0d23e10..aa56be0 100644 --- a/Source/GrasscutterTools/Properties/Settings.settings +++ b/Source/GrasscutterTools/Properties/Settings.settings @@ -62,5 +62,8 @@ + + + \ No newline at end of file