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;
|
|
}
|
|
}
|