123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- using Rokid.MRC;
- using System;
- using System.Collections.Generic;
- using Unity.Netcode;
- using UnityEngine;
- //客户端玩家数据管理,不允许一个客户端登录两次,用于后续公司账号
- public class PlayerManager
- {
- PlayerManager()
- {
- PlayerDataDic = new Dictionary<string, PlayerData>();
- m_ClientIDToPlayerId = new Dictionary<ulong, string>();
- }
- public static PlayerManager Instance => s_Instance ??= new PlayerManager();
- static PlayerManager s_Instance;
- //PlayerID——SessionPlayerData
- public Dictionary<string, PlayerData> PlayerDataDic;
- //ClientId——PlayerID
- private Dictionary<ulong, string> m_ClientIDToPlayerId;
- private bool m_HasSessionStarted;
- //客户端断开连接
- public void DisconnectClient(ulong clientId)
- {
- if(m_HasSessionStarted)
- {
- //将客户端标记为断线,但是不移除数据。便于后续重连
- if(m_ClientIDToPlayerId.TryGetValue(clientId, out var playerId))
- {
- if(GetPlayerData(playerId)?.ClientId == clientId)
- {
- var clientData = PlayerDataDic[playerId];
- clientData.IsConnected = false;
- PlayerDataDic[playerId] = clientData;
- }
- }
- }
- else
- {
- //未初始化管理器。移除数据(无需保存数据)
- if(m_ClientIDToPlayerId.TryGetValue(clientId, out var playerId))
- {
- m_ClientIDToPlayerId.Remove(clientId);
- PlayerData data = GetPlayerData(playerId);
- if(data != null)
- {
- if(data.IsVideoClient)
- {
- CameraController.Instance.ShutDownComposition();
- }
- if(data.ClientId == clientId)
- {
- PlayerDataDic.Remove(playerId);
- }
- }
- }
- }
- }
- //该客户端是否已连接
- public bool IsDuplicateConnection(string playerId)
- {
- return PlayerDataDic.ContainsKey(playerId) && PlayerDataDic[playerId].IsConnected;
- }
- //关键方法,当客户端连接(重连)到服务端,则保存(更新)客户端数据。playerId是客户端生成并发送到服务端的Guid
- public void SetupConnectingPlayerSessionData(ulong clientId, string playerId, PlayerData sessionPlayerData)
- {
- var isReconnecting = false;
- //判断是否同一客户端
- if(IsDuplicateConnection(playerId))
- {
- Debug.LogError($"Player ID {playerId} already exists. This is a duplicate connection. Rejecting this session data.");
- return;
- }
- //判断是否重连
- if(PlayerDataDic.ContainsKey(playerId))
- {
- if(!PlayerDataDic[playerId].IsConnected)
- {
- isReconnecting = true;
- }
- }
- //重连,则更新客户端数据
- if(isReconnecting)
- {
- sessionPlayerData = PlayerDataDic[playerId];
- sessionPlayerData.ClientId = clientId;
- sessionPlayerData.IsConnected = true;
- }
- //缓存数据
- m_ClientIDToPlayerId[clientId] = playerId;
- PlayerDataDic[playerId] = sessionPlayerData;
- }
- //根据ClientId,获取PlayerId
- public string GetPlayerId(ulong clientId)
- {
- if(m_ClientIDToPlayerId.TryGetValue(clientId, out string playerId))
- {
- return playerId;
- }
- Debug.Log($"No client player ID found mapped to the given client ID: {clientId}");
- return null;
- }
- //根据ClientId获取客户端数据SessionPlayerData
- public PlayerData GetPlayerData(ulong clientId)
- {
- var playerId = GetPlayerId(clientId);
- if(playerId != null)
- {
- return GetPlayerData(playerId);
- }
- Debug.Log($"No client player ID found mapped to the given client ID: {clientId}");
- return null;
- }
- public PlayerData GetPlayerData(string playerId)
- {
- if(PlayerDataDic.TryGetValue(playerId, out PlayerData data))
- {
- return data;
- }
- Debug.Log($"No PlayerData of matching player ID found: {playerId}");
- return null;
- }
- public PlayerData GetConnectedPlayerData()
- {
- foreach(var playerData in PlayerDataDic.Values)
- {
- if(playerData.IsConnected && playerData.ClientId != NetworkManager.Singleton.LocalClientId)
- {
- return playerData;
- }
- }
- return null;
- }
- //更新某个ClientId的客户端数据SessionPlayerData
- public void SetPlayerData(ulong clientId, PlayerData sessionPlayerData)
- {
- if(m_ClientIDToPlayerId.TryGetValue(clientId, out string playerId))
- {
- PlayerDataDic[playerId] = sessionPlayerData;
- }
- else
- {
- Debug.LogError($"No client player ID found mapped to the given client ID: {clientId}");
- }
- }
- //断开所有客户端
- public void CloseAllClient()
- {
- foreach(var playerData in PlayerDataDic.Values)
- {
- NetworkManager.Singleton?.DisconnectClient(playerData.ClientId);
- }
- OnServerEnded();
- }
- //标记管理器已经启动。可以缓存已断开连接的客户端数据
- public void OnSessionStarted()
- {
- m_HasSessionStarted = true;
- }
-
- //重新初始化已连接的客户端。清空所有断开的客户端数据(下次连上,则标识为新客户端)
- public void OnSessionEnded()
- {
- ClearDisconnectedPlayersData();
- ReinitializePlayersData();
- m_HasSessionStarted = false;
- }
- //服务端关闭,清空所有数据
- public void OnServerEnded()
- {
- PlayerDataDic.Clear();
- m_ClientIDToPlayerId.Clear();
- m_HasSessionStarted = false;
- }
- //重新初始化已连接的客户端。调用每个客户端的SessionPlayerData.Reinitialize方法
- void ReinitializePlayersData()
- {
- foreach(var id in m_ClientIDToPlayerId.Keys)
- {
- string playerId = m_ClientIDToPlayerId[id];
- PlayerData sessionPlayerData = PlayerDataDic[playerId];
- sessionPlayerData.Reinitialize();
- PlayerDataDic[playerId] = sessionPlayerData;
- }
- }
- //清空所有断开的客户端数据
- void ClearDisconnectedPlayersData()
- {
- //收集所有断开连接的客户端
- List<ulong> idsToClear = new List<ulong>();
- foreach(var id in m_ClientIDToPlayerId.Keys)
- {
- var data = GetPlayerData(id);
- if(data is { IsConnected: false })
- {
- idsToClear.Add(id);
- }
- }
- //移除数据
- foreach(var id in idsToClear)
- {
- string playerId = m_ClientIDToPlayerId[id];
- if(GetPlayerData(playerId)?.ClientId == id)
- {
- PlayerDataDic.Remove(playerId);
- }
- m_ClientIDToPlayerId.Remove(id);
- }
- }
- public bool HaveAnchorPlayer()
- {
- foreach(var client in PlayerDataDic)
- {
- PlayerData playerData = client.Value;
- if(playerData.IsConnected && playerData.Anchor != null)
- {
- return true;
- }
- }
- return false;
- }
- public bool HaveVideoPlayer()
- {
- foreach(var client in PlayerDataDic)
- {
- PlayerData playerData = client.Value;
- if(playerData.IsConnected && playerData.IsVideoClient)
- {
- return true;
- }
- }
- return false;
- }
- public PlayerData GetVideoPlayer()
- {
- foreach(var client in PlayerDataDic)
- {
- PlayerData playerData = client.Value;
- if(playerData.IsConnected && playerData.IsVideoClient)
- {
- return playerData;
- }
- }
- return null;
- }
- public bool HavePlayer()
- {
- foreach(var client in PlayerDataDic)
- {
- PlayerData playerData = client.Value;
- if(playerData.IsConnected && playerData.ClientId != 0)
- {
- return true;
- }
- }
- return false;
- }
- }
|