From 96a649930865f0b7430c3994b4a7a11bee0e614b Mon Sep 17 00:00:00 2001 From: grzybeek Date: Fri, 2 Jul 2021 15:05:36 +0200 Subject: [PATCH] added update checker on launch fix metatool availComp fix ymt's that have more in components than defined in error pop-up on failed loading, it shouldn't close itself now --- YMTEditor/MainWindow.xaml.cs | 133 ++++++++++++++++++++------- YMTEditor/Properties/AssemblyInfo.cs | 8 +- YMTEditor/XMLHandler.cs | 81 +++++++++++++--- YMTEditor/YMTEditor.csproj | 4 +- 4 files changed, 178 insertions(+), 48 deletions(-) diff --git a/YMTEditor/MainWindow.xaml.cs b/YMTEditor/MainWindow.xaml.cs index 43956c8..00545dd 100644 --- a/YMTEditor/MainWindow.xaml.cs +++ b/YMTEditor/MainWindow.xaml.cs @@ -1,15 +1,14 @@ using CodeWalker.GameFiles; using Microsoft.Win32; using System; -using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Configuration; using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; +using System.Reflection; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; using System.Windows.Navigation; namespace YMTEditor @@ -30,6 +29,7 @@ public partial class MainWindow : Window public MainWindow() { + InitializeComponent(); _componentsMenu = (MenuItem)FindName("ComponentsMenu"); @@ -45,6 +45,8 @@ public MainWindow() Props = new ObservableCollection(); PropsItemsControl.ItemsSource = Props; + + CheckForUpdates(); } private void OpenNEW_Click(object sender, RoutedEventArgs e) @@ -82,16 +84,26 @@ private void OpenXML_Click(object sender, RoutedEventArgs e) ClearEverything(); //so if we import another file when something is imported it will clear string filename = xmlFile.FileName; - XMLHandler.LoadXML(filename); - _componentsMenu.IsEnabled = true; - _componentsMenu.ToolTip = "Check/Uncheck components"; - _propsMenu.IsEnabled = true; - _propsMenu.ToolTip = "Check/Uncheck props"; - SetLogMessage("Loaded XML from path: " + filename); + try + { + XMLHandler.LoadXML(filename); + _componentsMenu.IsEnabled = true; + _componentsMenu.ToolTip = "Check/Uncheck components"; + _propsMenu.IsEnabled = true; + _propsMenu.ToolTip = "Check/Uncheck props"; + SetLogMessage("Loaded XML from path: " + filename); - fullName = Path.GetFileNameWithoutExtension(filename); + fullName = Path.GetFileNameWithoutExtension(filename); //removes .xml + fullName = Path.GetFileNameWithoutExtension(fullName); //removes .ymt + + this.Title = "YMTEditor by grzybeek - editing " + fullName + ".ymt.xml"; + } + catch (Exception) + { + ClearEverything(); + MessageBox.Show("Failed to load XML YMT, please report it!\n\nReport it on github or discord: grzybeek#9100\nPlease include XML YMT you tried to load!", "Error!", MessageBoxButton.OK, MessageBoxImage.Error); + } - this.Title = "YMTEditor by grzybeek - editing " + fullName + ".ymt.xml"; } } @@ -106,9 +118,17 @@ private void SaveXML_Click(object sender, RoutedEventArgs e) bool? result = xmlFile.ShowDialog(); if (result == true) { - string filename = xmlFile.FileName; - XMLHandler.SaveXML(filename); - SetLogMessage("Saved XML to path: " + filename); + try + { + string filename = xmlFile.FileName; + XMLHandler.SaveXML(filename); + SetLogMessage("Saved XML to path: " + filename); + } + catch (Exception) + { + MessageBox.Show("Failed to save XML YMT, please report it!\n\nReport it on github or discord: grzybeek#9100\nPlease include XML YMT you tried to save!", "Error!", MessageBoxButton.OK, MessageBoxImage.Error); + } + } } @@ -131,16 +151,25 @@ private void OpenYMT_Click(object sender, RoutedEventArgs e) RpfFile.LoadResourceFile(ymt, ymtBytes, 2); string xml = MetaXml.GetXml(ymt.Meta); - XMLHandler.LoadXML(xml); - _componentsMenu.IsEnabled = true; - _componentsMenu.ToolTip = "Check/Uncheck components"; - _propsMenu.IsEnabled = true; - _propsMenu.ToolTip = "Check/Uncheck props"; - SetLogMessage("Loaded YMT from path: " + filename); + try + { + XMLHandler.LoadXML(xml); + _componentsMenu.IsEnabled = true; + _componentsMenu.ToolTip = "Check/Uncheck components"; + _propsMenu.IsEnabled = true; + _propsMenu.ToolTip = "Check/Uncheck props"; + SetLogMessage("Loaded YMT from path: " + filename); - fullName = Path.GetFileNameWithoutExtension(filename); + fullName = Path.GetFileNameWithoutExtension(filename); - this.Title = "YMTEditor by grzybeek - editing " + fullName + ".ymt"; + this.Title = "YMTEditor by grzybeek - editing " + fullName + ".ymt"; + } + catch (Exception) + { + ClearEverything(); + MessageBox.Show("Failed to load YMT, please report it!\n\nReport it on github or discord: grzybeek#9100\nPlease include YMT you tried to load!", "Error!", MessageBoxButton.OK, MessageBoxImage.Error); + } + } } @@ -155,16 +184,25 @@ private void SaveYMT_Click(object sender, RoutedEventArgs e) bool? result = xmlFile.ShowDialog(); if (result == true) { - string filename = xmlFile.FileName; - System.Xml.XmlDocument newXml = XMLHandler.SaveYMT(filename); - - PedFile ymt = new PedFile(); - Meta meta = XmlMeta.GetMeta(newXml); - byte[] newYmtBytes = ResourceBuilder.Build(meta, 2); + try + { + string filename = xmlFile.FileName; + System.Xml.XmlDocument newXml = XMLHandler.SaveYMT(filename); - File.WriteAllBytes(filename, newYmtBytes); - - SetLogMessage("Saved YMT to path: " + filename); + PedFile ymt = new PedFile(); + Meta meta = XmlMeta.GetMeta(newXml); + byte[] newYmtBytes = ResourceBuilder.Build(meta, 2); + + File.WriteAllBytes(filename, newYmtBytes); + + SetLogMessage("Saved YMT to path: " + filename); + + } + catch (Exception) + { + MessageBox.Show("Failed to save YMT, please report it!\n\nReport it on github or discord: grzybeek#9100\nPlease include YMT you tried to save!", "Error!", MessageBoxButton.OK, MessageBoxImage.Error); + } + } } @@ -639,5 +677,38 @@ private void ClearEverything() Props.Clear(); } + + //version compare taken and edited from https://github.com/smallo92/Ymap-YbnMover/blob/master/ymapmover/Startup.cs + private void CheckForUpdates() + { + Assembly assembly = Assembly.GetExecutingAssembly(); + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + string version = fvi.FileVersion.ToString(); + + WebClient webclient = new WebClient(); + Stream stream = webclient.OpenRead("https://raw.githubusercontent.com/grzybeek/YMTEditor/master/YMTEditor/version.txt"); + StreamReader reader = new StreamReader(stream); + + string githubVersion = reader.ReadToEnd().ToString(); + + if(version != githubVersion) + { + MessageBoxResult result = MessageBox.Show(this, "There is new version of YMTEditor available!\nYour version: " + version + "\nAvailable version: " + githubVersion + " \n\nDo you want to download it now?\n\nClick YES to open website and close editor\nClick NO to open editor", "New version available!", MessageBoxButton.YesNo, MessageBoxImage.Information); + if (result == MessageBoxResult.Yes) + { + //probably better would be auto-updater but idk how to do it yet + Process.Start("https://github.com/grzybeek/YMTEditor/releases"); + Environment.Exit(0); + } + else if (result == MessageBoxResult.No) + { + //open editor + } + } + else + { + //good version, open editor + } + } } } diff --git a/YMTEditor/Properties/AssemblyInfo.cs b/YMTEditor/Properties/AssemblyInfo.cs index 04824a5..156822e 100644 --- a/YMTEditor/Properties/AssemblyInfo.cs +++ b/YMTEditor/Properties/AssemblyInfo.cs @@ -10,9 +10,9 @@ [assembly: AssemblyTitle("YMTEditor")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyCompany("")] [assembly: AssemblyProduct("YMTEditor")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2021")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -51,5 +51,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.0")] +[assembly: AssemblyFileVersion("1.0")] diff --git a/YMTEditor/XMLHandler.cs b/YMTEditor/XMLHandler.cs index c0641ca..ec2db71 100644 --- a/YMTEditor/XMLHandler.cs +++ b/YMTEditor/XMLHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; @@ -29,7 +30,7 @@ public static void LoadXML(string filePath) //loading *.ymt xmlFile = XDocument.Parse(filePath); } - + string usedPath = filePath; CPedVariationInfo = xmlFile.Element("CPedVariationInfo").FirstAttribute != null ? xmlFile.Element("CPedVariationInfo").FirstAttribute.Value.ToString() @@ -44,15 +45,38 @@ public static void LoadXML(string filePath) //generate used components foreach (var node in xmlFile.Descendants("availComp")) { + var availComponents = node.Value.Split(' '); //split on space + + if(availComponents[0].Length > 3)// that means we have weird availComp from metatool, for example: "00010203FF04FF...." + { + string s = availComponents[0].ToString(); + List temp = new List(); + int availlength = availComponents[0].Length; + int skipEvery = 2; //we have to split every 2 characters + for (int i = 0; i < availlength; i += skipEvery) + { + string a = s.Substring(i, skipEvery).Substring(1); + + if(a == "F") + { + a = "255"; + } + + temp.Add(a); + } + + availComponents = temp.ToArray(); + + } int compId = 0; //components id's int compIndex = 0; //order of our components in ymt - foreach(var comp in availComponents) + foreach (var comp in availComponents) { - if(comp != "255") + if (comp != "255") { string _name = Enum.GetName(typeof(YMTTypes.ComponentNumbers), compId); - ComponentData componentName = new ComponentData(_name, compId, compIndex, new ObservableCollection()) { compHeader = _name.ToUpper()}; + ComponentData componentName = new ComponentData(_name, compId, compIndex, new ObservableCollection()) { compHeader = _name.ToUpper() }; MainWindow.Components.Add(componentName); MenuItem item = (MenuItem)MainWindow._componentsMenu.FindName(_name); @@ -70,7 +94,7 @@ public static void LoadXML(string filePath) foreach (var prop in xmlFile.Descendants("aPropMetaData").Elements("Item")) { int p_anchorId = Convert.ToInt32(prop.Element("anchorId").FirstAttribute.Value); - + if (oldId != p_anchorId) { string _name = Enum.GetName(typeof(YMTTypes.PropNumbers), p_anchorId); @@ -87,7 +111,13 @@ public static void LoadXML(string filePath) //read components int compItemIndex = 0; //order of our components in ymt foreach (var node in xmlFile.Descendants("aComponentData3").Elements("Item")) - { + { + if (compItemIndex >= MainWindow.Components.Count()) + { + //some ymt's have more 's in component section than defined in , for example freemode male_heist or bikerdlc + //so just skip more than in availComp + return; + } ComponentData _curComp = MainWindow.Components.ElementAt(compItemIndex); //current component (jbib/lowr/teef etc) int _curCompDrawablesCount = 0; //count how many component has variations (000, 001, 002, etc) int _curCompAvailTex = 0; // not used by game probably, total amount of textures component has (numAvailTex) @@ -126,7 +156,31 @@ public static void LoadXML(string filePath) { string comphash_2FD08CEF = compInfo_node.Element("hash_2FD08CEF").Value.ToString(); //unknown usage string comphash_FC507D28 = compInfo_node.Element("hash_FC507D28").Value.ToString(); //unknown usage - string[] comphash_07AE529D = compInfo_node.Element("hash_07AE529D").Value.Split(' '); //probably expressionMods(?) - used for heels for example + + string[] comphash_07AE529D = null; //probably expressionMods(?) - used for heels for example + if (compInfo_node.Element("hash_07AE529D").Value.Length == 9) //normal "0 0 0 0 0" + { + comphash_07AE529D = compInfo_node.Element("hash_07AE529D").Value.Split(' '); + } + else if(compInfo_node.Element("hash_07AE529D").Value.Length == 10)//that means, we have weird metatool value "0000000000" without spaces + { + string s = compInfo_node.Element("hash_07AE529D").Value.ToString(); + List temp = new List(); + int stringlenght = s.Length; + int skipEvery = 2; //we have to split every 2 characters + for (int i = 0; i < stringlenght; i += skipEvery) + { + string a = s.Substring(i, skipEvery).Substring(1); + temp.Add(a); + } + + comphash_07AE529D = temp.ToArray(); + } + else //maybe there is other case and i don't about it, then just input zeros + { + comphash_07AE529D = new string[] { "0", "0", "0", "0", "0" }; + } + int compflags = Convert.ToInt32(compInfo_node.Element("flags").FirstAttribute.Value); //unknown usage string compinclusions = compInfo_node.Element("inclusions").Value.ToString(); //unknown usage string compexclusions = compInfo_node.Element("exclusions").Value.ToString(); //unknown usage @@ -138,9 +192,9 @@ public static void LoadXML(string filePath) string _name = Enum.GetName(typeof(YMTTypes.ComponentNumbers), comphash_D12F579D); int curCompIndex = ComponentData.GetComponentIndexByID(comphash_D12F579D); - if(curCompIndex != -1) + if (curCompIndex != -1) { - MainWindow.Components.ElementAt(curCompIndex).compList.ElementAt(comphash_FA1F27BF).drawableInfo.Add(new ComponentInfo(comphash_2FD08CEF, comphash_FC507D28, + MainWindow.Components.ElementAt(curCompIndex).compList.ElementAt(comphash_FA1F27BF).drawableInfo.Add(new ComponentInfo(comphash_2FD08CEF, comphash_FC507D28, comphash_07AE529D, compflags, compinclusions, compexclusions, comphash_6032815C, comphash_7E103C8B, comphash_D12F579D, comphash_FA1F27BF)); } } @@ -171,9 +225,9 @@ public static void LoadXML(string filePath) } PropData _curPropData = MainWindow.Props.Where(p => p.propId == p_anchorId).First(); - + PropDrawable _curPropDrawable = new PropDrawable(_curPropDrawableIndex, p_audioId, p_expressionMods, new ObservableCollection(), p_renderFlag, p_propFlag, p_flag, p_anchorId, p_propId, p_hash); - + int texturePropIndex = 0; foreach (var texData in propMetaData.Descendants("texData").Elements("Item")) { @@ -195,8 +249,11 @@ public static void LoadXML(string filePath) _curPropDrawableIndex++; oldPropId = p_anchorId; } - + } + + + } private static XElement XML_Schema(string filePath) diff --git a/YMTEditor/YMTEditor.csproj b/YMTEditor/YMTEditor.csproj index d39d1a8..f572463 100644 --- a/YMTEditor/YMTEditor.csproj +++ b/YMTEditor/YMTEditor.csproj @@ -150,7 +150,9 @@ false - + + +