ServerSettingsInspector.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // ----------------------------------------------------------------------------
  2. // <copyright file="ServerSettingsInspector.cs" company="Exit Games GmbH">
  3. // PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
  4. // </copyright>
  5. // <summary>
  6. // This is a custom editor for the ServerSettings scriptable object.
  7. // </summary>
  8. // <author>developer@exitgames.com</author>
  9. // ----------------------------------------------------------------------------
  10. using System;
  11. using UnityEditor;
  12. using UnityEngine;
  13. using Photon.Pun;
  14. using ExitGames.Client.Photon;
  15. using System.Collections.Generic;
  16. using System.Reflection;
  17. using Photon.Realtime;
  18. namespace Photon.Pun
  19. {
  20. [CustomEditor(typeof(ServerSettings))]
  21. public class ServerSettingsInspector : Editor
  22. {
  23. private string versionPhoton;
  24. private string[] regionsPrefsList;
  25. private string prefLabel;
  26. private const string notAvailableLabel = "n/a";
  27. private string rpcCrc;
  28. private bool showRpcs;
  29. private GUIStyle vertboxStyle;
  30. public void Awake()
  31. {
  32. this.versionPhoton = System.Reflection.Assembly.GetAssembly(typeof(PhotonPeer)).GetName().Version.ToString();
  33. }
  34. public override void OnInspectorGUI()
  35. {
  36. if (vertboxStyle == null)
  37. vertboxStyle = new GUIStyle("HelpBox") { padding = new RectOffset(6, 6, 6, 6) };
  38. SerializedObject sObj = new SerializedObject(this.target);
  39. ServerSettings settings = this.target as ServerSettings;
  40. EditorGUI.BeginChangeCheck();
  41. #region Version Vertical Box
  42. EditorGUILayout.BeginVertical(/*vertboxStyle*/);
  43. EditorGUILayout.BeginHorizontal();
  44. EditorGUILayout.PrefixLabel(new GUIContent("Version:", "Version of PUN and Photon3Unity3d.dll."));
  45. GUILayout.FlexibleSpace();
  46. var helpicorect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(16));
  47. EditorGUIUtility.AddCursorRect(helpicorect, MouseCursor.Link);
  48. if (GUI.Button(helpicorect, PhotonGUI.HelpIcon, GUIStyle.none))
  49. {
  50. Application.OpenURL(PhotonEditor.UrlPunSettings);
  51. }
  52. EditorGUILayout.EndHorizontal();
  53. EditorGUILayout.LabelField("Pun: " + PhotonNetwork.PunVersion + " Photon lib: " + this.versionPhoton);
  54. EditorGUILayout.EndVertical();
  55. #endregion Version Vertical Box
  56. EditorGUI.indentLevel--;
  57. SerializedProperty showSettingsProp = this.serializedObject.FindProperty("ShowSettings");
  58. bool showSettings = showSettingsProp.Foldout(new GUIContent("Server/Cloud Settings", "Core Photon Server/Cloud settings."));
  59. EditorGUI.indentLevel++;
  60. if (showSettings != settings.ShowSettings)
  61. {
  62. showSettingsProp.boolValue = showSettings;
  63. }
  64. if (showSettingsProp.boolValue)
  65. {
  66. SerializedProperty settingsSp = this.serializedObject.FindProperty("AppSettings");
  67. EditorGUI.indentLevel++;
  68. //Realtime APP ID
  69. this.BuildAppIdField(settingsSp.FindPropertyRelative("AppIdRealtime"), "App Id PUN");
  70. if (PhotonEditorUtils.HasChat)
  71. {
  72. this.BuildAppIdField(settingsSp.FindPropertyRelative("AppIdChat"));
  73. }
  74. if (PhotonEditorUtils.HasVoice)
  75. {
  76. this.BuildAppIdField(settingsSp.FindPropertyRelative("AppIdVoice"));
  77. }
  78. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("AppVersion"));
  79. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("UseNameServer"), new GUIContent("Use Name Server", "Photon Cloud requires this checked.\nUncheck for Photon Server SDK (OnPremise)."));
  80. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("FixedRegion"), new GUIContent("Fixed Region", "Photon Cloud setting, needs a Name Server.\nDefine one region to always connect to.\nLeave empty to use the best region from a server-side region list."));
  81. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("Server"), new GUIContent("Server", "Typically empty for Photon Cloud.\nFor Photon OnPremise, enter your host name or IP. Also uncheck \"Use Name Server\" for older Photon OnPremise servers."));
  82. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("Port"), new GUIContent("Port", "Leave 0 to use default Photon Cloud ports for the Name Server.\nOnPremise defaults to 5055 for UDP and 4530 for TCP."));
  83. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("ProxyServer"), new GUIContent("Proxy Server", "HTTP Proxy Server for WebSocket connection. See LoadBalancingClient.ProxyServerAddress for options."));
  84. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("Protocol"), new GUIContent("Protocol", "Use UDP where possible.\nWSS works on WebGL and Xbox exports.\nDefine WEBSOCKET for use on other platforms."));
  85. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("EnableProtocolFallback"), new GUIContent("Protocol Fallback", "Automatically try another network protocol, if initial connect fails.\nWill use default Name Server ports."));
  86. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("EnableLobbyStatistics"), new GUIContent("Lobby Statistics", "When using multiple room lists (lobbies), the server can send info about their usage."));
  87. EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("NetworkLogging"), new GUIContent("Network Logging", "Log level for the Photon libraries."));
  88. EditorGUI.indentLevel--;
  89. }
  90. EditorGUILayout.PropertyField(this.serializedObject.FindProperty("PunLogging"), new GUIContent("PUN Logging", "Log level for the PUN layer."));
  91. EditorGUILayout.PropertyField(this.serializedObject.FindProperty("EnableSupportLogger"), new GUIContent("Support Logger", "Logs additional info for debugging.\nUse this when you submit bugs to the Photon Team."));
  92. EditorGUILayout.PropertyField(this.serializedObject.FindProperty("RunInBackground"), new GUIContent("Run In Background", "Enables apps to keep the connection without focus. Android and iOS ignore this."));
  93. EditorGUILayout.PropertyField(this.serializedObject.FindProperty("StartInOfflineMode"), new GUIContent("Start In Offline Mode", "Simulates an online connection.\nPUN can be used as usual."));
  94. EditorGUILayout.PropertyField(this.serializedObject.FindProperty("DevRegion"), new GUIContent("Dev Region", "Photon Cloud setting, needs a Name Server.\nDefine region the Editor and Development builds will always connect to - ensuring all users can find common rooms.\nLeave empty to use the Fixed Region or best region from a server-side region list. This value will be ignored for non-Development builds."));
  95. #region Best Region Box
  96. EditorGUILayout.BeginVertical(vertboxStyle);
  97. if (!string.IsNullOrEmpty(PhotonNetwork.BestRegionSummaryInPreferences))
  98. {
  99. this.regionsPrefsList = PhotonNetwork.BestRegionSummaryInPreferences.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries);
  100. if (this.regionsPrefsList.Length < 2)
  101. {
  102. this.prefLabel = notAvailableLabel;
  103. }
  104. else
  105. {
  106. this.prefLabel = string.Format("'{0}' ping:{1}ms ", this.regionsPrefsList[0], this.regionsPrefsList[1]);
  107. }
  108. }
  109. else
  110. {
  111. this.prefLabel = notAvailableLabel;
  112. }
  113. EditorGUILayout.LabelField(new GUIContent("Best Region Preference: " + prefLabel, "Best region is used if Fixed Region is empty."));
  114. EditorGUILayout.BeginHorizontal();
  115. var resetrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
  116. var editrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
  117. if (GUI.Button(resetrect, "Reset", EditorStyles.miniButton))
  118. {
  119. ServerSettings.ResetBestRegionCodeInPreferences();
  120. }
  121. if (GUI.Button(editrect, "Edit Allowlist", EditorStyles.miniButton))
  122. {
  123. Application.OpenURL("https://dashboard.photonengine.com/en-US/App/RegionsWhitelistEdit/" + PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime);
  124. }
  125. EditorGUILayout.EndHorizontal();
  126. EditorGUILayout.EndVertical();
  127. #endregion Best Region Box
  128. //this.showRpcs = EditorGUILayout.Foldout(this.showRpcs, new GUIContent("RPCs", "RPC shortcut list."));
  129. EditorGUI.indentLevel--;
  130. this.showRpcs = this.showRpcs.Foldout(new GUIContent("RPCs", "RPC shortcut list."));
  131. EditorGUI.indentLevel++;
  132. if (this.showRpcs)
  133. {
  134. // first time check to get the rpc has proper
  135. if (string.IsNullOrEmpty(this.rpcCrc))
  136. {
  137. this.rpcCrc = this.RpcListHashCode().ToString("X");
  138. }
  139. #region Begin Vertical Box CRC
  140. EditorGUILayout.BeginVertical(vertboxStyle);
  141. EditorGUILayout.BeginHorizontal();
  142. EditorGUILayout.PrefixLabel("List CRC");
  143. EditorGUI.indentLevel--;
  144. var copyrect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(16));
  145. EditorGUILayout.GetControlRect(GUILayout.MaxWidth(12));
  146. var hashrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(16)); // new Rect(copyrect) { xMin = copyrect.xMin + 32 };
  147. EditorGUIUtility.AddCursorRect(copyrect, MouseCursor.Link);
  148. EditorGUI.LabelField(copyrect, new GUIContent("", "Copy Hashcode to Clipboard"));
  149. if (GUI.Button(copyrect, PhotonGUI.CopyIcon, GUIStyle.none))
  150. {
  151. Debug.Log("RPC-List HashCode copied into your ClipBoard: " + this.rpcCrc + ". Make sure clients that send each other RPCs have the same RPC-List.");
  152. EditorGUIUtility.systemCopyBuffer = this.rpcCrc;
  153. }
  154. EditorGUI.SelectableLabel(hashrect, this.rpcCrc);
  155. EditorGUILayout.EndHorizontal();
  156. EditorGUI.indentLevel++;
  157. EditorGUILayout.BeginHorizontal();
  158. var refreshrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
  159. var clearrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
  160. if (GUI.Button(refreshrect, "Refresh RPCs", EditorStyles.miniButton))
  161. {
  162. PhotonEditor.UpdateRpcList();
  163. this.Repaint();
  164. }
  165. if (GUI.Button(clearrect, "Clear RPCs", EditorStyles.miniButton))
  166. {
  167. PhotonEditor.ClearRpcList();
  168. }
  169. EditorGUILayout.EndHorizontal();
  170. EditorGUILayout.EndVertical();
  171. #endregion End Vertical Box CRC
  172. EditorGUI.indentLevel++;
  173. SerializedProperty sRpcs = sObj.FindProperty("RpcList");
  174. EditorGUILayout.PropertyField(sRpcs, true);
  175. EditorGUI.indentLevel--;
  176. }
  177. if (EditorGUI.EndChangeCheck())
  178. {
  179. sObj.ApplyModifiedProperties();
  180. this.serializedObject.ApplyModifiedProperties();
  181. // cache the rpc hash
  182. this.rpcCrc = this.RpcListHashCode().ToString("X");
  183. }
  184. #region Simple Settings
  185. /// Conditional Simple Sync Settings DrawGUI - Uses reflection to avoid having to hard connect the libraries
  186. var SettingsScriptableObjectBaseType = GetType("Photon.Utilities.SettingsScriptableObjectBase");
  187. if (SettingsScriptableObjectBaseType != null)
  188. {
  189. EditorGUILayout.GetControlRect(false, 3);
  190. EditorGUILayout.LabelField("Simple Extension Settings", (GUIStyle)"BoldLabel");
  191. var drawAllMethod = SettingsScriptableObjectBaseType.GetMethod("DrawAllSettings");
  192. if (drawAllMethod != null && this != null)
  193. {
  194. bool initializeAsOpen = false;
  195. drawAllMethod.Invoke(null, new object[2] { this, initializeAsOpen });
  196. }
  197. }
  198. #endregion
  199. }
  200. private static Type GetType(string typeName)
  201. {
  202. var type = Type.GetType(typeName);
  203. if (type != null) return type;
  204. foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
  205. {
  206. type = a.GetType(typeName);
  207. if (type != null)
  208. return type;
  209. }
  210. return null;
  211. }
  212. private int RpcListHashCode()
  213. {
  214. // this is a hashcode generated to (more) easily compare this Editor's RPC List with some other
  215. int hashCode = PhotonNetwork.PhotonServerSettings.RpcList.Count + 1;
  216. foreach (string s in PhotonNetwork.PhotonServerSettings.RpcList)
  217. {
  218. int h1 = s.GetHashCode();
  219. hashCode = ((h1 << 5) + h1) ^ hashCode;
  220. }
  221. return hashCode;
  222. }
  223. private void BuildAppIdField(SerializedProperty property, string label = null)
  224. {
  225. EditorGUILayout.BeginHorizontal();
  226. if (label != null)
  227. {
  228. EditorGUILayout.PropertyField(property, new GUIContent(label), GUILayout.MinWidth(32));
  229. }
  230. else
  231. {
  232. EditorGUILayout.PropertyField(property, GUILayout.MinWidth(32));
  233. }
  234. property.stringValue = property.stringValue.Trim();
  235. string appId = property.stringValue;
  236. string url = "https://dashboard.photonengine.com/en-US/PublicCloud";
  237. if (!string.IsNullOrEmpty(appId))
  238. {
  239. url = string.Format("https://dashboard.photonengine.com/en-US/App/Manage/{0}", appId);
  240. }
  241. if (GUILayout.Button("Dashboard", EditorStyles.miniButton, GUILayout.MinWidth(78), GUILayout.MaxWidth(78)))
  242. {
  243. Application.OpenURL(url);
  244. }
  245. EditorGUILayout.EndHorizontal();
  246. }
  247. }
  248. }