mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-26 09:35:26 +00:00
commit
ff85a56a91
Binary file not shown.
@ -1,9 +1,9 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3045401868
|
||||
CRC: 3416116897
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: fbaaf26c59dbb62b2ffc0c3939c0880a
|
||||
Hash: f304be71f6b3202b0c75695ffc81dd4e
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 47ee499ae8022a6b96ca6a5fd541f154
|
||||
@ -27,6 +27,7 @@ Assets:
|
||||
- Assets/NetworkPlayer.prefab
|
||||
- Assets/NetworkCameraRoot.prefab
|
||||
- Assets/NetworkProbe.prefab
|
||||
- Assets/NetworkOrb.prefab
|
||||
- Assets/NetworkManager.prefab
|
||||
- Assets/NetworkShip.prefab
|
||||
Dependencies: []
|
||||
|
@ -7,15 +7,9 @@ namespace QSB.Animation
|
||||
{
|
||||
public override EventType Type => EventType.AnimTrigger;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<short, float>.AddListener(EventNames.QSBAnimTrigger, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger<short, float>.AddListener(EventNames.QSBAnimTrigger, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<short, float>.RemoveListener(EventNames.QSBAnimTrigger, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger<short, float>.RemoveListener(EventNames.QSBAnimTrigger, Handler);
|
||||
|
||||
private void Handler(short triggerId, float value) => SendEvent(CreateMessage(triggerId, value));
|
||||
|
||||
|
@ -8,15 +8,9 @@ namespace QSB.DeathSync
|
||||
{
|
||||
public override EventType Type => EventType.PlayerDeath;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<DeathType>.AddListener(EventNames.QSBPlayerDeath, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger<DeathType>.AddListener(EventNames.QSBPlayerDeath, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<DeathType>.RemoveListener(EventNames.QSBPlayerDeath, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger<DeathType>.RemoveListener(EventNames.QSBPlayerDeath, Handler);
|
||||
|
||||
private void Handler(DeathType type) => SendEvent(CreateMessage(type));
|
||||
|
||||
|
@ -8,15 +8,9 @@ namespace QSB.ElevatorSync
|
||||
{
|
||||
public override EventType Type => EventType.Elevator;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<int, ElevatorDirection>.AddListener(EventNames.QSBStartLift, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger<int, ElevatorDirection>.AddListener(EventNames.QSBStartLift, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<int, ElevatorDirection>.RemoveListener(EventNames.QSBStartLift, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger<int, ElevatorDirection>.RemoveListener(EventNames.QSBStartLift, Handler);
|
||||
|
||||
private void Handler(int id, ElevatorDirection direction) => SendEvent(CreateMessage(id, direction));
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using QSB.DeathSync;
|
||||
using QSB.ElevatorSync;
|
||||
using QSB.GeyserSync;
|
||||
using QSB.OrbSync;
|
||||
using QSB.TimeSync;
|
||||
using QSB.Tools;
|
||||
using QSB.TransformSync;
|
||||
@ -37,7 +38,9 @@ namespace QSB.Events
|
||||
new ElevatorEvent(),
|
||||
new GeyserEvent(),
|
||||
new ServerTimeEvent(),
|
||||
new AnimTriggerEvent()
|
||||
new AnimTriggerEvent(),
|
||||
new OrbSlotEvent(),
|
||||
new OrbUserEvent()
|
||||
};
|
||||
|
||||
_eventList.ForEach(ev => ev.SetupListener());
|
||||
|
@ -16,6 +16,7 @@
|
||||
public static string UnequipTranslator = "UnequipTranslator";
|
||||
public static string ExitShip = "ExitShip";
|
||||
public static string RestartTimeLoop = "RestartTimeLoop";
|
||||
public static string WakeUp = "WakeUp";
|
||||
|
||||
public static string QSBPlayerDeath = "QSBPlayerDeath";
|
||||
public static string QSBPlayerJoin = "QSBPlayerJoin";
|
||||
@ -29,5 +30,7 @@
|
||||
public static string QSBStartLift = "QSBStartLift";
|
||||
public static string QSBGeyserState = "QSBGeyserState";
|
||||
public static string QSBAnimTrigger = "QSBAnimTrigger";
|
||||
public static string QSBOrbSlot = "QSBOrbSlot";
|
||||
public static string QSBOrbUser = "QSBOrbUser";
|
||||
}
|
||||
}
|
||||
|
@ -8,15 +8,9 @@ namespace QSB.Events
|
||||
{
|
||||
public override EventType Type => EventType.PlayerJoin;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<string>.AddListener(EventNames.QSBPlayerJoin, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger<string>.AddListener(EventNames.QSBPlayerJoin, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<string>.RemoveListener(EventNames.QSBPlayerJoin, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger<string>.RemoveListener(EventNames.QSBPlayerJoin, Handler);
|
||||
|
||||
private void Handler(string name) => SendEvent(CreateMessage(name));
|
||||
|
||||
|
@ -9,15 +9,9 @@ namespace QSB.Events
|
||||
{
|
||||
public override EventType Type => EventType.PlayerLeave;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<uint, uint[]>.AddListener(EventNames.QSBPlayerLeave, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger<uint, uint[]>.AddListener(EventNames.QSBPlayerLeave, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<uint, uint[]>.RemoveListener(EventNames.QSBPlayerLeave, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger<uint, uint[]>.RemoveListener(EventNames.QSBPlayerLeave, Handler);
|
||||
|
||||
private void Handler(uint playerId, uint[] netIds) => SendEvent(CreateMessage(playerId, netIds));
|
||||
|
||||
|
@ -10,15 +10,9 @@ namespace QSB.Events
|
||||
{
|
||||
public override EventType Type => EventType.PlayerReady;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger<bool>.AddListener(EventNames.QSBPlayerReady, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger<bool>.AddListener(EventNames.QSBPlayerReady, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger<bool>.RemoveListener(EventNames.QSBPlayerReady, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger<bool>.RemoveListener(EventNames.QSBPlayerReady, Handler);
|
||||
|
||||
private void Handler(bool ready) => SendEvent(CreateMessage(ready));
|
||||
|
||||
|
@ -9,15 +9,9 @@ namespace QSB.Events
|
||||
{
|
||||
public override EventType Type => EventType.FullStateRequest;
|
||||
|
||||
public override void SetupListener()
|
||||
{
|
||||
GlobalMessenger.AddListener(EventNames.QSBPlayerStatesRequest, Handler);
|
||||
}
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBPlayerStatesRequest, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
{
|
||||
GlobalMessenger.RemoveListener(EventNames.QSBPlayerStatesRequest, Handler);
|
||||
}
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBPlayerStatesRequest, Handler);
|
||||
|
||||
private void Handler() => SendEvent(CreateMessage());
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
PlayerReady,
|
||||
ProbeActiveChange,
|
||||
Elevator,
|
||||
Geyser
|
||||
Geyser,
|
||||
OrbSlot,
|
||||
OrbUser
|
||||
}
|
||||
}
|
||||
|
52
QSB/OrbSync/OrbManager.cs
Normal file
52
QSB/OrbSync/OrbManager.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB.OrbSync
|
||||
{
|
||||
public class OrbManager : MonoBehaviour
|
||||
{
|
||||
public static OrbManager Instance { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void BuildOrbSlots()
|
||||
{
|
||||
DebugLog.DebugWrite("Building QSBOrbSlots...");
|
||||
|
||||
var orbSlots = Resources.FindObjectsOfTypeAll<NomaiInterfaceSlot>();
|
||||
for (var id = 0; id < orbSlots.Length; id++)
|
||||
{
|
||||
var qsbOrbSlot = WorldRegistry.GetObject<QSBOrbSlot>(id) ?? new QSBOrbSlot();
|
||||
qsbOrbSlot.Init(orbSlots[id], id);
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"Finished orb build with {WorldRegistry.OldOrbList.Count} interface orbs and {WorldRegistry.OrbSyncList.Count} orb syncs.");
|
||||
}
|
||||
|
||||
public void BuildOrbs()
|
||||
{
|
||||
DebugLog.DebugWrite("Building orb syncs...");
|
||||
WorldRegistry.OldOrbList.Clear();
|
||||
|
||||
WorldRegistry.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
|
||||
if (NetworkServer.active)
|
||||
{
|
||||
DebugLog.DebugWrite("IS SERVER - INSTANTIATING!");
|
||||
WorldRegistry.OrbSyncList.Clear();
|
||||
WorldRegistry.OldOrbList.ForEach(x => NetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.OrbPrefab)));
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueBuildSlots()
|
||||
{
|
||||
DebugLog.DebugWrite("Queueing build of QSBOrbSlots...");
|
||||
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, BuildOrbSlots);
|
||||
}
|
||||
}
|
||||
}
|
61
QSB/OrbSync/OrbPatches.cs
Normal file
61
QSB/OrbSync/OrbPatches.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using QSB.Events;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.OrbSync
|
||||
{
|
||||
public static class OrbPatches
|
||||
{
|
||||
public static void StartDragCallEvent(bool __result, NomaiInterfaceOrb __instance)
|
||||
{
|
||||
if (__result)
|
||||
{
|
||||
GlobalMessenger<int>.FireEvent(EventNames.QSBOrbUser, WorldRegistry.OldOrbList.FindIndex(x => x == __instance));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckOrbCollision(ref bool __result, NomaiInterfaceSlot __instance, NomaiInterfaceOrb orb,
|
||||
bool ____ignoreDraggedOrbs, float ____radius, float ____exitRadius, ref NomaiInterfaceOrb ____occupyingOrb)
|
||||
{
|
||||
if (____ignoreDraggedOrbs && orb.IsBeingDragged())
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
var orbDistance = Vector3.Distance(orb.transform.position, __instance.transform.position);
|
||||
var triggerRadius = orb.IsBeingDragged() ? ____exitRadius : ____radius;
|
||||
if (____occupyingOrb == null && orbDistance < ____radius)
|
||||
{
|
||||
____occupyingOrb = orb;
|
||||
if (Time.timeSinceLevelLoad > 1f)
|
||||
{
|
||||
WorldRegistry.HandleSlotStateChange(__instance, orb, true);
|
||||
WorldRegistry.RaiseEvent(__instance, "OnSlotActivated");
|
||||
}
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
if (____occupyingOrb == null || ____occupyingOrb != orb)
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
if (orbDistance > triggerRadius)
|
||||
{
|
||||
WorldRegistry.HandleSlotStateChange(__instance, orb, false);
|
||||
____occupyingOrb = null;
|
||||
WorldRegistry.RaiseEvent(__instance, "OnSlotDeactivated");
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void AddPatches()
|
||||
{
|
||||
QSB.Helper.HarmonyHelper.AddPostfix<NomaiInterfaceOrb>("StartDragFromPosition", typeof(OrbPatches), nameof(StartDragCallEvent));
|
||||
QSB.Helper.HarmonyHelper.AddPrefix<NomaiInterfaceSlot>("CheckOrbCollision", typeof(OrbPatches), nameof(CheckOrbCollision));
|
||||
}
|
||||
}
|
||||
}
|
30
QSB/OrbSync/OrbSlotEvent.cs
Normal file
30
QSB/OrbSync/OrbSlotEvent.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.OrbSync
|
||||
{
|
||||
public class OrbSlotEvent : QSBEvent<BoolWorldObjectMessage>
|
||||
{
|
||||
public override EventType Type => EventType.OrbSlot;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger<int, bool>.AddListener(EventNames.QSBOrbSlot, Handler);
|
||||
|
||||
public override void CloseListener() => GlobalMessenger<int, bool>.RemoveListener(EventNames.QSBOrbSlot, Handler);
|
||||
|
||||
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
|
||||
|
||||
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new BoolWorldObjectMessage
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ObjectId = id,
|
||||
State = state
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(BoolWorldObjectMessage message)
|
||||
{
|
||||
var orbSlot = WorldRegistry.GetObject<QSBOrbSlot>(message.ObjectId);
|
||||
orbSlot?.SetState(message.State);
|
||||
}
|
||||
}
|
||||
}
|
73
QSB/OrbSync/OrbUserEvent.cs
Normal file
73
QSB/OrbSync/OrbUserEvent.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB.OrbSync
|
||||
{
|
||||
public class OrbUserEvent : QSBEvent<WorldObjectMessage>
|
||||
{
|
||||
public override EventType Type => EventType.OrbUser;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger<int>.AddListener(EventNames.QSBOrbUser, Handler);
|
||||
|
||||
public override void CloseListener() => GlobalMessenger<int>.RemoveListener(EventNames.QSBOrbUser, Handler);
|
||||
|
||||
private void Handler(int id) => SendEvent(CreateMessage(id));
|
||||
|
||||
private WorldObjectMessage CreateMessage(int id) => new WorldObjectMessage
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ObjectId = id
|
||||
};
|
||||
|
||||
public override void OnServerReceive(WorldObjectMessage message)
|
||||
{
|
||||
var fromPlayer = NetworkServer.connections
|
||||
.First(x => x.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value == message.FromId);
|
||||
if (WorldRegistry.OrbSyncList.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - OrbSyncList is empty. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
var orb = WorldRegistry.OrbSyncList
|
||||
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
|
||||
if (orb == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No orb found for user event. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
var orbIdentity = orb.GetComponent<NetworkIdentity>();
|
||||
if (orbIdentity == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Orb identity is null. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (orbIdentity.clientAuthorityOwner != null)
|
||||
{
|
||||
orbIdentity.RemoveClientAuthority(orbIdentity.clientAuthorityOwner);
|
||||
}
|
||||
orbIdentity.AssignClientAuthority(fromPlayer);
|
||||
orb.enabled = true;
|
||||
}
|
||||
|
||||
public override void OnReceiveRemote(WorldObjectMessage message)
|
||||
{
|
||||
var orb = WorldRegistry.OrbSyncList
|
||||
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
|
||||
orb.enabled = true;
|
||||
}
|
||||
|
||||
public override void OnReceiveLocal(WorldObjectMessage message)
|
||||
{
|
||||
if (NetworkServer.active)
|
||||
{
|
||||
OnServerReceive(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
QSB/OrbSync/QSBOrbSlot.cs
Normal file
38
QSB/OrbSync/QSBOrbSlot.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using QSB.Events;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.OrbSync
|
||||
{
|
||||
public class QSBOrbSlot : WorldObject
|
||||
{
|
||||
public NomaiInterfaceSlot InterfaceSlot { get; private set; }
|
||||
|
||||
private bool _initialized;
|
||||
|
||||
public void Init(NomaiInterfaceSlot slot, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
InterfaceSlot = slot;
|
||||
_initialized = true;
|
||||
WorldRegistry.AddObject(this);
|
||||
}
|
||||
|
||||
public void HandleEvent(bool state)
|
||||
{
|
||||
if (QSB.HasWokenUp)
|
||||
{
|
||||
GlobalMessenger<int, bool>.FireEvent(EventNames.QSBOrbSlot, ObjectId, state);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetState(bool state)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var ev = state ? "OnSlotActivated" : "OnSlotDeactivated";
|
||||
WorldRegistry.RaiseEvent(InterfaceSlot, ev);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ namespace QSB
|
||||
|
||||
public PlayerInfo(uint id)
|
||||
{
|
||||
DebugLog.DebugWrite($"Creating PlayerInfo with id {id}");
|
||||
PlayerId = id;
|
||||
}
|
||||
|
||||
@ -39,8 +40,6 @@ namespace QSB
|
||||
FlagsHelper.Unset(ref states, state);
|
||||
}
|
||||
State = states;
|
||||
//DebugLog.DebugWrite($"State of player {NetId} is now : {Environment.NewLine}" +
|
||||
// $"{DebugLog.GenerateTable(Enum.GetNames(typeof(State)).ToList(), FlagsHelper.FlagsToListSet(State))}");
|
||||
}
|
||||
|
||||
public void UpdateStateObjects()
|
||||
|
@ -3,6 +3,7 @@ using QSB.Messaging;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
@ -20,6 +21,8 @@ namespace QSB
|
||||
{
|
||||
if (id == uint.MaxValue || id == 0U)
|
||||
{
|
||||
var stacktrace = new StackTrace();
|
||||
DebugLog.ToConsole($"GetPlayer() got uint.MaxValue or 0 - returning default. Ran from {stacktrace.GetFrame(1).GetMethod().DeclaringType.Name}.{stacktrace.GetFrame(1).GetMethod().Name}.", MessageType.Warning);
|
||||
return default;
|
||||
}
|
||||
var player = PlayerList.FirstOrDefault(x => x.PlayerId == id);
|
||||
@ -39,6 +42,12 @@ namespace QSB
|
||||
PlayerList.Remove(GetPlayer(id));
|
||||
}
|
||||
|
||||
public static void RemoveAllPlayers()
|
||||
{
|
||||
DebugLog.DebugWrite($"Removing all players.", MessageType.Info);
|
||||
PlayerList.Clear();
|
||||
}
|
||||
|
||||
public static bool PlayerExists(uint id)
|
||||
{
|
||||
return id != uint.MaxValue && PlayerList.Any(x => x.PlayerId == id);
|
||||
@ -50,8 +59,6 @@ namespace QSB
|
||||
player.Name = message.PlayerName;
|
||||
player.IsReady = message.PlayerReady;
|
||||
player.State = message.PlayerState;
|
||||
//DebugLog.DebugWrite($"Updating state of player {player.NetId} to : {Environment.NewLine}" +
|
||||
// $"{DebugLog.GenerateTable(Enum.GetNames(typeof(State)).ToList(), FlagsHelper.FlagsToListSet(player.State))}");
|
||||
if (LocalPlayer.IsReady)
|
||||
{
|
||||
player.UpdateStateObjects();
|
||||
@ -76,28 +83,69 @@ namespace QSB
|
||||
|
||||
public static uint GetPlayerOfObject(this PlayerSyncObject syncObject)
|
||||
{
|
||||
if (PlayerList.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No players exist to find owner of object. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Error);
|
||||
syncObject.PreviousPlayerId = uint.MaxValue;
|
||||
return uint.MaxValue;
|
||||
}
|
||||
// Get all Player IDs
|
||||
var playerIds = PlayerList.Select(x => x.PlayerId).ToList();
|
||||
// Get highest ID below the given syncobject's netid. A netid cannot belong to a netid above it, only below or equal to it.
|
||||
var lowerBound = playerIds.Where(x => x <= syncObject.AttachedNetId).ToList().Max();
|
||||
if (playerIds.Min() > syncObject.AttachedNetId)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Minimum playerid is greater than syncobject's netid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
|
||||
syncObject.PreviousPlayerId = uint.MaxValue;
|
||||
return uint.MaxValue;
|
||||
}
|
||||
// If the player list count is not the same as the count of the same type syncobject (eg. 3 players and 4 PlayerTransformSyncs)
|
||||
// and the highest ID below the syncobject's id is the same as the highest player id.
|
||||
if (PlayerList.Count != PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType()) && lowerBound == playerIds.Max())
|
||||
{
|
||||
// If the previous player id was not the error value, return it. To smooth over discrepancies between player list and object list.
|
||||
if (syncObject.PreviousPlayerId != uint.MaxValue)
|
||||
{
|
||||
return syncObject.PreviousPlayerId;
|
||||
}
|
||||
// If the syncobject is a PlayerTransformSync, make a player.
|
||||
if (syncObject.GetType() == typeof(PlayerTransformSync) && syncObject.AttachedNetId != 0U)
|
||||
{
|
||||
return GetPlayer(syncObject.AttachedNetId).PlayerId;
|
||||
}
|
||||
DebugLog.ToConsole($"Warning - Unequal player:syncobject count. ({PlayerList.Count}:{PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType())}) (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
|
||||
syncObject.PreviousPlayerId = uint.MaxValue;
|
||||
return uint.MaxValue;
|
||||
}
|
||||
if (syncObject.PreviousPlayerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Syncobject previously had uint.MaxValue as it's playerid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
|
||||
}
|
||||
syncObject.PreviousPlayerId = lowerBound;
|
||||
return lowerBound;
|
||||
}
|
||||
|
||||
public static List<uint> GetPlayerNetIds(PlayerInfo player)
|
||||
{
|
||||
var count = PlayerSyncObjects.DistinctBy(x => x.AttachedNetId).Count(x => x.Player.PlayerId == player.PlayerId);
|
||||
if (PlayerSyncObjects.Count == 0)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
int count = 0;
|
||||
int totalCount = PlayerSyncObjects.Count;
|
||||
PlayerSyncObjects.RemoveAll(x => x == null);
|
||||
PlayerSyncObjects.RemoveAll(x => x.GetComponent<NetworkIdentity>() == null);
|
||||
if (PlayerSyncObjects.Count != totalCount)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Removed {totalCount - PlayerSyncObjects.Count} items from PlayerSyncObjects.", MessageType.Warning);
|
||||
}
|
||||
foreach (var item in PlayerSyncObjects.DistinctBy(x => x.AttachedNetId))
|
||||
{
|
||||
if (item.PlayerId == player.PlayerId)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return Enumerable.Range((int)player.PlayerId, count).Select(x => (uint)x).ToList();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using OWML.ModHelper;
|
||||
using QSB.DeathSync;
|
||||
using QSB.ElevatorSync;
|
||||
using QSB.GeyserSync;
|
||||
using QSB.OrbSync;
|
||||
using QSB.Tools;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
@ -18,6 +19,7 @@ namespace QSB
|
||||
public static int Port { get; private set; }
|
||||
public static bool DebugMode { get; private set; }
|
||||
public static AssetBundle NetworkAssetBundle { get; private set; }
|
||||
public static bool HasWokenUp { get; set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@ -43,6 +45,7 @@ namespace QSB
|
||||
gameObject.AddComponent<DebugActions>();
|
||||
gameObject.AddComponent<ElevatorManager>();
|
||||
gameObject.AddComponent<GeyserManager>();
|
||||
gameObject.AddComponent<OrbManager>();
|
||||
gameObject.AddComponent<QSBSectorManager>();
|
||||
}
|
||||
|
||||
|
@ -136,6 +136,11 @@
|
||||
<Compile Include="Events\EventNames.cs" />
|
||||
<Compile Include="DeathSync\PlayerDeathEvent.cs" />
|
||||
<Compile Include="Events\IQSBEvent.cs" />
|
||||
<Compile Include="OrbSync\OrbManager.cs" />
|
||||
<Compile Include="OrbSync\OrbSlotEvent.cs" />
|
||||
<Compile Include="OrbSync\OrbPatches.cs" />
|
||||
<Compile Include="OrbSync\OrbUserEvent.cs" />
|
||||
<Compile Include="OrbSync\QSBOrbSlot.cs" />
|
||||
<Compile Include="PlayerSyncObject.cs" />
|
||||
<Compile Include="QSBNetworkLobby.cs" />
|
||||
<Compile Include="QSBSceneManager.cs" />
|
||||
@ -145,6 +150,7 @@
|
||||
<Compile Include="Events\PlayerLeaveEvent.cs" />
|
||||
<Compile Include="Tools\PlayerProbeEvent.cs" />
|
||||
<Compile Include="Events\PlayerReadyEvent.cs" />
|
||||
<Compile Include="TransformSync\NomaiOrbTransformSync.cs" />
|
||||
<Compile Include="TransformSync\PlayerSectorEvent.cs" />
|
||||
<Compile Include="Events\PlayerStatesRequestEvent.cs" />
|
||||
<Compile Include="Animation\PlayerSuitEvent.cs" />
|
||||
|
@ -1,11 +1,15 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper.Events;
|
||||
using QSB.Animation;
|
||||
using QSB.DeathSync;
|
||||
using QSB.ElevatorSync;
|
||||
using QSB.Events;
|
||||
using QSB.GeyserSync;
|
||||
using QSB.OrbSync;
|
||||
using QSB.TimeSync;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -16,6 +20,7 @@ namespace QSB
|
||||
public class QSBNetworkManager : NetworkManager
|
||||
{
|
||||
private const int MaxConnections = 128;
|
||||
private const int MaxBufferedPackets = 64;
|
||||
|
||||
public static QSBNetworkManager Instance { get; private set; }
|
||||
|
||||
@ -27,6 +32,7 @@ namespace QSB
|
||||
private GameObject _shipPrefab;
|
||||
private GameObject _cameraPrefab;
|
||||
private GameObject _probePrefab;
|
||||
public GameObject OrbPrefab;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@ -56,7 +62,21 @@ namespace QSB
|
||||
spawnPrefabs.Add(_probePrefab);
|
||||
DebugLog.LogState("ProbePrefab", _probePrefab);
|
||||
|
||||
OrbPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkorb.prefab");
|
||||
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
|
||||
spawnPrefabs.Add(OrbPrefab);
|
||||
DebugLog.LogState("OrbPrefab", OrbPrefab);
|
||||
|
||||
ConfigureNetworkManager();
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool inUniverse)
|
||||
{
|
||||
if (inUniverse)
|
||||
{
|
||||
OrbManager.Instance.BuildOrbs();
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureNetworkManager()
|
||||
@ -67,8 +87,20 @@ namespace QSB
|
||||
customConfig = true;
|
||||
connectionConfig.AddChannel(QosType.Reliable);
|
||||
connectionConfig.AddChannel(QosType.Unreliable);
|
||||
this.SetValue("m_MaxBufferedPackets", MaxBufferedPackets);
|
||||
channels.Add(QosType.Reliable);
|
||||
channels.Add(QosType.Unreliable);
|
||||
|
||||
gameObject.AddComponent<Events.PlayerState>();
|
||||
}
|
||||
|
||||
public override void OnStartServer()
|
||||
{
|
||||
DebugLog.DebugWrite("~~ ON START SERVER ~~", MessageType.Info);
|
||||
if (WorldRegistry.OrbSyncList.Count == 0 && QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
QSB.Helper.Events.Unity.RunWhen(() => NetworkServer.active, OrbManager.Instance.BuildOrbs);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnServerAddPlayer(NetworkConnection connection, short playerControllerId) // Called on the server when a client joins
|
||||
@ -80,8 +112,6 @@ namespace QSB
|
||||
NetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
|
||||
NetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
|
||||
NetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
|
||||
|
||||
gameObject.AddComponent<Events.PlayerState>();
|
||||
}
|
||||
|
||||
public override void OnClientConnect(NetworkConnection connection) // Called on the client when connecting to a server
|
||||
@ -92,13 +122,17 @@ namespace QSB
|
||||
gameObject.AddComponent<RespawnOnDeath>();
|
||||
gameObject.AddComponent<PreventShipDestruction>();
|
||||
|
||||
QSBSectorManager.Instance.RebuildSectors();
|
||||
OrbManager.Instance.QueueBuildSlots();
|
||||
|
||||
if (NetworkClient.active && !NetworkServer.active)
|
||||
{
|
||||
gameObject.AddComponent<Events.PlayerState>();
|
||||
GeyserManager.Instance.EmptyUpdate();
|
||||
WakeUpPatches.AddPatches();
|
||||
}
|
||||
|
||||
OrbPatches.AddPatches();
|
||||
|
||||
_lobby.CanEditName = false;
|
||||
|
||||
OnNetworkManagerReady?.Invoke();
|
||||
@ -111,7 +145,6 @@ namespace QSB
|
||||
|
||||
QSB.Helper.Events.Unity.RunWhen(() => EventList.Ready,
|
||||
() => GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest));
|
||||
|
||||
}
|
||||
|
||||
public override void OnStopClient() // Called on the client when closing connection
|
||||
@ -127,7 +160,14 @@ namespace QSB
|
||||
{
|
||||
PlayerRegistry.GetPlayerNetIds(player).ForEach(CleanupNetworkBehaviour);
|
||||
}
|
||||
PlayerRegistry.PlayerList.ForEach(x => PlayerRegistry.PlayerList.Remove(x));
|
||||
PlayerRegistry.RemoveAllPlayers();
|
||||
|
||||
WorldRegistry.RemoveObjects<QSBOrbSlot>();
|
||||
WorldRegistry.RemoveObjects<QSBElevator>();
|
||||
WorldRegistry.RemoveObjects<QSBGeyser>();
|
||||
WorldRegistry.RemoveObjects<QSBSector>();
|
||||
DebugLog.DebugWrite("Clearing OrbSyncList...", MessageType.Info);
|
||||
WorldRegistry.OrbSyncList.Clear();
|
||||
|
||||
_lobby.CanEditName = true;
|
||||
}
|
||||
@ -137,6 +177,16 @@ namespace QSB
|
||||
var playerId = connection.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value;
|
||||
var netIds = connection.clientOwnedObjects.Select(x => x.Value).ToArray();
|
||||
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, playerId, netIds);
|
||||
|
||||
foreach (var item in WorldRegistry.OrbSyncList)
|
||||
{
|
||||
var identity = item.GetComponent<NetworkIdentity>();
|
||||
if (identity.clientAuthorityOwner == connection)
|
||||
{
|
||||
identity.RemoveClientAuthority(connection);
|
||||
}
|
||||
}
|
||||
|
||||
PlayerRegistry.GetPlayer(playerId).HudMarker?.Remove();
|
||||
CleanupConnection(connection);
|
||||
}
|
||||
@ -150,6 +200,12 @@ namespace QSB
|
||||
DebugLog.ToConsole("[S] Server stopped!", MessageType.Info);
|
||||
PlayerRegistry.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
||||
NetworkServer.connections.ToList().ForEach(CleanupConnection);
|
||||
|
||||
WorldRegistry.RemoveObjects<QSBOrbSlot>();
|
||||
WorldRegistry.RemoveObjects<QSBElevator>();
|
||||
WorldRegistry.RemoveObjects<QSBGeyser>();
|
||||
WorldRegistry.RemoveObjects<QSBSector>();
|
||||
|
||||
base.OnStopServer();
|
||||
}
|
||||
|
||||
@ -173,11 +229,8 @@ namespace QSB
|
||||
DebugLog.ToConsole($"{playerName} disconnected.", MessageType.Info);
|
||||
PlayerRegistry.RemovePlayer(playerId);
|
||||
|
||||
if (playerId != PlayerRegistry.LocalPlayerId) // We don't want to delete the local player!
|
||||
{
|
||||
var netIds = connection.clientOwnedObjects?.Select(x => x.Value).ToList();
|
||||
netIds.ForEach(CleanupNetworkBehaviour);
|
||||
}
|
||||
var netIds = connection.clientOwnedObjects?.Select(x => x.Value).ToList();
|
||||
netIds.ForEach(CleanupNetworkBehaviour);
|
||||
}
|
||||
|
||||
public void CleanupNetworkBehaviour(uint netId)
|
||||
@ -192,15 +245,26 @@ namespace QSB
|
||||
|
||||
if (transformSync != null)
|
||||
{
|
||||
DebugLog.DebugWrite($" * Removing TransformSync from syncobjects");
|
||||
PlayerRegistry.PlayerSyncObjects.Remove(transformSync);
|
||||
if (transformSync.SyncedTransform != null && netId != PlayerRegistry.LocalPlayerId && !networkBehaviour.hasAuthority)
|
||||
{
|
||||
DebugLog.DebugWrite($" * Destroying {transformSync.SyncedTransform.gameObject.name}");
|
||||
Destroy(transformSync.SyncedTransform.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
var animationSync = networkBehaviour.GetComponent<AnimationSync>();
|
||||
|
||||
if (animationSync != null)
|
||||
{
|
||||
DebugLog.DebugWrite($" * Removing AnimationSync from syncobjects");
|
||||
PlayerRegistry.PlayerSyncObjects.Remove(animationSync);
|
||||
}
|
||||
|
||||
if (!networkBehaviour.hasAuthority)
|
||||
{
|
||||
DebugLog.DebugWrite($" * Destroying {networkBehaviour.gameObject.name}");
|
||||
Destroy(networkBehaviour.gameObject);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,15 @@ namespace QSB.TimeSync
|
||||
}
|
||||
|
||||
GlobalMessenger.AddListener(EventNames.RestartTimeLoop, OnLoopStart);
|
||||
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
|
||||
}
|
||||
|
||||
private void OnWakeUp()
|
||||
{
|
||||
if (NetworkServer.active)
|
||||
{
|
||||
QSB.HasWokenUp = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@ -59,6 +68,7 @@ namespace QSB.TimeSync
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
|
||||
{
|
||||
QSB.HasWokenUp = false;
|
||||
if (isInUniverse)
|
||||
{
|
||||
Init();
|
||||
@ -165,6 +175,7 @@ namespace QSB.TimeSync
|
||||
EnableInput();
|
||||
}
|
||||
_isFirstFastForward = false;
|
||||
QSB.HasWokenUp = true;
|
||||
Physics.SyncTransforms();
|
||||
SpinnerUI.Hide();
|
||||
DebugLog.DebugWrite("ResetTimeScale - Request state!");
|
||||
|
@ -7,7 +7,6 @@ namespace QSB.Tools
|
||||
{
|
||||
public class PlayerToolsManager
|
||||
{
|
||||
private static Transform _cameraBody;
|
||||
private static Transform _toolStowTransform;
|
||||
private static Transform _toolHoldTransform;
|
||||
private static Material _playerToolsMaterial;
|
||||
@ -20,16 +19,15 @@ namespace QSB.Tools
|
||||
|
||||
public static void Init(Transform camera)
|
||||
{
|
||||
_cameraBody = camera;
|
||||
CreateStowTransforms();
|
||||
CreateStowTransforms(camera);
|
||||
|
||||
_playerToolsMaterial = GameObject.Find("PlayerSuit_Jetpack").GetComponent<MeshRenderer>().materials[0];
|
||||
_lightbulbMaterial = GameObject.Find("Props_HEA_Lantern (10)/Lantern_Lamp").GetComponent<MeshRenderer>().materials[0];
|
||||
|
||||
CreateFlashlight();
|
||||
CreateSignalscope();
|
||||
CreateProbeLauncher();
|
||||
CreateTranslator();
|
||||
CreateFlashlight(camera);
|
||||
CreateSignalscope(camera);
|
||||
CreateProbeLauncher(camera);
|
||||
CreateTranslator(camera);
|
||||
}
|
||||
|
||||
public static void CreateProbe(Transform body, PlayerInfo player)
|
||||
@ -38,22 +36,22 @@ namespace QSB.Tools
|
||||
player.Probe = newProbe;
|
||||
}
|
||||
|
||||
private static void CreateStowTransforms()
|
||||
private static void CreateStowTransforms(Transform cameraBody)
|
||||
{
|
||||
var stow = new GameObject("ToolStowTransform");
|
||||
_toolStowTransform = stow.transform;
|
||||
stow.transform.parent = _cameraBody;
|
||||
stow.transform.parent = cameraBody;
|
||||
stow.transform.localPosition = Vector3.zero;
|
||||
stow.transform.localRotation = Quaternion.Euler(45f, 0f, 0f);
|
||||
|
||||
var hold = new GameObject("ToolHoldTransform");
|
||||
_toolHoldTransform = hold.transform;
|
||||
hold.transform.parent = _cameraBody;
|
||||
hold.transform.parent = cameraBody;
|
||||
hold.transform.localPosition = Vector3.zero;
|
||||
hold.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
|
||||
}
|
||||
|
||||
private static void CreateFlashlight()
|
||||
private static GameObject CreateFlashlight(Transform cameraBody)
|
||||
{
|
||||
var flashlightRoot = Object.Instantiate(GameObject.Find("FlashlightRoot"));
|
||||
flashlightRoot.SetActive(false);
|
||||
@ -63,12 +61,14 @@ namespace QSB.Tools
|
||||
component.Init(oldComponent);
|
||||
oldComponent.enabled = false;
|
||||
|
||||
flashlightRoot.transform.parent = _cameraBody;
|
||||
flashlightRoot.transform.parent = cameraBody;
|
||||
flashlightRoot.transform.localPosition = FlashlightOffset;
|
||||
flashlightRoot.SetActive(true);
|
||||
|
||||
return flashlightRoot;
|
||||
}
|
||||
|
||||
private static void CreateSignalscope()
|
||||
private static GameObject CreateSignalscope(Transform cameraBody)
|
||||
{
|
||||
var signalscopeRoot = Object.Instantiate(GameObject.Find("Signalscope"));
|
||||
signalscopeRoot.SetActive(false);
|
||||
@ -89,13 +89,15 @@ namespace QSB.Tools
|
||||
|
||||
GetRenderer(signalscopeRoot, "Props_HEA_Signalscope").material = _playerToolsMaterial;
|
||||
|
||||
signalscopeRoot.transform.parent = _cameraBody;
|
||||
signalscopeRoot.transform.parent = cameraBody;
|
||||
signalscopeRoot.transform.localPosition = Vector3.zero;
|
||||
signalscopeRoot.transform.localScale = SignalscopeScale;
|
||||
signalscopeRoot.SetActive(true);
|
||||
|
||||
return signalscopeRoot;
|
||||
}
|
||||
|
||||
private static void CreateTranslator()
|
||||
private static GameObject CreateTranslator(Transform cameraBody)
|
||||
{
|
||||
var original = GameObject.Find("NomaiTranslatorProp");
|
||||
|
||||
@ -128,13 +130,15 @@ namespace QSB.Tools
|
||||
GetRenderer(translatorRoot, "Props_HEA_Translator_Button_L").material = _lightbulbMaterial;
|
||||
GetRenderer(translatorRoot, "Props_HEA_Translator_Button_R").material = _lightbulbMaterial;
|
||||
|
||||
translatorRoot.transform.parent = _cameraBody;
|
||||
translatorRoot.transform.parent = cameraBody;
|
||||
translatorRoot.transform.localPosition = Vector3.zero;
|
||||
translatorRoot.transform.localScale = TranslatorScale;
|
||||
QSB.Helper.Events.Unity.FireOnNextUpdate(() => translatorRoot.SetActive(true));
|
||||
|
||||
return translatorRoot;
|
||||
}
|
||||
|
||||
private static void CreateProbeLauncher()
|
||||
private static GameObject CreateProbeLauncher(Transform cameraBody)
|
||||
{
|
||||
var launcherRoot = new GameObject("ProbeLauncher");
|
||||
var modelOrig = GameObject.Find("PlayerCamera/ProbeLauncher/Props_HEA_ProbeLauncher");
|
||||
@ -167,9 +171,11 @@ namespace QSB.Tools
|
||||
GetRenderer(launcherRoot, "PressureGauge_Arrow").material = _playerToolsMaterial;
|
||||
GetRenderer(launcherRoot, "ProbeLauncherChassis").material = _playerToolsMaterial;
|
||||
|
||||
launcherRoot.transform.parent = _cameraBody;
|
||||
launcherRoot.transform.parent = cameraBody;
|
||||
launcherRoot.transform.localPosition = ProbeLauncherOffset;
|
||||
launcherRoot.SetActive(true);
|
||||
|
||||
return launcherRoot;
|
||||
}
|
||||
|
||||
private static MeshRenderer GetRenderer(GameObject root, string gameObjectName)
|
||||
|
96
QSB/TransformSync/NomaiOrbTransformSync.cs
Normal file
96
QSB/TransformSync/NomaiOrbTransformSync.cs
Normal file
@ -0,0 +1,96 @@
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB.TransformSync
|
||||
{
|
||||
public class NomaiOrbTransformSync : NetworkBehaviour
|
||||
{
|
||||
public NomaiInterfaceOrb AttachedOrb { get; private set; }
|
||||
public Transform OrbTransform { get; private set; }
|
||||
|
||||
private int Index => WorldRegistry.OrbSyncList.IndexOf(this);
|
||||
|
||||
private const int MaxUpdatesBeforeDisable = 5;
|
||||
|
||||
private bool _isInitialized;
|
||||
private bool _isReady;
|
||||
private Transform _orbParent;
|
||||
private int _updateCount;
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
WorldRegistry.OrbSyncList.Add(this);
|
||||
|
||||
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, () => QSB.Helper.Events.Unity.FireOnNextUpdate(OnReady));
|
||||
}
|
||||
|
||||
private void OnReady()
|
||||
{
|
||||
AttachedOrb = WorldRegistry.OldOrbList[Index];
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
DontDestroyOnLoad(this);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
WorldRegistry.OrbSyncList.Remove(this);
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse) => _isInitialized = false;
|
||||
|
||||
protected void Init()
|
||||
{
|
||||
OrbTransform = AttachedOrb.transform;
|
||||
_orbParent = AttachedOrb.GetAttachedOWRigidbody().GetOrigParent();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isInitialized && _isReady)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else if (_isInitialized && !_isReady)
|
||||
{
|
||||
_isInitialized = false;
|
||||
}
|
||||
|
||||
if (OrbTransform == null || !_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
protected virtual void UpdateTransform()
|
||||
{
|
||||
if (hasAuthority)
|
||||
{
|
||||
transform.position = _orbParent.InverseTransformPoint(OrbTransform.position);
|
||||
transform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
|
||||
return;
|
||||
}
|
||||
OrbTransform.position = _orbParent.TransformPoint(transform.position);
|
||||
OrbTransform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
|
||||
|
||||
if (transform.localPosition == Vector3.zero)
|
||||
{
|
||||
_updateCount++;
|
||||
}
|
||||
if (_updateCount >= MaxUpdatesBeforeDisable)
|
||||
{
|
||||
enabled = false;
|
||||
_updateCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ namespace QSB.TransformSync
|
||||
{
|
||||
var body = GetProbe();
|
||||
|
||||
_disabledSocket = Player.Camera.transform;
|
||||
SetSocket(Player.Camera.transform);
|
||||
Player.ProbeBody = body.gameObject;
|
||||
|
||||
return body;
|
||||
@ -48,16 +48,37 @@ namespace QSB.TransformSync
|
||||
|
||||
PlayerToolsManager.CreateProbe(body, Player);
|
||||
|
||||
_disabledSocket = Player.ProbeLauncher.ToolGameObject.transform;
|
||||
QSB.Helper.Events.Unity.RunWhen(() => (Player.ProbeLauncher != null), () => SetSocket(Player.ProbeLauncher.ToolGameObject.transform));
|
||||
Player.ProbeBody = body.gameObject;
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
private void SetSocket(Transform socket)
|
||||
{
|
||||
DebugLog.DebugWrite($"Setting DisabledSocket for {AttachedNetId} to {socket.name}");
|
||||
_disabledSocket = socket;
|
||||
}
|
||||
|
||||
protected override void UpdateTransform()
|
||||
{
|
||||
base.UpdateTransform();
|
||||
if (Player.GetState(State.ProbeActive) || ReferenceSector.Sector == null)
|
||||
if (Player == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Player is null for {AttachedNetId}!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (ReferenceSector == null)
|
||||
{
|
||||
DebugLog.ToConsole($"ReferenceSector is null for {AttachedNetId}!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (_disabledSocket == null)
|
||||
{
|
||||
DebugLog.ToConsole($"DisabledSocket is null for {AttachedNetId}! (ProbeLauncher null? : {Player.ProbeLauncher == null})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (Player.GetState(State.ProbeActive) || ReferenceSector?.Sector == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ namespace QSB.TransformSync
|
||||
|
||||
var transformSync = PlayerRegistry.GetSyncObject<TransformSync>(message.AboutId);
|
||||
|
||||
QSB.Helper.Events.Unity.RunWhen(() => transformSync.SyncedTransform != null,
|
||||
() => transformSync.SetReferenceSector(sector));
|
||||
QSB.Helper.Events.Unity.RunWhen(() => transformSync?.SyncedTransform != null,
|
||||
() => transformSync?.SetReferenceSector(sector));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,11 +18,12 @@ namespace QSB.TransformSync
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
QSBSceneManager.OnSceneLoaded += (OWScene scene, bool universe) => RebuildSectors();
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
|
||||
public void RebuildSectors()
|
||||
{
|
||||
WorldRegistry.RemoveObjects<QSBSector>();
|
||||
var sectors = Resources.FindObjectsOfTypeAll<Sector>().ToList();
|
||||
for (var id = 0; id < sectors.Count; id++)
|
||||
{
|
||||
|
@ -64,7 +64,7 @@ namespace QSB.TransformSync
|
||||
|
||||
if (SyncedTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"SyncedTransform {AttachedNetId} ({Player.PlayerId}.{GetType().Name}) is null!");
|
||||
DebugLog.ToConsole($"Warning - SyncedTransform {AttachedNetId} ({Player.PlayerId}.{GetType().Name}) is null.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ namespace QSB.TransformSync
|
||||
{
|
||||
if (ReferenceSector.Sector == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Sector is null for referencesector for {AttachedNetId} ({Player.PlayerId}.{GetType().Name})!", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - Sector is null for referencesector for {AttachedNetId}. ({Player.PlayerId}.{GetType().Name})", MessageType.Error);
|
||||
}
|
||||
transform.position = ReferenceSector.Transform.InverseTransformPoint(SyncedTransform.position);
|
||||
transform.rotation = ReferenceSector.Transform.InverseTransformRotation(SyncedTransform.rotation);
|
||||
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OWML.Logging;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.Utility
|
||||
@ -9,7 +9,12 @@ namespace QSB.Utility
|
||||
{
|
||||
public static void ToConsole(string message, MessageType type = MessageType.Message)
|
||||
{
|
||||
QSB.Helper.Console.WriteLine(message, type);
|
||||
var console = (ModSocketOutput)QSB.Helper.Console;
|
||||
var method = console.GetType()
|
||||
.GetMethods(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
||||
.Last(x => x.Name == "WriteLine");
|
||||
var callingType = GetCallingType(new StackTrace());
|
||||
method.Invoke(console, new object[] { type, message, callingType });
|
||||
}
|
||||
|
||||
public static void ToHud(string message)
|
||||
@ -36,30 +41,20 @@ namespace QSB.Utility
|
||||
}
|
||||
}
|
||||
|
||||
public static string GenerateTable(List<string> columnsData, List<string> rowData)
|
||||
{
|
||||
var longestKey = columnsData.OrderByDescending(s => s.Length).First();
|
||||
var longestValue = rowData.OrderByDescending(s => s.Length).First();
|
||||
var longestObject = (longestKey.Length > longestValue.Length) ? longestKey : longestValue;
|
||||
var columns = "|";
|
||||
var data = "|";
|
||||
foreach (var item in columnsData)
|
||||
{
|
||||
columns += $" {item.PadRight(longestObject.Length)} |";
|
||||
}
|
||||
foreach (var item in rowData)
|
||||
{
|
||||
data += $" {item.PadRight(longestObject.Length)} |";
|
||||
}
|
||||
return columns + Environment.NewLine + data;
|
||||
}
|
||||
|
||||
public static void LogState(string name, bool state)
|
||||
{
|
||||
var status = state ? "OK" : "FAIL";
|
||||
var messageType = state ? MessageType.Success : MessageType.Error;
|
||||
DebugWrite($"* {name} {status}", messageType);
|
||||
if (!state) // to stop "OK" spam
|
||||
{
|
||||
DebugWrite($"* {name} {status}", messageType);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetCallingType(StackTrace frame)
|
||||
{
|
||||
var stackFrame = frame.GetFrames().First(x => x.GetMethod().DeclaringType.Name != "DebugLog");
|
||||
return stackFrame.GetMethod().DeclaringType.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Utility
|
||||
namespace QSB.Utility
|
||||
{
|
||||
// Stolen from here : https://stackoverflow.com/questions/3261451/using-a-bitmask-in-c-sharp
|
||||
|
||||
@ -28,15 +25,7 @@ namespace QSB.Utility
|
||||
var flagsValue = (int)(object)flags;
|
||||
var flagValue = (int)(object)flag;
|
||||
|
||||
flags = (T)(object)(flagsValue & (~flagValue));
|
||||
}
|
||||
|
||||
public static List<string> FlagsToListSet<T>(T flags) where T : struct
|
||||
{
|
||||
var temp = new List<string>();
|
||||
var array = (T[])Enum.GetValues(flags.GetType());
|
||||
Array.ForEach(array, x => temp.Add(Convert.ToString(IsSet(flags, x) ? 1 : 0)));
|
||||
return temp;
|
||||
flags = (T)(object)(flagsValue & ~flagValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
using OWML.Common;
|
||||
using QSB.OrbSync;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace QSB.WorldSync
|
||||
{
|
||||
public static class WorldRegistry
|
||||
{
|
||||
private static readonly List<WorldObject> _worldObjects = new List<WorldObject>();
|
||||
private static readonly List<WorldObject> WorldObjects = new List<WorldObject>();
|
||||
public static List<NomaiOrbTransformSync> OrbSyncList = new List<NomaiOrbTransformSync>();
|
||||
public static List<NomaiInterfaceOrb> OldOrbList = new List<NomaiInterfaceOrb>();
|
||||
|
||||
public static void AddObject(WorldObject worldObject)
|
||||
{
|
||||
if (_worldObjects.Contains(worldObject))
|
||||
if (WorldObjects.Contains(worldObject))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_worldObjects.Add(worldObject);
|
||||
WorldObjects.Add(worldObject);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetObjects<T>()
|
||||
{
|
||||
return _worldObjects.OfType<T>();
|
||||
return WorldObjects.OfType<T>();
|
||||
}
|
||||
|
||||
public static T GetObject<T>(int id) where T : WorldObject
|
||||
{
|
||||
return GetObjects<T>().FirstOrDefault(x => x.ObjectId == id);
|
||||
}
|
||||
|
||||
public static void RemoveObjects<T>() where T : WorldObject
|
||||
{
|
||||
WorldObjects.RemoveAll(x => x.GetType() == typeof(T));
|
||||
}
|
||||
|
||||
public static void HandleSlotStateChange(NomaiInterfaceSlot slot, NomaiInterfaceOrb affectingOrb, bool state)
|
||||
{
|
||||
var slotList = GetObjects<QSBOrbSlot>();
|
||||
if (slotList.Count() == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No QSBOrbSlots found when handling slot state change.", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
var qsbSlot = slotList.First(x => x.InterfaceSlot == slot);
|
||||
var orbSync = OrbSyncList.First(x => x.AttachedOrb == affectingOrb);
|
||||
if (orbSync.hasAuthority)
|
||||
{
|
||||
qsbSlot.HandleEvent(state);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RaiseEvent(object instance, string eventName)
|
||||
{
|
||||
if (!(instance.GetType()
|
||||
.GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic)?
|
||||
.GetValue(instance) is MulticastDelegate multiDelegate))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var delegateList = multiDelegate.GetInvocationList().ToList();
|
||||
delegateList.ForEach(x => x.DynamicInvoke(instance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
"settings": {
|
||||
"defaultServerIP": "localhost",
|
||||
"port": 7777,
|
||||
"debugMode": true
|
||||
"debugMode": false
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"filename": "QSB.dll",
|
||||
"author": "Raicuparta, AmazingAlek & misternebula",
|
||||
"author": "Nebula, Alek & Rai",
|
||||
"name": "Quantum Space Buddies",
|
||||
"description": "Adds online multiplayer to the game.",
|
||||
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
|
||||
|
@ -61,8 +61,7 @@ MonoBehaviour:
|
||||
m_ScriptCRCCheck: 1
|
||||
m_MaxDelay: 0.01
|
||||
m_LogLevel: 2
|
||||
m_PlayerPrefab: {fileID: 1211347487444314, guid: 163f71f5a4ce8e543bbf5632a3585dc7,
|
||||
type: 2}
|
||||
m_PlayerPrefab: {fileID: 0}
|
||||
m_AutoCreatePlayer: 1
|
||||
m_PlayerSpawnMethod: 0
|
||||
m_OfflineScene:
|
||||
|
96
UnityProject/Assets/NetworkOrb.prefab
Normal file
96
UnityProject/Assets/NetworkOrb.prefab
Normal file
@ -0,0 +1,96 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1252242529042024}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1252242529042024
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4745039063230268}
|
||||
- component: {fileID: 114872848302743272}
|
||||
- component: {fileID: 114240702864939342}
|
||||
m_Layer: 0
|
||||
m_Name: NetworkOrb
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4745039063230268
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1252242529042024}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &114240702864939342
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1252242529042024}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -1768714887, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_TransformSyncMode: 1
|
||||
m_SendInterval: 0.09090909
|
||||
m_SyncRotationAxis: 0
|
||||
m_RotationSyncCompression: 0
|
||||
m_SyncSpin: 0
|
||||
m_MovementTheshold: 0.001
|
||||
m_VelocityThreshold: 0.0001
|
||||
m_SnapThreshold: 5
|
||||
m_InterpolateRotation: 1
|
||||
m_InterpolateMovement: 1
|
||||
--- !u!114 &114872848302743272
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1252242529042024}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 372142912, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_SceneId:
|
||||
m_Value: 0
|
||||
m_AssetId:
|
||||
i0: 16
|
||||
i1: 54
|
||||
i2: 85
|
||||
i3: 231
|
||||
i4: 191
|
||||
i5: 68
|
||||
i6: 98
|
||||
i7: 228
|
||||
i8: 25
|
||||
i9: 191
|
||||
i10: 115
|
||||
i11: 12
|
||||
i12: 196
|
||||
i13: 32
|
||||
i14: 194
|
||||
i15: 197
|
||||
m_ServerOnly: 0
|
||||
m_LocalPlayerAuthority: 1
|
8
UnityProject/Assets/NetworkOrb.prefab.meta
Normal file
8
UnityProject/Assets/NetworkOrb.prefab.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 103655e7bf4462e419bf730cc420c2c5
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName: network
|
||||
assetBundleVariant:
|
@ -53,7 +53,7 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_TransformSyncMode: 1
|
||||
m_SendInterval: 0.09090909
|
||||
m_SendInterval: 0.083333336
|
||||
m_SyncRotationAxis: 7
|
||||
m_RotationSyncCompression: 0
|
||||
m_SyncSpin: 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user