mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-05 06:39:50 +00:00
AAA
This commit is contained in:
parent
ec724f7353
commit
3523f3b806
11
QSB/Animation/Character/CharacterAnimManager.cs
Normal file
11
QSB/Animation/Character/CharacterAnimManager.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.Animation.Character
|
||||
{
|
||||
internal class CharacterAnimManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
=> QSBWorldSync.Init<QSBCharacterAnimController, CharacterAnimController>();
|
||||
}
|
||||
}
|
112
QSB/Animation/Character/Patches/CharacterAnimationPatches.cs
Normal file
112
QSB/Animation/Character/Patches/CharacterAnimationPatches.cs
Normal file
@ -0,0 +1,112 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
public class CharacterAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnAnimatorIK", typeof(CharacterAnimationPatches), nameof(AnimController_OnAnimatorIK));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneEntry", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneEntry));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneExit", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneExit));
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnAnimatorIK");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneExit");
|
||||
}
|
||||
|
||||
public static bool AnimController_OnAnimatorIK(
|
||||
CharacterAnimController __instance,
|
||||
float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
DampedSpring3D ___lookSpring,
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // TODO : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
Vector3 position;
|
||||
if (____inConversation)
|
||||
{
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - {__instance.name} is in conversation with a null player! Defaulting to active camera.", MessageType.Error);
|
||||
position = Locator.GetActiveCamera().transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
position = player.CameraBody == null
|
||||
? Locator.GetActiveCamera().transform.position
|
||||
: player.CameraBody.transform.position;
|
||||
}
|
||||
}
|
||||
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0)
|
||||
{
|
||||
position = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position).CameraBody.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
position = QSBPlayerManager.GetClosestPlayerToWorldPoint(__instance.transform.position, true).CameraBody.transform.position;
|
||||
}
|
||||
|
||||
var localPosition = ____animator.transform.InverseTransformPoint(position);
|
||||
|
||||
var targetWeight = ___headTrackingWeight;
|
||||
if (___lookOnlyWhenTalking)
|
||||
{
|
||||
if (!____inConversation || qsbObj.GetPlayersInHeadZone().Count == 0)
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (qsbObj.GetPlayersInHeadZone().Count == 0)
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
|
||||
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
|
||||
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
|
||||
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
|
||||
____animator.SetLookAtWeight(____currentLookWeight);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneExit(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneEntry(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.Character.WorldObjects
|
||||
{
|
||||
class QSBCharacterAnimController : WorldObject<CharacterAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new List<PlayerInfo>();
|
||||
|
||||
public override void Init(CharacterAnimController controller, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = controller;
|
||||
}
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
|
||||
public void StartConversation()
|
||||
{
|
||||
AttachedObject.SetValue("_inConversation", true);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnStartConversation");
|
||||
}
|
||||
|
||||
public void EndConversation()
|
||||
{
|
||||
AttachedObject.SetValue("_inConversation", false);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnEndConversation");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using OWML.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public static class AnimControllerPatch
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class AnimFloatParam
|
||||
{
|
@ -7,7 +7,7 @@ using QuantumUNET.Components;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class AnimationSync : PlayerSyncObject
|
||||
{
|
||||
@ -32,6 +32,7 @@ namespace QSB.Animation
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
DebugLog.DebugWrite($"Awake AnimationSync {PlayerId}");
|
||||
InvisibleAnimator = gameObject.AddComponent<Animator>();
|
||||
NetworkAnimator = gameObject.AddComponent<QNetworkAnimator>();
|
||||
NetworkAnimator.enabled = false;
|
||||
@ -42,6 +43,7 @@ namespace QSB.Animation
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
DebugLog.DebugWrite($"OnDestroy AnimationSync {PlayerId}");
|
||||
base.OnDestroy();
|
||||
Destroy(InvisibleAnimator);
|
||||
Destroy(NetworkAnimator);
|
@ -1,4 +1,4 @@
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public enum AnimationType
|
||||
{
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class AnimatorMirror : MonoBehaviour
|
||||
{
|
@ -1,8 +1,9 @@
|
||||
using QuantumUNET;
|
||||
using QSB.Animation.Player;
|
||||
using QuantumUNET;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class CrouchSync : QNetworkBehaviour
|
||||
{
|
@ -1,8 +1,9 @@
|
||||
using QSB.Events;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
class AnimationTriggerEvent : QSBEvent<AnimationTriggerMessage>
|
||||
{
|
@ -1,7 +1,7 @@
|
||||
using QSB.Messaging;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class AnimationTriggerMessage : PlayerMessage
|
||||
{
|
@ -1,9 +1,10 @@
|
||||
using QSB.Events;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class ChangeAnimTypeEvent : QSBEvent<EnumMessage<AnimationType>>
|
||||
{
|
@ -1,8 +1,9 @@
|
||||
using QSB.Events;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class CrouchEvent : QSBEvent<FloatMessage>
|
||||
{
|
@ -1,8 +1,9 @@
|
||||
using QSB.Events;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class PlayerSuitEvent : QSBEvent<ToggleMessage>
|
||||
{
|
@ -7,11 +7,11 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.Patches
|
||||
{
|
||||
class AnimationPatches : QSBPatch
|
||||
class PlayerAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches() => QSBCore.HarmonyHelper.AddPrefix<PlayerAnimController>("LateUpdate", typeof(AnimationPatches), nameof(PlayerAnimController_LateUpdate));
|
||||
public override void DoPatches() => QSBCore.HarmonyHelper.AddPrefix<PlayerAnimController>("LateUpdate", typeof(PlayerAnimationPatches), nameof(PlayerAnimController_LateUpdate));
|
||||
public override void DoUnpatches() => QSBCore.HarmonyHelper.Unpatch<PlayerAnimController>("LateUpdate");
|
||||
|
||||
public static bool PlayerAnimController_LateUpdate(
|
@ -2,7 +2,7 @@
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class PlayerHeadRotationSync : MonoBehaviour
|
||||
{
|
@ -1,5 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
@ -64,12 +65,8 @@ namespace QSB.ConversationSync.Events
|
||||
CharacterDialogueTree tree)
|
||||
{
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueID = characterId;
|
||||
controller.SetValue("_inConversation", true);
|
||||
controller.SetValue("_playerInHeadZone", true);
|
||||
if (controller.GetValue<bool>("_hasTalkAnimation"))
|
||||
{
|
||||
controller.GetValue<Animator>("_animator").SetTrigger("Talking");
|
||||
}
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(controller);
|
||||
qsbObj.StartConversation();
|
||||
tree.GetInteractVolume().DisableInteraction();
|
||||
}
|
||||
|
||||
@ -79,12 +76,8 @@ namespace QSB.ConversationSync.Events
|
||||
CharacterDialogueTree tree)
|
||||
{
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueID = -1;
|
||||
controller.SetValue("_inConversation", false);
|
||||
controller.SetValue("_playerInHeadZone", false);
|
||||
if (controller.GetValue<bool>("_hasTalkAnimation"))
|
||||
{
|
||||
controller.GetValue<Animator>("_animator").SetTrigger("Idle");
|
||||
}
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(controller);
|
||||
qsbObj.EndConversation();
|
||||
tree.GetInteractVolume().EnableInteraction();
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ namespace QSB.ConversationSync.Patches
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("InputDialogueOption", typeof(ConversationPatches), nameof(Tree_InputDialogueOption));
|
||||
QSBCore.HarmonyHelper.AddPostfix<CharacterDialogueTree>("StartConversation", typeof(ConversationPatches), nameof(Tree_StartConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("EndConversation", typeof(ConversationPatches), nameof(Tree_EndConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnAnimatorIK", typeof(ConversationPatches), nameof(AnimController_OnAnimatorIK));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneExit", typeof(ConversationPatches), nameof(AnimController_OnZoneExit));
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
@ -28,8 +26,6 @@ namespace QSB.ConversationSync.Patches
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("InputDialogueOption");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("StartConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("EndConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnAnimatorIK");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneExit");
|
||||
}
|
||||
|
||||
public static void Tree_StartConversation(CharacterDialogueTree __instance)
|
||||
@ -82,45 +78,5 @@ namespace QSB.ConversationSync.Patches
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.LocalPlayer.CurrentDialogueID != -1,
|
||||
() => ConversationManager.Instance.SendCharacterDialogue(QSBPlayerManager.LocalPlayer.CurrentDialogueID, key));
|
||||
}
|
||||
|
||||
public static bool AnimController_OnAnimatorIK(float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
DampedSpring3D ___lookSpring,
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
Vector3 position;
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
position = Locator.GetActiveCamera().transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
position = player.CameraBody == null
|
||||
? Locator.GetActiveCamera().transform.position
|
||||
: player.CameraBody.transform.position;
|
||||
}
|
||||
var localPosition = ____animator.transform.InverseTransformPoint(position);
|
||||
var targetWeight = ___headTrackingWeight * Mathf.Min(1, !___lookOnlyWhenTalking
|
||||
? !____playerInHeadZone ? 0 : 1
|
||||
: !____inConversation || !____playerInHeadZone ? 0 : 1);
|
||||
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
|
||||
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
|
||||
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
|
||||
____animator.SetLookAtWeight(____currentLookWeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneExit(CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
return playerId == uint.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
@ -61,5 +61,7 @@
|
||||
public static string QSBCampfireState = "QSBCampfireState";
|
||||
public static string QSBMarshmallowEvent = "QSBMarshmallowEvent";
|
||||
public static string QSBAnimTrigger = "QSBAnimTrigger";
|
||||
public static string QSBEnterHeadZone = "QSBEnterHeadZone";
|
||||
public static string QSBExitHeadZone = "QSBExitHeadZone";
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
using QSB.CampfireSync.Events;
|
||||
using QSB.ConversationSync.Events;
|
||||
using QSB.DeathSync.Events;
|
||||
|
@ -1,5 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments.QSBCamera;
|
||||
using QSB.Player;
|
||||
|
@ -35,10 +35,15 @@ namespace QSB.OrbSync.TransformSync
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
public void OnDestroy() => QSBWorldSync.OrbSyncList.Remove(this);
|
||||
public void OnDestroy()
|
||||
{
|
||||
DebugLog.DebugWrite($"OnDestroy - parented to {gameObject.transform.parent.name}");
|
||||
QSBWorldSync.OrbSyncList.Remove(this);
|
||||
}
|
||||
|
||||
protected void Init()
|
||||
{
|
||||
DebugLog.DebugWrite($"Init");
|
||||
OrbTransform = AttachedOrb.transform;
|
||||
_orbParent = AttachedOrb.GetAttachedOWRigidbody().GetOrigParent();
|
||||
_isInitialized = true;
|
||||
|
@ -15,6 +15,7 @@ using QSB.QuantumSync.Patches;
|
||||
using QSB.RoastingSync.Patches;
|
||||
using QSB.StatueSync.Patches;
|
||||
using QSB.TimeSync.Patches;
|
||||
using QSB.TransformSync.Patches;
|
||||
using QSB.TranslationSync.Patches;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
@ -53,7 +54,9 @@ namespace QSB.Patches
|
||||
new CampfirePatches(),
|
||||
new RoastingPatches(),
|
||||
new PlayerPatches(),
|
||||
new AnimationPatches()
|
||||
new PlayerAnimationPatches(),
|
||||
new CharacterAnimationPatches(),
|
||||
new TransformSyncPatches()
|
||||
};
|
||||
|
||||
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
|
||||
|
@ -7,6 +7,8 @@
|
||||
EnterShrine = 2,
|
||||
ExitShrine = 3,
|
||||
EnterPlatform = 4,
|
||||
ExitPlatform = 5
|
||||
ExitPlatform = 5,
|
||||
EnterHeadZone = 6,
|
||||
ExitHeadZone = 7
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using QSB.Events;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.PoolSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
@ -17,6 +19,8 @@ namespace QSB.Player.Events
|
||||
GlobalMessenger.AddListener(EventNames.QSBExitShrine, () => Handler(EnterLeaveType.ExitShrine));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBEnterPlatform, (int id) => Handler(EnterLeaveType.EnterPlatform, id));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBExitPlatform, (int id) => Handler(EnterLeaveType.ExitPlatform, id));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBEnterHeadZone, (int id) => Handler(EnterLeaveType.EnterHeadZone, id));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBExitHeadZone, (int id) => Handler(EnterLeaveType.ExitHeadZone, id));
|
||||
}
|
||||
|
||||
public override void CloseListener()
|
||||
@ -64,6 +68,12 @@ namespace QSB.Player.Events
|
||||
CustomNomaiRemoteCameraPlatform.CustomPlatformList[message.ObjectId]
|
||||
.OnRemotePlayerExit(message.AboutId);
|
||||
break;
|
||||
case EnterLeaveType.EnterHeadZone:
|
||||
QSBWorldSync.GetWorldFromId<QSBCharacterAnimController>(message.ObjectId).AddPlayerToHeadZone(player);
|
||||
break;
|
||||
case EnterLeaveType.ExitHeadZone:
|
||||
QSBWorldSync.GetWorldFromId<QSBCharacterAnimController>(message.ObjectId).RemovePlayerFromHeadZone(player);
|
||||
break;
|
||||
default:
|
||||
DebugLog.ToConsole($"Warning - Unknown EnterLeaveType : {message.EnumValue}", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.ProbeSync;
|
||||
|
@ -135,5 +135,22 @@ namespace QSB.Player
|
||||
renderer.enabled = visible;
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(Vector3 worldPoint, bool includeLocalPlayer)
|
||||
{
|
||||
return includeLocalPlayer
|
||||
? GetClosestPlayerToWorldPoint(PlayerList, worldPoint)
|
||||
: GetClosestPlayerToWorldPoint(PlayerList.Where(x => x != LocalPlayer).ToList(), worldPoint);
|
||||
}
|
||||
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(List<PlayerInfo> playerList, Vector3 worldPoint)
|
||||
{
|
||||
if (playerList.Count == 0)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - Cannot get closest player from empty player list.", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
return playerList.Where(x => x.PlayerStates.IsReady).OrderBy(x => Vector3.Distance(x.Body.transform.position, worldPoint)).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Instruments;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Player.TransformSync
|
||||
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
|
@ -102,17 +102,20 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Animation\AnimationSync.cs" />
|
||||
<Compile Include="Animation\AnimationType.cs" />
|
||||
<Compile Include="Animation\Events\AnimationTriggerEvent.cs" />
|
||||
<Compile Include="Animation\Events\AnimationTriggerMessage.cs" />
|
||||
<Compile Include="Animation\Events\CrouchEvent.cs" />
|
||||
<Compile Include="Animation\AnimatorMirror.cs" />
|
||||
<Compile Include="Animation\AnimControllerPatch.cs" />
|
||||
<Compile Include="Animation\AnimFloatParam.cs" />
|
||||
<Compile Include="Animation\CrouchSync.cs" />
|
||||
<Compile Include="Animation\Patches\AnimationPatches.cs" />
|
||||
<Compile Include="Animation\PlayerHeadRotationSync.cs" />
|
||||
<Compile Include="Animation\Character\CharacterAnimManager.cs" />
|
||||
<Compile Include="Animation\Character\Patches\CharacterAnimationPatches.cs" />
|
||||
<Compile Include="Animation\Character\WorldObjects\QSBCharacterAnimController.cs" />
|
||||
<Compile Include="Animation\Player\AnimationSync.cs" />
|
||||
<Compile Include="Animation\Player\AnimationType.cs" />
|
||||
<Compile Include="Animation\Player\Events\AnimationTriggerEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\AnimationTriggerMessage.cs" />
|
||||
<Compile Include="Animation\Player\Events\CrouchEvent.cs" />
|
||||
<Compile Include="Animation\Player\AnimatorMirror.cs" />
|
||||
<Compile Include="Animation\Player\AnimControllerPatch.cs" />
|
||||
<Compile Include="Animation\Player\AnimFloatParam.cs" />
|
||||
<Compile Include="Animation\Player\CrouchSync.cs" />
|
||||
<Compile Include="Animation\Player\Patches\PlayerAnimationPatches.cs" />
|
||||
<Compile Include="Animation\Player\PlayerHeadRotationSync.cs" />
|
||||
<Compile Include="CampfireSync\CampfireManager.cs" />
|
||||
<Compile Include="CampfireSync\Events\CampfireStateEvent.cs" />
|
||||
<Compile Include="CampfireSync\Patches\CampfirePatches.cs" />
|
||||
@ -135,7 +138,7 @@
|
||||
<Compile Include="Events\EventNames.cs" />
|
||||
<Compile Include="DeathSync\Events\PlayerDeathEvent.cs" />
|
||||
<Compile Include="Events\IQSBEvent.cs" />
|
||||
<Compile Include="Animation\Events\ChangeAnimTypeEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\ChangeAnimTypeEvent.cs" />
|
||||
<Compile Include="FrequencySync\Events\IdentifyFrequencyEvent.cs" />
|
||||
<Compile Include="FrequencySync\Events\IdentifySignalEvent.cs" />
|
||||
<Compile Include="FrequencySync\Patches\FrequencyPatches.cs" />
|
||||
@ -234,6 +237,7 @@
|
||||
<Compile Include="StatueSync\Patches\StatuePatches.cs" />
|
||||
<Compile Include="StatueSync\StatueManager.cs" />
|
||||
<Compile Include="RoastingSync\TransformSync\RoastingStickTransformSync.cs" />
|
||||
<Compile Include="TransformSync\Patches\TransformSyncPatches.cs" />
|
||||
<Compile Include="TransformSync\QSBNetworkTransform.cs" />
|
||||
<Compile Include="TranslationSync\Events\SetAsTranslatedEvent.cs" />
|
||||
<Compile Include="TranslationSync\Events\SetAsTranslatedMessage.cs" />
|
||||
@ -252,7 +256,7 @@
|
||||
<Compile Include="Player\Events\PlayerReadyEvent.cs" />
|
||||
<Compile Include="OrbSync\TransformSync\NomaiOrbTransformSync.cs" />
|
||||
<Compile Include="Player\Events\PlayerStatesRequestEvent.cs" />
|
||||
<Compile Include="Animation\Events\PlayerSuitEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\PlayerSuitEvent.cs" />
|
||||
<Compile Include="TimeSync\Events\ServerTimeEvent.cs" />
|
||||
<Compile Include="GeyserSync\Events\GeyserEvent.cs" />
|
||||
<Compile Include="GeyserSync\GeyserManager.cs" />
|
||||
|
@ -1,6 +1,7 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Character;
|
||||
using QSB.CampfireSync;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.ElevatorSync;
|
||||
@ -111,6 +112,7 @@ namespace QSB
|
||||
gameObject.AddComponent<StatueManager>();
|
||||
gameObject.AddComponent<PoolManager>();
|
||||
gameObject.AddComponent<CampfireManager>();
|
||||
gameObject.AddComponent<CharacterAnimManager>();
|
||||
|
||||
DebugBoxManager.Init();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.DeathSync;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments;
|
||||
|
26
QSB/TransformSync/Patches/TransformSyncPatches.cs
Normal file
26
QSB/TransformSync/Patches/TransformSyncPatches.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.TransformSync.Patches
|
||||
{
|
||||
class TransformSyncPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
//QSBCore.HarmonyHelper.AddPrefix<LoadManager>("LoadSceneAsync", typeof(TransformSyncPatches), nameof(Deparent));
|
||||
//QSBCore.HarmonyHelper.AddPrefix<LoadManager>("LoadScene", typeof(TransformSyncPatches), nameof(Deparent));
|
||||
//QSBCore.HarmonyHelper.AddPrefix<LoadManager>("ReloadSceneAsync", typeof(TransformSyncPatches), nameof(Deparent));;
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
{
|
||||
//QSBCore.HarmonyHelper.Unpatch<LoadManager>("LoadSceneAsync");
|
||||
//QSBCore.HarmonyHelper.Unpatch<LoadManager>("LoadScene");
|
||||
//QSBCore.HarmonyHelper.Unpatch<LoadManager>("ReloadSceneAsync");
|
||||
}
|
||||
|
||||
//public static void Deparent()
|
||||
// => QSBNetworkTransform.DeparentAllTransforms();
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ namespace QSB.TransformSync
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
DebugLog.DebugWrite($"Start {PlayerId}.{GetType().Name}");
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
@ -51,6 +52,7 @@ namespace QSB.TransformSync
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
DebugLog.DebugWrite($"OnDestroy {PlayerId}.{GetType().Name}");
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject);
|
||||
@ -68,6 +70,7 @@ namespace QSB.TransformSync
|
||||
|
||||
protected void Init()
|
||||
{
|
||||
DebugLog.DebugWrite($"Init {PlayerId}.{GetType().Name}");
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
SetReferenceSector(SectorSync.GetClosestSector(AttachedObject.transform));
|
||||
_isInitialized = true;
|
||||
@ -84,10 +87,10 @@ namespace QSB.TransformSync
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
writer.Write(transform.localPosition);
|
||||
SerializeRotation(writer, transform.localRotation);
|
||||
_prevPosition = transform.localPosition;
|
||||
_prevRotation = transform.localRotation;
|
||||
writer.Write(transform.position);
|
||||
SerializeRotation(writer, transform.rotation);
|
||||
_prevPosition = transform.position;
|
||||
_prevRotation = transform.rotation;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
@ -110,20 +113,20 @@ namespace QSB.TransformSync
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
var localPosition = reader.ReadVector3();
|
||||
var localRotation = DeserializeRotation(reader);
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
transform.localPosition = localPosition;
|
||||
transform.localRotation = localRotation;
|
||||
transform.position = pos;
|
||||
transform.rotation = rot;
|
||||
|
||||
if (transform.position == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given localPosition was {localPosition} at sector {sector?.Name}", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given position was {pos} at sector {sector?.Name}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,21 +162,23 @@ namespace QSB.TransformSync
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
transform.position = AttachedObject.transform.position;
|
||||
transform.rotation = AttachedObject.transform.rotation;
|
||||
transform.position = ReferenceSector.Transform.InverseTransformPoint(AttachedObject.transform.position);
|
||||
transform.rotation = ReferenceSector.Transform.InverseTransformRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, transform.localPosition);
|
||||
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, transform.localRotation, ref _rotationSmoothVelocity, SmoothTime);
|
||||
var localToWorldPos = ReferenceSector.Transform.TransformPoint(transform.position);
|
||||
var localToWorldRot = ReferenceSector.Transform.TransformRotation(transform.rotation);
|
||||
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, localToWorldPos);
|
||||
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, localToWorldRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasMoved()
|
||||
{
|
||||
var displacementMagnitude = (transform.localPosition - _prevPosition).magnitude;
|
||||
var displacementMagnitude = (transform.position - _prevPosition).magnitude;
|
||||
return displacementMagnitude > 1E-03f
|
||||
|| Quaternion.Angle(transform.localRotation, _prevRotation) > 1E-03f;
|
||||
|| Quaternion.Angle(transform.rotation, _prevRotation) > 1E-03f;
|
||||
}
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
@ -183,7 +188,6 @@ namespace QSB.TransformSync
|
||||
return;
|
||||
}
|
||||
ReferenceSector = sector;
|
||||
transform.SetParent(sector.Transform, true);
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject was null for {PlayerId}.{GetType().Name} when trying to set reference sector to {sector.Name}. Waiting until not null...", MessageType.Warning);
|
||||
@ -200,6 +204,15 @@ namespace QSB.TransformSync
|
||||
|
||||
private void ReparentAttachedObject(Transform sectorTransform)
|
||||
{
|
||||
if (AttachedObject.transform.parent != null && AttachedObject.transform.parent.GetComponent<Sector>() == null)
|
||||
{
|
||||
DebugLog.DebugWrite($" - ERROR - Trying to reparent attachedObject which wasnt attached to sector!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"Reparent {AttachedObject.name} to {sectorTransform.name}");
|
||||
}
|
||||
AttachedObject.transform.SetParent(sectorTransform, true);
|
||||
AttachedObject.transform.localScale = GetType() == typeof(PlayerTransformSync)
|
||||
? Vector3.one / 10
|
||||
@ -211,7 +224,6 @@ namespace QSB.TransformSync
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
{
|
||||
DebugLog.DebugWrite($"Warning - {PlayerId}.{GetType().Name} moved too fast!", MessageType.Warning);
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
"settings": {
|
||||
"defaultServerIP": "localhost",
|
||||
"port": 7777,
|
||||
"debugMode": false,
|
||||
"debugMode": true,
|
||||
"showLinesInDebug": false,
|
||||
"socketedObjToDebug": -1
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ namespace QuantumUNET.Components
|
||||
};
|
||||
if (HasAuthority && LocalPlayerAuthority)
|
||||
{
|
||||
if (QNetworkClient.allClients.Count <= 0)
|
||||
if (QNetworkClient.AllClients.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ namespace QuantumUNET.Components
|
||||
QLog.FatalError($"Exception in OnStartServer:{ex.Message} {ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
if (QNetworkClient.active && QNetworkServer.localClientActive)
|
||||
if (QNetworkClient.Active && QNetworkServer.localClientActive)
|
||||
{
|
||||
QClientScene.SetLocalObject(NetId, gameObject);
|
||||
OnStartClient();
|
||||
|
@ -22,7 +22,6 @@ namespace QuantumUNET.Components
|
||||
public bool autoCreatePlayer { get; set; } = true;
|
||||
public bool isNetworkActive;
|
||||
public bool useWebSockets { get; set; }
|
||||
public bool useSimulator { get; set; }
|
||||
public bool clientLoadedScene { get; set; }
|
||||
public string serverBindAddress { get; set; } = "";
|
||||
public string networkAddress { get; set; } = "localhost";
|
||||
@ -236,7 +235,7 @@ namespace QuantumUNET.Components
|
||||
{
|
||||
OnStopClient();
|
||||
QClientScene.DestroyAllClientObjects();
|
||||
QClientScene.HandleClientDisconnect(client.connection);
|
||||
QClientScene.HandleClientDisconnect(client.Connection);
|
||||
client = null;
|
||||
if (!string.IsNullOrEmpty(offlineScene))
|
||||
{
|
||||
@ -289,14 +288,7 @@ namespace QuantumUNET.Components
|
||||
QLog.Error("Must set the Network Address field in the manager");
|
||||
return null;
|
||||
}
|
||||
if (useSimulator)
|
||||
{
|
||||
client.ConnectWithSimulator(networkAddress, networkPort, simulatedLatency, packetLossPercentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Connect(networkAddress, networkPort);
|
||||
}
|
||||
client.Connect(networkAddress, networkPort);
|
||||
OnStartClient(client);
|
||||
s_Address = networkAddress;
|
||||
return client;
|
||||
@ -313,7 +305,7 @@ namespace QuantumUNET.Components
|
||||
if (StartServer(config, maxConnections))
|
||||
{
|
||||
var networkClient = ConnectLocalClient();
|
||||
OnServerConnect(networkClient.connection);
|
||||
OnServerConnect(networkClient.Connection);
|
||||
OnStartClient(networkClient);
|
||||
result = networkClient;
|
||||
}
|
||||
@ -462,7 +454,7 @@ namespace QuantumUNET.Components
|
||||
if (IsClientConnected() && client != null)
|
||||
{
|
||||
RegisterClientMessages(client);
|
||||
OnClientSceneChanged(client.connection);
|
||||
OnClientSceneChanged(client.Connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace QuantumUNET.Components
|
||||
{
|
||||
var xOffset = 10;
|
||||
var yOffset = 30;
|
||||
var flag = Manager.client == null || Manager.client.connection == null || Manager.client.connection.connectionId == -1;
|
||||
var flag = Manager.client == null || Manager.client.Connection == null || Manager.client.Connection.connectionId == -1;
|
||||
if (!Manager.IsClientConnected() && !QNetworkServer.active)
|
||||
{
|
||||
if (flag)
|
||||
@ -69,7 +69,7 @@ namespace QuantumUNET.Components
|
||||
{
|
||||
if (GUI.Button(new Rect(xOffset, yOffset, 200f, 20f), "Client Ready"))
|
||||
{
|
||||
QClientScene.Ready(Manager.client.connection);
|
||||
QClientScene.Ready(Manager.client.Connection);
|
||||
if (QClientScene.localPlayers.Count == 0)
|
||||
{
|
||||
QClientScene.AddPlayer(0);
|
||||
|
@ -153,7 +153,7 @@ namespace QuantumUNET.Components
|
||||
{
|
||||
if (LastSyncTime != 0f)
|
||||
{
|
||||
if (QNetworkServer.active || QNetworkClient.active)
|
||||
if (QNetworkServer.active || QNetworkClient.Active)
|
||||
{
|
||||
if (IsServer || IsClient)
|
||||
{
|
||||
|
@ -94,11 +94,11 @@ namespace QuantumUNET
|
||||
}
|
||||
s_InternalMessage.Reader.ReadInt16();
|
||||
s_InternalMessage.ChannelId = msg.channelId;
|
||||
s_InternalMessage.Connection = connection;
|
||||
s_InternalMessage.Connection = Connection;
|
||||
s_InternalMessage.MsgType = s_InternalMessage.Reader.ReadInt16();
|
||||
m_Connection.InvokeHandler(s_InternalMessage);
|
||||
m_FreeMessages.Push(msg);
|
||||
connection.lastMessageTime = Time.time;
|
||||
Connection.lastMessageTime = Time.time;
|
||||
}
|
||||
m_InternalMsgs = internalMsgs;
|
||||
m_InternalMsgs.Clear();
|
||||
|
@ -13,45 +13,28 @@ namespace QuantumUNET
|
||||
{
|
||||
public class QNetworkClient
|
||||
{
|
||||
public QNetworkClient()
|
||||
{
|
||||
m_MsgBuffer = new byte[65535];
|
||||
m_MsgReader = new NetworkReader(m_MsgBuffer);
|
||||
AddClient(this);
|
||||
}
|
||||
|
||||
public QNetworkClient(QNetworkConnection conn)
|
||||
{
|
||||
m_MsgBuffer = new byte[65535];
|
||||
m_MsgReader = new NetworkReader(m_MsgBuffer);
|
||||
AddClient(this);
|
||||
SetActive(true);
|
||||
m_Connection = conn;
|
||||
m_AsyncConnect = ConnectState.Connected;
|
||||
conn.SetHandlers(m_MessageHandlers);
|
||||
RegisterSystemHandlers(false);
|
||||
}
|
||||
|
||||
public static List<QNetworkClient> allClients { get; private set; } = new List<QNetworkClient>();
|
||||
|
||||
public static bool active { get; private set; }
|
||||
|
||||
internal void SetHandlers(QNetworkConnection conn) => conn.SetHandlers(m_MessageHandlers);
|
||||
|
||||
public string serverIp { get; private set; } = "";
|
||||
|
||||
public int serverPort { get; private set; }
|
||||
|
||||
public QNetworkConnection connection => m_Connection;
|
||||
|
||||
public static List<QNetworkClient> AllClients { get; private set; } = new List<QNetworkClient>();
|
||||
public static bool Active { get; private set; }
|
||||
public string ServerIp { get; private set; } = "";
|
||||
public int ServerPort { get; private set; }
|
||||
public QNetworkConnection Connection => m_Connection;
|
||||
internal int hostId { get; private set; } = -1;
|
||||
|
||||
public Dictionary<short, QNetworkMessageDelegate> handlers => m_MessageHandlers.GetHandlers();
|
||||
|
||||
public int numChannels => hostTopology.DefaultConfig.ChannelCount;
|
||||
|
||||
public HostTopology hostTopology { get; private set; }
|
||||
|
||||
private const int k_MaxEventsPerFrame = 500;
|
||||
private int m_HostPort;
|
||||
private int m_ClientConnectionId = -1;
|
||||
private int m_StatResetTime;
|
||||
private static readonly QCRCMessage s_CRCMessage = new QCRCMessage();
|
||||
private readonly QNetworkMessageHandlers m_MessageHandlers = new QNetworkMessageHandlers();
|
||||
protected QNetworkConnection m_Connection;
|
||||
private readonly byte[] m_MsgBuffer;
|
||||
private readonly NetworkReader m_MsgReader;
|
||||
protected ConnectState m_AsyncConnect = ConnectState.None;
|
||||
private string m_RequestedServerHost = "";
|
||||
|
||||
public int hostPort
|
||||
{
|
||||
get => m_HostPort;
|
||||
@ -70,11 +53,30 @@ namespace QuantumUNET
|
||||
}
|
||||
|
||||
public bool isConnected => m_AsyncConnect == ConnectState.Connected;
|
||||
|
||||
public Type networkConnectionClass { get; private set; } = typeof(QNetworkConnection);
|
||||
|
||||
public void SetNetworkConnectionClass<T>() where T : QNetworkConnection => networkConnectionClass = typeof(T);
|
||||
|
||||
public QNetworkClient()
|
||||
{
|
||||
m_MsgBuffer = new byte[65535];
|
||||
m_MsgReader = new NetworkReader(m_MsgBuffer);
|
||||
AddClient(this);
|
||||
}
|
||||
|
||||
public QNetworkClient(QNetworkConnection conn)
|
||||
{
|
||||
m_MsgBuffer = new byte[65535];
|
||||
m_MsgReader = new NetworkReader(m_MsgBuffer);
|
||||
AddClient(this);
|
||||
SetActive(true);
|
||||
m_Connection = conn;
|
||||
m_AsyncConnect = ConnectState.Connected;
|
||||
conn.SetHandlers(m_MessageHandlers);
|
||||
RegisterSystemHandlers(false);
|
||||
}
|
||||
|
||||
internal void SetHandlers(QNetworkConnection conn) => conn.SetHandlers(m_MessageHandlers);
|
||||
|
||||
public bool Configure(ConnectionConfig config, int maxConnections)
|
||||
{
|
||||
var topology = new HostTopology(config, maxConnections);
|
||||
@ -87,159 +89,26 @@ namespace QuantumUNET
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ReconnectToNewHost(string serverIp, int serverPort)
|
||||
{
|
||||
bool result;
|
||||
if (!active)
|
||||
{
|
||||
QLog.Error("Reconnect - NetworkClient must be active");
|
||||
result = false;
|
||||
}
|
||||
else if (m_Connection == null)
|
||||
{
|
||||
QLog.Error("Reconnect - no old connection exists");
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLog.Log($"NetworkClient Reconnect {serverIp}:{serverPort}");
|
||||
QClientScene.HandleClientDisconnect(m_Connection);
|
||||
QClientScene.ClearLocalPlayers();
|
||||
m_Connection.Disconnect();
|
||||
m_Connection = null;
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
this.serverPort = serverPort;
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
this.serverIp = serverIp;
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else if (serverIp.Equals("127.0.0.1") || serverIp.Equals("localhost"))
|
||||
{
|
||||
this.serverIp = "127.0.0.1";
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLog.Log($"Async DNS START:{serverIp}");
|
||||
m_AsyncConnect = ConnectState.Resolving;
|
||||
Dns.BeginGetHostAddresses(serverIp, GetHostAddressesCallback, this);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ReconnectToNewHost(EndPoint secureTunnelEndPoint)
|
||||
{
|
||||
bool result;
|
||||
if (!active)
|
||||
{
|
||||
QLog.Error("Reconnect - NetworkClient must be active");
|
||||
result = false;
|
||||
}
|
||||
else if (m_Connection == null)
|
||||
{
|
||||
QLog.Error("Reconnect - no old connection exists");
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLog.Log("NetworkClient Reconnect to remoteSockAddr");
|
||||
QClientScene.HandleClientDisconnect(m_Connection);
|
||||
QClientScene.ClearLocalPlayers();
|
||||
m_Connection.Disconnect();
|
||||
m_Connection = null;
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
if (secureTunnelEndPoint == null)
|
||||
{
|
||||
QLog.Error("Reconnect failed: null endpoint passed in");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else if (secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetwork && secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetworkV6)
|
||||
{
|
||||
QLog.Error("Reconnect failed: Endpoint AddressFamily must be either InterNetwork or InterNetworkV6");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullName = secureTunnelEndPoint.GetType().FullName;
|
||||
if (fullName == "System.Net.IPEndPoint")
|
||||
{
|
||||
var ipendPoint = (IPEndPoint)secureTunnelEndPoint;
|
||||
Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
|
||||
result = m_AsyncConnect != ConnectState.Failed;
|
||||
}
|
||||
else if (fullName != "UnityEngine.XboxOne.XboxOneEndPoint" && fullName != "UnityEngine.PS4.SceEndPoint")
|
||||
{
|
||||
QLog.Error("Reconnect failed: invalid Endpoint (not IPEndPoint or XboxOneEndPoint or SceEndPoint)");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RemoteEndPoint = secureTunnelEndPoint;
|
||||
m_AsyncConnect = ConnectState.Connecting;
|
||||
byte b;
|
||||
try
|
||||
{
|
||||
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(hostId, m_RemoteEndPoint, 0, out b);
|
||||
}
|
||||
catch (Exception arg)
|
||||
{
|
||||
QLog.Error($"Reconnect failed: Exception when trying to connect to EndPoint: {arg}");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
return false;
|
||||
}
|
||||
if (m_ClientConnectionId == 0)
|
||||
{
|
||||
QLog.Error($"Reconnect failed: Unable to connect to EndPoint ({b})");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Connection = (QNetworkConnection)Activator.CreateInstance(networkConnectionClass);
|
||||
m_Connection.SetHandlers(m_MessageHandlers);
|
||||
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ConnectWithSimulator(string serverIp, int serverPort, int latency, float packetLoss)
|
||||
{
|
||||
m_UseSimulator = true;
|
||||
m_SimulatedLatency = latency;
|
||||
m_PacketLoss = packetLoss;
|
||||
Connect(serverIp, serverPort);
|
||||
}
|
||||
|
||||
private static bool IsValidIpV6(string address) =>
|
||||
address.All(c => c == ':' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
|
||||
|
||||
public void Connect(string serverIp, int serverPort)
|
||||
{
|
||||
PrepareForConnect();
|
||||
this.serverPort = serverPort;
|
||||
this.ServerPort = serverPort;
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
this.serverIp = serverIp;
|
||||
this.ServerIp = serverIp;
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else if (serverIp.Equals("127.0.0.1") || serverIp.Equals("localhost"))
|
||||
{
|
||||
this.serverIp = "127.0.0.1";
|
||||
this.ServerIp = "127.0.0.1";
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else if (serverIp.IndexOf(":") != -1 && IsValidIpV6(serverIp))
|
||||
{
|
||||
this.serverIp = serverIp;
|
||||
this.ServerIp = serverIp;
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else
|
||||
@ -251,63 +120,6 @@ namespace QuantumUNET
|
||||
}
|
||||
}
|
||||
|
||||
public void Connect(EndPoint secureTunnelEndPoint)
|
||||
{
|
||||
PrepareForConnect();
|
||||
QLog.Log("Client Connect to remoteSockAddr");
|
||||
if (secureTunnelEndPoint == null)
|
||||
{
|
||||
QLog.Error("Connect failed: null endpoint passed in");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else if (secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetwork && secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetworkV6)
|
||||
{
|
||||
QLog.Error("Connect failed: Endpoint AddressFamily must be either InterNetwork or InterNetworkV6");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullName = secureTunnelEndPoint.GetType().FullName;
|
||||
if (fullName == "System.Net.IPEndPoint")
|
||||
{
|
||||
var ipendPoint = (IPEndPoint)secureTunnelEndPoint;
|
||||
Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
|
||||
}
|
||||
else if (fullName != "UnityEngine.XboxOne.XboxOneEndPoint" && fullName != "UnityEngine.PS4.SceEndPoint" && fullName != "UnityEngine.PSVita.SceEndPoint")
|
||||
{
|
||||
QLog.Error("Connect failed: invalid Endpoint (not IPEndPoint or XboxOneEndPoint or SceEndPoint)");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte b = 0;
|
||||
m_RemoteEndPoint = secureTunnelEndPoint;
|
||||
m_AsyncConnect = ConnectState.Connecting;
|
||||
try
|
||||
{
|
||||
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(hostId, m_RemoteEndPoint, 0, out b);
|
||||
}
|
||||
catch (Exception arg)
|
||||
{
|
||||
QLog.Error($"Connect failed: Exception when trying to connect to EndPoint: {arg}");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
return;
|
||||
}
|
||||
if (m_ClientConnectionId == 0)
|
||||
{
|
||||
QLog.Error($"Connect failed: Unable to connect to EndPoint ({b})");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Connection = (QNetworkConnection)Activator.CreateInstance(networkConnectionClass);
|
||||
m_Connection.SetHandlers(m_MessageHandlers);
|
||||
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PrepareForConnect()
|
||||
{
|
||||
SetActive(true);
|
||||
@ -320,21 +132,7 @@ namespace QuantumUNET
|
||||
connectionConfig.UsePlatformSpecificProtocols = false;
|
||||
hostTopology = new HostTopology(connectionConfig, 8);
|
||||
}
|
||||
if (m_UseSimulator)
|
||||
{
|
||||
var num = m_SimulatedLatency / 3 - 1;
|
||||
if (num < 1)
|
||||
{
|
||||
num = 1;
|
||||
}
|
||||
var num2 = m_SimulatedLatency * 3;
|
||||
QLog.Log($"AddHost Using Simulator {num}/{num2}");
|
||||
hostId = NetworkTransport.AddHostWithSimulator(hostTopology, num, num2, m_HostPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
}
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
}
|
||||
|
||||
internal static void GetHostAddressesCallback(IAsyncResult ar)
|
||||
@ -350,10 +148,10 @@ namespace QuantumUNET
|
||||
}
|
||||
else
|
||||
{
|
||||
networkClient.serverIp = array[0].ToString();
|
||||
networkClient.ServerIp = array[0].ToString();
|
||||
networkClient.m_AsyncConnect = ConnectState.Resolved;
|
||||
QLog.Log(
|
||||
$"Async DNS Result:{networkClient.serverIp} for {networkClient.m_RequestedServerHost}: {networkClient.serverIp}");
|
||||
$"Async DNS Result:{networkClient.ServerIp} for {networkClient.m_RequestedServerHost}: {networkClient.ServerIp}");
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
@ -367,25 +165,10 @@ namespace QuantumUNET
|
||||
|
||||
internal void ContinueConnect()
|
||||
{
|
||||
if (m_UseSimulator)
|
||||
{
|
||||
var num = m_SimulatedLatency / 3;
|
||||
if (num < 1)
|
||||
{
|
||||
num = 1;
|
||||
}
|
||||
QLog.Log(
|
||||
$"Connect Using Simulator {m_SimulatedLatency / 3}/{m_SimulatedLatency}");
|
||||
var conf = new ConnectionSimulatorConfig(num, m_SimulatedLatency, num, m_SimulatedLatency, m_PacketLoss);
|
||||
m_ClientConnectionId = NetworkTransport.ConnectWithSimulator(hostId, serverIp, serverPort, 0, out var b, conf);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ClientConnectionId = NetworkTransport.Connect(hostId, serverIp, serverPort, 0, out var b);
|
||||
}
|
||||
m_ClientConnectionId = NetworkTransport.Connect(hostId, ServerIp, ServerPort, 0, out var b);
|
||||
m_Connection = (QNetworkConnection)Activator.CreateInstance(networkConnectionClass);
|
||||
m_Connection.SetHandlers(m_MessageHandlers);
|
||||
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
m_Connection.Initialize(ServerIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
}
|
||||
|
||||
public virtual void Disconnect()
|
||||
@ -541,7 +324,7 @@ namespace QuantumUNET
|
||||
hostId = -1;
|
||||
}
|
||||
RemoveClient(this);
|
||||
if (allClients.Count == 0)
|
||||
if (AllClients.Count == 0)
|
||||
{
|
||||
SetActive(false);
|
||||
}
|
||||
@ -748,7 +531,7 @@ namespace QuantumUNET
|
||||
public static Dictionary<short, QNetworkConnection.PacketStat> GetTotalConnectionStats()
|
||||
{
|
||||
var dictionary = new Dictionary<short, QNetworkConnection.PacketStat>();
|
||||
foreach (var networkClient in allClients)
|
||||
foreach (var networkClient in AllClients)
|
||||
{
|
||||
var connectionStats = networkClient.GetConnectionStats();
|
||||
foreach (var key in connectionStats.Keys)
|
||||
@ -769,73 +552,45 @@ namespace QuantumUNET
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
internal static void AddClient(QNetworkClient client) => allClients.Add(client);
|
||||
internal static void AddClient(QNetworkClient client) => AllClients.Add(client);
|
||||
|
||||
internal static bool RemoveClient(QNetworkClient client) => allClients.Remove(client);
|
||||
internal static bool RemoveClient(QNetworkClient client) => AllClients.Remove(client);
|
||||
|
||||
internal static void UpdateClients()
|
||||
{
|
||||
for (var i = 0; i < allClients.Count; i++)
|
||||
for (var i = 0; i < AllClients.Count; i++)
|
||||
{
|
||||
if (allClients[i] != null)
|
||||
if (AllClients[i] != null)
|
||||
{
|
||||
allClients[i].Update();
|
||||
AllClients[i].Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
allClients.RemoveAt(i);
|
||||
AllClients.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShutdownAll()
|
||||
{
|
||||
while (allClients.Count != 0)
|
||||
while (AllClients.Count != 0)
|
||||
{
|
||||
allClients[0].Shutdown();
|
||||
AllClients[0].Shutdown();
|
||||
}
|
||||
allClients = new List<QNetworkClient>();
|
||||
active = false;
|
||||
AllClients = new List<QNetworkClient>();
|
||||
Active = false;
|
||||
QClientScene.Shutdown();
|
||||
}
|
||||
|
||||
internal static void SetActive(bool state)
|
||||
{
|
||||
if (!active && state)
|
||||
if (!Active && state)
|
||||
{
|
||||
NetworkTransport.Init();
|
||||
}
|
||||
active = state;
|
||||
Active = state;
|
||||
}
|
||||
|
||||
private const int k_MaxEventsPerFrame = 500;
|
||||
private int m_HostPort;
|
||||
|
||||
private bool m_UseSimulator;
|
||||
|
||||
private int m_SimulatedLatency;
|
||||
|
||||
private float m_PacketLoss;
|
||||
private int m_ClientConnectionId = -1;
|
||||
|
||||
private int m_StatResetTime;
|
||||
|
||||
private EndPoint m_RemoteEndPoint;
|
||||
|
||||
private static readonly QCRCMessage s_CRCMessage = new QCRCMessage();
|
||||
|
||||
private readonly QNetworkMessageHandlers m_MessageHandlers = new QNetworkMessageHandlers();
|
||||
|
||||
protected QNetworkConnection m_Connection;
|
||||
|
||||
private readonly byte[] m_MsgBuffer;
|
||||
|
||||
private readonly NetworkReader m_MsgReader;
|
||||
|
||||
protected ConnectState m_AsyncConnect = ConnectState.None;
|
||||
|
||||
private string m_RequestedServerHost = "";
|
||||
|
||||
protected enum ConnectState
|
||||
{
|
||||
None,
|
||||
|
@ -1173,7 +1173,7 @@ namespace QuantumUNET
|
||||
};
|
||||
SendToObservers(uv.gameObject, 1, objectDestroyMessage);
|
||||
uv.ClearObservers();
|
||||
if (QNetworkClient.active && instance.m_LocalClientActive)
|
||||
if (QNetworkClient.Active && instance.m_LocalClientActive)
|
||||
{
|
||||
uv.OnNetworkDestroy();
|
||||
QClientScene.SetLocalObject(objectDestroyMessage.NetId, null);
|
||||
|
Loading…
x
Reference in New Issue
Block a user