using ABI_RC.Core.Player; using UnityEngine; namespace NAK.Melons.AASBufferFix; public class AASBufferFix : MonoBehaviour { public bool isAcceptingAAS = true; internal PuppetMaster puppetMaster; //outside buffers that dont get nuked on avatar load private float[] aasBufferFloat = new float[0]; private int[] aasBufferInt = new int[0]; private byte[] aasBufferByte = new byte[0]; //footprint is each parameter bit type count multiplied together private int aasFootprint = -1; private int avatarFootprint = 0; public void Start() { puppetMaster = GetComponent(); } public void OnAvatarInstantiated(Animator animator) { //create the loaded avatar footprint avatarFootprint = Utils.GenerateAnimatorAASFootprint(animator); //previous "bad data" now matches, apply buffered data if (SyncDataMatchesExpected()) { ApplyExternalAASBuffer(); } } public void OnAvatarDestroyed() { aasFootprint = -1; avatarFootprint = 0; isAcceptingAAS = false; } public void OnApplyAAS(float[] settingsFloat, int[] settingsInt, byte[] settingsByte) { //create the synced data footprint aasFootprint = ((settingsFloat.Length * 32) + 1) * ((settingsInt.Length * 32) + 1) * ((settingsByte.Length * 8) + 1); if (!SyncDataMatchesExpected()) { if (avatarFootprint == 0) { //we are receiving synced data, but the avatar has not loaded on our end //we can only assume the data is correct, and store it for later StoreExternalAASBuffer(settingsFloat, settingsInt, settingsByte); return; } //avatar is loaded on our screen, but wearer is syncing bad data //we will need to wait until it has loaded on their end //there is also a chance the avatar is hidden, so the animator returned 1 on initialization //(this was only one encounter during testing, someone being hidden by safety on world load) } else { //synced data matches what we expect ApplyExternalAAS(settingsFloat, settingsInt, settingsByte); } } public void ApplyExternalAASBuffer() { isAcceptingAAS = true; puppetMaster?.ApplyAdvancedAvatarSettings(aasBufferFloat, aasBufferInt, aasBufferByte); } public void ApplyExternalAAS(float[] settingsFloat, int[] settingsInt, byte[] settingsByte) { isAcceptingAAS = true; puppetMaster?.ApplyAdvancedAvatarSettings(settingsFloat, settingsInt, settingsByte); } public void StoreExternalAASBuffer(float[] settingsFloat, int[] settingsInt, byte[] settingsByte) { Array.Resize(ref aasBufferFloat, settingsFloat.Length); Array.Resize(ref aasBufferInt, settingsInt.Length); Array.Resize(ref aasBufferByte, settingsByte.Length); Array.Copy(settingsFloat, aasBufferFloat, settingsFloat.Length); Array.Copy(settingsInt, aasBufferInt, settingsInt.Length); Array.Copy(settingsByte, aasBufferByte, settingsByte.Length); } public bool SyncDataMatchesExpected() { return aasFootprint == avatarFootprint; } }