2025-09-17 16:40:02 -07:00

77 lines
2.4 KiB
C#

using AssetRipper.AssemblyDumper.InjectedTypes;
using AssetRipper.AssemblyDumper.Types;
using AssetRipper.Assets;
namespace AssetRipper.AssemblyDumper.Passes;
internal static class Pass505_FixOldAudioClip
{
public static void DoPass()
{
TypeDefinition helperType = SharedState.Instance.InjectHelperType(typeof(AudioClipHelper));
MethodDefinition helperMethod = helperType.Methods.Single(m => m.Name == nameof(AudioClipHelper.ReadOldByteArray));
foreach (GeneratedClassInstance instance in SharedState.Instance.ClassGroups[83].Instances)
{
if (instance.TryGetStreamField(out FieldDefinition? streamField))
{
MethodDefinition readReleaseMethod = instance.Type.Methods.Single(m => m.Name == nameof(UnityObjectBase.ReadRelease));
MethodDefinition readEditorMethod = instance.Type.Methods.Single(m => m.Name == nameof(UnityObjectBase.ReadEditor));
FieldDefinition dataField = instance.Type.GetFieldByName("m_AudioData");
FixMethod(readReleaseMethod, helperMethod, dataField, streamField);
FixMethod(readEditorMethod, helperMethod, dataField, streamField);
}
}
}
private static void FixMethod(MethodDefinition readMethod, MethodDefinition helperMethod, FieldDefinition dataField, FieldDefinition streamField)
{
CilInstructionCollection instructions = readMethod.GetInstructions();
//remove bad instructions
while (instructions.Count > 0)
{
int index = instructions.Count - 1;
CilInstruction instruction = instructions[index];
instructions.RemoveAt(index);
if (instruction.OpCode == CilOpCodes.Ldarg_0)
{
break;
}
}
instructions.Add(CilOpCodes.Ldarg_0);//for the store field
instructions.Add(CilOpCodes.Ldarg_0);
instructions.Add(CilOpCodes.Ldarg_1);
instructions.Add(CilOpCodes.Ldarg_0);
instructions.Add(CilOpCodes.Ldfld, streamField);
instructions.Add(CilOpCodes.Call, helperMethod);
instructions.Add(CilOpCodes.Stfld, dataField);
instructions.Add(CilOpCodes.Ret);
}
private static bool TryGetStreamField(this GeneratedClassInstance instance, [NotNullWhen(true)] out FieldDefinition? streamField)
{
if (instance.Type.TryGetFieldByName("m_Stream", out streamField))
{
CorLibTypeSignature? fieldType = streamField.Signature?.FieldType as CorLibTypeSignature;
if (fieldType is not null && fieldType.ElementType == ElementType.I4)
{
return true;
}
else
{
streamField = null;
return false;
}
}
else
{
return false;
}
}
}