You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.7 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using UnityEngine.Networking;
  6. namespace Networking.Server
  7. {
  8. [CreateAssetMenu(menuName = "Major Project/Networking/ClientList", order = 150)]
  9. public class ConnectionHandler : ScriptableObject, IEnumerable<ClientData>
  10. {
  11. #region Public Variables
  12. /// <summary>
  13. /// All Clients which are Currently Connected;
  14. /// </summary>
  15. public List<ClientData> ConnectedClients;
  16. /// <summary>
  17. /// Clients which connected at one point but no longer are
  18. /// Usefull if a client needs to reconnect
  19. /// </summary>
  20. public List<ClientData> DisconnectedClients;
  21. /// <summary>
  22. /// Called when a client connects or disconnet
  23. /// </summary>
  24. public System.Action<List<ClientData>> OnClientsChange;
  25. #endregion Public Variables
  26. #region Private Variables
  27. public NetworkServerSimple server;
  28. #endregion Private Variables
  29. /// <summary>
  30. /// Clears the lists
  31. /// </summary>
  32. public void Reset()
  33. {
  34. ConnectedClients = new List<ClientData>();
  35. DisconnectedClients = new List<ClientData>();
  36. }
  37. /// <summary>
  38. /// Resets the client list + registers handlers with the server
  39. /// </summary>
  40. /// <param name="serverObject">Server to register handlers with</param>
  41. public void SetUp(ServerObject serverObject)
  42. {
  43. this.server = serverObject.server;
  44. Reset();
  45. server.RegisterHandler(MsgType.Connect, OnClientConnect);
  46. server.RegisterHandler(MsgType.Disconnect, OnClientDisconnect);
  47. server.RegisterHandler(LoginProtocols.SendingLoginDetails, OnClientLogin);
  48. }
  49. public void OnClientConnect(NetworkMessage msg)
  50. {
  51. if (ConnectedClients.Any(p => p.ID == msg.channelId))
  52. {
  53. Debug.LogError("Client[" + msg.channelId + "] already connected");
  54. msg.conn.Send(LoginProtocols.LoginFail, new LoginProtocols.EmptyMsg());
  55. return;
  56. }
  57. msg.conn.Send(LoginProtocols.RequestLoginDetails, new LoginProtocols.EmptyMsg());
  58. }
  59. public void OnClientDisconnect(NetworkMessage msg)
  60. {
  61. if (!ConnectedClients.Any(p => p.ID == msg.conn.connectionId))
  62. {
  63. Debug.LogError("Unknown client disconnect [" + msg.conn.connectionId + "]");
  64. return;
  65. }
  66. ClientData client = ConnectedClients.FirstOrDefault(p => p.ID == msg.conn.connectionId);
  67. ConnectedClients.Remove(client);
  68. DisconnectedClients.Add(client);
  69. Debug.Log("Disconnected: " + client.Name);
  70. OnClientsChange.Invoke(ConnectedClients);
  71. }
  72. public void OnClientLogin(NetworkMessage msg)
  73. {
  74. LoginProtocols.LoginMsg loginMsg;
  75. if (!msg.TryRead(out loginMsg))
  76. {
  77. Debug.Log("Recieved unknown message from client");
  78. msg.conn.Send(LoginProtocols.LoginFail, new LoginProtocols.EmptyMsg());
  79. return;
  80. }
  81. if (ConnectedClients.Any(p => p.ID == msg.channelId))
  82. {
  83. Debug.LogError("Client[" + msg.channelId + "] already connected");
  84. msg.conn.Send(LoginProtocols.LoginFail, new LoginProtocols.EmptyMsg());
  85. return;
  86. }
  87. ClientData newClient = DisconnectedClients.FirstOrDefault(p => p.ID == msg.conn.connectionId);
  88. if (newClient != default)
  89. {
  90. Debug.Log("Reconnection: " + loginMsg.Name + ((loginMsg.Name != newClient.Name) ? (" (Prev. " + newClient.Name +")") : ""));
  91. DisconnectedClients.Remove(newClient);
  92. }
  93. else
  94. {
  95. Debug.Log("new Connection: " + loginMsg.Name);
  96. newClient = new ClientData();
  97. }
  98. newClient.Color = loginMsg.Color;
  99. newClient.Name = loginMsg.Name;
  100. newClient.conn = msg.conn;
  101. ConnectedClients.Add(newClient);
  102. newClient.conn.Send(LoginProtocols.LoginSuccess, new LoginProtocols.LoginMsg(newClient.Name, newClient.Color));
  103. OnClientsChange.Invoke(ConnectedClients);
  104. }
  105. #region IEnumerable Implementation
  106. public IEnumerator<ClientData> GetEnumerator()
  107. {
  108. return ((IEnumerable<ClientData>)ConnectedClients).GetEnumerator();
  109. }
  110. IEnumerator IEnumerable.GetEnumerator()
  111. {
  112. return ((IEnumerable<ClientData>)ConnectedClients).GetEnumerator();
  113. }
  114. #endregion IEnumerable Implementation
  115. }
  116. [System.Serializable]
  117. public class ClientData
  118. {
  119. /// <summary>
  120. /// Client Name
  121. /// </summary>
  122. public string Name;
  123. /// <summary>
  124. /// Color which represents player, picked by player
  125. /// </summary>
  126. public Color Color;
  127. /// <summary>
  128. /// Clients Current Score
  129. /// </summary>
  130. public int Score;
  131. /// <summary>
  132. /// Clients character animal - needed for instantiation
  133. /// </summary>
  134. public string characterAnimal;
  135. /// <summary>
  136. /// Clients number of collected items - for colelction level
  137. /// </summary>
  138. public int collected;
  139. /// <summary>
  140. /// Network connection ID
  141. /// </summary>
  142. public int ID { get { return (conn != null) ? conn.connectionId : -1; }}
  143. /// <summary>
  144. /// Connection to Client
  145. /// </summary>
  146. public NetworkConnection conn;
  147. }
  148. }