diff options
author | chai <215380520@qq.com> | 2024-03-13 11:00:58 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2024-03-13 11:00:58 +0800 |
commit | 6ce8b9e22fc13be34b442c7b6af48b42cd44275a (patch) | |
tree | b38119d2acf0a982cb67e381f146924b9bfc3b3f /Landfall.Network |
+init
Diffstat (limited to 'Landfall.Network')
-rw-r--r-- | Landfall.Network/LoginInformation.cs | 6 | ||||
-rw-r--r-- | Landfall.Network/NetworkController.cs | 65 | ||||
-rw-r--r-- | Landfall.Network/NetworkManager.cs | 213 | ||||
-rw-r--r-- | Landfall.Network/PacketType.cs | 10 | ||||
-rw-r--r-- | Landfall.Network/Player.cs | 13 |
5 files changed, 307 insertions, 0 deletions
diff --git a/Landfall.Network/LoginInformation.cs b/Landfall.Network/LoginInformation.cs new file mode 100644 index 0000000..989d15e --- /dev/null +++ b/Landfall.Network/LoginInformation.cs @@ -0,0 +1,6 @@ +namespace Landfall.Network; + +public class LoginInformation +{ + public string PlayerName { get; set; } +} diff --git a/Landfall.Network/NetworkController.cs b/Landfall.Network/NetworkController.cs new file mode 100644 index 0000000..22791ab --- /dev/null +++ b/Landfall.Network/NetworkController.cs @@ -0,0 +1,65 @@ +using UnityEngine; + +namespace Landfall.Network; + +public class NetworkController : MonoBehaviour +{ + [SerializeField] + private MonoBehaviour[] m_ScriptsToDisable; + + [SerializeField] + private Camera[] m_CamerasToDisable; + + [SerializeField] + private Transform m_Hip; + + private bool m_HasControl; + + private NetworkManager m_NetworkManager; + + private string m_Name; + + public void Init(NetworkManager manager, bool hasControl, string playerName) + { + m_NetworkManager = manager; + m_HasControl = hasControl; + GetComponent<HasControl>().ChangeControl(m_HasControl); + m_Name = playerName; + } + + private void StripPlayer() + { + if (!m_HasControl) + { + MonoBehaviour[] scriptsToDisable = m_ScriptsToDisable; + foreach (MonoBehaviour monoBehaviour in scriptsToDisable) + { + monoBehaviour.enabled = false; + } + Camera[] camerasToDisable = m_CamerasToDisable; + foreach (Camera camera in camerasToDisable) + { + camera.enabled = false; + } + } + } + + private void Update() + { + if (m_HasControl) + { + SendUpdatesToServer(); + } + } + + private void SendUpdatesToServer() + { + Vector3 position = m_Hip.position; + m_NetworkManager.UpdateFromLocalClient(position); + } + + public void UpdatePosition(Vector3 newPos) + { + base.transform.position = newPos; + } +} diff --git a/Landfall.Network/NetworkManager.cs b/Landfall.Network/NetworkManager.cs new file mode 100644 index 0000000..89d790a --- /dev/null +++ b/Landfall.Network/NetworkManager.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using Lidgren.Network; +using UnityEngine; + +namespace Landfall.Network; + +public class NetworkManager : MonoBehaviour +{ + [SerializeField] + private GameObject m_PlayerPrefab; + + private GameObject m_SpawnedPlayer; + + private NetClient m_Client; + + private List<NetPlayer> m_Players = new List<NetPlayer>(); + + private NetPlayer m_LocalPlayer; + + private string m_LocalName; + + public bool Active { get; private set; } + + private void Awake() + { + } + + private void Start() + { + InitNetwork(); + } + + private void InitNetwork() + { + if (!StartClient()) + { + Debug.LogError("Could Not Connect to server!"); + return; + } + Debug.Log("Connected To Server!"); + SpawnPlayer(); + } + + public bool StartClient() + { + m_LocalName = "Philip " + UnityEngine.Random.Range(0, int.MaxValue); + LoginInformation loginInformation = new LoginInformation(); + loginInformation.PlayerName = m_LocalName; + LoginInformation ob = loginInformation; + NetPeerConfiguration netPeerConfiguration = new NetPeerConfiguration("RobotsNetwork"); + netPeerConfiguration.EnableMessageType(NetIncomingMessageType.Data); + m_Client = new NetClient(netPeerConfiguration); + m_Client.Start(); + NetOutgoingMessage netOutgoingMessage = m_Client.CreateMessage(); + netOutgoingMessage.Write((byte)1); + netOutgoingMessage.WriteAllProperties(ob); + m_Client.Connect("127.0.0.1", 1337, netOutgoingMessage); + return EstablishConnection(); + } + + private bool EstablishConnection() + { + DateTime now = DateTime.Now; + do + { + NetIncomingMessage netIncomingMessage; + if ((netIncomingMessage = m_Client.ReadMessage()) != null) + { + NetIncomingMessageType messageType = netIncomingMessage.MessageType; + if (messageType == NetIncomingMessageType.StatusChanged && netIncomingMessage.SenderConnection.Status == NetConnectionStatus.Connected) + { + Active = true; + NetOutgoingMessage netOutgoingMessage = m_Client.CreateMessage(); + netOutgoingMessage.Write((byte)4); + m_Client.SendMessage(netOutgoingMessage, NetDeliveryMethod.ReliableOrdered); + return true; + } + } + } + while (DateTime.Now.Subtract(now).Seconds <= 5); + return false; + } + + private void SpawnPlayer() + { + m_SpawnedPlayer = UnityEngine.Object.Instantiate(m_PlayerPrefab); + m_LocalPlayer = new NetPlayer + { + PlayerName = m_LocalName, + PlayerObject = m_SpawnedPlayer + }; + m_SpawnedPlayer.GetComponent<NetworkController>().Init(this, hasControl: true, m_LocalName); + m_SpawnedPlayer.SetActive(value: true); + } + + private void Update() + { + if (Active) + { + ReadMessages(); + } + } + + private void ReadMessages() + { + NetIncomingMessage netIncomingMessage; + while ((netIncomingMessage = m_Client.ReadMessage()) != null) + { + if (netIncomingMessage.MessageType == NetIncomingMessageType.Data) + { + PacketType packetType = (PacketType)netIncomingMessage.ReadByte(); + Debug.Log("Recieved Message: " + packetType); + switch (packetType) + { + case PacketType.Login: + { + bool flag = netIncomingMessage.ReadBoolean(); + RecieveAllPlayers(netIncomingMessage); + break; + } + case PacketType.NewPlayer: + RecieveNewPlayer(netIncomingMessage); + break; + case PacketType.AllPlayers: + RecieveAllPlayers(netIncomingMessage); + break; + case PacketType.Ping: + Debug.Log("Recieved Ping!"); + break; + case PacketType.PlayerUpdate: + RecievedPlayerUpdate(netIncomingMessage); + break; + } + } + } + } + + private void RecievedPlayerUpdate(NetIncomingMessage msg) + { + Vector3 newPos = msg.ReadVector3(); + string playerName = msg.ReadString(); + NetPlayer netPlayer = FindPlayerByName(playerName); + netPlayer.PlayerObject.GetComponent<NetworkController>().UpdatePosition(newPos); + } + + private NetPlayer FindPlayerByName(string playerName) + { + foreach (NetPlayer player in m_Players) + { + if (player.PlayerName == playerName) + { + return player; + } + } + throw new Exception("Could not find player woth name: " + playerName); + } + + private void RecieveNewPlayer(NetIncomingMessage msg) + { + Player player = new Player(); + msg.ReadAllProperties(player); + SpawnRemotePlayer(player); + } + + private void RecieveAllPlayers(NetIncomingMessage message) + { + byte b = message.ReadByte(); + for (byte b2 = 0; b2 < b; b2 = (byte)(b2 + 1)) + { + Player player = new Player(); + message.ReadAllProperties(player); + if (IsNewPlayer(player)) + { + SpawnRemotePlayer(player); + } + } + } + + private bool IsNewPlayer(Player player) + { + foreach (NetPlayer player2 in m_Players) + { + if (player2.PlayerName == player.Name) + { + return false; + } + } + return true; + } + + private void SpawnRemotePlayer(Player newPlayer) + { + GameObject gameObject = UnityEngine.Object.Instantiate(m_PlayerPrefab); + gameObject.name = newPlayer.Name; + gameObject.GetComponent<NetworkController>().Init(this, hasControl: false, newPlayer.Name); + gameObject.SetActive(value: true); + m_Players.Add(new NetPlayer + { + PlayerObject = gameObject, + PlayerName = newPlayer.Name + }); + } + + public void UpdateFromLocalClient(Vector3 position) + { + NetOutgoingMessage netOutgoingMessage = m_Client.CreateMessage(); + netOutgoingMessage.Write((byte)5); + netOutgoingMessage.Write(position); + netOutgoingMessage.Write(m_LocalName); + m_Client.SendMessage(netOutgoingMessage, NetDeliveryMethod.Unreliable); + } +} diff --git a/Landfall.Network/PacketType.cs b/Landfall.Network/PacketType.cs new file mode 100644 index 0000000..e137b60 --- /dev/null +++ b/Landfall.Network/PacketType.cs @@ -0,0 +1,10 @@ +namespace Landfall.Network; + +public enum PacketType : byte +{ + Login = 1, + NewPlayer, + AllPlayers, + Ping, + PlayerUpdate +} diff --git a/Landfall.Network/Player.cs b/Landfall.Network/Player.cs new file mode 100644 index 0000000..3f5a66f --- /dev/null +++ b/Landfall.Network/Player.cs @@ -0,0 +1,13 @@ +using Lidgren.Network; +using UnityEngine; + +namespace Landfall.Network; + +public class Player +{ + public string Name { get; set; } + + public NetConnection Connection { get; set; } + + public Vector3 Position { get; set; } +} |