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");
}
}
}
}
}