mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
LuaNetworkVariables: idk
This commit is contained in:
parent
db07d53971
commit
fe768029eb
19 changed files with 1680 additions and 0 deletions
146
LuaNetworkVariables/NetworkVariables/LuaNetVarController.Base.cs
Normal file
146
LuaNetworkVariables/NetworkVariables/LuaNetVarController.Base.cs
Normal file
|
@ -0,0 +1,146 @@
|
|||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Core.Util;
|
||||
using ABI_RC.Systems.ModNetwork;
|
||||
using ABI.CCK.Components;
|
||||
using ABI.Scripting.CVRSTL.Common;
|
||||
using MoonSharp.Interpreter;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
|
||||
public partial class LuaNetVarController : MonoBehaviour
|
||||
{
|
||||
private static readonly HashSet<int> _hashes = new();
|
||||
|
||||
private const string MODULE_ID = "NAK.LNV:";
|
||||
|
||||
private int _uniquePathHash;
|
||||
private string ModNetworkID { get; set; }
|
||||
private CVRLuaClientBehaviour _luaClientBehaviour;
|
||||
|
||||
private readonly Dictionary<string, DynValue> _registeredNetworkVars = new();
|
||||
private readonly Dictionary<string, DynValue> _registeredNotifyCallbacks = new();
|
||||
private readonly Dictionary<string, DynValue> _registeredEventCallbacks = new();
|
||||
private readonly HashSet<string> _dirtyVariables = new();
|
||||
|
||||
private bool _requestInitialSync;
|
||||
private CVRSpawnable _spawnable;
|
||||
private CVRObjectSync _objectSync;
|
||||
|
||||
#region Unity Events
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!Initialize())
|
||||
return;
|
||||
|
||||
// TODO: a manager script should be in charge of this
|
||||
// TODO: disabling object will kill coroutine
|
||||
StartCoroutine(SendVariableUpdatesCoroutine());
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
=> Cleanup();
|
||||
|
||||
#endregion Unity Events
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private bool Initialize()
|
||||
{
|
||||
if (!TryGetComponent(out _luaClientBehaviour)) return false;
|
||||
if (!TryGetUniqueNetworkID(out _uniquePathHash)) return false;
|
||||
|
||||
ModNetworkID = MODULE_ID + _uniquePathHash.ToString("X8");
|
||||
|
||||
if (ModNetworkID.Length > ModNetworkManager.MaxMessageIdLength)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error($"ModNetworkID ({ModNetworkID}) exceeds max length of {ModNetworkManager.MaxMessageIdLength} characters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_hashes.Add(_uniquePathHash);
|
||||
ModNetworkManager.Subscribe(ModNetworkID, OnMessageReceived);
|
||||
LuaNetVarsMod.Logger.Msg($"Registered LuaNetVarController with ModNetworkID: {ModNetworkID}");
|
||||
|
||||
switch (_luaClientBehaviour.Context.objContext)
|
||||
{
|
||||
case CVRLuaObjectContext.AVATAR:
|
||||
_requestInitialSync = !_luaClientBehaviour.Context.IsWornByMe;
|
||||
break;
|
||||
case CVRLuaObjectContext.PROP:
|
||||
_spawnable = _luaClientBehaviour.Context.RootComponent as CVRSpawnable;
|
||||
_requestInitialSync = !_luaClientBehaviour.Context.IsSpawnedByMe;
|
||||
break;
|
||||
case CVRLuaObjectContext.WORLD:
|
||||
_objectSync = GetComponentInParent<CVRObjectSync>();
|
||||
_requestInitialSync = true; // idk probably works
|
||||
break;
|
||||
default:
|
||||
_requestInitialSync = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: evaluate if having dedicated globals is better behaviour (i think so)
|
||||
// private void ConfigureLuaEnvironment()
|
||||
// {
|
||||
// _luaClientBehaviour.script.Globals["SendLuaEvent"] = DynValue.NewCallback(SendLuaEventCallback);
|
||||
// }
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
_eventTracker.Clear();
|
||||
|
||||
if (_uniquePathHash == 0 || string.IsNullOrEmpty(ModNetworkID))
|
||||
return;
|
||||
|
||||
ModNetworkManager.Unsubscribe(ModNetworkID);
|
||||
LuaNetVarsMod.Logger.Msg($"Unsubscribed LuaNetVarController with ModNetworkID: {ModNetworkID}");
|
||||
_hashes.Remove(_uniquePathHash);
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator SendVariableUpdatesCoroutine()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
if (IsSyncOwner()) SendVariableUpdates();
|
||||
if (!_requestInitialSync) continue;
|
||||
_requestInitialSync = false;
|
||||
RequestVariableSync();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
#region Ownership Methods
|
||||
|
||||
public bool IsSyncOwner()
|
||||
{
|
||||
if (_objectSync) return _objectSync.SyncedByMe; // idk
|
||||
if (_spawnable)
|
||||
{
|
||||
if (_spawnable.IsSyncedByMe()) return true; // is held / attached locally
|
||||
CVRSyncHelper.PropData propData = CVRSyncHelper.Props.Find(x => x.InstanceId == _spawnable.instanceId);
|
||||
if (propData != null) return propData.syncedBy == MetaPort.Instance.ownerId; // last updated by me
|
||||
return false; // not held / attached locally and not last updated by me
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public string GetSyncOwner()
|
||||
{
|
||||
if (_objectSync) return _objectSync.syncedBy;
|
||||
if (_spawnable)
|
||||
{
|
||||
CVRSyncHelper.PropData propData = CVRSyncHelper.Props.Find(x => x.InstanceId == _spawnable.instanceId);
|
||||
return propData?.syncedBy ?? string.Empty;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#endregion Ownership Methods
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue