using System.Collections; using System.Collections.Generic; using UnityEngine; using MLAPI.Serialization.Pooled; namespace BossRoom { public enum ConnectStatus { SUCCESS, //client successfully connected. This may also be a successful reconnect. ESERVERFULL, //can't join, server is already at capacity. EMATCHSTARTED, //can't join, match is already in progress. EUNKNOWN, //can't join, reason unknown. } /// /// The GameNetHub is a general-purpose relay for game network messages between the client and server. It is available /// as soon as the initial network connection has completed, and persists across all scenes. Its purpose is to move non-GameObject-specific /// methods between server and client. Generally these have to do with connection, and match end conditions. /// /// /// /// public class GameNetHub : MonoBehaviour { public GameObject NetworkingManagerGO; private BossRoomClient.GNH_Client m_clientLogic; private BossRoomServer.GNH_Server m_serverLogic; public MLAPI.NetworkingManager NetManager { get; private set; } // Start is called before the first frame update void Start() { Object.DontDestroyOnLoad(this.gameObject); NetManager = NetworkingManagerGO.GetComponent(); //because we are not a true NetworkedBehavior, we don't get NetworkStart messages. But we still need to run at that point //where we know if we're a host or client. So we fake a "NetworkingManager.OnNetworkStarted" event out of the existing OnServerStarted //and OnClientConnectedCallback events. //FIXME_DMW could this be improved? NetManager.OnServerStarted += () => { NetworkStart(); }; NetManager.OnClientConnectedCallback += (clientId) => { if (clientId == NetManager.LocalClientId) { NetworkStart(); } }; } private void RegisterClientMessageHandlers() { MLAPI.Messaging.CustomMessagingManager.RegisterNamedMessageHandler("S2C_ConnectResult", (senderClientId, stream) => { using (PooledBitReader reader = PooledBitReader.Get(stream)) { ConnectStatus status = (ConnectStatus)reader.ReadInt32(); BossRoomState state = (BossRoomState)reader.ReadInt32(); m_clientLogic.RecvConnectFinished(status, state); } }); } private void RegisterServerMessageHandlers() { //TODO: plug in any C->S message handlers here. } /// /// This method runs when NetworkingManager has started up (following a succesful connect on the client, or directly after StartHost is invoked /// on the host). It is named to match NetworkedBehaviour.NetworkStart, and serves the same role, even though GameNetHub itself isn't a NetworkedBehaviour. /// public void NetworkStart() { if (NetManager.IsClient) { m_clientLogic = new BossRoomClient.GNH_Client(this); RegisterClientMessageHandlers(); } if ( NetManager.IsServer ) { m_serverLogic = new BossRoomServer.GNH_Server(this); RegisterServerMessageHandlers(); } if( NetManager.IsHost ) { //special host code. This is what kicks off the flow that happens on a regular client //when it has finished connecting successfully. A dedicated server would remove this. m_clientLogic.RecvConnectFinished(ConnectStatus.SUCCESS, BossRoomState.CHARSELECT); } } /// /// Wraps the invocation of NetworkingManager.StartClient, including our GUID as the payload. /// /// the IP address of the host to connect to. (IPV4 only) /// The port of the host to connect to. public void StartClient(string ipaddress, int port) { BossRoomClient.GNH_Client.StartClient(this, ipaddress, port); } /// /// Wraps the invocation of NetworkingManager.StartHost. /// /// The IP address of the network interface we should listen to connections on. (IPV4 only) /// The port we should listen on. public void StartHost(string ipaddress, int port ) { BossRoomServer.GNH_Server.StartHost(this, ipaddress, port); } //Server->Client RPCs public void S2C_ConnectResult( ulong netId, ConnectStatus status, BossRoomState targetState ) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteInt32((int)status); writer.WriteInt32((int)targetState); MLAPI.Messaging.CustomMessagingManager.SendNamedMessage("S2C_ConnectResult", netId, stream, "MLAPI_INTERNAL"); } } } } }