Seven is the number.
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.

411 lines
14 KiB

4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
  1. // ----------------------------------------------------------------------------
  2. // <copyright file="SupportLogger.cs" company="Exit Games GmbH">
  3. // Loadbalancing Framework for Photon - Copyright (C) 2018 Exit Games GmbH
  4. // </copyright>
  5. // <summary>
  6. // Implements callbacks of the Realtime API to logs selected information
  7. // for support cases.
  8. // </summary>
  9. // <author>developer@photonengine.com</author>
  10. // ----------------------------------------------------------------------------
  11. #if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER
  12. #define SUPPORTED_UNITY
  13. #endif
  14. namespace Photon.Realtime
  15. {
  16. using System.Text;
  17. using System.Collections;
  18. using System.Collections.Generic;
  19. using Stopwatch = System.Diagnostics.Stopwatch;
  20. using ExitGames.Client.Photon;
  21. #if SUPPORTED_UNITY
  22. using UnityEngine;
  23. #endif
  24. #if SUPPORTED_UNITY || NETFX_CORE
  25. using Hashtable = ExitGames.Client.Photon.Hashtable;
  26. using SupportClass = ExitGames.Client.Photon.SupportClass;
  27. #endif
  28. /// <summary>
  29. /// Helper class to debug log basic information about Photon client and vital traffic statistics.
  30. /// </summary>
  31. /// <remarks>
  32. /// Set SupportLogger.Client for this to work.
  33. /// </remarks>
  34. #if SUPPORTED_UNITY
  35. [DisallowMultipleComponent]
  36. [AddComponentMenu("")] // hide from Unity Menus and searches
  37. public class SupportLogger : MonoBehaviour, IConnectionCallbacks , IMatchmakingCallbacks , IInRoomCallbacks, ILobbyCallbacks, IErrorInfoCallback
  38. #else
  39. public class SupportLogger : IConnectionCallbacks, IInRoomCallbacks, IMatchmakingCallbacks , ILobbyCallbacks
  40. #endif
  41. {
  42. /// <summary>
  43. /// Toggle to enable or disable traffic statistics logging.
  44. /// </summary>
  45. public bool LogTrafficStats = true;
  46. private bool loggedStillOfflineMessage;
  47. private LoadBalancingClient client;
  48. private Stopwatch startStopwatch;
  49. private int pingMax;
  50. private int pingMin;
  51. /// <summary>
  52. /// Photon client to log information and statistics from.
  53. /// </summary>
  54. public LoadBalancingClient Client
  55. {
  56. get { return this.client; }
  57. set
  58. {
  59. if (this.client != value)
  60. {
  61. if (this.client != null)
  62. {
  63. this.client.RemoveCallbackTarget(this);
  64. }
  65. this.client = value;
  66. if (this.client != null)
  67. {
  68. this.client.AddCallbackTarget(this);
  69. }
  70. }
  71. }
  72. }
  73. #if SUPPORTED_UNITY
  74. protected void Start()
  75. {
  76. this.LogBasics();
  77. if (this.startStopwatch == null)
  78. {
  79. this.startStopwatch = new Stopwatch();
  80. this.startStopwatch.Start();
  81. }
  82. }
  83. protected void OnDestroy()
  84. {
  85. this.Client = null; // will remove this SupportLogger as callback target
  86. }
  87. protected void OnApplicationPause(bool pause)
  88. {
  89. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnApplicationPause: " + pause + " connected: " + (this.client == null ? "no (client is null)" : this.client.IsConnected.ToString()));
  90. }
  91. protected void OnApplicationQuit()
  92. {
  93. this.CancelInvoke();
  94. }
  95. #endif
  96. public void StartLogStats()
  97. {
  98. #if SUPPORTED_UNITY
  99. this.InvokeRepeating("LogStats", 10, 10);
  100. #else
  101. Debug.Log("Not implemented for non-Unity projects.");
  102. #endif
  103. }
  104. public void StopLogStats()
  105. {
  106. #if SUPPORTED_UNITY
  107. this.CancelInvoke("LogStats");
  108. #else
  109. Debug.Log("Not implemented for non-Unity projects.");
  110. #endif
  111. }
  112. private void StartTrackValues()
  113. {
  114. #if SUPPORTED_UNITY
  115. this.InvokeRepeating("TrackValues", 0.5f, 0.5f);
  116. #else
  117. Debug.Log("Not implemented for non-Unity projects.");
  118. #endif
  119. }
  120. private void StopTrackValues()
  121. {
  122. #if SUPPORTED_UNITY
  123. this.CancelInvoke("TrackValues");
  124. #else
  125. Debug.Log("Not implemented for non-Unity projects.");
  126. #endif
  127. }
  128. private string GetFormattedTimestamp()
  129. {
  130. if (this.startStopwatch == null)
  131. {
  132. this.startStopwatch = new Stopwatch();
  133. this.startStopwatch.Start();
  134. }
  135. return string.Format("[{0}.{1}]", this.startStopwatch.Elapsed.Seconds, this.startStopwatch.Elapsed.Milliseconds);
  136. }
  137. // called via InvokeRepeatedly
  138. private void TrackValues()
  139. {
  140. if (this.client != null)
  141. {
  142. int currentRtt = this.client.LoadBalancingPeer.RoundTripTime;
  143. if (currentRtt > this.pingMax)
  144. {
  145. this.pingMax = currentRtt;
  146. }
  147. if (currentRtt < this.pingMin)
  148. {
  149. this.pingMin = currentRtt;
  150. }
  151. }
  152. }
  153. /// <summary>
  154. /// Debug logs vital traffic statistics about the attached Photon Client.
  155. /// </summary>
  156. public void LogStats()
  157. {
  158. if (this.client == null || this.client.State == ClientState.PeerCreated)
  159. {
  160. return;
  161. }
  162. if (this.LogTrafficStats)
  163. {
  164. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger " + this.client.LoadBalancingPeer.VitalStatsToString(false) + " Ping min/max: " + this.pingMin + "/" + this.pingMax);
  165. }
  166. }
  167. /// <summary>
  168. /// Debug logs basic information (AppId, AppVersion, PeerID, Server address, Region) about the attached Photon Client.
  169. /// </summary>
  170. private void LogBasics()
  171. {
  172. if (this.client != null)
  173. {
  174. List<string> buildProperties = new List<string>(10);
  175. #if SUPPORTED_UNITY
  176. buildProperties.Add(Application.unityVersion);
  177. buildProperties.Add(Application.platform.ToString());
  178. #endif
  179. #if ENABLE_IL2CPP
  180. buildProperties.Add("ENABLE_IL2CPP");
  181. #endif
  182. #if ENABLE_MONO
  183. buildProperties.Add("ENABLE_MONO");
  184. #endif
  185. #if DEBUG
  186. buildProperties.Add("DEBUG");
  187. #endif
  188. #if MASTER
  189. buildProperties.Add("MASTER");
  190. #endif
  191. #if NET_4_6
  192. buildProperties.Add("NET_4_6");
  193. #endif
  194. #if NET_STANDARD_2_0
  195. buildProperties.Add("NET_STANDARD_2_0");
  196. #endif
  197. #if NETFX_CORE
  198. buildProperties.Add("NETFX_CORE");
  199. #endif
  200. #if NET_LEGACY
  201. buildProperties.Add("NET_LEGACY");
  202. #endif
  203. #if UNITY_64
  204. buildProperties.Add("UNITY_64");
  205. #endif
  206. StringBuilder sb = new StringBuilder();
  207. string appIdShort = string.IsNullOrEmpty(this.client.AppId) || this.client.AppId.Length < 8 ? this.client.AppId : string.Concat(this.client.AppId.Substring(0, 8), "***");
  208. sb.AppendFormat("{0} SupportLogger Info: ", this.GetFormattedTimestamp());
  209. sb.AppendFormat("AppID: \"{0}\" AppVersion: \"{1}\" Client: v{2} ({4}) Build: {3} ", appIdShort, this.client.AppVersion, this.client.LoadBalancingPeer.ClientVersion, string.Join(", ", buildProperties.ToArray()), this.client.LoadBalancingPeer.TargetFramework);
  210. if (this.client != null && this.client.LoadBalancingPeer != null && this.client.LoadBalancingPeer.SocketImplementation != null)
  211. {
  212. sb.AppendFormat("Socket: {0} ", this.client.LoadBalancingPeer.SocketImplementation.Name);
  213. }
  214. sb.AppendFormat("UserId: \"{0}\" AuthType: {1} AuthMode: {2} {3} ", this.client.UserId, (this.client.AuthValues != null) ? this.client.AuthValues.AuthType.ToString() : "N/A", this.client.AuthMode, this.client.EncryptionMode);
  215. sb.AppendFormat("State: {0} ", this.client.State);
  216. sb.AppendFormat("PeerID: {0} ", this.client.LoadBalancingPeer.PeerID);
  217. sb.AppendFormat("NameServer: {0} Current Server: {1} IP: {2} Region: {3} ", this.client.NameServerHost, this.client.CurrentServerAddress, this.client.LoadBalancingPeer.ServerIpAddress, this.client.CloudRegion);
  218. Debug.LogWarning(sb.ToString());
  219. }
  220. }
  221. public void OnConnected()
  222. {
  223. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnConnected().");
  224. this.pingMax = 0;
  225. this.pingMin = this.client.LoadBalancingPeer.RoundTripTime;
  226. this.LogBasics();
  227. if (this.LogTrafficStats)
  228. {
  229. this.client.LoadBalancingPeer.TrafficStatsEnabled = false;
  230. this.client.LoadBalancingPeer.TrafficStatsEnabled = true;
  231. this.StartLogStats();
  232. }
  233. this.StartTrackValues();
  234. }
  235. public void OnConnectedToMaster()
  236. {
  237. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnConnectedToMaster().");
  238. }
  239. public void OnFriendListUpdate(List<FriendInfo> friendList)
  240. {
  241. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnFriendListUpdate(friendList).");
  242. }
  243. public void OnJoinedLobby()
  244. {
  245. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnJoinedLobby(" + this.client.CurrentLobby + ").");
  246. }
  247. public void OnLeftLobby()
  248. {
  249. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnLeftLobby().");
  250. }
  251. public void OnCreateRoomFailed(short returnCode, string message)
  252. {
  253. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnCreateRoomFailed(" + returnCode+","+message+").");
  254. }
  255. public void OnJoinedRoom()
  256. {
  257. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnJoinedRoom(" + this.client.CurrentRoom + "). " + this.client.CurrentLobby + " GameServer:" + this.client.GameServerAddress);
  258. }
  259. public void OnJoinRoomFailed(short returnCode, string message)
  260. {
  261. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnJoinRoomFailed(" + returnCode+","+message+").");
  262. }
  263. public void OnJoinRandomFailed(short returnCode, string message)
  264. {
  265. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnJoinRandomFailed(" + returnCode+","+message+").");
  266. }
  267. public void OnCreatedRoom()
  268. {
  269. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnCreatedRoom(" + this.client.CurrentRoom + "). " + this.client.CurrentLobby + " GameServer:" + this.client.GameServerAddress);
  270. }
  271. public void OnLeftRoom()
  272. {
  273. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnLeftRoom().");
  274. }
  275. public void OnDisconnected(DisconnectCause cause)
  276. {
  277. this.StopLogStats();
  278. this.StopTrackValues();
  279. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnDisconnected(" + cause + ").");
  280. this.LogBasics();
  281. this.LogStats();
  282. }
  283. public void OnRegionListReceived(RegionHandler regionHandler)
  284. {
  285. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnRegionListReceived(regionHandler).");
  286. }
  287. public void OnRoomListUpdate(List<RoomInfo> roomList)
  288. {
  289. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnRoomListUpdate(roomList). roomList.Count: " + roomList.Count);
  290. }
  291. public void OnPlayerEnteredRoom(Player newPlayer)
  292. {
  293. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnPlayerEnteredRoom(" + newPlayer+").");
  294. }
  295. public void OnPlayerLeftRoom(Player otherPlayer)
  296. {
  297. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnPlayerLeftRoom(" + otherPlayer+").");
  298. }
  299. public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
  300. {
  301. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnRoomPropertiesUpdate(propertiesThatChanged).");
  302. }
  303. public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
  304. {
  305. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnPlayerPropertiesUpdate(targetPlayer,changedProps).");
  306. }
  307. public void OnMasterClientSwitched(Player newMasterClient)
  308. {
  309. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnMasterClientSwitched(" + newMasterClient+").");
  310. }
  311. public void OnCustomAuthenticationResponse(Dictionary<string, object> data)
  312. {
  313. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnCustomAuthenticationResponse(" + data.ToStringFull()+").");
  314. }
  315. public void OnCustomAuthenticationFailed (string debugMessage)
  316. {
  317. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnCustomAuthenticationFailed(" + debugMessage+").");
  318. }
  319. public void OnLobbyStatisticsUpdate(List<TypedLobbyInfo> lobbyStatistics)
  320. {
  321. Debug.Log(this.GetFormattedTimestamp() + " SupportLogger OnLobbyStatisticsUpdate(lobbyStatistics).");
  322. }
  323. #if !SUPPORTED_UNITY
  324. private static class Debug
  325. {
  326. public static void Log(string msg)
  327. {
  328. System.Diagnostics.Debug.WriteLine(msg);
  329. }
  330. public static void LogWarning(string msg)
  331. {
  332. System.Diagnostics.Debug.WriteLine(msg);
  333. }
  334. public static void LogError(string msg)
  335. {
  336. System.Diagnostics.Debug.WriteLine(msg);
  337. }
  338. }
  339. #endif
  340. public void OnErrorInfo(ErrorInfo errorInfo)
  341. {
  342. Debug.LogError(errorInfo.ToString());
  343. }
  344. }
  345. }