deterministic manager

This commit is contained in:
JohnCorby 2022-01-26 18:54:50 -08:00
parent d2599a7e88
commit 0e1f7f180b
7 changed files with 72 additions and 20 deletions

View File

@ -20,6 +20,8 @@ namespace QSB.Anglerfish.WorldObjects
public override void Init()
{
DebugLog.DebugWrite($"{this} | {AttachedObject.DeterministicPath()} | {AttachedObject.GetInstanceID()}");
if (QSBCore.IsHost)
{
Object.Instantiate(QSBNetworkManager.singleton.AnglerPrefab).SpawnWithServerAuthority();

View File

@ -16,6 +16,8 @@ namespace QSB.JellyfishSync.WorldObjects
public override void Init()
{
DebugLog.DebugWrite($"{this} | {AttachedObject.DeterministicPath()} | {AttachedObject.GetInstanceID()}");
if (QSBCore.IsHost)
{
Object.Instantiate(QSBNetworkManager.singleton.JellyfishPrefab).SpawnWithServerAuthority();

View File

@ -95,6 +95,7 @@ namespace QSB
}
QSBPatchManager.Init();
DeterministicManager.Init();
gameObject.AddComponent<QSBNetworkManager>();
gameObject.AddComponent<DebugActions>();

View File

@ -0,0 +1,64 @@
using HarmonyLib;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace QSB.Utility
{
[HarmonyPatch]
public static class DeterministicManager
{
public static void Init() =>
Harmony.CreateAndPatchAll(typeof(DeterministicManager));
/// <summary>
/// called after all objects ready
/// </summary>
public static void ClearCache() => _cache.Clear();
private static readonly Dictionary<Transform, (int SiblingIndex, Transform Parent)> _cache = new();
[HarmonyPrefix]
[HarmonyPatch(typeof(OWRigidbody), nameof(OWRigidbody.Awake))]
private static void OWRigidbody_Awake(OWRigidbody __instance)
{
var transform = __instance.transform;
_cache.Add(transform, (transform.GetSiblingIndex(), transform.parent));
}
/// <summary>
/// only call this before all objects ready
/// </summary>
public static string DeterministicPath(this Component component)
{
var sb = new StringBuilder();
var transform = component.transform;
while (true)
{
if (!_cache.TryGetValue(transform, out var data))
{
data = (transform.GetSiblingIndex(), transform.parent);
_cache.Add(transform, data);
}
if (!data.Parent)
{
break;
}
sb.Append(data.SiblingIndex);
transform = data.Parent;
}
sb.Append(transform.name);
return sb.ToString();
}
/// <summary>
/// only call this before all objects ready
/// </summary>
public static IEnumerable<T> SortDeterministic<T>(this IEnumerable<T> components) where T : Component
=> components.OrderBy(DeterministicPath);
}
}

View File

@ -4,7 +4,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using Object = UnityEngine.Object;
@ -46,23 +45,6 @@ namespace QSB.Utility
public static void SpawnWithServerAuthority(this GameObject go) =>
NetworkServer.Spawn(go, NetworkServer.localConnection);
public static string DeterministicPath(this Component component)
{
var sb = new StringBuilder();
var transform = component.transform;
while (transform.parent)
{
sb.Append(transform.GetSiblingIndex());
transform = transform.parent;
}
sb.Append(transform.name);
return sb.ToString();
}
public static IEnumerable<T> SortDeterministic<T>(this IEnumerable<T> components) where T : Component
=> components.OrderBy(DeterministicPath);
#endregion
#region C#

View File

@ -63,6 +63,7 @@ namespace QSB.WorldSync
{
AllObjectsReady = true;
DebugLog.DebugWrite("World Objects ready.", MessageType.Success);
DeterministicManager.ClearCache();
if (!QSBCore.IsHost)
{

View File

@ -3,9 +3,9 @@
"overrideAppId": -1,
"debugMode": true,
"drawLines": true,
"showQuantumVisibilityObjects": true,
"showQuantumVisibilityObjects": false,
"showDebugLabels": true,
"avoidTimeSync": false,
"skipTitleScreen": true,
"greySkybox": true
"greySkybox": false
}