401 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			401 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
| using System;
 | |
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| using System.Reflection;
 | |
| using AmazonInternal.ThirdParty;
 | |
| using UnityEditor;
 | |
| using UnityEditor.PackageManager;
 | |
| using UnityEditor.PackageManager.Requests;
 | |
| using UnityEngine;
 | |
| using UnityEngine.Networking;
 | |
| public class AmazonSDKManager : EditorWindow {
 | |
|     static string AmazonSdkVersion;
 | |
|     static AddRequest Request;
 | |
| 
 | |
|     static void AddEditorCoroutine () {
 | |
|         // Add a package to the Project
 | |
|         Request = Client.Add ("com.unity.editorcoroutine");
 | |
|         EditorApplication.update += Progress;
 | |
|     }
 | |
| 
 | |
|     static void Progress () {
 | |
|         if (Request.IsCompleted) {
 | |
|             if (Request.Status == StatusCode.Success)
 | |
|                 Debug.Log ("Installed: " + Request.Result.packageId);
 | |
|             else if (Request.Status >= StatusCode.Failure)
 | |
|                 Debug.Log (Request.Error.message);
 | |
| 
 | |
|             EditorApplication.update -= Progress;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| //    [MenuItem ("Amazon/About Amazon SDK", false, 0)]
 | |
|     public static void About () {
 | |
|         AmazonAboutDialog.ShowDialog ();
 | |
|     }
 | |
| 
 | |
| //    [MenuItem ("Amazon/Documentation...", false, 1)]
 | |
|     public static void Documentation () {
 | |
|         Application.OpenURL (AmazonConstants.docUrl);
 | |
|     }
 | |
| 
 | |
| //    [MenuItem ("Amazon/Manage SDKs...", false, 4)]
 | |
|     public static void SdkManagerProd () {
 | |
|         AmazonSDKManager.ShowSDKManager ();
 | |
|     }
 | |
| 
 | |
|     private const string downloadDir = "Assets/Amazon";
 | |
| 
 | |
|     private struct SdkInfo {
 | |
|         public string Name;
 | |
|         public string Key;
 | |
|         public string Url;
 | |
|         public string LatestVersion;
 | |
|         public string CurrentVersion;
 | |
|         public string Filename;
 | |
| 
 | |
|         public bool FromJson (string name, Dictionary<string, object> dict) {
 | |
|             if (string.IsNullOrEmpty (name) || dict == null)
 | |
|                 return false;
 | |
| 
 | |
|             object obj;
 | |
|             Key = name;
 | |
|             if (dict.TryGetValue ("name", out obj))
 | |
|                 Name = obj as string;
 | |
|             if (dict.TryGetValue ("link", out obj))
 | |
|                 Url = obj as string;
 | |
|             if (dict.TryGetValue ("version", out obj))
 | |
|                 LatestVersion = obj as string;
 | |
|             if (!string.IsNullOrEmpty (Url)) {
 | |
|                 var uri = new Uri (Url);
 | |
|                 var path = uri.IsAbsoluteUri ? uri.AbsolutePath : uri.LocalPath;
 | |
|                 Filename = Path.GetFileName (path);
 | |
|             }
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         public bool FromConfig(AmazonPackageConfig config)
 | |
|         {
 | |
|             if (config == null || string.IsNullOrEmpty(config.Name) || !string.IsNullOrEmpty(Key) && Key != config.Name)
 | |
|                 return false;
 | |
|             CurrentVersion = config.Version;
 | |
|             return true;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // Version and download info for the SDK and network mediation adapters.
 | |
|     private static SdkInfo amazonSdkInfo;
 | |
|     private static readonly SortedDictionary<string, SdkInfo> sdkInfo = new SortedDictionary<string, SdkInfo> ();
 | |
| 
 | |
|     // Async download operations tracked here.
 | |
|     private AmazonCoroutines.AmazonCoroutine coroutine;
 | |
|     private UnityWebRequest downloader;
 | |
|     private string activity;
 | |
| 
 | |
|     // Custom style for LabelFields.  (Don't make static or the dialog doesn't recover well from Unity compiling
 | |
|     // a new or changed editor script.)
 | |
|     private GUIStyle labelStyle;
 | |
|     private GUIStyle labelStyleArea;
 | |
|     private GUIStyle labelStyleLink;
 | |
|     private GUIStyle headerStyle;
 | |
|     private readonly GUILayoutOption fieldWidth = GUILayout.Width (60);
 | |
| 
 | |
|     private Vector2 scrollPos;
 | |
| 
 | |
|     public static void ShowSDKManager () {
 | |
|         var win = GetWindow<AmazonSDKManager> (true);
 | |
|         win.titleContent = new GUIContent ("Amazon SDK Manager");
 | |
|         win.Focus ();
 | |
|     }
 | |
| 
 | |
|     void Awake () {
 | |
|         labelStyle = new GUIStyle (EditorStyles.label) {
 | |
|             fontSize = 14,
 | |
|             fontStyle = FontStyle.Bold
 | |
|         };
 | |
|         labelStyleArea = new GUIStyle (EditorStyles.label) {
 | |
|             wordWrap = true
 | |
|         };
 | |
|         labelStyleLink = new GUIStyle (EditorStyles.label) {
 | |
|             normal = { textColor = Color.blue },
 | |
|             active = { textColor = Color.white },
 | |
|         };
 | |
|         headerStyle = new GUIStyle (EditorStyles.label) {
 | |
|             fontSize = 12,
 | |
|             fontStyle = FontStyle.Bold,
 | |
|             fixedHeight = 18
 | |
|         };
 | |
|         CancelOperation ();
 | |
|     }
 | |
| 
 | |
|     void OnEnable () {
 | |
|         coroutine = this.StartCoroutine (GetSDKVersions ());
 | |
|     }
 | |
| 
 | |
|     void OnDisable () {
 | |
|         CancelOperation ();
 | |
|     }
 | |
| 
 | |
|     public void deleteUnwantedFiles()
 | |
|     {
 | |
|         String[] filesToDel =
 | |
|             {
 | |
|                 "Assets/Amazon/Scripts/Internal/AdResponce.cs",
 | |
|                 "Assets/Amazon/Scripts/Internal/AdResponce.cs.meta",
 | |
|                 "Assets/Amazon/Scripts/Internal/IOS/IOSAdResponce.cs",
 | |
|                 "Assets/Amazon/Scripts/Internal/IOS/IOSAdResponce.cs.meta",
 | |
|                 "Assets/Amazon/Scripts/Internal/Android/AndroidAdResponce.cs",
 | |
|                 "Assets/Amazon/Scripts/Internal/Android/AndroidAdResponce.cs.meta",
 | |
|                 "Assets/Amazon/Plugins/Android/aps-sdk.aar",
 | |
|                 "Assets/Amazon/Plugins/Android/aps-sdk.aar.meta",
 | |
|                 "Assets/Amazon/Scripts/Mediations/AdMobMediation/Plugins/Android/aps-admob-adapter.aar",
 | |
|                 "Assets/Amazon/Scripts/Mediations/AdMobMediation/Plugins/Android/aps-admob-adapter.aar.meta",
 | |
|                 "Assets/Amazon/Scripts/Mediations/APSConnectionUtil",
 | |
|                 "Assets/Amazon/Scripts/Mediations/APSConnectionUtil.meta",
 | |
|                 "Assets/Amazon/Scripts/Mediations/MoPubMediation",
 | |
|                 "Assets/Amazon/Scripts/Mediations/MoPubMediation.meta",
 | |
|                 "Assets/APSConnectionUtil",
 | |
|                 "Assets/APSConnectionUtil.meta",
 | |
|                 "Assets/Amazon/Sample/AmazonMoPubDemo.cs",
 | |
|                 "Assets/Amazon/Sample/AmazonMoPubDemo.cs.meta",
 | |
|                 "Assets/Amazon/Sample/APSMoPubMediation.unity",
 | |
|                 "Assets/Amazon/Sample/APSMoPubMediation.unity.meta"
 | |
|             };
 | |
| 
 | |
|         foreach (String fileToDel in filesToDel)
 | |
|         {
 | |
|             if (Directory.Exists(fileToDel))
 | |
|             {
 | |
|                 Directory.Delete(fileToDel, true);
 | |
|             } else if (File.Exists(fileToDel))
 | |
|             {
 | |
|                 File.Delete(fileToDel);
 | |
|             }
 | |
|             
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private IEnumerator GetSDKVersions () {
 | |
|         // Wait one frame so that we don't try to show the progress bar in the middle of OnGUI().
 | |
|         yield return null;
 | |
| 
 | |
|         activity = "Downloading SDK version manifest...";
 | |
| 
 | |
|         UnityWebRequest www = new UnityWebRequest (AmazonConstants.manifestURL) {
 | |
|             downloadHandler = new DownloadHandlerBuffer (),
 | |
|             timeout = 10, // seconds
 | |
|         };
 | |
|         yield return www.SendWebRequest ();
 | |
| 
 | |
|         if (!string.IsNullOrEmpty (www.error)) {
 | |
|             Debug.LogError (www.error);
 | |
|             EditorUtility.DisplayDialog (
 | |
|                 "SDK Manager Service",
 | |
|                 "The services we need are not accessible. Please consider integrating manually.\n\n" +
 | |
|                 "For instructions, see " + AmazonConstants.helpLink,
 | |
|                 "OK");
 | |
|         }
 | |
| 
 | |
|         var json = www.downloadHandler.text;
 | |
|         if (string.IsNullOrEmpty (json)) {
 | |
|             json = "{}";
 | |
|             Debug.LogError ("Unable to retrieve SDK version manifest.  Showing installed SDKs only.");
 | |
|         }
 | |
|         www.Dispose ();
 | |
| 
 | |
|         // Got the file.  Now extract info on latest SDKs available.
 | |
|         amazonSdkInfo = new SdkInfo ();
 | |
|         sdkInfo.Clear ();
 | |
|         var dict = Json.Deserialize (json) as Dictionary<string, object>;
 | |
|         if (dict != null) {
 | |
|             object obj;
 | |
|             if (dict.TryGetValue ("sdk", out obj)) {
 | |
|                 amazonSdkInfo.FromJson ("sdk", obj as Dictionary<string, object>);
 | |
|                 amazonSdkInfo.CurrentVersion = AmazonConstants.VERSION;
 | |
|             }
 | |
|             if (dict.TryGetValue ("adapters", out obj)){
 | |
|                 var info = new SdkInfo ();
 | |
|                 foreach (var item in obj as Dictionary<string, object>) {
 | |
|                     if (info.FromJson (item.Key, item.Value as Dictionary<string, object>))
 | |
|                             sdkInfo[info.Key] = info;
 | |
|                 }
 | |
| 
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         var baseType = typeof(AmazonPackageConfig);
 | |
|         var configs = from t in Assembly.GetExecutingAssembly().GetTypes()
 | |
|                       where t.IsSubclassOf(baseType) && !t.IsAbstract
 | |
|                       select Activator.CreateInstance(t) as AmazonPackageConfig;
 | |
|         foreach (var config in configs) {
 | |
|             SdkInfo info;
 | |
|             sdkInfo.TryGetValue(config.Name, out info);
 | |
|             if (info.FromConfig(config) && info.Key != null)
 | |
|                 sdkInfo[info.Key] = info;
 | |
|         }
 | |
|         coroutine = null;
 | |
| 
 | |
|         deleteUnwantedFiles();
 | |
|         Repaint ();
 | |
|     }
 | |
| 
 | |
|     void OnGUI () {
 | |
|         // Is any async job in progress?
 | |
|         var stillWorking = coroutine != null || downloader != null;
 | |
| 
 | |
|         GUILayout.Space (5);
 | |
|         EditorGUILayout.LabelField ("Amazon SDKs", labelStyle, GUILayout.Height (20));
 | |
|         using (new EditorGUILayout.VerticalScope("box")) {
 | |
|             SdkHeaders();
 | |
|             SdkRow(amazonSdkInfo);
 | |
|         }
 | |
| 
 | |
|         if (sdkInfo.Count > 0) {
 | |
|             GUILayout.Space (5);
 | |
|             EditorGUILayout.LabelField ("Mediated Networks", labelStyle, GUILayout.Height (20));
 | |
|             using (new EditorGUILayout.VerticalScope ("box"))
 | |
|             using (var s = new EditorGUILayout.ScrollViewScope (scrollPos, false, false)) {
 | |
|                 scrollPos = s.scrollPosition;
 | |
|                 SdkHeaders ();
 | |
|                 foreach (var item in sdkInfo)
 | |
|                     SdkRow (item.Value);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Indicate async operation in progress.
 | |
|         using (new EditorGUILayout.HorizontalScope (GUILayout.ExpandWidth (false)))
 | |
|         EditorGUILayout.LabelField (stillWorking ? activity : " ");
 | |
| 
 | |
|         using (new EditorGUILayout.HorizontalScope ()) {
 | |
|             GUILayout.Space (10);
 | |
|             if (!stillWorking) {
 | |
|                 if (GUILayout.Button ("Done", fieldWidth))
 | |
|                     Close ();
 | |
|             } else {
 | |
|                 if (GUILayout.Button ("Cancel", fieldWidth))
 | |
|                     CancelOperation ();
 | |
|             }
 | |
|             if (GUILayout.Button ("Help", fieldWidth))
 | |
|                 Application.OpenURL (AmazonConstants.helpLink);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void SdkHeaders () {
 | |
|         using (new EditorGUILayout.HorizontalScope (GUILayout.ExpandWidth (false))) {
 | |
|             GUILayout.Space (10);
 | |
|             EditorGUILayout.LabelField ("Package", headerStyle);
 | |
|             GUILayout.Button ("Version", headerStyle);
 | |
|             GUILayout.Space (3);
 | |
|             GUILayout.Button ("Action", headerStyle, fieldWidth);
 | |
|             GUILayout.Button (" ", headerStyle, GUILayout.Width (1));
 | |
|             GUILayout.Space (5);
 | |
|         }
 | |
|         GUILayout.Space (4);
 | |
|     }
 | |
| 
 | |
|     private void SdkRow (SdkInfo info, Func<bool, bool> customButton = null) {
 | |
|         var lat = info.LatestVersion;
 | |
|         var cur = info.CurrentVersion;
 | |
|         var isInst = !string.IsNullOrEmpty (cur);
 | |
|         var canInst = !string.IsNullOrEmpty (lat) && (!isInst || AmazonUtils.CompareVersions (cur, lat) < 0);
 | |
|         // Is any async job in progress?
 | |
|         var stillWorking = coroutine != null || downloader != null;
 | |
| 
 | |
|         string tooltip = string.Empty;
 | |
|         if (isInst && (AmazonUtils.CompareVersions (cur, lat) != 0))
 | |
|             tooltip += "\n  Installed:  " + cur;
 | |
|         if (!string.IsNullOrEmpty (tooltip))
 | |
|             tooltip = info.Name + "\n  Package:  " + (lat ?? "n/a") + tooltip;
 | |
| 
 | |
|         GUILayout.Space (4);
 | |
|         using (new EditorGUILayout.HorizontalScope (GUILayout.ExpandWidth (false))) {
 | |
|             GUILayout.Space (10);
 | |
|             EditorGUILayout.LabelField (new GUIContent { text = info.Name, tooltip = tooltip });
 | |
|             GUILayout.Button (new GUIContent {
 | |
|                 text = lat ?? "--",
 | |
|                     tooltip = tooltip
 | |
|             }, canInst ? EditorStyles.boldLabel : EditorStyles.label);
 | |
|             GUILayout.Space (3);
 | |
|             if (customButton == null || !customButton (canInst)) {
 | |
|                 GUI.enabled = !stillWorking && (canInst);
 | |
|                 if (GUILayout.Button (new GUIContent {
 | |
|                         text = isInst ? "Upgrade" : "Install",
 | |
|                             tooltip = tooltip
 | |
|                     }, fieldWidth))
 | |
|                     this.StartCoroutine (DownloadSDK (info));
 | |
|                 GUI.enabled = true;
 | |
|             }
 | |
|                 // Need to fill space so that the Install/Upgrade buttons all line up nicely.
 | |
|             GUILayout.Button (" ", EditorStyles.label, GUILayout.Width (17));
 | |
|             GUILayout.Space (5);
 | |
|         }
 | |
|         GUILayout.Space (4);
 | |
|     }
 | |
| 
 | |
|     private void CancelOperation () {
 | |
|         // Stop any async action taking place.
 | |
| 
 | |
|         if (downloader != null) {
 | |
|             downloader.Abort (); // The coroutine should resume and clean up.
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         if (coroutine != null)
 | |
|             this.StopCoroutine (coroutine.routine);
 | |
|         coroutine = null;
 | |
|         downloader = null;
 | |
|     }
 | |
| 
 | |
|     private IEnumerator DownloadSDK (SdkInfo info) {
 | |
|         var path = Path.Combine (downloadDir, info.Filename);
 | |
| 
 | |
|         activity = string.Format ("Downloading {0}...", info.Filename);
 | |
|         Debug.Log (activity);
 | |
| 
 | |
|         // Start the async download job.
 | |
|         downloader = new UnityWebRequest (info.Url) {
 | |
|             downloadHandler = new DownloadHandlerFile (path),
 | |
|             timeout = 60, // seconds
 | |
|         };
 | |
|         downloader.SendWebRequest ();
 | |
| 
 | |
|         // Pause until download done/cancelled/fails, keeping progress bar up to date.
 | |
|         while (!downloader.isDone) {
 | |
|             yield return null;
 | |
|             var progress = Mathf.FloorToInt (downloader.downloadProgress * 100);
 | |
|             if (EditorUtility.DisplayCancelableProgressBar ("Amazon SDK Manager", activity, progress))
 | |
|                 downloader.Abort ();
 | |
|         }
 | |
|         EditorUtility.ClearProgressBar ();
 | |
| 
 | |
|         if (string.IsNullOrEmpty (downloader.error))
 | |
|             AssetDatabase.ImportPackage (path, true); // OK, got the file, so let the user import it if they want.
 | |
|         else {
 | |
|             var error = downloader.error;
 | |
|             if (downloader.isNetworkError) {
 | |
|                 if (error.EndsWith ("destination host"))
 | |
|                     error += ": " + info.Url;
 | |
|             } else if (downloader.isHttpError) {
 | |
|                 switch (downloader.responseCode) {
 | |
|                     case 404:
 | |
|                         var file = Path.GetFileName (new Uri (info.Url).LocalPath);
 | |
|                         error = string.Format ("File {0} not found on server.", file);
 | |
|                         break;
 | |
|                     default:
 | |
|                         error = downloader.responseCode + "\n" + error;
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             Debug.LogError (error);
 | |
|         }
 | |
| 
 | |
|         // Reset async state so the GUI is operational again.
 | |
|         downloader.Dispose ();
 | |
|         downloader = null;
 | |
|         coroutine = null;
 | |
|     }
 | |
| }
 |