Fix crash on load of meta files with secondary type / no slot info.

This commit is contained in:
Ottermandias 2021-04-20 15:41:05 +02:00
parent c3a8b4cb0b
commit 234712ca99
4 changed files with 47 additions and 34 deletions

View file

@ -55,7 +55,7 @@ namespace Penumbra.Importer
ObjectType.Unknown => false,
ObjectType.Weapon => false,
ObjectType.World => false,
_ => false
_ => false,
};
}
@ -93,11 +93,8 @@ namespace Penumbra.Importer
}
PrimaryId = ushort.Parse( match.Groups[ "PrimaryId" ].Value );
if( !match.Groups[ "Slot" ].Success )
if( match.Groups[ "Slot" ].Success )
{
return;
}
switch( PrimaryType )
{
case ObjectType.Equipment:
@ -116,6 +113,7 @@ namespace Penumbra.Importer
break;
}
}
if( match.Groups[ "SecondaryType" ].Success
&& GameData.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) )

View file

@ -108,7 +108,7 @@ namespace Penumbra.MetaData
protected T GetEntry< T >( T[]?[] blocks, ushort idx, T defaultEntry )
{
// Skip the zeroth item.
idx = idx == 0 ? 1 : idx;
idx = idx == 0 ? ( ushort )1 : idx;
var block = BlockIdx( idx );
var array = block < blocks.Length ? blocks[ block ] : null;
if( array == null )
@ -122,7 +122,7 @@ namespace Penumbra.MetaData
protected ref T GetTrueEntry< T >( T[]?[] blocks, ushort idx )
{
// Skip the zeroth item.
idx = idx == 0 ? 1 : idx;
idx = idx == 0 ? ( ushort )1 : idx;
var block = BlockIdx( idx );
if( block >= TotalBlockCount )
{

View file

@ -101,7 +101,7 @@ namespace Penumbra.MetaData
return 0;
}
return !setDict.TryGetValue( setId, out var entry ) ? 0 : entry;
return !setDict.TryGetValue( setId, out var entry ) ? (ushort) 0 : entry;
}
public byte[] WriteBytes()

View file

@ -1,6 +1,8 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Dalamud.Plugin;
using Lumina.Data.Files;
using Penumbra.Game;
using Penumbra.Mods;
@ -9,9 +11,13 @@ namespace Penumbra.MetaData
{
public static class ImcExtensions
{
public static bool Equal( this ImcFile.ImageChangeData lhs, ImcFile.ImageChangeData rhs ) =>
lhs.MaterialId == rhs.MaterialId && lhs.DecalId == rhs.DecalId && lhs.AttributeMask == rhs.AttributeMask
&& lhs.SoundId == rhs.SoundId && lhs.VfxId == rhs.VfxId && lhs.MaterialAnimationId == rhs.MaterialAnimationId;
public static bool Equal( this ImcFile.ImageChangeData lhs, ImcFile.ImageChangeData rhs )
=> lhs.MaterialId == rhs.MaterialId
&& lhs.DecalId == rhs.DecalId
&& lhs.AttributeMask == rhs.AttributeMask
&& lhs.SoundId == rhs.SoundId
&& lhs.VfxId == rhs.VfxId
&& lhs.MaterialAnimationId == rhs.MaterialAnimationId;
private static void WriteBytes( this ImcFile.ImageChangeData variant, BinaryWriter bw )
{
@ -67,7 +73,7 @@ namespace Penumbra.MetaData
EquipSlot.RingR => 3,
EquipSlot.Feet => 4,
EquipSlot.RingL => 4,
_ => throw new InvalidEnumArgumentException()
_ => throw new InvalidEnumArgumentException(),
};
}
@ -76,20 +82,29 @@ namespace Penumbra.MetaData
return ref parts[ idx ].DefaultVariant;
}
if( imc.Variant > parts[ idx ].Variants.Length )
{
PluginLog.Debug( "Trying to manipulate invalid variant {Variant} of {NumVariants} in file {FileName}.", imc.Variant,
parts[ idx ].Variants.Length, file.FilePath.Path );
return ref parts[ idx ].Variants[ parts[ idx ].Variants.Length - 1 ];
}
else
{
return ref parts[ idx ].Variants[ imc.Variant - 1 ];
}
}
public static ImcFile Clone( this ImcFile file )
{
var ret = new ImcFile
{
Count = file.Count,
PartMask = file.PartMask
PartMask = file.PartMask,
};
var parts = file.GetParts().Select( P => new ImcFile.ImageChangeParts()
{
DefaultVariant = P.DefaultVariant,
Variants = ( ImcFile.ImageChangeData[] )P.Variants.Clone()
Variants = ( ImcFile.ImageChangeData[] )P.Variants.Clone(),
} ).ToArray();
var prop = ret.GetType().GetField( "Parts", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance );
prop!.SetValue( ret, parts );