123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using Rokid.MRC;
- using System;
- using System.Collections;
- using Unity.Multiplayer.Samples.Utilities;
- using Unity.Netcode;
- using UnityEngine;
- //Host模式的稳定状态。服务端开启成功后,最终在这个状态
- class HostingState : OnlineState
- {
- //客户端登录信息最大尺寸
- const int MaxConnectPayload = 1024;
- public override void Enter()
- {
- //Todo,服务端切换场景
- }
- public override void Exit()
- {
- //玩家信息管理,将所有玩家踢下线
- PlayerManager.Instance.OnServerEnded();
- }
- //某个客户端连接到服务端,但是还没通过登录验证
- public override void OnClientConnected(ulong clientId)
- {
- //触发消息,此时的客户端数据,可能是之前遗留的。Todo,在ApprovalCheck中触发
- //MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = ServerSessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId)?.PlayerName });
- }
- //客户端断开连接
- public override void OnClientDisconnect(ulong clientId)
- {
- if(clientId == m_ConnectionManager.NetworkManager.LocalClientId)
- {
- //服务端自己关闭
- m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
- }
- else
- {
- //其他客户端断开连接。移除该客户端数据
- string playerId = PlayerManager.Instance.GetPlayerId(clientId);
- if(playerId != null)
- {
- //设置玩家断线
- PlayerManager.Instance.DisconnectClient(clientId);
- //有该玩家数据,则触发
- MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.GenericDisconnect, PlayerName = PlayerManager.Instance.GetPlayerData(playerId)?.PlayerName });
- }
- }
- }
- //服务端主动关闭
- public override void OnUserRequestedShutdown()
- {
- //给所有客户端发消息
- m_ConnectionManager.SendServerToAllClientsSetDisconnectReason(ConnectStatus.HostEndedSession);
- //关闭服务端
- m_ConnectionManager.NetworkManager.StartCoroutine(WaitToShutdown());
- }
- //处理其他客户端登录请求
- public override void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
- {
- //客户端数据(Json格式),包括玩家名称、Guid等信息
- var connectionData = request.Payload;
- var clientId = request.ClientNetworkId;
- if(connectionData.Length > MaxConnectPayload)
- {
- //数据超标
- response.Approved = false;
- return;
- }
- //解析数据
- string payload = System.Text.Encoding.UTF8.GetString(connectionData);
- ConnectionPayload connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload);
- //连接状态
- ConnectStatus gameReturnStatus = GetConnectStatus(connectionPayload);
- if(gameReturnStatus == ConnectStatus.Success)
- {
- //连接成功
- //保存客户端登录信息
- PlayerData playerData = new PlayerData(clientId, connectionPayload, true);
- PlayerManager.Instance.SetupConnectingPlayerSessionData(clientId, connectionPayload.playerId , playerData);
- //延迟生成锚点,因为客户端此时还未收到连接成功信息,如果服务端在此时就生成Anchor,客户端不会同步生成
- //NetworkObject必须由服务端生成,客户端没有权限
- if(connectionPayload.needAnchor)
- {
- m_ConnectionManager.NetworkManager.StartCoroutine(WaitForClientConnected(playerData, connectionPayload.needAnchor));
- }
- //触发消息
- MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = PlayerManager.Instance.GetPlayerData(clientId)?.PlayerName });
- response.Approved = true;
- response.CreatePlayerObject = false;
- response.Position = Vector3.zero;
- response.Rotation = Quaternion.identity;
- return;
- }
- IEnumerator WaitToDenyApproval()
- {
- response.Pending = true;
- response.Approved = false;
- m_ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
- yield return null;
- response.Pending = false;
- }
- //连接失败,则告诉客户端原因
- m_ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
- m_ConnectionManager.NetworkManager.StartCoroutine(WaitToDenyApproval());
- }
- IEnumerator WaitForClientConnected(PlayerData playerData, bool showAnchor)
- {
- yield return new WaitUntil(() =>
- {
- if(m_ConnectionManager.NetworkManager.ConnectedClients.ContainsKey(playerData.ClientId))
- {
- return true;
- }
- return false;
- });
-
- //生成Anchor模型
- playerData.Anchor = ResourceManager.Instance.CreateClientAnchor(playerData);
- playerData.Anchor.SetActive(showAnchor);
- MessageCenter.SendMessage(GlobalDefine.ClientAnchorInstantiate, null);
- }
- //返回连接状态
- ConnectStatus GetConnectStatus(ConnectionPayload connectionPayload)
- {
- if(m_ConnectionManager.NetworkManager.ConnectedClientsIds.Count > m_ConnectionManager.MaxConnectedPlayers)
- {
- return ConnectStatus.ServerFull;
- }
- //该客户端是Debug版本,不允许
- //if(connectionPayload.isDebug != Debug.isDebugBuild)
- //{
- // return ConnectStatus.IncompatibleBuildType;
- //}
- //判断是否视频流
- if(connectionPayload.isVideo && PlayerManager.Instance.HaveVideoPlayer())
- {
- return ConnectStatus.AlreadyHaveVideoClient;
- }
- //是否已经有该玩家
- if(PlayerManager.Instance.IsDuplicateConnection(connectionPayload.playerId))
- {
- //已经有该客户端,重复登录
- return ConnectStatus.LoggedInAgain;
- }
- else
- {
- return ConnectStatus.Success;
- }
- }
- //切换到OfflineState状态
- IEnumerator WaitToShutdown()
- {
- yield return null;
- m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
- }
- }
|