627 lines
27 KiB
C#
627 lines
27 KiB
C#
|
|
using System;
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.IO;
|
||
|
|
using System.Linq;
|
||
|
|
#if !UNITY_2020_1_OR_NEWER
|
||
|
|
using System.Reflection;
|
||
|
|
#endif
|
||
|
|
using System.Xml.Linq;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEditor.PackageManager;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||
|
|
{
|
||
|
|
[Serializable]
|
||
|
|
public class PackageInfo
|
||
|
|
{
|
||
|
|
// ReSharper disable InconsistentNaming - For JSON Deserialization
|
||
|
|
public string Name;
|
||
|
|
public string Version;
|
||
|
|
}
|
||
|
|
|
||
|
|
public interface IPackageManagerClient
|
||
|
|
{
|
||
|
|
IEnumerator AddNetwork(Network network, bool showImport);
|
||
|
|
void RemoveNetwork(Network network);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class AppLovinPackageManager
|
||
|
|
{
|
||
|
|
private const string AppLovinMediationAmazonAdapterDependenciesPath = "Amazon/Scripts/Mediations/AppLovinMediation/Editor/Dependencies.xml";
|
||
|
|
|
||
|
|
#if UNITY_2019_2_OR_NEWER
|
||
|
|
private static readonly IPackageManagerClient _upmPackageManager = new AppLovinUpmPackageManager();
|
||
|
|
#endif
|
||
|
|
private static readonly IPackageManagerClient _assetsPackageManager = new AppLovinAssetsPackageManager();
|
||
|
|
|
||
|
|
private static IPackageManagerClient PackageManagerClient
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
#if UNITY_2019_2_OR_NEWER
|
||
|
|
return AppLovinIntegrationManager.IsPluginInPackageManager ? _upmPackageManager : _assetsPackageManager;
|
||
|
|
#else
|
||
|
|
return _assetsPackageManager;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
internal static PluginData PluginData { get; set; }
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Checks whether or not an adapter with the given version or newer exists.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="adapterName">The name of the network (the root adapter folder name in "MaxSdk/Mediation/" folder.</param>
|
||
|
|
/// <param name="iosVersion">The min iOS adapter version to check for. Can be <c>null</c> if we want to check for any version.</param>
|
||
|
|
/// <param name="androidVersion">The min android adapter version to check for. Can be <c>null</c> if we want to check for any version.</param>
|
||
|
|
/// <returns><c>true</c> if an adapter with the min version is installed.</returns>
|
||
|
|
internal static bool IsAdapterInstalled(string adapterName, string iosVersion = null, string androidVersion = null)
|
||
|
|
{
|
||
|
|
var dependencyFilePathList = GetAssetPathListForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml");
|
||
|
|
if (dependencyFilePathList.Count <= 0) return false;
|
||
|
|
|
||
|
|
var currentVersion = GetCurrentVersions(dependencyFilePathList);
|
||
|
|
if (iosVersion != null)
|
||
|
|
{
|
||
|
|
var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion);
|
||
|
|
if (iosVersionComparison == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (androidVersion != null)
|
||
|
|
{
|
||
|
|
var androidVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Android, androidVersion);
|
||
|
|
if (androidVersionComparison == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Checks whether an adapter is installed using the plugin data.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="pluginData">The plugin data to check for the adapter</param>
|
||
|
|
/// <param name="adapterName">The name of the network.</param>
|
||
|
|
/// <returns>Whether an adapter is installed in the plugin data</returns>
|
||
|
|
internal static bool IsAdapterInstalled(PluginData pluginData, string adapterName)
|
||
|
|
{
|
||
|
|
var network = pluginData.MediatedNetworks.Where(mediatedNetwork => mediatedNetwork.Name.Equals(adapterName)).ToList().FirstOrDefault();
|
||
|
|
var networkVersion = network != null ? network.CurrentVersions : null;
|
||
|
|
var currentVersion = networkVersion != null ? networkVersion.Unity : "";
|
||
|
|
|
||
|
|
return MaxSdkUtils.IsValidString(currentVersion);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the mediation networks that are currently installed in the project. If using UPM, checks
|
||
|
|
/// for networks in Packages folder and Mediation folder in case a custom adapter was added to the project.
|
||
|
|
/// </summary>
|
||
|
|
/// <returns>A list of the installed mediation network names.</returns>
|
||
|
|
internal static List<string> GetInstalledMediationNetworks()
|
||
|
|
{
|
||
|
|
var installedNetworks = new List<string>();
|
||
|
|
var installedNetworksInAssets = AppLovinAssetsPackageManager.GetInstalledMediationNetworks();
|
||
|
|
installedNetworks.AddRange(installedNetworksInAssets);
|
||
|
|
|
||
|
|
#if UNITY_2019_2_OR_NEWER
|
||
|
|
var installedNetworksInPackages = AppLovinUpmPackageManager.GetInstalledMediationNetworks();
|
||
|
|
installedNetworks.AddRange(installedNetworksInPackages);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (IsAmazonAppLovinAdapterInstalled())
|
||
|
|
{
|
||
|
|
installedNetworks.Add("AmazonAdMarketplace");
|
||
|
|
}
|
||
|
|
|
||
|
|
return installedNetworks;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Adds a network to the project.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network to add.</param>
|
||
|
|
/// <param name="showImport">Whether to show the import window (only for non UPM)</param>
|
||
|
|
internal static IEnumerator AddNetwork(Network network, bool showImport)
|
||
|
|
{
|
||
|
|
yield return PackageManagerClient.AddNetwork(network, showImport);
|
||
|
|
|
||
|
|
AppLovinEditorCoroutine.StartCoroutine(RefreshAssetsAtEndOfFrame(network));
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Removes a network from the project.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network to remove.</param>
|
||
|
|
internal static void RemoveNetwork(Network network)
|
||
|
|
{
|
||
|
|
PackageManagerClient.RemoveNetwork(network);
|
||
|
|
|
||
|
|
AppLovinEditorCoroutine.StartCoroutine(RefreshAssetsAtEndOfFrame(network));
|
||
|
|
}
|
||
|
|
|
||
|
|
#region Utility
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the list of all asset paths for a given MAX plugin export path.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="exportPath">The actual exported path of the asset.</param>
|
||
|
|
/// <returns>The exported path of the MAX plugin asset or an empty list if the asset is not found.</returns>
|
||
|
|
private static List<string> GetAssetPathListForExportPath(string exportPath)
|
||
|
|
{
|
||
|
|
var assetLabelToFind = "l:al_max_export_path-" + exportPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||
|
|
var assetGuids = AssetDatabase.FindAssets(assetLabelToFind);
|
||
|
|
|
||
|
|
var assetPaths = new List<string>();
|
||
|
|
foreach (var assetGuid in assetGuids)
|
||
|
|
{
|
||
|
|
assetPaths.Add(AssetDatabase.GUIDToAssetPath(assetGuid));
|
||
|
|
}
|
||
|
|
|
||
|
|
return assetPaths.Count <= 0 ? new List<string>() : assetPaths;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Updates the CurrentVersion fields for a given network data object.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">Network for which to update the current versions.</param>
|
||
|
|
internal static void UpdateCurrentVersions(Network network)
|
||
|
|
{
|
||
|
|
var assetPaths = GetAssetPathListForExportPath(network.DependenciesFilePath);
|
||
|
|
#if UNITY_2019_2_OR_NEWER
|
||
|
|
if (HasDuplicateAdapters(assetPaths))
|
||
|
|
{
|
||
|
|
ShowDeleteDuplicateAdapterPrompt(network);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
var currentVersions = GetCurrentVersions(assetPaths);
|
||
|
|
network.CurrentVersions = currentVersions;
|
||
|
|
|
||
|
|
// If AppLovin mediation plugin, get the version from MaxSdk and the latest and current version comparison.
|
||
|
|
if (network.Name.Equals("APPLOVIN_NETWORK"))
|
||
|
|
{
|
||
|
|
network.CurrentVersions.Unity = MaxSdk.Version;
|
||
|
|
|
||
|
|
var unityVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Unity, network.LatestVersions.Unity);
|
||
|
|
var androidVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Android, network.LatestVersions.Android);
|
||
|
|
var iosVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Ios, network.LatestVersions.Ios);
|
||
|
|
|
||
|
|
// Overall version is same if all the current and latest (from db) versions are same.
|
||
|
|
if (unityVersionComparison == MaxSdkUtils.VersionComparisonResult.Equal &&
|
||
|
|
androidVersionComparison == MaxSdkUtils.VersionComparisonResult.Equal &&
|
||
|
|
iosVersionComparison == MaxSdkUtils.VersionComparisonResult.Equal)
|
||
|
|
{
|
||
|
|
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Equal;
|
||
|
|
}
|
||
|
|
// One of the installed versions is newer than the latest versions which means that the publisher is on a beta version.
|
||
|
|
else if (unityVersionComparison == MaxSdkUtils.VersionComparisonResult.Greater ||
|
||
|
|
androidVersionComparison == MaxSdkUtils.VersionComparisonResult.Greater ||
|
||
|
|
iosVersionComparison == MaxSdkUtils.VersionComparisonResult.Greater)
|
||
|
|
{
|
||
|
|
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Greater;
|
||
|
|
}
|
||
|
|
// We have a new version available if all Android, iOS and Unity has a newer version available in db.
|
||
|
|
else
|
||
|
|
{
|
||
|
|
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Lesser;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// For all other mediation adapters, get the version comparison using their Unity versions.
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// If adapter is indeed installed, compare the current (installed) and the latest (from db) versions, so that we can determine if the publisher is on an older, current or a newer version of the adapter.
|
||
|
|
// If the publisher is on a newer version of the adapter than the db version, that means they are on a beta version.
|
||
|
|
if (MaxSdkUtils.IsValidString(currentVersions.Unity))
|
||
|
|
{
|
||
|
|
network.CurrentToLatestVersionComparisonResult = AppLovinIntegrationManagerUtils.CompareUnityMediationVersions(currentVersions.Unity, network.LatestVersions.Unity);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (MaxSdkUtils.IsValidString(network.CurrentVersions.Unity) && AppLovinAutoUpdater.MinAdapterVersions.ContainsKey(network.Name))
|
||
|
|
{
|
||
|
|
var comparisonResult = AppLovinIntegrationManagerUtils.CompareUnityMediationVersions(network.CurrentVersions.Unity, AppLovinAutoUpdater.MinAdapterVersions[network.Name]);
|
||
|
|
// Requires update if current version is lower than the min required version.
|
||
|
|
network.RequiresUpdate = comparisonResult < 0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// Reset value so that the Integration manager can hide the alert icon once adapter is updated.
|
||
|
|
network.RequiresUpdate = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#if UNITY_2019_2_OR_NEWER
|
||
|
|
/// <summary>
|
||
|
|
/// Checks whether a network has duplicate adapters installed in both the Assets folder and via UPM.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="dependencyPaths">The list of paths to the dependencies.xml files</param>
|
||
|
|
/// <returns><c>True</c> if there are adapters in both the Assets folder and installed via UPM</returns>
|
||
|
|
private static bool HasDuplicateAdapters(List<string> dependencyPaths)
|
||
|
|
{
|
||
|
|
var inPackagesFolder = dependencyPaths.Any(path => path.Contains("Packages"));
|
||
|
|
var inAssetsFolder = dependencyPaths.Any(path => path.Contains("Assets"));
|
||
|
|
|
||
|
|
return inPackagesFolder && inAssetsFolder;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Displays a prompt informing the user that duplicate adapters were detected
|
||
|
|
/// and allows them to choose which version to keep.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network that has duplicate adapters installed.</param>
|
||
|
|
private static void ShowDeleteDuplicateAdapterPrompt(Network network)
|
||
|
|
{
|
||
|
|
var keepAssetsAdapter = EditorUtility.DisplayDialog("Duplicate Adapters Detected",
|
||
|
|
"The " + network.DisplayName + " adapter is installed in both the Assets folder and via UPM. Please choose which version to keep.",
|
||
|
|
"Keep Assets Folder Version",
|
||
|
|
"Keep UPM Version");
|
||
|
|
DeleteDuplicateAdapter(network, keepAssetsAdapter);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Removes a duplicate adapter by either deleting it from the Assets folder
|
||
|
|
/// or uninstalling it from the Unity Package Manager (UPM).
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network for which the duplicate adapter is being removed.</param>
|
||
|
|
/// <param name="keepAssetsAdapter">If <c>true</c>, retains the adapter in the Assets folder and removes the UPM version;
|
||
|
|
/// otherwise, deletes the adapter from the Assets folder.</param>
|
||
|
|
internal static void DeleteDuplicateAdapter(Network network, bool keepAssetsAdapter)
|
||
|
|
{
|
||
|
|
if (keepAssetsAdapter)
|
||
|
|
{
|
||
|
|
var appLovinManifest = AppLovinUpmManifest.Load();
|
||
|
|
AppLovinUpmPackageManager.RemovePackages(network, appLovinManifest);
|
||
|
|
appLovinManifest.Save();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
foreach (var pluginFilePath in network.PluginFilePaths)
|
||
|
|
{
|
||
|
|
var filePath = Path.Combine(AppLovinIntegrationManager.MediationDirectory, pluginFilePath.Replace("MaxSdk/Mediation/", ""));
|
||
|
|
FileUtil.DeleteFileOrDirectory(filePath);
|
||
|
|
FileUtil.DeleteFileOrDirectory(filePath + ".meta");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
AppLovinUpmPackageManager.ResolvePackageManager();
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the current versions for a given network's dependency file paths. UPM will have multiple paths
|
||
|
|
/// for each network - one each for iOS and Android.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="dependencyPaths">A list of dependency file paths to extract current versions from.</param>
|
||
|
|
/// <returns>Current versions of a given network's dependency files.</returns>
|
||
|
|
private static Versions GetCurrentVersions(List<string> dependencyPaths)
|
||
|
|
{
|
||
|
|
var currentVersions = new Versions();
|
||
|
|
foreach (var dependencyPath in dependencyPaths)
|
||
|
|
{
|
||
|
|
GetCurrentVersion(currentVersions, dependencyPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (currentVersions.Android != null && currentVersions.Ios != null)
|
||
|
|
{
|
||
|
|
currentVersions.Unity = "android_" + currentVersions.Android + "_ios_" + currentVersions.Ios;
|
||
|
|
}
|
||
|
|
else if (currentVersions.Android != null)
|
||
|
|
{
|
||
|
|
currentVersions.Unity = "android_" + currentVersions.Android;
|
||
|
|
}
|
||
|
|
else if (currentVersions.Ios != null)
|
||
|
|
{
|
||
|
|
currentVersions.Unity = "ios_" + currentVersions.Ios;
|
||
|
|
}
|
||
|
|
|
||
|
|
return currentVersions;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Extracts the current version of a network from its dependency.xml file.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="currentVersions">The Versions object we are using.</param>
|
||
|
|
/// <param name="dependencyPath">The path to the dependency.xml file.</param>
|
||
|
|
private static void GetCurrentVersion(Versions currentVersions, string dependencyPath)
|
||
|
|
{
|
||
|
|
XDocument dependency;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
dependency = XDocument.Load(dependencyPath);
|
||
|
|
}
|
||
|
|
#pragma warning disable 0168
|
||
|
|
catch (IOException exception)
|
||
|
|
#pragma warning restore 0168
|
||
|
|
{
|
||
|
|
// Couldn't find the dependencies file. The plugin is not installed.
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// <dependencies>
|
||
|
|
// <androidPackages>
|
||
|
|
// <androidPackage spec="com.applovin.mediation:network_name-adapter:1.2.3.4" />
|
||
|
|
// </androidPackages>
|
||
|
|
// <iosPods>
|
||
|
|
// <iosPod name="AppLovinMediationNetworkNameAdapter" version="2.3.4.5" />
|
||
|
|
// </iosPods>
|
||
|
|
// </dependencies>
|
||
|
|
string androidVersion = null;
|
||
|
|
string iosVersion = null;
|
||
|
|
var dependenciesElement = dependency.Element("dependencies");
|
||
|
|
if (dependenciesElement != null)
|
||
|
|
{
|
||
|
|
var androidPackages = dependenciesElement.Element("androidPackages");
|
||
|
|
if (androidPackages != null)
|
||
|
|
{
|
||
|
|
var adapterPackage = androidPackages.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("androidPackage")
|
||
|
|
&& element.FirstAttribute.Name.LocalName.Equals("spec")
|
||
|
|
&& element.FirstAttribute.Value.StartsWith("com.applovin"));
|
||
|
|
if (adapterPackage != null)
|
||
|
|
{
|
||
|
|
androidVersion = adapterPackage.FirstAttribute.Value.Split(':').Last();
|
||
|
|
// Hack alert: Some Android versions might have square brackets to force a specific version. Remove them if they are detected.
|
||
|
|
if (androidVersion.StartsWith("["))
|
||
|
|
{
|
||
|
|
androidVersion = androidVersion.Trim('[', ']');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var iosPods = dependenciesElement.Element("iosPods");
|
||
|
|
if (iosPods != null)
|
||
|
|
{
|
||
|
|
var adapterPod = iosPods.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("iosPod")
|
||
|
|
&& element.FirstAttribute.Name.LocalName.Equals("name")
|
||
|
|
&& element.FirstAttribute.Value.StartsWith("AppLovin"));
|
||
|
|
if (adapterPod != null)
|
||
|
|
{
|
||
|
|
iosVersion = adapterPod.Attributes().First(attribute => attribute.Name.LocalName.Equals("version")).Value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (androidVersion != null)
|
||
|
|
{
|
||
|
|
currentVersions.Android = androidVersion;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (iosVersion != null)
|
||
|
|
{
|
||
|
|
currentVersions.Ios = iosVersion;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Check for the Amazon AppLovin adapter in the project.
|
||
|
|
/// </summary>
|
||
|
|
/// <returns>Whether the AppLovin Adapter is installed through the Amazon SDK.</returns>
|
||
|
|
private static bool IsAmazonAppLovinAdapterInstalled()
|
||
|
|
{
|
||
|
|
string[] dependenciesFiles = AssetDatabase.FindAssets("t:TextAsset Dependencies", new[] {"Assets"})
|
||
|
|
.Select(AssetDatabase.GUIDToAssetPath)
|
||
|
|
.ToArray();
|
||
|
|
|
||
|
|
// Use regex to search for Amazon and then AppLovin in the file paths of the dependencies.xml files.
|
||
|
|
return dependenciesFiles.Any(filePath => filePath.Contains(AppLovinMediationAmazonAdapterDependenciesPath));
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Refresh assets and update current versions after a slight delay to allow for Client.Resolve to finish.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network that was just installed/removed.</param>
|
||
|
|
private static IEnumerator RefreshAssetsAtEndOfFrame(Network network)
|
||
|
|
{
|
||
|
|
yield return new WaitForEndOfFrame();
|
||
|
|
UpdateCurrentVersions(network);
|
||
|
|
AssetDatabase.Refresh();
|
||
|
|
}
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
}
|
||
|
|
|
||
|
|
#if UNITY_2019_2_OR_NEWER
|
||
|
|
public class AppLovinUpmPackageManager : IPackageManagerClient
|
||
|
|
{
|
||
|
|
public const string PackageNamePrefixAppLovin = "com.applovin.mediation.ads";
|
||
|
|
private const string PackageNamePrefixNetwork = "com.applovin.mediation.adapters";
|
||
|
|
private const string PackageNamePrefixDsp = "com.applovin.mediation.dsp";
|
||
|
|
|
||
|
|
private const float TimeoutFetchPackageCollectionSeconds = 10f;
|
||
|
|
|
||
|
|
#if !UNITY_2020_1_OR_NEWER
|
||
|
|
private static Type packageManagerClientType;
|
||
|
|
private static MethodInfo packageManagerResolveMethod;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
public static List<string> GetInstalledMediationNetworks()
|
||
|
|
{
|
||
|
|
// Return empty list if we failed to get the package list
|
||
|
|
var packageCollection = GetPackageCollectionSync(TimeoutFetchPackageCollectionSeconds);
|
||
|
|
if (packageCollection == null)
|
||
|
|
{
|
||
|
|
return new List<string>();
|
||
|
|
}
|
||
|
|
|
||
|
|
return packageCollection.Where(package => package.name.StartsWith(PackageNamePrefixNetwork) || package.name.StartsWith(PackageNamePrefixDsp))
|
||
|
|
.SelectMany(package => package.keywords)
|
||
|
|
.Where(keyword => keyword.StartsWith("dir:"))
|
||
|
|
.Select(keyword => keyword.Replace("dir:", ""))
|
||
|
|
.Distinct()
|
||
|
|
.ToList();
|
||
|
|
}
|
||
|
|
|
||
|
|
public IEnumerator AddNetwork(Network network, bool showImport)
|
||
|
|
{
|
||
|
|
var appLovinManifest = AppLovinUpmManifest.Load();
|
||
|
|
AddPackages(network, appLovinManifest);
|
||
|
|
appLovinManifest.Save();
|
||
|
|
|
||
|
|
// Remove any versions of the adapter in the Assets folder
|
||
|
|
AppLovinPackageManager.DeleteDuplicateAdapter(network, false);
|
||
|
|
ResolvePackageManager();
|
||
|
|
|
||
|
|
yield break;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void RemoveNetwork(Network network)
|
||
|
|
{
|
||
|
|
var appLovinManifest = AppLovinUpmManifest.Load();
|
||
|
|
RemovePackages(network, appLovinManifest);
|
||
|
|
appLovinManifest.Save();
|
||
|
|
ResolvePackageManager();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Adds a network's packages to the package manager removes any beta version that exists
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network to add.</param>
|
||
|
|
/// <param name="appLovinManifest">The AppLovinUpmManifest instance to edit</param>
|
||
|
|
internal static void AddPackages(Network network, AppLovinUpmManifest appLovinManifest)
|
||
|
|
{
|
||
|
|
foreach (var packageInfo in network.Packages)
|
||
|
|
{
|
||
|
|
appLovinManifest.AddPackageDependency(packageInfo.Name, packageInfo.Version);
|
||
|
|
RemoveBetaPackage(packageInfo.Name, appLovinManifest);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Removes a network's packages from the package manager
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="network">The network to add.</param>
|
||
|
|
/// <param name="appLovinManifest">The AppLovinUpmManifest instance to edit</param>
|
||
|
|
internal static void RemovePackages(Network network, AppLovinUpmManifest appLovinManifest)
|
||
|
|
{
|
||
|
|
foreach (var packageInfo in network.Packages)
|
||
|
|
{
|
||
|
|
appLovinManifest.RemovePackageDependency(packageInfo.Name);
|
||
|
|
RemoveBetaPackage(packageInfo.Name, appLovinManifest);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Removes the beta version of a package name
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="packageName">The name of the package to remove a beta for</param>
|
||
|
|
/// <param name="appLovinManifest">The AppLovinUpmManifest instance to edit</param>
|
||
|
|
private static void RemoveBetaPackage(string packageName, AppLovinUpmManifest appLovinManifest)
|
||
|
|
{
|
||
|
|
var prefix = "";
|
||
|
|
if (packageName.Contains(PackageNamePrefixNetwork))
|
||
|
|
{
|
||
|
|
prefix = PackageNamePrefixNetwork;
|
||
|
|
}
|
||
|
|
else if (packageName.Contains(PackageNamePrefixDsp))
|
||
|
|
{
|
||
|
|
prefix = PackageNamePrefixDsp;
|
||
|
|
}
|
||
|
|
else if (packageName.Contains(PackageNamePrefixAppLovin))
|
||
|
|
{
|
||
|
|
prefix = PackageNamePrefixAppLovin;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var betaPackageName = packageName.Replace(prefix, prefix + ".beta");
|
||
|
|
appLovinManifest.RemovePackageDependency(betaPackageName);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Resolves the Unity Package Manager so any changes made to the manifest.json file are reflected in the Unity Editor.
|
||
|
|
/// </summary>
|
||
|
|
internal static void ResolvePackageManager()
|
||
|
|
{
|
||
|
|
#if UNITY_2020_1_OR_NEWER
|
||
|
|
Client.Resolve();
|
||
|
|
#else
|
||
|
|
packageManagerClientType = packageManagerClientType ?? typeof(Client);
|
||
|
|
if (packageManagerClientType != null)
|
||
|
|
{
|
||
|
|
packageManagerResolveMethod = packageManagerResolveMethod ?? packageManagerClientType.GetMethod("Resolve", BindingFlags.NonPublic | BindingFlags.Static);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (packageManagerResolveMethod != null)
|
||
|
|
{
|
||
|
|
packageManagerResolveMethod.Invoke(null, null);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the PackageCollection from the Unity Package Manager synchronously.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="timeoutSeconds">How long to wait before exiting with a timeout error</param>
|
||
|
|
/// <returns></returns>
|
||
|
|
private static PackageCollection GetPackageCollectionSync(float timeoutSeconds = -1)
|
||
|
|
{
|
||
|
|
var request = Client.List();
|
||
|
|
|
||
|
|
// Just wait till the request is complete
|
||
|
|
var now = DateTime.Now;
|
||
|
|
while (!request.IsCompleted)
|
||
|
|
{
|
||
|
|
// Wait indefinitely if there is no timeout set.
|
||
|
|
if (timeoutSeconds < 0) continue;
|
||
|
|
|
||
|
|
var delta = DateTime.Now - now;
|
||
|
|
if (delta.TotalSeconds > timeoutSeconds)
|
||
|
|
{
|
||
|
|
MaxSdkLogger.UserError("Failed to list UPM packages: Timeout");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!request.IsCompleted)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (request.Status >= StatusCode.Failure)
|
||
|
|
{
|
||
|
|
MaxSdkLogger.UserError("Failed to list packages: " + request.Error.message);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return (request.Status == StatusCode.Success) ? request.Result : null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
public class AppLovinAssetsPackageManager : IPackageManagerClient
|
||
|
|
{
|
||
|
|
public static List<string> GetInstalledMediationNetworks()
|
||
|
|
{
|
||
|
|
var maxMediationDirectory = AppLovinIntegrationManager.MediationDirectory;
|
||
|
|
if (!Directory.Exists(maxMediationDirectory)) return new List<string>();
|
||
|
|
|
||
|
|
var mediationNetworkDirectories = Directory.GetDirectories(maxMediationDirectory);
|
||
|
|
return mediationNetworkDirectories.Select(Path.GetFileName).ToList();
|
||
|
|
}
|
||
|
|
|
||
|
|
public IEnumerator AddNetwork(Network network, bool showImport)
|
||
|
|
{
|
||
|
|
yield return AppLovinIntegrationManager.Instance.DownloadPlugin(network, showImport);
|
||
|
|
}
|
||
|
|
|
||
|
|
public void RemoveNetwork(Network network)
|
||
|
|
{
|
||
|
|
foreach (var pluginFilePath in network.PluginFilePaths)
|
||
|
|
{
|
||
|
|
var filePath = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, pluginFilePath);
|
||
|
|
FileUtil.DeleteFileOrDirectory(filePath);
|
||
|
|
FileUtil.DeleteFileOrDirectory(filePath + ".meta");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|