HostingState.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using Rokid.MRC;
  2. using System;
  3. using System.Collections;
  4. using Unity.Multiplayer.Samples.Utilities;
  5. using Unity.Netcode;
  6. using UnityEngine;
  7. //Host模式的稳定状态。服务端开启成功后,最终在这个状态
  8. class HostingState : OnlineState
  9. {
  10. //客户端登录信息最大尺寸
  11. const int MaxConnectPayload = 1024;
  12. public override void Enter()
  13. {
  14. //Todo,服务端切换场景
  15. }
  16. public override void Exit()
  17. {
  18. //玩家信息管理,将所有玩家踢下线
  19. PlayerManager.Instance.OnServerEnded();
  20. }
  21. //某个客户端连接到服务端,但是还没通过登录验证
  22. public override void OnClientConnected(ulong clientId)
  23. {
  24. //触发消息,此时的客户端数据,可能是之前遗留的。Todo,在ApprovalCheck中触发
  25. //MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = ServerSessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId)?.PlayerName });
  26. }
  27. //客户端断开连接
  28. public override void OnClientDisconnect(ulong clientId)
  29. {
  30. if(clientId == m_ConnectionManager.NetworkManager.LocalClientId)
  31. {
  32. //服务端自己关闭
  33. m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
  34. }
  35. else
  36. {
  37. //其他客户端断开连接。移除该客户端数据
  38. string playerId = PlayerManager.Instance.GetPlayerId(clientId);
  39. if(playerId != null)
  40. {
  41. //设置玩家断线
  42. PlayerManager.Instance.DisconnectClient(clientId);
  43. //有该玩家数据,则触发
  44. MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.GenericDisconnect, PlayerName = PlayerManager.Instance.GetPlayerData(playerId)?.PlayerName });
  45. }
  46. }
  47. }
  48. //服务端主动关闭
  49. public override void OnUserRequestedShutdown()
  50. {
  51. //给所有客户端发消息
  52. m_ConnectionManager.SendServerToAllClientsSetDisconnectReason(ConnectStatus.HostEndedSession);
  53. //关闭服务端
  54. m_ConnectionManager.NetworkManager.StartCoroutine(WaitToShutdown());
  55. }
  56. //处理其他客户端登录请求
  57. public override void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
  58. {
  59. //客户端数据(Json格式),包括玩家名称、Guid等信息
  60. var connectionData = request.Payload;
  61. var clientId = request.ClientNetworkId;
  62. if(connectionData.Length > MaxConnectPayload)
  63. {
  64. //数据超标
  65. response.Approved = false;
  66. return;
  67. }
  68. //解析数据
  69. string payload = System.Text.Encoding.UTF8.GetString(connectionData);
  70. ConnectionPayload connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload);
  71. //连接状态
  72. ConnectStatus gameReturnStatus = GetConnectStatus(connectionPayload);
  73. if(gameReturnStatus == ConnectStatus.Success)
  74. {
  75. //连接成功
  76. //保存客户端登录信息
  77. PlayerData playerData = new PlayerData(clientId, connectionPayload, true);
  78. PlayerManager.Instance.SetupConnectingPlayerSessionData(clientId, connectionPayload.playerId , playerData);
  79. //延迟生成锚点,因为客户端此时还未收到连接成功信息,如果服务端在此时就生成Anchor,客户端不会同步生成
  80. //NetworkObject必须由服务端生成,客户端没有权限
  81. if(connectionPayload.needAnchor)
  82. {
  83. m_ConnectionManager.NetworkManager.StartCoroutine(WaitForClientConnected(playerData, connectionPayload.needAnchor));
  84. }
  85. //触发消息
  86. MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = PlayerManager.Instance.GetPlayerData(clientId)?.PlayerName });
  87. response.Approved = true;
  88. response.CreatePlayerObject = false;
  89. response.Position = Vector3.zero;
  90. response.Rotation = Quaternion.identity;
  91. return;
  92. }
  93. IEnumerator WaitToDenyApproval()
  94. {
  95. response.Pending = true;
  96. response.Approved = false;
  97. m_ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
  98. yield return null;
  99. response.Pending = false;
  100. }
  101. //连接失败,则告诉客户端原因
  102. m_ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
  103. m_ConnectionManager.NetworkManager.StartCoroutine(WaitToDenyApproval());
  104. }
  105. IEnumerator WaitForClientConnected(PlayerData playerData, bool showAnchor)
  106. {
  107. yield return new WaitUntil(() =>
  108. {
  109. if(m_ConnectionManager.NetworkManager.ConnectedClients.ContainsKey(playerData.ClientId))
  110. {
  111. return true;
  112. }
  113. return false;
  114. });
  115. //生成Anchor模型
  116. playerData.Anchor = ResourceManager.Instance.CreateClientAnchor(playerData);
  117. playerData.Anchor.SetActive(showAnchor);
  118. MessageCenter.SendMessage(GlobalDefine.ClientAnchorInstantiate, null);
  119. }
  120. //返回连接状态
  121. ConnectStatus GetConnectStatus(ConnectionPayload connectionPayload)
  122. {
  123. if(m_ConnectionManager.NetworkManager.ConnectedClientsIds.Count > m_ConnectionManager.MaxConnectedPlayers)
  124. {
  125. return ConnectStatus.ServerFull;
  126. }
  127. //该客户端是Debug版本,不允许
  128. //if(connectionPayload.isDebug != Debug.isDebugBuild)
  129. //{
  130. // return ConnectStatus.IncompatibleBuildType;
  131. //}
  132. //判断是否视频流
  133. if(connectionPayload.isVideo && PlayerManager.Instance.HaveVideoPlayer())
  134. {
  135. return ConnectStatus.AlreadyHaveVideoClient;
  136. }
  137. //是否已经有该玩家
  138. if(PlayerManager.Instance.IsDuplicateConnection(connectionPayload.playerId))
  139. {
  140. //已经有该客户端,重复登录
  141. return ConnectStatus.LoggedInAgain;
  142. }
  143. else
  144. {
  145. return ConnectStatus.Success;
  146. }
  147. }
  148. //切换到OfflineState状态
  149. IEnumerator WaitToShutdown()
  150. {
  151. yield return null;
  152. m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
  153. }
  154. }