mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
CVRLuaToolsExtension: Fixed tracking of lua components on multiple of same asset with same Instance Id
This commit is contained in:
parent
6810bcf021
commit
db87288da6
5 changed files with 55 additions and 62 deletions
|
@ -9,79 +9,64 @@ namespace NAK.CVRLuaToolsExtension;
|
||||||
|
|
||||||
public static class LuaHotReloadManager
|
public static class LuaHotReloadManager
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, List<int>> s_AssetIdToLuaClientBehaviourIds = new();
|
// (asset id + lua component id) -> index is component reference
|
||||||
private static readonly Dictionary<int, CVRLuaClientBehaviour> s_LuaComponentIdsToLuaClientBehaviour = new();
|
private static readonly List<int> s_CombinedKeys = new();
|
||||||
|
private static readonly List<CVRLuaClientBehaviour> s_LuaComponentInstances = new();
|
||||||
|
|
||||||
#region Game Events
|
#region Game Events
|
||||||
|
|
||||||
public static void OnCVRLuaBaseBehaviourLoadAndRunScript(CVRLuaClientBehaviour clientBehaviour)
|
public static void OnCVRLuaBaseBehaviourLoadAndRunScript(CVRLuaClientBehaviour clientBehaviour)
|
||||||
{
|
{
|
||||||
//CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Script awake: {clientBehaviour.name}");
|
|
||||||
|
|
||||||
if (!clientBehaviour.IsScriptEligibleForHotReload())
|
if (!clientBehaviour.IsScriptEligibleForHotReload())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var assetId = clientBehaviour.GetAssetIdFromScript();
|
// check if the component is already in the list (shouldn't happen)
|
||||||
if (!s_AssetIdToLuaClientBehaviourIds.ContainsKey(assetId))
|
if (s_LuaComponentInstances.Contains(clientBehaviour))
|
||||||
s_AssetIdToLuaClientBehaviourIds[assetId] = new List<int>();
|
|
||||||
|
|
||||||
var luaComponentId = GetGameObjectPathHashCode(clientBehaviour.transform);
|
|
||||||
if (s_AssetIdToLuaClientBehaviourIds[assetId].Contains(luaComponentId))
|
|
||||||
{
|
{
|
||||||
CVRLuaToolsExtensionMod.Logger.Warning(
|
CVRLuaToolsExtensionMod.Logger.Warning($"[LuaHotReloadManager] Script already added: {clientBehaviour.name}");
|
||||||
$"[LuaHotReloadManager] Script already exists: {clientBehaviour.name}");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// combine the assetId and instanceId into a single key, so multiple instances of the same script can be tracked
|
||||||
|
string assetId = clientBehaviour.GetAssetIdFromScript();
|
||||||
|
int instanceId = GetGameObjectPathHashCode(clientBehaviour.transform);
|
||||||
|
int combinedKey = GenerateCombinedKey(assetId.GetHashCode(), instanceId);
|
||||||
|
|
||||||
|
s_CombinedKeys.Add(combinedKey);
|
||||||
|
s_LuaComponentInstances.Add(clientBehaviour);
|
||||||
|
|
||||||
s_AssetIdToLuaClientBehaviourIds[assetId].Add(luaComponentId);
|
|
||||||
s_LuaComponentIdsToLuaClientBehaviour[luaComponentId] = clientBehaviour;
|
|
||||||
CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Added script: {clientBehaviour.name}");
|
CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Added script: {clientBehaviour.name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnCVRLuaBaseBehaviourDestroy(CVRLuaClientBehaviour clientBehaviour)
|
public static void OnCVRLuaBaseBehaviourDestroy(CVRLuaClientBehaviour clientBehaviour)
|
||||||
{
|
{
|
||||||
//CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Script destroy: {clientBehaviour.name}");
|
if (!clientBehaviour.IsScriptEligibleForHotReload())
|
||||||
|
|
||||||
var assetId = clientBehaviour.GetAssetIdFromScript();
|
|
||||||
if (!s_AssetIdToLuaClientBehaviourIds.ContainsKey(assetId))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var luaClientBehaviourIds = s_AssetIdToLuaClientBehaviourIds[assetId];
|
if (!s_LuaComponentInstances.Contains(clientBehaviour))
|
||||||
foreach (var luaComponentId in luaClientBehaviourIds)
|
|
||||||
{
|
{
|
||||||
if (!s_LuaComponentIdsToLuaClientBehaviour.TryGetValue(luaComponentId,
|
CVRLuaToolsExtensionMod.Logger.Warning($"[LuaHotReloadManager] Eligible for Hot Reload script destroyed without being tracked first: {clientBehaviour.name}");
|
||||||
out CVRLuaClientBehaviour luaClientBehaviour))
|
return;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (luaClientBehaviour != clientBehaviour)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
s_LuaComponentIdsToLuaClientBehaviour.Remove(luaComponentId);
|
|
||||||
luaClientBehaviourIds.Remove(luaComponentId);
|
|
||||||
if (luaClientBehaviourIds.Count == 0) s_AssetIdToLuaClientBehaviourIds.Remove(assetId);
|
|
||||||
CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Removed script: {clientBehaviour.name}");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int index = s_LuaComponentInstances.IndexOf(clientBehaviour);
|
||||||
|
s_CombinedKeys.RemoveAt(index);
|
||||||
|
s_LuaComponentInstances.RemoveAt(index);
|
||||||
|
|
||||||
|
CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Removed script: {clientBehaviour.name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnReceiveUpdatedScript(ScriptInfo info)
|
public static void OnReceiveUpdatedScript(ScriptInfo info)
|
||||||
{
|
{
|
||||||
if (!s_AssetIdToLuaClientBehaviourIds.TryGetValue(info.AssetId, out var luaComponentIds))
|
int combinedKey = GenerateCombinedKey(info.AssetId.GetHashCode(), info.LuaComponentId);
|
||||||
{
|
|
||||||
CVRLuaToolsExtensionMod.Logger.Warning(
|
|
||||||
$"[LuaHotReloadManager] No scripts found for asset id: {info.AssetId}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach (var luaComponentId in luaComponentIds)
|
for (int i = 0; i < s_CombinedKeys.Count; i++)
|
||||||
{
|
{
|
||||||
if (!s_LuaComponentIdsToLuaClientBehaviour.TryGetValue(luaComponentId,
|
if (combinedKey != s_CombinedKeys[i])
|
||||||
out CVRLuaClientBehaviour clientBehaviour))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
found = true;
|
CVRLuaClientBehaviour clientBehaviour = s_LuaComponentInstances[i];
|
||||||
//CVRLuaToolsExtensionMod.Logger.Msg($"[LuaHotReloadManager] Reloading script: {info.ScriptName} for {clientBehaviour.name}");
|
|
||||||
|
|
||||||
if (clientBehaviour.asset.m_ScriptPath == info.ScriptPath)
|
if (clientBehaviour.asset.m_ScriptPath == info.ScriptPath)
|
||||||
{
|
{
|
||||||
|
@ -89,6 +74,7 @@ public static class LuaHotReloadManager
|
||||||
clientBehaviour.asset.name = info.ScriptName;
|
clientBehaviour.asset.name = info.ScriptName;
|
||||||
clientBehaviour.asset.m_ScriptText = info.ScriptText;
|
clientBehaviour.asset.m_ScriptText = info.ScriptText;
|
||||||
clientBehaviour.Restart();
|
clientBehaviour.Restart();
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -102,25 +88,31 @@ public static class LuaHotReloadManager
|
||||||
clientBehaviour.asset.m_ScriptText = info.ScriptText;
|
clientBehaviour.asset.m_ScriptText = info.ScriptText;
|
||||||
|
|
||||||
clientBehaviour.Restart();
|
clientBehaviour.Restart();
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) CohtmlHud.Instance.ViewDropTextImmediate("(Local) CVRLuaTools", "Received script update", "Reloaded script: " + info.ScriptName);
|
if (found)
|
||||||
|
{
|
||||||
|
CohtmlHud.Instance.ViewDropTextImmediate("(Local) CVRLuaTools", "Received script update", "Reloaded script: " + info.ScriptName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Game Events
|
#endregion Game Events
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
|
private static int GenerateCombinedKey(int assetId, int instanceId)
|
||||||
|
{
|
||||||
|
return (assetId << 16) | instanceId; // yes
|
||||||
|
}
|
||||||
|
|
||||||
private static int GetGameObjectPathHashCode(Transform transform)
|
private static int GetGameObjectPathHashCode(Transform transform)
|
||||||
{
|
{
|
||||||
// Attempt to find the root component transform in one step
|
|
||||||
|
|
||||||
Transform rootComponentTransform = null;
|
|
||||||
|
|
||||||
// both CVRAvatar & CVRSpawnable *should* have an asset info component
|
// both CVRAvatar & CVRSpawnable *should* have an asset info component
|
||||||
|
Transform rootComponentTransform = null;
|
||||||
CVRAssetInfo rootComponent = transform.GetComponentInParent<CVRAssetInfo>(true);
|
CVRAssetInfo rootComponent = transform.GetComponentInParent<CVRAssetInfo>(true);
|
||||||
if (rootComponent != null && rootComponent.type != CVRAssetInfo.AssetType.World)
|
if (rootComponent != null && rootComponent.type != CVRAssetInfo.AssetType.World) // ignore if under world instance
|
||||||
rootComponentTransform = rootComponent.transform;
|
rootComponentTransform = rootComponent.transform;
|
||||||
|
|
||||||
// easy case, no need to crawl up the hierarchy
|
// easy case, no need to crawl up the hierarchy
|
||||||
|
|
|
@ -4,6 +4,7 @@ using ABI.CCK.Components;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using NAK.CVRLuaToolsExtension.NamedPipes;
|
using NAK.CVRLuaToolsExtension.NamedPipes;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NAK.CVRLuaToolsExtension;
|
namespace NAK.CVRLuaToolsExtension;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,6 @@ using System.Reflection;
|
||||||
namespace NAK.CVRLuaToolsExtension.Properties;
|
namespace NAK.CVRLuaToolsExtension.Properties;
|
||||||
internal static class AssemblyInfoParams
|
internal static class AssemblyInfoParams
|
||||||
{
|
{
|
||||||
public const string Version = "1.0.0";
|
public const string Version = "1.0.1";
|
||||||
public const string Author = "NotAKidoS";
|
public const string Author = "NotAKidoS";
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
# IKSimulatedRootAngleFix
|
# CVRLuaToolsExtension
|
||||||
|
|
||||||
Fixes a small issue with Desktop & HalfBody root angle being incorrectly calculated while on rotating Movement Parents. If you've ever noticed your body/feet insisting on facing opposite of the direction you are rotating, this fixes that.
|
Extension mod for [CVRLuaTools](https://github.com/NotAKidoS/CVRLuaTools) Hot Reload functionality.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
{
|
{
|
||||||
"_id": -1,
|
"_id": -1,
|
||||||
"name": "AASDefaultProfileFix",
|
"name": "CVRLuaToolsExtension",
|
||||||
"modversion": "1.0.0",
|
"modversion": "1.0.0",
|
||||||
"gameversion": "2024r175",
|
"gameversion": "2024r175",
|
||||||
"loaderversion": "0.6.1",
|
"loaderversion": "0.6.1",
|
||||||
"modtype": "Mod",
|
"modtype": "Mod",
|
||||||
"author": "NotAKidoS",
|
"author": "NotAKidoS",
|
||||||
"description": "Fixes the Default AAS profile not being applied when loading into an avatar without a profile selected.\n\nBy default, the game will not apply anything and the avatar will default to the state found within the Controller parameters.",
|
"description": "Extension mod for [CVRLuaTools](https://github.com/NotAKidoS/CVRLuaTools) Hot Reload functionality.",
|
||||||
"searchtags": [
|
"searchtags": [
|
||||||
"aas",
|
"lua",
|
||||||
"profile",
|
"scripting",
|
||||||
"default",
|
"hotreload",
|
||||||
"fix",
|
"reload",
|
||||||
"meow"
|
"development"
|
||||||
],
|
],
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"None"
|
"None"
|
||||||
],
|
],
|
||||||
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r33/AASDefaultProfileFix.dll",
|
"downloadlink": "https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r33/CVRLuaToolsExtension.dll",
|
||||||
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/AASDefaultProfileFix/",
|
"sourcelink": "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/CVRLuaToolsExtension/",
|
||||||
"changelog": "- Initial release",
|
"changelog": "- Initial release",
|
||||||
"embedcolor": "#f61963"
|
"embedcolor": "#f61963"
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue