ATIntegrationManagerWindow.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. namespace AnyThink.Scripts.IntegrationManager.Editor
  11. {
  12. public class ATIntegrationManagerWindow : EditorWindow
  13. {
  14. private const string windowTitle = "AnyThink Integration Manager";
  15. private const string uninstallIconExportPath = "AnyThinkPlugin/Resources/Images/uninstall_icon.png";
  16. private const string alertIconExportPath = "AnyThinkPlugin/Resources/Images/alert_icon.png";
  17. private const string warningIconExportPath = "AnyThinkPlugin/Resources/Images/warning_icon.png";
  18. private static readonly Color darkModeTextColor = new Color(0.29f, 0.6f, 0.8f);
  19. private GUIStyle titleLabelStyle;
  20. private GUIStyle headerLabelStyle;
  21. private GUIStyle environmentValueStyle;
  22. private GUIStyle wrapTextLabelStyle;
  23. private GUIStyle linkLabelStyle;
  24. private GUIStyle iconStyle;
  25. private GUIStyle tipTextStyle;
  26. private Texture2D uninstallIcon;
  27. private Texture2D alertIcon;
  28. private Texture2D warningIcon;
  29. private Vector2 scrollPosition;
  30. private static readonly Vector2 windowMinSize = new Vector2(850, 750);
  31. private const float actionFieldWidth = 80f;
  32. private const float upgradeAllButtonWidth = 80f;
  33. private const float networkFieldMinWidth = 200f;
  34. private const float versionFieldMinWidth = 200f;
  35. private const float privacySettingLabelWidth = 200f;
  36. private const float networkFieldWidthPercentage = 0.22f;
  37. private const float versionFieldWidthPercentage = 0.36f; // There are two version fields. Each take 40% of the width, network field takes the remaining 20%.
  38. private static float previousWindowWidth = windowMinSize.x;
  39. private static GUILayoutOption networkWidthOption = GUILayout.Width(networkFieldMinWidth);
  40. private static GUILayoutOption versionWidthOption = GUILayout.Width(versionFieldMinWidth);
  41. private static GUILayoutOption sdkKeyTextFieldWidthOption = GUILayout.Width(520);
  42. private static GUILayoutOption privacySettingFieldWidthOption = GUILayout.Width(400);
  43. private static readonly GUILayoutOption fieldWidth = GUILayout.Width(actionFieldWidth);
  44. private static readonly GUILayoutOption upgradeAllButtonFieldWidth = GUILayout.Width(upgradeAllButtonWidth);
  45. private ATEditorCoroutine loadDataCoroutine;
  46. private PluginData pluginData;
  47. private bool pluginDataLoadFailed;
  48. private bool networkButtonsEnabled = true;
  49. private bool shouldShowGoogleWarning;
  50. private int curSelectCountryInt;
  51. // private int dropdownIndex = 0;
  52. private int androidVersionPopupIndex;
  53. private int iosVersionPopupIndex;
  54. public static void ShowManager()
  55. {
  56. var manager = GetWindow<ATIntegrationManagerWindow>(utility: true, title: windowTitle, focus: true);
  57. manager.minSize = windowMinSize;
  58. // manager.maxSize = windowMinSize;
  59. }
  60. //定义UI的Style
  61. private void Awake()
  62. {
  63. titleLabelStyle = new GUIStyle(EditorStyles.label)
  64. {
  65. fontSize = 14,
  66. fontStyle = FontStyle.Bold,
  67. fixedHeight = 20
  68. };
  69. headerLabelStyle = new GUIStyle(EditorStyles.label)
  70. {
  71. fontSize = 12,
  72. fontStyle = FontStyle.Bold,
  73. fixedHeight = 18
  74. };
  75. environmentValueStyle = new GUIStyle(EditorStyles.label)
  76. {
  77. alignment = TextAnchor.MiddleRight
  78. };
  79. linkLabelStyle = new GUIStyle(EditorStyles.label)
  80. {
  81. wordWrap = true,
  82. normal = { textColor = EditorGUIUtility.isProSkin ? darkModeTextColor : Color.blue }
  83. };
  84. wrapTextLabelStyle = new GUIStyle(EditorStyles.label)
  85. {
  86. wordWrap = true
  87. };
  88. iconStyle = new GUIStyle(EditorStyles.miniButton)
  89. {
  90. fixedWidth = 18,
  91. fixedHeight = 18,
  92. padding = new RectOffset(1, 1, 1, 1)
  93. };
  94. tipTextStyle = new GUIStyle(EditorStyles.label)
  95. {
  96. normal = { textColor = Color.yellow }
  97. };
  98. // Load uninstall icon texture.
  99. var uninstallIconData = File.ReadAllBytes(ATSdkUtil.GetAssetPathForExportPath(uninstallIconExportPath));
  100. uninstallIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false); // 1. Initial size doesn't matter here, will be automatically resized once the image asset is loaded. 2. Set mipChain to false, else the texture has a weird blurry effect.
  101. uninstallIcon.LoadImage(uninstallIconData);
  102. // Load alert icon texture.
  103. var alertIconData = File.ReadAllBytes(ATSdkUtil.GetAssetPathForExportPath(alertIconExportPath));
  104. alertIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false);
  105. alertIcon.LoadImage(alertIconData);
  106. // Load warning icon texture.
  107. var warningIconData = File.ReadAllBytes(ATSdkUtil.GetAssetPathForExportPath(warningIconExportPath));
  108. warningIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false);
  109. warningIcon.LoadImage(warningIconData);
  110. loadPluginData();
  111. //热更新
  112. ATIntegrationHotFix.Instance.loadHotFixData();
  113. }
  114. //这个方法在插件启动时会调用,然后脚本重新加载时也会重新调用,所以加载数据放在Awake中
  115. private void OnEnable()
  116. {
  117. }
  118. private void OnDisable()
  119. {
  120. if (loadDataCoroutine != null)
  121. {
  122. loadDataCoroutine.Stop();
  123. loadDataCoroutine = null;
  124. }
  125. ATIntegrationManager.Instance.CancelDownload();
  126. EditorUtility.ClearProgressBar();
  127. // Saves the AppLovinSettings object if it has been changed.
  128. AssetDatabase.SaveAssets();
  129. }
  130. private void OnDestroy() {
  131. ATLog.log("OnDestroy() >>> called");
  132. }
  133. private void OnGUI()
  134. {
  135. // OnGUI is called on each frame draw, so we don't want to do any unnecessary calculation if we can avoid it. So only calculate it when the width actually changed.
  136. if (Math.Abs(previousWindowWidth - position.width) > 1)
  137. {
  138. previousWindowWidth = position.width;
  139. CalculateFieldWidth();
  140. }
  141. using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollPosition, false, false))
  142. {
  143. scrollPosition = scrollView.scrollPosition;
  144. GUILayout.Space(5);
  145. // EditorGUILayout.LabelField("Region (Only for Android, iOS is not affected by region)", titleLabelStyle);
  146. EditorGUILayout.LabelField("Region", titleLabelStyle);
  147. DrawCountryUI();
  148. DrawCountrySwitchTip();
  149. DrawAndroidXUI();
  150. DrawAdombAppId();
  151. EditorGUILayout.LabelField("AnyThink Plugin Details", titleLabelStyle);
  152. //显示插件版本号
  153. DrawPluginDetails();
  154. //绘制SDK版本下架提示
  155. DrawSdkVersionOffTip();
  156. //绘制Networks
  157. DrawMediatedNetworks();
  158. }
  159. if (GUI.changed)
  160. {
  161. AssetDatabase.SaveAssets();
  162. }
  163. }
  164. /// <summary>
  165. /// Callback method that will be called with progress updates when the plugin is being downloaded.
  166. /// </summary>
  167. public static void OnDownloadPluginProgress(string pluginName, float progress, bool done)
  168. {
  169. ATLog.logFormat("OnDownloadPluginProgress() >>> pluginName: {0}, progress: {1}, done: {2}", new object[] { pluginName, progress, done });
  170. // Download is complete. Clear progress bar.
  171. if (done || progress == 1)
  172. {
  173. EditorUtility.ClearProgressBar();
  174. AssetDatabase.Refresh();
  175. }
  176. // Download is in progress, update progress bar.
  177. else
  178. {
  179. if (EditorUtility.DisplayCancelableProgressBar(windowTitle, string.Format("Downloading {0} plugin...", pluginName), progress))
  180. {
  181. ATLog.log("OnDownloadPluginProgress() >>> click cancel download");
  182. ATIntegrationManager.Instance.CancelDownload();
  183. EditorUtility.ClearProgressBar();
  184. AssetDatabase.Refresh();
  185. }
  186. }
  187. }
  188. public void DeleteSdkVersion(PluginData pluginData, int index, int os) {
  189. var sdkVersion = "";
  190. if (os == ATConfig.OS_IOS) {
  191. sdkVersion = pluginData.iosVersions[index];
  192. } else {
  193. sdkVersion = pluginData.androidVersions[index];
  194. }
  195. ATIntegrationManager.Instance.deleteSdk(pluginData, sdkVersion, os);
  196. }
  197. public void ExChangeSDKVersion(PluginData pluginData, int index, int os) {
  198. NetworkRequestParams requestParams = pluginData.requestParams;
  199. if (requestParams == null) {
  200. requestParams = new NetworkRequestParams();
  201. }
  202. requestParams.os = os;
  203. if (os == ATConfig.OS_ANDROID) { //Android
  204. requestParams.androidVersion = pluginData.androidVersions[index];
  205. } else {
  206. requestParams.iosVersion = pluginData.iosVersions[index];
  207. }
  208. pluginData.requestParams = requestParams;
  209. // ATLog.log("ExChangeSDKVersion() >>> versions.Android: " + versions.Android + " versions.Ios: " + versions.Ios);
  210. loadNetworksData(pluginData);
  211. }
  212. //获取插件和SDK的版本数据
  213. private void loadPluginData()
  214. {
  215. if (loadDataCoroutine != null)
  216. {
  217. loadDataCoroutine.Stop();
  218. }
  219. loadDataCoroutine = ATEditorCoroutine.startCoroutine(ATIntegrationManager.Instance.loadPluginData(data =>
  220. {
  221. if (data == null)
  222. {
  223. pluginDataLoadFailed = true;
  224. }
  225. else
  226. {
  227. ATLog.log("loadNetworksData() >>> pluginData: " + data);
  228. pluginData = data;
  229. pluginDataLoadFailed = false;
  230. var versions = pluginData.anyThink.CurrentVersions;
  231. if (versions != null) {
  232. var requestParams = new NetworkRequestParams();
  233. requestParams.androidVersion = versions.Android;
  234. requestParams.iosVersion = versions.Ios;
  235. pluginData.requestParams = requestParams;
  236. }
  237. loadNetworksData(pluginData);
  238. }
  239. CalculateFieldWidth();
  240. Repaint();
  241. }));
  242. }
  243. //获取networks
  244. private void loadNetworksData(PluginData pluginData)
  245. {
  246. ATEditorCoroutine.startCoroutine(ATIntegrationManager.Instance.loadNetworksData(pluginData, data =>
  247. {
  248. pluginData = data;
  249. Network network = pluginData.anyThink;
  250. if (!string.IsNullOrEmpty(network.AndroidDownloadUrl) || !string.IsNullOrEmpty(network.iOSDownloadloadUrl)) {
  251. ATIntegrationManager.Instance.downloadCorePlugin(data);
  252. }
  253. Repaint();
  254. }));
  255. }
  256. //切换国家,重新加载数据
  257. private void switchCountry(int country)
  258. {
  259. ATIntegrationManager.Instance.switchCountry(pluginData, country);
  260. //重新开始走network
  261. loadPluginData();
  262. }
  263. private void CalculateFieldWidth()
  264. {
  265. var currentWidth = position.width;
  266. var availableWidth = currentWidth - actionFieldWidth - 80; // NOTE: Magic number alert. This is the sum of all the spacing the fields and other UI elements.
  267. var networkLabelWidth = Math.Max(networkFieldMinWidth, availableWidth * networkFieldWidthPercentage);
  268. networkWidthOption = GUILayout.Width(networkLabelWidth);
  269. var versionLabelWidth = Math.Max(versionFieldMinWidth, availableWidth * versionFieldWidthPercentage);
  270. versionWidthOption = GUILayout.Width(versionLabelWidth);
  271. const int textFieldOtherUiElementsWidth = 45; // NOTE: Magic number alert. This is the sum of all the spacing the fields and other UI elements.
  272. var availableTextFieldWidth = currentWidth - networkLabelWidth - textFieldOtherUiElementsWidth;
  273. sdkKeyTextFieldWidthOption = GUILayout.Width(availableTextFieldWidth);
  274. var availableUserDescriptionTextFieldWidth = currentWidth - privacySettingLabelWidth - textFieldOtherUiElementsWidth;
  275. privacySettingFieldWidthOption = GUILayout.Width(availableUserDescriptionTextFieldWidth);
  276. }
  277. private void DrawCountryUI()
  278. {
  279. // GUILayout.BeginHorizontal();
  280. GUILayout.Space(4);
  281. using (new EditorGUILayout.HorizontalScope("box"))
  282. {
  283. GUILayout.Space(5);
  284. int countryInt = ATConfig.getDefCountry(); //默认是中国
  285. if (pluginData != null)
  286. {
  287. countryInt = pluginData.country;
  288. }
  289. string[] options = ATConfig.getCountryArray();
  290. // 创建Dropdown组件
  291. int curDropdownIndex = ATDataUtil.isChina(countryInt) ? 0 : 1;
  292. if (options.Length == 1) {
  293. curDropdownIndex = 0;
  294. }
  295. int dropdownIndex = EditorGUILayout.Popup("Select Region:", curDropdownIndex, options);
  296. if (options.Length > 1) {
  297. curSelectCountryInt = dropdownIndex == 0 ? ATConfig.CHINA_COUNTRY : ATConfig.NONCHINA_COUNTRY;
  298. //变化才设置
  299. if (pluginData != null && curSelectCountryInt != countryInt)
  300. {
  301. ATLog.log("DrawCountryUI() >>> curSelectCountryInt: " + curSelectCountryInt + " countryInt: " + countryInt);
  302. //Unity需要更换Network
  303. switchCountry(curSelectCountryInt);
  304. }
  305. }
  306. GUILayout.Space(5);
  307. }
  308. GUILayout.Space(4);
  309. // GUILayout.EndHorizontal();
  310. }
  311. private void DrawCountrySwitchTip()
  312. {
  313. var integratedTip = ATConfig.getRegionIntegrateTip();
  314. if (string.IsNullOrEmpty(integratedTip)) {
  315. return;
  316. }
  317. GUILayout.Space(4);
  318. // textStyle.fontStyle = FontStyle.Bold;
  319. EditorGUILayout.LabelField(integratedTip, tipTextStyle);
  320. GUILayout.Space(4);
  321. }
  322. private void DrawAndroidXUI()
  323. {
  324. bool isChina = ATConfig.isSelectedChina();
  325. // if (!ATConfig.isSelectedChina()) {
  326. // return;
  327. // }
  328. EditorGUILayout.LabelField("AndroidX (Only for Android)", titleLabelStyle);
  329. GUILayout.Space(4);
  330. using (new EditorGUILayout.HorizontalScope("box"))
  331. {
  332. GUILayout.Space(5);
  333. int androidXSetting = ATIntegrationManager.Instance.getAndroidXSetting(pluginData);
  334. string[] options = new string[] { "Default", "Enable", "Disable" };
  335. if (!isChina) {
  336. options = new string[] { "Default", "Enable" };
  337. }
  338. // 创建Dropdown组件
  339. int lastDropdownIndex = androidXSetting;
  340. int curDropdownIndex = EditorGUILayout.Popup("Enable AndroidX:", lastDropdownIndex, options);
  341. //变化才设置
  342. if (curDropdownIndex != lastDropdownIndex)
  343. {
  344. ATLog.log("DrawAndroidXUI() >>> curDropdownIndex: " + curDropdownIndex + " lastDropdownIndex: " + lastDropdownIndex);
  345. ATIntegrationManager.Instance.saveAndroidXSetting(pluginData, curDropdownIndex);
  346. }
  347. GUILayout.Space(5);
  348. }
  349. GUILayout.Space(4);
  350. }
  351. private void DrawPluginDetails()
  352. {
  353. // GUILayout.BeginHorizontal();
  354. GUILayout.Space(10);
  355. using (new EditorGUILayout.VerticalScope("box"))
  356. {
  357. // Draw plugin version details
  358. DrawHeaders("Platform", true);
  359. DrawPluginDetailRow("Unity Plugin", ATConfig.PLUGIN_VERSION, "", "");
  360. if (pluginData == null)
  361. {
  362. DrawEmptyPluginData("loading sdk data ...");
  363. return;
  364. }
  365. var anythink = pluginData.anyThink;
  366. var android_version = "";
  367. var ios_version = "";
  368. if (anythink != null) {
  369. android_version = anythink.CurrentVersions.Android;
  370. ios_version = anythink.CurrentVersions.Ios;
  371. }
  372. //绘制Android
  373. using (new EditorGUILayout.HorizontalScope())
  374. {
  375. GUILayout.Space(5);
  376. EditorGUILayout.LabelField(new GUIContent("Android"), networkWidthOption);
  377. EditorGUILayout.LabelField(new GUIContent(android_version), versionWidthOption);
  378. GUILayout.Space(3);
  379. string[] androidVersions = pluginData.androidVersions;
  380. if (androidVersions != null && androidVersions.Length > 0) {
  381. List<int> androidVersionsInt = new List<int>();
  382. int androidLength = androidVersions.Length;
  383. for (int i = 0; i < androidLength; i = i + 1)
  384. {
  385. androidVersionsInt.Add(i);
  386. }
  387. // 创建Dropdown组件
  388. androidVersionPopupIndex = EditorGUILayout.IntPopup(androidVersionPopupIndex, androidVersions, androidVersionsInt.ToArray(), versionWidthOption);
  389. GUILayout.FlexibleSpace();
  390. string selectedAndroidVersion = androidVersions[androidVersionPopupIndex];
  391. string action = "Exchange";
  392. if (!string.IsNullOrEmpty(android_version) && Equals(android_version, selectedAndroidVersion)) {
  393. action = "Delete";
  394. }
  395. GUI.enabled = (!Equals(android_version, selectedAndroidVersion)) || action == "Delete";
  396. if (GUILayout.Button(new GUIContent(action), fieldWidth))
  397. {
  398. //切换AndroidSDK版本
  399. if (action == "Delete") {
  400. DeleteSdkVersion(pluginData, androidVersionPopupIndex, ATConfig.OS_ANDROID);
  401. } else {
  402. ExChangeSDKVersion(pluginData, androidVersionPopupIndex, ATConfig.OS_ANDROID);
  403. }
  404. }
  405. GUI.enabled = true;
  406. GUILayout.Space(5);
  407. } else {
  408. EditorGUILayout.LabelField(new GUIContent("loading..."), versionWidthOption);
  409. }
  410. GUILayout.Space(3);
  411. }
  412. //绘制iOS
  413. using (new EditorGUILayout.HorizontalScope())
  414. {
  415. GUILayout.Space(5);
  416. EditorGUILayout.LabelField(new GUIContent("iOS"), networkWidthOption);
  417. EditorGUILayout.LabelField(new GUIContent(ios_version), versionWidthOption);
  418. GUILayout.Space(3);
  419. string[] iosVersions = pluginData.iosVersions;
  420. if (iosVersions != null && iosVersions.Length > 0) {
  421. List<int> iosVersionsInt = new List<int>();
  422. int androidLength = iosVersions.Length;
  423. for (int i = 0; i < androidLength; i = i + 1)
  424. {
  425. iosVersionsInt.Add(i);
  426. }
  427. // 创建Dropdown组件
  428. iosVersionPopupIndex = EditorGUILayout.IntPopup(iosVersionPopupIndex, iosVersions, iosVersionsInt.ToArray(), versionWidthOption);
  429. GUILayout.FlexibleSpace();
  430. string selectedIosVersion = iosVersions[iosVersionPopupIndex];
  431. string action = "Exchange";
  432. if (!string.IsNullOrEmpty(ios_version) && Equals(ios_version, selectedIosVersion)) {
  433. action = "Delete";
  434. }
  435. GUI.enabled = !Equals(ios_version, selectedIosVersion) || action == "Delete";
  436. if (GUILayout.Button(new GUIContent(action), fieldWidth))
  437. {
  438. if (action == "Delete") {
  439. DeleteSdkVersion(pluginData, iosVersionPopupIndex, ATConfig.OS_IOS);
  440. } else {
  441. ExChangeSDKVersion(pluginData, iosVersionPopupIndex, ATConfig.OS_IOS);
  442. }
  443. }
  444. GUI.enabled = true;
  445. GUILayout.Space(5);
  446. } else {
  447. EditorGUILayout.LabelField(new GUIContent("loading..."), versionWidthOption);
  448. }
  449. GUILayout.Space(3);
  450. }
  451. GUILayout.Space(4);
  452. #if !UNITY_2018_2_OR_NEWER
  453. EditorGUILayout.HelpBox("AnyThink Unity plugin will soon require Unity 2018.2 or newer to function. Please upgrade to a newer Unity version.", MessageType.Warning);
  454. #endif
  455. }
  456. GUILayout.Space(5);
  457. // GUILayout.EndHorizontal();
  458. }
  459. private void DrawSdkVersionOffTip()
  460. {
  461. if (pluginData == null) {
  462. return;
  463. }
  464. var anythink = pluginData.anyThink;
  465. if (anythink == null) {
  466. return;
  467. }
  468. var android_version = "";
  469. var ios_version = "";
  470. if (anythink != null) {
  471. android_version = anythink.CurrentVersions.Android;
  472. ios_version = anythink.CurrentVersions.Ios;
  473. //判断android版本是否版本列表中
  474. string[] androidVersions = pluginData.androidVersions;
  475. string[] iosVersions = pluginData.iosVersions;
  476. //The currently installed Android version and io version have been offline
  477. StringBuilder sb = new StringBuilder();
  478. sb.Append("Tips: The currently installed ");
  479. var android_version_off = false;
  480. if (!string.IsNullOrEmpty(android_version) && androidVersions != null && androidVersions.Length > 0) {
  481. if (!IsCharInStringArray(android_version, androidVersions)) {
  482. sb.Append("Android version(");
  483. sb.Append(android_version);
  484. sb.Append(") ");
  485. android_version_off = true;
  486. }
  487. }
  488. var ios_version_off = false;
  489. if (!string.IsNullOrEmpty(ios_version) && iosVersions != null && iosVersions.Length > 0) {
  490. if (!IsCharInStringArray(ios_version, iosVersions)) {
  491. if (android_version_off) {
  492. sb.Append("and ");
  493. }
  494. sb.Append("iOS version(");
  495. sb.Append(ios_version);
  496. sb.Append(") ");
  497. ios_version_off = true;
  498. }
  499. }
  500. if (android_version_off || ios_version_off) {
  501. sb.Append("have been offline, please install the latest version.");
  502. GUILayout.Space(4);
  503. EditorGUILayout.LabelField(sb.ToString(), tipTextStyle);
  504. GUILayout.Space(4);
  505. } else {
  506. sb.Clear();
  507. }
  508. }
  509. }
  510. private bool IsCharInStringArray(string character, string[] array)
  511. {
  512. // 遍历数组中的每个字符串
  513. foreach (string str in array)
  514. {
  515. // 如果当前字符串包含指定的字符,则返回true
  516. if (str == character)
  517. {
  518. return true;
  519. }
  520. }
  521. // 如果没有找到字符,则返回false
  522. return false;
  523. }
  524. private void DrawHeaders(string firstColumnTitle, bool drawAction)
  525. {
  526. using (new EditorGUILayout.HorizontalScope())
  527. {
  528. GUILayout.Space(5);
  529. EditorGUILayout.LabelField(firstColumnTitle, headerLabelStyle, networkWidthOption);
  530. EditorGUILayout.LabelField("Current Version", headerLabelStyle, versionWidthOption);
  531. GUILayout.Space(3);
  532. EditorGUILayout.LabelField("SDK Versions", headerLabelStyle, versionWidthOption);
  533. GUILayout.Space(3);
  534. if (drawAction)
  535. {
  536. GUILayout.FlexibleSpace();
  537. GUILayout.Button("Actions", headerLabelStyle, fieldWidth);
  538. GUILayout.Space(5);
  539. }
  540. }
  541. GUILayout.Space(4);
  542. }
  543. private void DrawPluginDetailRow(string platform, string currentVersion, string sdkversions, string actions)
  544. {
  545. using (new EditorGUILayout.HorizontalScope())
  546. {
  547. GUILayout.Space(5);
  548. EditorGUILayout.LabelField(new GUIContent(platform), networkWidthOption);
  549. EditorGUILayout.LabelField(new GUIContent(currentVersion), versionWidthOption);
  550. GUILayout.Space(3);
  551. EditorGUILayout.LabelField(new GUIContent(sdkversions), versionWidthOption);
  552. GUILayout.Space(3);
  553. // EditorGUILayout.LabelField(new GUIContent(actions), versionWidthOption);
  554. // GUILayout.Space(3);
  555. }
  556. GUILayout.Space(4);
  557. }
  558. private void DrawEmptyPluginData(string tip)
  559. {
  560. GUILayout.Space(5);
  561. // Plugin data failed to load. Show error and retry button.
  562. if (pluginDataLoadFailed)
  563. {
  564. GUILayout.Space(10);
  565. GUILayout.BeginHorizontal();
  566. GUILayout.Space(5);
  567. EditorGUILayout.LabelField("Failed to load plugin data. Please click retry or restart the integration manager.", titleLabelStyle);
  568. if (GUILayout.Button("Retry", fieldWidth))
  569. {
  570. pluginDataLoadFailed = false;
  571. loadPluginData();
  572. }
  573. GUILayout.Space(5);
  574. GUILayout.EndHorizontal();
  575. GUILayout.Space(10);
  576. }
  577. // Still loading, show loading label.
  578. else
  579. {
  580. GUILayout.Space(10);
  581. GUILayout.BeginHorizontal();
  582. // GUILayout.FlexibleSpace();
  583. EditorGUILayout.LabelField(tip, titleLabelStyle);
  584. // GUILayout.FlexibleSpace();
  585. GUILayout.EndHorizontal();
  586. GUILayout.Space(10);
  587. }
  588. GUILayout.Space(5);
  589. }
  590. //绘制Admob Id
  591. private void DrawAdombAppId() {
  592. var integrationManager = ATIntegrationManager.Instance;
  593. bool isAdmobInstalledForAndroid = integrationManager.isAdmobInstalled(ATConfig.OS_ANDROID);
  594. bool isAdmobInstalledForIos = integrationManager.isAdmobInstalled(ATConfig.OS_IOS);
  595. if (isAdmobInstalledForAndroid || isAdmobInstalledForIos) {
  596. EditorGUILayout.LabelField("Admob AppId", titleLabelStyle);
  597. GUILayout.Space(5);
  598. using (new EditorGUILayout.VerticalScope("box"))
  599. {
  600. GUILayout.Space(10);
  601. if (isAdmobInstalledForAndroid) {
  602. var androidAdmobAppId = DrawTextField("App ID (Android)", integrationManager.getAdmobAppIdByOs(pluginData, ATConfig.OS_ANDROID), networkWidthOption);
  603. integrationManager.setAdmobAppidByOs(pluginData, ATConfig.OS_ANDROID, androidAdmobAppId);
  604. }
  605. if (isAdmobInstalledForIos) {
  606. if (isAdmobInstalledForAndroid) {
  607. GUILayout.Space(10);
  608. }
  609. var iosAdmobAppId = DrawTextField("App ID (iOS)", integrationManager.getAdmobAppIdByOs(pluginData, ATConfig.OS_IOS), networkWidthOption);
  610. integrationManager.setAdmobAppidByOs(pluginData, ATConfig.OS_IOS, iosAdmobAppId);
  611. }
  612. }
  613. }
  614. }
  615. private string DrawTextField(string fieldTitle, string text, GUILayoutOption labelWidth, GUILayoutOption textFieldWidthOption = null)
  616. {
  617. GUILayout.BeginHorizontal();
  618. GUILayout.Space(4);
  619. EditorGUILayout.LabelField(new GUIContent(fieldTitle), labelWidth);
  620. GUILayout.Space(4);
  621. text = (textFieldWidthOption == null) ? GUILayout.TextField(text) : GUILayout.TextField(text, textFieldWidthOption);
  622. GUILayout.Space(4);
  623. GUILayout.EndHorizontal();
  624. GUILayout.Space(4);
  625. return text;
  626. }
  627. private void DrawMediatedNetworks()
  628. {
  629. GUILayout.Space(5);
  630. EditorGUILayout.LabelField("Ad Networks", titleLabelStyle);
  631. GUILayout.Space(5);
  632. GUILayout.BeginHorizontal();
  633. using (new EditorGUILayout.VerticalScope("box"))
  634. {
  635. DrawHeaders("Network", true);
  636. string clickTip = "You need to select an sdk version and click the Exchange button.";
  637. // Immediately after downloading and importing a plugin the entire IDE reloads and current versions can be null in that case. Will just show loading text in that case.
  638. if (pluginData == null)
  639. {
  640. ATLog.log("DrawMediatedNetworks failed.");
  641. DrawEmptyPluginData("loading sdk data ...");
  642. } else if(pluginData.mediatedNetworks == null) {
  643. DrawEmptyPluginData(clickTip);
  644. } else {
  645. var networks = pluginData.mediatedNetworks;
  646. var length = networks.Length;
  647. ATLog.log("DrawMediatedNetworks() >>> networks length: " + length);
  648. if (length == 0) {
  649. DrawEmptyPluginData(clickTip);
  650. return;
  651. }
  652. int versionEmptyLength = 0;
  653. foreach (var network in networks)
  654. {
  655. if (network.isVersionEmpty()) {
  656. // ATLog.log("DrawMediatedNetworks() >>> isVersionEmpty name: " + network.Name);
  657. versionEmptyLength = versionEmptyLength + 1;
  658. } else {
  659. DrawNetworkDetailRow2(network);
  660. }
  661. }
  662. ATLog.log("DrawMediatedNetworks() >>> versionEmptyLength: " + versionEmptyLength);
  663. if (versionEmptyLength == length) {
  664. DrawEmptyPluginData(clickTip);
  665. }
  666. GUILayout.Space(10);
  667. }
  668. }
  669. GUILayout.Space(5);
  670. GUILayout.EndHorizontal();
  671. }
  672. //绘制network的每一行
  673. private void DrawNetworkDetailRow2(Network network) {
  674. using (new EditorGUILayout.VerticalScope("box"))
  675. {
  676. GUILayout.Space(4);
  677. string a_action = "";
  678. string i_action = "";
  679. string cur_a_version = "";
  680. string cur_i_version = "";
  681. string last_a_version = "";
  682. string last_i_version = "";
  683. if (network.CurrentVersions != null)
  684. {
  685. cur_a_version = network.CurrentVersions.Android;
  686. cur_i_version = network.CurrentVersions.Ios;
  687. }
  688. if (network.LatestVersions != null)
  689. {
  690. last_a_version = network.LatestVersions.Android;
  691. last_i_version = network.LatestVersions.Ios;
  692. }
  693. //Android Action按钮状态
  694. ATLog.log("DrawNetworkDetailRow2() >>> cur_a_version: " + cur_a_version + " last_i_version: " + last_i_version +
  695. " name: " + network.DisplayName + " last_a_version: " + last_a_version);
  696. if (string.IsNullOrEmpty(cur_a_version)) {
  697. a_action = "Install";
  698. } else if (ATDataUtil.CompareVersions(cur_a_version, last_a_version) == VersionComparisonResult.Lesser) {
  699. a_action = "Upgrade";
  700. } else if(ATDataUtil.CompareVersions(cur_a_version, last_a_version) == VersionComparisonResult.Equal) {
  701. a_action = "Installed";
  702. }
  703. bool hasAndroid = false;
  704. if (!string.IsNullOrEmpty(last_a_version)) {
  705. hasAndroid = true;
  706. DrawRowNetwork(network, ATConfig.OS_ANDROID, cur_a_version, last_a_version, a_action, true);
  707. }
  708. //iOS Action按钮状态
  709. // var i_compare_result = ATDataUtil.CompareVersions(cur_i_version, last_i_version);
  710. if (string.IsNullOrEmpty(cur_i_version)) {
  711. i_action = "Install";
  712. } else if (ATDataUtil.CompareVersions(cur_i_version, last_i_version) == VersionComparisonResult.Lesser) {
  713. i_action = "Upgrade";
  714. } else if(ATDataUtil.CompareVersions(cur_i_version, last_i_version) == VersionComparisonResult.Equal) {
  715. i_action = "Installed";
  716. }
  717. if (!string.IsNullOrEmpty(last_i_version)) {
  718. DrawRowNetwork(network, ATConfig.OS_IOS, cur_i_version, last_i_version, i_action, !hasAndroid);
  719. }
  720. GUILayout.Space(4);
  721. }
  722. }
  723. private void DrawRowNetwork(Network network, int os, string curVersion, string lastVersion, string action, bool isShowNetworkName)
  724. {
  725. GUILayout.Space(5);
  726. if (os == ATConfig.OS_ANDROID) {
  727. if (!string.IsNullOrEmpty(curVersion)) {
  728. curVersion = "Android-" + curVersion;
  729. } else {
  730. curVersion = "Not Installed";
  731. }
  732. lastVersion = "Android-" + lastVersion;
  733. } else {
  734. if (!string.IsNullOrEmpty(curVersion)) {
  735. curVersion = "iOS-" + curVersion;
  736. } else {
  737. curVersion = "Not Installed";
  738. }
  739. lastVersion = "iOS-" + lastVersion;
  740. }
  741. using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandHeight(false)))
  742. {
  743. GUILayout.Space(5);
  744. if (isShowNetworkName) {
  745. EditorGUILayout.LabelField(new GUIContent(network.DisplayName), networkWidthOption);
  746. } else {
  747. EditorGUILayout.LabelField(new GUIContent(""), networkWidthOption);
  748. }
  749. EditorGUILayout.LabelField(new GUIContent(curVersion), versionWidthOption);
  750. GUILayout.Space(3);
  751. EditorGUILayout.LabelField(new GUIContent(lastVersion), versionWidthOption);
  752. GUILayout.Space(3);
  753. GUILayout.FlexibleSpace();
  754. if (network.isReqiureUpdate())
  755. {
  756. GUILayout.Label(new GUIContent { image = alertIcon, tooltip = "Adapter not compatible, please update to the latest version." }, iconStyle);
  757. }
  758. GUI.enabled = action != "Installed";
  759. if (GUILayout.Button(new GUIContent(action), fieldWidth))
  760. {
  761. ATIntegrationManager.Instance.networkInstallOrUpdate(pluginData, network, os);
  762. }
  763. GUI.enabled = true;
  764. GUILayout.Space(2);
  765. GUI.enabled = action == "Installed";
  766. if (GUILayout.Button(new GUIContent { image = uninstallIcon, tooltip = "Uninstall" }, iconStyle))
  767. {
  768. EditorUtility.DisplayProgressBar("Integration Manager", "Deleting " + network.Name + "...", 0.5f);
  769. ATIntegrationManager.Instance.uninstallNetwork(network, os);
  770. //Refresh UI
  771. AssetDatabase.Refresh();
  772. EditorUtility.ClearProgressBar();
  773. }
  774. GUI.enabled = true;
  775. GUILayout.Space(5);
  776. }
  777. }
  778. }
  779. }