using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Text; using Toolbox; using System.Windows.Forms; using Toolbox.Library; using Toolbox.Library.Forms; using Toolbox.Library.IO; using ByamlExt.Byaml; using ByamlExt; using SharpYaml.Serialization; using SharpYaml; using Syroot.BinaryData; using Toolbox.Library.Security.Cryptography; namespace FirstPlugin { public class BYAML : IEditor, IFileFormat, IConvertableTextFormat { public FileType FileType { get; set; } = FileType.Parameter; public bool CanSave { get; set; } public string[] Description { get; set; } = new string[] { "BYAML" }; public string[] Extension { get; set; } = new string[] { "*.byaml", "*.byml", "*.bprm", "*.sbyml" }; public string FileName { get; set; } public string FilePath { get; set; } public IFileInfo IFileInfo { get; set; } public bool Identify(System.IO.Stream stream) { using (var reader = new Toolbox.Library.IO.FileReader(stream, true)) { //File too small to have any data if (stream.Length <= 8) return false; if (reader.CheckSignature(2, "BY") || reader.CheckSignature(2, "YB")) return true; else return false; } } public Type[] Types { get { List types = new List(); types.Add(typeof(MenuExt)); return types.ToArray(); } } private static new Dictionary hashes = new Dictionary(); public static Dictionary Hashes { get { if (hashes.Count == 0) CreateHashList(); return hashes; } } private static void CreateHashList() { string dir = Path.Combine(Runtime.ExecutableDir, "Hashes"); if (!Directory.Exists(dir)) return; foreach (var file in Directory.GetFiles(dir)) { if (Utils.GetExtension(file) != ".txt") continue; foreach (string hashStr in File.ReadAllLines(file)) { CheckHash(hashStr); } } } private static void CheckHash(string hashStr) { uint hash = Crc32.Compute(hashStr); if (!hashes.ContainsKey(hash)) hashes.Add(hash, hashStr); } #region Text Converter Interface public TextFileType TextFileType => TextFileType.Yaml; public bool CanConvertBack => true; public string ConvertToString() { if (TextFileType == TextFileType.Xml) return XmlByamlConverter.ToXML(BymlData); else return YamlByamlConverter.ToYaml(BymlData); } public void ConvertFromString(string text) { if (TextFileType == TextFileType.Xml) BymlData = XmlByamlConverter.FromXML(text); else BymlData = YamlByamlConverter.FromYaml(text); } #endregion class MenuExt : IFileMenuExtension { public STToolStripItem[] NewFileMenuExtensions => null; public STToolStripItem[] NewFromFileMenuExtensions => null; public STToolStripItem[] ToolsMenuExtensions => toolFileExt; public STToolStripItem[] TitleBarExtensions => null; public STToolStripItem[] CompressionMenuExtensions => null; public STToolStripItem[] ExperimentalMenuExtensions => null; public STToolStripItem[] EditMenuExtensions => null; public ToolStripButton[] IconButtonMenuExtensions => null; STToolStripItem[] toolFileExt = new STToolStripItem[1]; public MenuExt() { toolFileExt[0] = new STToolStripItem("BYAML"); toolFileExt[0].DropDownItems.Add(new STToolStripItem("Convert to Big Endian", ConvertLEtoBE)); toolFileExt[0].DropDownItems.Add(new STToolStripItem("Convert to Little Endian", ConvertBEtoLE)); } public void ConvertLEtoBE(object sender, EventArgs args) { var byamlF = new BYAML(); byamlF.IFileInfo = new IFileInfo(); OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = Utils.GetAllFilters(byamlF); if (ofd.ShowDialog() == DialogResult.OK) { byamlF.Load(new FileStream(ofd.FileName, FileMode.Open)); byamlF.BymlData.byteOrder = Syroot.BinaryData.ByteOrder.BigEndian; SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = Utils.GetAllFilters(byamlF); if (sfd.ShowDialog() == DialogResult.OK) { STFileSaver.SaveFileFormat(byamlF, sfd.FileName); } } } public void ConvertBEtoLE(object sender, EventArgs args) { var byamlF = new BYAML(); byamlF.IFileInfo = new IFileInfo(); OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = Utils.GetAllFilters(byamlF); if (ofd.ShowDialog() == DialogResult.OK) { byamlF.Load(new FileStream(ofd.FileName, FileMode.Open)); byamlF.BymlData.byteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = Utils.GetAllFilters(byamlF); if (sfd.ShowDialog() == DialogResult.OK) { STFileSaver.SaveFileFormat(byamlF, sfd.FileName); } } } } public static bool IsHash(string k) { if (k == null) return false; return IsHex(k.ToArray()); } private static bool IsHex(IEnumerable chars) { bool isHex; foreach (var c in chars) { isHex = ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); if (!isHex) return false; } return true; } bool IsDialog = false; public BymlFileData BymlData; public UserControl OpenForm() { ByamlEditor editor = new ByamlEditor(); editor.FileFormat = this; editor.Text = FileName; editor.Dock = DockStyle.Fill; /* if (FileName.Contains("_muunt")) { var muuntEditor = new Turbo.TurboMuuntEditor(); muuntEditor.LoadByaml(this, Path.GetDirectoryName(FilePath)); return muuntEditor; }*/ return editor; } public void FillEditor(UserControl control) { // if (control is Turbo.TurboMuuntEditor) // return; ((ByamlEditor)control).UpdateByaml( BymlData.RootNode, BymlData.SupportPaths, BymlData.Version, BymlData.byteOrder, IsDialog, this); } public void Load(Stream stream) { CanSave = true; //Keep the stream open. //This is for the file to optionally be reloaded for different encoding types IsDialog = IFileInfo != null && IFileInfo.InArchive; BymlData = ByamlFile.LoadN(stream); } public void ReloadEncoding(Encoding encoding) { BymlFileData.Encoding = encoding; //Reopen and reload the byml data if (IFileInfo.ArchiveParent != null) { foreach (var file in IFileInfo.ArchiveParent.Files) { var name = Path.GetFileName(file.FileName); if (name == FileName) BymlData = ByamlFile.LoadN(new MemoryStream(file.FileData)); } } else if (File.Exists(FilePath)) { var file = File.OpenRead(FilePath); BymlData = ByamlFile.LoadN(file); file.Close(); } } public void Unload() { } public void Save(System.IO.Stream stream) { ByamlFile.SaveN(stream, new BymlFileData { Version = BymlData.Version, byteOrder = BymlData.byteOrder, SupportPaths = BymlData.SupportPaths, RootNode = BymlData.RootNode }); } } }