From 35c6e0ec8880e81dfa68bd042e998c4a7a3f8729 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 25 Sep 2022 18:32:31 +0200 Subject: [PATCH] Fix some unnecessary crashes on mtrl. --- Penumbra.GameData/Files/MtrlFile.Write.cs | 19 ++++++++++++------- Penumbra.GameData/Files/MtrlFile.cs | 11 ++++++++++- Penumbra/UI/Classes/ModEditWindow.FileEdit.cs | 3 ++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Penumbra.GameData/Files/MtrlFile.Write.cs b/Penumbra.GameData/Files/MtrlFile.Write.cs index 4b54c30f..43225ea2 100644 --- a/Penumbra.GameData/Files/MtrlFile.Write.cs +++ b/Penumbra.GameData/Files/MtrlFile.Write.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using System.Linq; using System.Text; @@ -46,14 +47,19 @@ public partial class MtrlFile } w.Write( AdditionalData ); - foreach( var row in ColorSets.Select( c => c.Rows ) ) + var dataSetSize = 0; + foreach( var row in ColorSets.Where( c => c.HasRows ).Select( c => c.Rows ) ) { - w.Write( row.AsBytes() ); + var span = row.AsBytes(); + w.Write( span ); + dataSetSize += span.Length; } foreach( var row in ColorDyeSets.Select( c => c.Rows ) ) { - w.Write( row.AsBytes() ); + var span = row.AsBytes(); + w.Write( span ); + dataSetSize += span.Length; } w.Write( ( ushort )( ShaderPackage.ShaderValues.Length * 4 ) ); @@ -88,19 +94,18 @@ public partial class MtrlFile w.Write( value ); } - WriteHeader( w, ( ushort )w.BaseStream.Position, cumulativeStringOffset ); + WriteHeader( w, ( ushort )w.BaseStream.Position, dataSetSize, cumulativeStringOffset ); } return stream.ToArray(); } - private void WriteHeader( BinaryWriter w, ushort fileSize, ushort shaderPackageNameOffset ) + private void WriteHeader( BinaryWriter w, ushort fileSize, int dataSetSize, ushort shaderPackageNameOffset ) { w.BaseStream.Seek( 0, SeekOrigin.Begin ); w.Write( Version ); w.Write( fileSize ); - w.Write( ( ushort )( ColorSets.Length * ColorSet.RowArray.NumRows * ColorSet.Row.Size - + ColorDyeSets.Length * ColorDyeSet.RowArray.NumRows * 2 ) ); + w.Write( ( ushort )dataSetSize ); w.Write( ( ushort )( shaderPackageNameOffset + ShaderPackage.Name.Length + 1 ) ); w.Write( shaderPackageNameOffset ); w.Write( ( byte )Textures.Length ); diff --git a/Penumbra.GameData/Files/MtrlFile.cs b/Penumbra.GameData/Files/MtrlFile.cs index 76257c1f..aa78b7ab 100644 --- a/Penumbra.GameData/Files/MtrlFile.cs +++ b/Penumbra.GameData/Files/MtrlFile.cs @@ -143,6 +143,7 @@ public partial class MtrlFile : IWritable public RowArray Rows; public string Name; public ushort Index; + public bool HasRows; } public unsafe struct ColorDyeSet @@ -305,7 +306,15 @@ public partial class MtrlFile : IWritable AdditionalData = r.ReadBytes( additionalDataSize ); for( var i = 0; i < ColorSets.Length; ++i ) { - ColorSets[ i ].Rows = r.ReadStructure< ColorSet.RowArray >(); + if( stream.Position + ColorSet.RowArray.NumRows * ColorSet.Row.Size <= stream.Length ) + { + ColorSets[ i ].Rows = r.ReadStructure< ColorSet.RowArray >(); + ColorSets[ i ].HasRows = true; + } + else + { + ColorSets[i].HasRows = false; + } } for( var i = 0; i < ColorDyeSets.Length; ++i ) diff --git a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs index 99c25d26..cc4ef1c9 100644 --- a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs +++ b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Numerics; using Dalamud.Interface; using ImGuiNET; @@ -259,7 +260,7 @@ public partial class ModEditWindow private static bool DrawMaterialColorSetChange( MtrlFile file, bool disabled ) { - if( file.ColorSets.Length == 0 ) + if( !file.ColorSets.Any(c => c.HasRows ) ) { return false; }