using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
namespace Networking.Server
{
[CreateAssetMenu(menuName = "Major Project/Networking/ClientList", order = 150)]
public class ConnectionHandler : ScriptableObject
{
#region Public Variables
///
/// All Clients which are Currently Connected;
///
public List ConnectedClients;
///
/// Clients which connected at one point but no longer are
/// Usefull if a client needs to reconnect
///
public List DisconnectedClients;
///
/// Called when a client connects or disconnet
///
public System.Action> OnClientsChange;
#endregion Public Variables
#region Private Variables
public NetworkServerSimple server;
#endregion Private Variables
///
/// Clears the lists
///
public void Reset()
{
ConnectedClients = new List();
DisconnectedClients = new List();
}
///
/// Resets the client list + registers handlers with the server
///
/// Server to register handlers with
public void SetUp(ServerObject serverObject)
{
this.server = serverObject.server;
Reset();
server.RegisterHandler(MsgType.Connect, OnClientConnect);
server.RegisterHandler(MsgType.Disconnect, OnClientDisconnect);
server.RegisterHandler(LoginProtocols.SendingLoginDetails, OnClientLogin);
}
public void OnClientConnect(NetworkMessage msg)
{
if (ConnectedClients.Any(p => p.ID == msg.channelId))
{
Debug.LogError("Client[" + msg.channelId + "] already connected");
msg.conn.Send(LoginProtocols.LoginFail, new LoginProtocols.EmptyMsg());
return;
}
msg.conn.Send(LoginProtocols.RequestLoginDetails, new LoginProtocols.EmptyMsg());
}
public void OnClientDisconnect(NetworkMessage msg)
{
if (!ConnectedClients.Any(p => p.ID == msg.conn.connectionId))
{
Debug.LogError("Unknown client disconnect [" + msg.conn.connectionId + "]");
return;
}
ClientData client = ConnectedClients.FirstOrDefault(p => p.ID == msg.conn.connectionId);
ConnectedClients.Remove(client);
DisconnectedClients.Add(client);
Debug.Log("Disconnected: " + client.Name);
OnClientsChange.Invoke(ConnectedClients);
}
public void OnClientLogin(NetworkMessage msg)
{
LoginProtocols.LoginMsg loginMsg;
if (!msg.TryRead(out loginMsg))
{
Debug.Log("Recieved unknown message from client");
msg.conn.Send(LoginProtocols.LoginFail, new LoginProtocols.EmptyMsg());
return;
}
if (ConnectedClients.Any(p => p.ID == msg.channelId))
{
Debug.LogError("Client[" + msg.channelId + "] already connected");
msg.conn.Send(LoginProtocols.LoginFail, new LoginProtocols.EmptyMsg());
return;
}
ClientData newClient = DisconnectedClients.FirstOrDefault(p => p.ID == msg.conn.connectionId);
if (newClient != default)
{
Debug.Log("Reconnection: " + loginMsg.Name + ((loginMsg.Name != newClient.Name) ? (" (Prev. " + newClient.Name +")") : ""));
DisconnectedClients.Remove(newClient);
}
else
{
Debug.Log("new Connection: " + loginMsg.Name);
newClient = new ClientData();
}
newClient.Color = loginMsg.Color;
newClient.Name = loginMsg.Name;
newClient.conn = msg.conn;
ConnectedClients.Add(newClient);
newClient.conn.Send(LoginProtocols.LoginSuccess, new LoginProtocols.LoginMsg(newClient.Name, newClient.Color));
OnClientsChange.Invoke(ConnectedClients);
}
}
[System.Serializable]
public class ClientData
{
///
/// Client Name
///
public string Name;
///
/// Color which represents player, picked by player
///
public Color Color;
///
/// Clients Current Score
///
public int Score;
///
/// Clients character animal - needed for instantiation
///
public string characterAnimal;
///
/// Clients number of collected items - for colelction level
///
public int collected;
///
/// Network connection ID
///
public int ID { get { return (conn != null) ? conn.connectionId : -1; }}
///
/// Connection to Client
///
public NetworkConnection conn;
}
}