Skip to content

Commit 234712c

Browse files
committed
Fix crash on load of meta files with secondary type / no slot info.
1 parent c3a8b4c commit 234712c

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

Penumbra/Importer/TexToolsMeta.cs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static bool ValidType( ObjectType type )
5555
ObjectType.Unknown => false,
5656
ObjectType.Weapon => false,
5757
ObjectType.World => false,
58-
_ => false
58+
_ => false,
5959
};
6060
}
6161

@@ -93,32 +93,30 @@ public Info( GamePath fileName )
9393
}
9494

9595
PrimaryId = ushort.Parse( match.Groups[ "PrimaryId" ].Value );
96-
if( !match.Groups[ "Slot" ].Success )
96+
if( match.Groups[ "Slot" ].Success )
9797
{
98-
return;
99-
}
100-
101-
switch( PrimaryType )
102-
{
103-
case ObjectType.Equipment:
104-
case ObjectType.Accessory:
105-
if( GameData.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) )
106-
{
107-
EquipSlot = tmpSlot;
108-
}
109-
110-
break;
111-
case ObjectType.Character:
112-
if( GameData.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) )
113-
{
114-
CustomizationType = tmpCustom;
115-
}
116-
117-
break;
98+
switch( PrimaryType )
99+
{
100+
case ObjectType.Equipment:
101+
case ObjectType.Accessory:
102+
if( GameData.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) )
103+
{
104+
EquipSlot = tmpSlot;
105+
}
106+
107+
break;
108+
case ObjectType.Character:
109+
if( GameData.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) )
110+
{
111+
CustomizationType = tmpCustom;
112+
}
113+
114+
break;
115+
}
118116
}
119117

120118
if( match.Groups[ "SecondaryType" ].Success
121-
&& GameData.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) )
119+
&& GameData.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) )
122120
{
123121
SecondaryId = ushort.Parse( match.Groups[ "SecondaryId" ].Value );
124122
}
@@ -217,8 +215,8 @@ private void DeserializeEstEntries( Info info, byte[]? data )
217215
var id = reader.ReadUInt16();
218216
var value = reader.ReadUInt16();
219217
if( !gr.IsValid()
220-
|| info.PrimaryType == ObjectType.Character && info.SecondaryType != BodySlot.Face && info.SecondaryType != BodySlot.Hair
221-
|| info.PrimaryType == ObjectType.Equipment && info.EquipSlot != EquipSlot.Head && info.EquipSlot != EquipSlot.Body )
218+
|| info.PrimaryType == ObjectType.Character && info.SecondaryType != BodySlot.Face && info.SecondaryType != BodySlot.Hair
219+
|| info.PrimaryType == ObjectType.Equipment && info.EquipSlot != EquipSlot.Head && info.EquipSlot != EquipSlot.Body )
222220
{
223221
continue;
224222
}

Penumbra/MetaData/EqpFile.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ protected bool CollapseBlock< T >( T[]?[] blocks, int idx )
108108
protected T GetEntry< T >( T[]?[] blocks, ushort idx, T defaultEntry )
109109
{
110110
// Skip the zeroth item.
111-
idx = idx == 0 ? 1 : idx;
111+
idx = idx == 0 ? ( ushort )1 : idx;
112112
var block = BlockIdx( idx );
113113
var array = block < blocks.Length ? blocks[ block ] : null;
114114
if( array == null )
@@ -122,7 +122,7 @@ protected T GetEntry< T >( T[]?[] blocks, ushort idx, T defaultEntry )
122122
protected ref T GetTrueEntry< T >( T[]?[] blocks, ushort idx )
123123
{
124124
// Skip the zeroth item.
125-
idx = idx == 0 ? 1 : idx;
125+
idx = idx == 0 ? ( ushort )1 : idx;
126126
var block = BlockIdx( idx );
127127
if( block >= TotalBlockCount )
128128
{
@@ -141,7 +141,7 @@ protected byte[] WriteBytes< T >( T[]?[] blocks, Func< T, ulong > transform )
141141
using var bw = new BinaryWriter( mem );
142142

143143
foreach( var parameter in blocks.Where( array => array != null )
144-
.SelectMany( array => array ) )
144+
.SelectMany( array => array ) )
145145
{
146146
bw.Write( transform( parameter ) );
147147
}

Penumbra/MetaData/EstFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public ushort GetEntry( GenderRace gr, ushort setId )
101101
return 0;
102102
}
103103

104-
return !setDict.TryGetValue( setId, out var entry ) ? 0 : entry;
104+
return !setDict.TryGetValue( setId, out var entry ) ? (ushort) 0 : entry;
105105
}
106106

