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.

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