using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; #if UNITY_2019_2_OR_NEWER namespace AppLovinMax.Scripts.IntegrationManager.Editor { /// /// Moves our SDK Unity Plugin from under the Assets folder to the Unity Package Manager. /// public static class AppLovinPluginMigrationHelper { private const string ApplovinRegistryName = "AppLovin MAX Unity"; private const string ApplovinRegistryUrl = "https://unity.packages.applovin.com/"; private static readonly List AppLovinRegistryScopes = new List() {"com.applovin.mediation.ads", "com.applovin.mediation.adapters", "com.applovin.mediation.dsp"}; private const string OpenUpmRegistryName = "package.openupm.com"; private const string OpenUpmRegistryUrl = "https://package.openupm.com"; private static readonly List OpenUpmRegistryScopes = new List() {"com.google.external-dependency-manager"}; private static List betaNetworkPluginFilePaths = new List(); /// /// Attempts to move the Unity plugin to UPM by adding the AppLovin scoped registry and dependencies to the manifest. /// /// The Unity Plugin data for our sdk and mediation adapters. /// Whether to delete the EDM folder under "Assets" internal static void MigrateToUnityPackageManager(PluginData pluginData, bool deleteExternalDependencyManager) { MaxSdkLogger.UserDebug("Moving AppLovin Unity Plugin to package manager"); if (deleteExternalDependencyManager) { DeleteExternalDependencyManager(); } var appLovinManifest = AppLovinUpmManifest.Load(); MigrateAdapters(pluginData, appLovinManifest); MigratePlugin(pluginData, appLovinManifest); appLovinManifest.Save(); AppLovinUpmPackageManager.ResolvePackageManager(); DeletePluginFiles(); } /// /// Add all currently installed networks to the manifest. /// internal static void MigrateAdapters(PluginData pluginData, AppLovinUpmManifest appLovinManifest) { var allNetworks = pluginData.MediatedNetworks.Concat(pluginData.PartnerMicroSdks).ToArray(); betaNetworkPluginFilePaths.Clear(); // Add every currently installed network and separate it by android and iOS. foreach (var network in allNetworks) { var currentVersion = network.CurrentVersions != null ? network.CurrentVersions.Unity : ""; if (string.IsNullOrEmpty(currentVersion)) continue; if (currentVersion.Contains("beta")) { betaNetworkPluginFilePaths.AddRange(network.PluginFilePaths); continue; } AppLovinUpmPackageManager.AddPackages(network, appLovinManifest); } } /// /// Add the AppLovin scoped registry to the manifest if it doesn't exist. Otherwise update it. /// private static void MigratePlugin(PluginData pluginData, AppLovinUpmManifest appLovinManifest) { appLovinManifest.AddOrUpdateRegistry(ApplovinRegistryName, ApplovinRegistryUrl, AppLovinRegistryScopes); appLovinManifest.AddOrUpdateRegistry(OpenUpmRegistryName, OpenUpmRegistryUrl, OpenUpmRegistryScopes); var appLovinVersion = pluginData.AppLovinMax.LatestVersions.Unity; appLovinManifest.AddPackageDependency(AppLovinUpmPackageManager.PackageNamePrefixAppLovin, appLovinVersion); } #region Utility /// /// Delete the external dependency manager folder from the project. /// private static void DeleteExternalDependencyManager() { var externalDependencyManagerPath = Path.Combine(Application.dataPath, "ExternalDependencyManager"); FileUtil.DeleteFileOrDirectory(externalDependencyManagerPath); FileUtil.DeleteFileOrDirectory(externalDependencyManagerPath + ".meta"); } /// /// Deletes all the files in the plugin directory except the AppLovinSettings.asset file. /// private static void DeletePluginFiles() { if (AppLovinIntegrationManager.IsPluginInPackageManager) return; var pluginPath = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, "MaxSdk"); var appLovinSettingsPath = Path.Combine(pluginPath, "Resources/AppLovinSettings.asset"); var appLovinResourcesDirectory = Path.Combine(pluginPath, "Resources"); var appLovinSettingsTempPath = Path.Combine(Path.GetTempPath(), "AppLovinSettings.asset"); var appLovinMediationTempPath = Path.Combine(Path.GetTempPath(), "Mediation"); // Ensure there aren't any errors when moving the files due to the directories/files already existing. FileUtil.DeleteFileOrDirectory(appLovinSettingsTempPath); FileUtil.DeleteFileOrDirectory(appLovinMediationTempPath); var mediationAssetsDir = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, "MaxSdk/Mediation"); // Move the AppLovinSettings.asset file and any beta adapters to a temporary directory. File.Move(appLovinSettingsPath, appLovinSettingsTempPath); var adapterSaved = MoveBetaAdaptersIfNeeded(mediationAssetsDir, appLovinMediationTempPath); // Move the meta file if the adapter was saved to save the asset labels if (adapterSaved) { File.Move(mediationAssetsDir, appLovinMediationTempPath + ".meta"); } // Delete the plugin directory and then move the AppLovinSettings.asset and beta adapters back. FileUtil.DeleteFileOrDirectory(pluginPath); Directory.CreateDirectory(appLovinResourcesDirectory); File.Move(appLovinSettingsTempPath, appLovinSettingsPath); MoveBetaAdaptersIfNeeded(appLovinMediationTempPath, mediationAssetsDir); if (adapterSaved) { File.Move(appLovinMediationTempPath + ".meta", mediationAssetsDir); } FileUtil.DeleteFileOrDirectory(appLovinMediationTempPath); } /// /// Moves the beta adapters from a source mediation directory to a destination mediation directory. /// /// The directory containing the beta adapters to be moved. /// The target directory where the beta adapters should be moved. private static bool MoveBetaAdaptersIfNeeded(string sourceMediationDirectory, string destinationMediationDirectory) { if (betaNetworkPluginFilePaths.Count == 0 || !Directory.Exists(sourceMediationDirectory)) return false; var movedAdapter = false; Directory.CreateDirectory(destinationMediationDirectory); foreach (var pluginFilePath in betaNetworkPluginFilePaths) { var sourceDirectory = Path.Combine(sourceMediationDirectory, Path.GetFileName(pluginFilePath)); var destinationDirectory = Path.Combine(destinationMediationDirectory, Path.GetFileName(pluginFilePath)); if (Directory.Exists(sourceDirectory)) { Directory.Move(sourceDirectory, destinationDirectory); movedAdapter = true; } } return movedAdapter; } #endregion } } #endif