107107
public byte[] WriteBytes()

Penumbra/MetaData/ImcExtensions.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
using System;
12
using System.ComponentModel;
23
using System.IO;
34
using System.Linq;
5+
using Dalamud.Plugin;
46
using Lumina.Data.Files;
57
using Penumbra.Game;
68
using Penumbra.Mods;
@@ -9,9 +11,13 @@ namespace Penumbra.MetaData
911
{
1012
public static class ImcExtensions
1113
{
12-
public static bool Equal( this ImcFile.ImageChangeData lhs, ImcFile.ImageChangeData rhs ) =>
13-
lhs.MaterialId == rhs.MaterialId && lhs.DecalId == rhs.DecalId && lhs.AttributeMask == rhs.AttributeMask
14-
&& lhs.SoundId == rhs.SoundId && lhs.VfxId == rhs.VfxId && lhs.MaterialAnimationId == rhs.MaterialAnimationId;
14+
public static bool Equal( this ImcFile.ImageChangeData lhs, ImcFile.ImageChangeData rhs )
15+
=> lhs.MaterialId == rhs.MaterialId
16+
&& lhs.DecalId == rhs.DecalId
17+
&& lhs.AttributeMask == rhs.AttributeMask
18+
&& lhs.SoundId == rhs.SoundId
19+
&& lhs.VfxId == rhs.VfxId
20+
&& lhs.MaterialAnimationId == rhs.MaterialAnimationId;
1521

1622
private static void WriteBytes( this ImcFile.ImageChangeData variant, BinaryWriter bw )
1723
{
@@ -67,7 +73,7 @@ public static ref ImcFile.ImageChangeData GetValue( this ImcFile file, MetaManip
6773
EquipSlot.RingR => 3,
6874
EquipSlot.Feet => 4,
6975
EquipSlot.RingL => 4,
70-
_ => throw new InvalidEnumArgumentException()
76+
_ => throw new InvalidEnumArgumentException(),
7177
};
7278
}
7379

@@ -76,20 +82,29 @@ public static ref ImcFile.ImageChangeData GetValue( this ImcFile file, MetaManip
7682
return ref parts[ idx ].DefaultVariant;
7783
}
7884

79-
return ref parts[ idx ].Variants[ imc.Variant - 1 ];
85+
if( imc.Variant > parts[ idx ].Variants.Length )
86+
{
87+
PluginLog.Debug( "Trying to manipulate invalid variant {Variant} of {NumVariants} in file {FileName}.", imc.Variant,
88+
parts[ idx ].Variants.Length, file.FilePath.Path );
89+
return ref parts[ idx ].Variants[ parts[ idx ].Variants.Length - 1 ];
90+
}
91+
else
92+
{
93+
return ref parts[ idx ].Variants[ imc.Variant - 1 ];
94+
}
8095
}
8196

8297
public static ImcFile Clone( this ImcFile file )
8398
{
8499
var ret = new ImcFile
85100
{
86101
Count = file.Count,
87-
PartMask = file.PartMask
102+
PartMask = file.PartMask,
88103
};
89104
var parts = file.GetParts().Select( P => new ImcFile.ImageChangeParts()
90105
{
91106
DefaultVariant = P.DefaultVariant,
92-
Variants = ( ImcFile.ImageChangeData[] )P.Variants.Clone()
107+
Variants = ( ImcFile.ImageChangeData[] )P.Variants.Clone(),
93108
} ).ToArray();
94109
var prop = ret.GetType().GetField( "Parts", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance );
95110
prop!.SetValue( ret, parts );

0 commit comments

Comments
 (0)