MCI18n/MainWindowViewModel.cs

262 lines
12 KiB
C#
Raw Normal View History

2025-06-22 11:33:58 +08:00

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MCI18n.Models;
2025-06-22 11:33:58 +08:00
using MCI18n.Utilities;
using Microsoft.Win32;
using SharpNBT;
using SharpNBT.SNBT;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace MCI18n
{
public partial class MainWindowViewModel : ObservableObject
{
private List<CompoundTag> _oriQuestsData;
private List<string> _updatedChapters;
private List<QuestLangModel> _langs;
[ObservableProperty]
private ObservableCollection<ChapterModel> _chapters;
2025-06-22 11:33:58 +08:00
[ObservableProperty]
private ObservableCollection<QuestModel> _selectedQuests;
2025-06-22 11:33:58 +08:00
[ObservableProperty]
private bool _loading = false;
2025-06-22 11:33:58 +08:00
[RelayCommand]
private void LoadQuests()
{
var openFolderDialog = new OpenFolderDialog
{
Title = "选择ftbquests文件夹",
Multiselect = false
2025-06-22 11:33:58 +08:00
};
if (openFolderDialog.ShowDialog() == true)
2025-06-22 11:33:58 +08:00
{
try
{
var folderPath = openFolderDialog.FolderName;
GlobalContext.MultipleLangSupport = Path.Exists(Path.Combine(folderPath, "quests", "lang"));
if (GlobalContext.MultipleLangSupport)
{
var enLangFile = Path.Combine(folderPath, "quests", "lang", "en_us.snbt");
var langData = StringNbt.Parse(File.ReadAllText(enLangFile));
_langs = [];
foreach (var item in langData)
{
var langKeys = item.Name.Split('.');
var langItem = new QuestLangModel
{
Type = langKeys[0],
Id = langKeys[1],
DocType = langKeys[2],
};
if (item is StringTag langTag)
{
langItem.Value = langTag.Value;
}
else if(item is ListTag valueList)
{
var descList = new StringBuilder();
foreach (var value in valueList)
{
descList.AppendLine((value as StringTag).Value);
}
langItem.Value = descList.ToString();
}
_langs.Add(langItem);
}
}
if(_langs != null)
{
var windowTitle = "FTB Quests Editor - " + _langs.FirstOrDefault(it => it.Type == "file" && it.Id == "0000000000000001" && it.DocType == "title").Value;
Application.Current.MainWindow.Title = windowTitle;
}
if (Path.Exists(Path.Combine(folderPath, "quests", "chapters")))
{
var fullQuestsPath = Path.Combine(folderPath, "quests", "chapters");
var questFiles = Directory.GetFiles(fullQuestsPath, "*.snbt", SearchOption.AllDirectories);
_oriQuestsData = new List<CompoundTag>();
_updatedChapters = new List<string>();
Chapters = new ObservableCollection<ChapterModel>();
foreach (var file in questFiles)
{
var questData = StringNbt.Parse(File.ReadAllText(file));
_oriQuestsData.Add(questData);
var chapterId = (questData["id"] as StringTag)?.Value;
var chapterName = (questData["filename"] as StringTag)?.Value ;
var chapterTitle = questData.ContainsKey("title") ? (questData["title"] as StringTag)?.Value : "";
var chapter = new ChapterModel
{
Id = chapterId,
Name = chapterName,
Title = chapterTitle
};
if (GlobalContext.MultipleLangSupport)
{
chapter.Title = GetMutliLang("chapter",chapter.Id, "title");
}
Chapters.Add(chapter);
var quests = questData["quests"];
if(quests is ListTag questList)
{
foreach (var item in questList)
{
if (item is CompoundTag questTag)
{
var questId = (questTag["id"] as StringTag)?.Value;
var questTitle = "";
if (questTag.ContainsKey("title"))
{
questTitle = (questTag["title"] as StringTag)?.Value ?? "";
}
else if (GlobalContext.MultipleLangSupport)
{
questTitle = GetMutliLang("quest", questId, "title");
}
var questSubTitle = "";
if (questTag.ContainsKey("subtitle"))
{
questSubTitle = (questTag["subtitle"] as StringTag)?.Value ?? "";
}
else if (GlobalContext.MultipleLangSupport)
{
questSubTitle = GetMutliLang("quest", questId, "quest_subtitle");
}
var questDescriptions = new StringBuilder();
if (questTag.ContainsKey("description"))
{
if (questTag["description"] is ListTag descriptions)
{
foreach (var desc in descriptions)
{
questDescriptions.AppendLine((desc as StringTag)?.Value);
}
}
}
else if (GlobalContext.MultipleLangSupport)
{
var desc = GetMutliLang("quest", questId, "quest_desc");
questDescriptions.AppendLine(desc);
}
2025-06-22 11:33:58 +08:00
var questModel = new QuestModel
{
Id = questId,
Title = questTitle,
SubTitle = questSubTitle,
Description = questDescriptions.ToString()
};
chapter.Quests.Add(questModel);
}
}
}
}
SelectedQuests = Chapters.First()?.Quests ?? [];
}
else
{
MessageBox.Show("文件夹选择错误!");
}
//var questData = StringNbt.Parse(File.ReadAllText(CurrentFilePath));
//SnbtWriter.SaveToFile(questData, CurrentFilePath + ".r", prettyPrint: true);
2025-06-22 11:33:58 +08:00
}
catch (Exception ex)
{
MessageBox.Show($"加载文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
[RelayCommand]
private void SaveQuest()
{
}
[RelayCommand]
private void SaveQuestAs()
{
if (GlobalContext.MultipleLangSupport)
{
/// 另存为多语言文件
var saveFileDialog = new SaveFileDialog
{
Title = "保存多语言文件",
Filter = "SNBT 文件 (*.snbt)|*.snbt",
FileName = "zh_cn.snbt",
};
if (saveFileDialog.ShowDialog() == true)
{
try
{
var filePath = saveFileDialog.FileName;
var langData = new CompoundTag("");
foreach (var chapter in Chapters)
{
langData.Add(new StringTag($"chapter.{chapter.Id}.title", chapter.Title));
if (chapter.Quests != null)
{
foreach (var quest in chapter.Quests)
{
langData.Add(new StringTag($"quest.{quest.Id}.title", quest.Title));
langData.Add(new StringTag($"quest.{quest.Id}.quest_subtitle", quest.SubTitle));
var descLines = quest.Description.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
var descList = new ListTag($"quest.{quest.Id}.quest_desc",TagType.String);
foreach (var line in descLines)
{
descList.Add(new StringTag(null, line));
}
langData.Add(descList);
}
}
}
SnbtWriter.SaveToFile(langData, filePath, prettyPrint: true);
MessageBox.Show("多语言文件保存成功!", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show($"保存文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
2025-06-22 11:33:58 +08:00
}
[RelayCommand]
private void CreateNewQuest()
{
}
internal void ChapterSelectionChanged(ChapterModel selectedChapter)
{
if (selectedChapter != null && selectedChapter.Quests != null)
{
SelectedQuests = selectedChapter.Quests;
}
else
{
SelectedQuests = [];
}
}
private string GetMutliLang(string type,string id,string docType)
{
return _langs?.FirstOrDefault(it => it.Type == type && it.Id == id && it.DocType == docType)?.Value ?? "";
}
2025-06-22 11:33:58 +08:00
}
}