private static void UpdateAppTransportSecuritySettingsIfNeeded(PlistDocument plist) { var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory; var mediationDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation/"); var projectHasAtsRequiringNetworks = AtsRequiringNetworks.Any(atsRequiringNetwork => Directory.Exists(Path.Combine(mediationDir, atsRequiringNetwork))); if (!projectHasAtsRequiringNetworks) { return; } var root = plist.root.values; PlistElement atsRoot; root.TryGetValue("NSAppTransportSecurity", out atsRoot); if (atsRoot == null || atsRoot.GetType() != typeof(PlistElementDict)) { // Add the missing App Transport Security settings for publishers if needed. MaxSdkLogger.UserDebug("Adding App Transport Security settings..."); atsRoot = plist.root.CreateDict("NSAppTransportSecurity"); atsRoot.AsDict().SetBoolean("NSAllowsArbitraryLoads", true); } var atsRootDict = atsRoot.AsDict().values; // Check if both NSAllowsArbitraryLoads and NSAllowsArbitraryLoadsInWebContent are present and remove NSAllowsArbitraryLoadsInWebContent if both are present. if (atsRootDict.ContainsKey("NSAllowsArbitraryLoads") && atsRootDict.ContainsKey("NSAllowsArbitraryLoadsInWebContent")) { MaxSdkLogger.UserDebug("Removing NSAllowsArbitraryLoadsInWebContent"); atsRootDict.Remove("NSAllowsArbitraryLoadsInWebContent"); } }
static MaxInitialize() { AppLovinAutoUpdater.Update(); #if UNITY_IOS // Check that the publisher is targeting iOS 9.0+ if (!PlayerSettings.iOS.targetOSVersionString.StartsWith("9.") && !PlayerSettings.iOS.targetOSVersionString.StartsWith("1")) { MaxSdkLogger.UserError("Detected iOS project version less than iOS 9 - The AppLovin MAX SDK WILL NOT WORK ON < iOS9!!!"); } #endif var changesMade = false; // Check if we have legacy adapter CHANGELOGs. foreach (var network in Networks) { var mediationAdapterDir = Path.Combine("Assets", "MaxSdk/Mediation/" + network); // If new directory exists if (CheckExistence(mediationAdapterDir)) { var androidChangelogFile = Path.Combine(mediationAdapterDir, AndroidChangelog); if (CheckExistence(androidChangelogFile)) { FileUtil.DeleteFileOrDirectory(androidChangelogFile); changesMade = true; } var iosChangelogFile = Path.Combine(mediationAdapterDir, IosChangelog); if (CheckExistence(iosChangelogFile)) { FileUtil.DeleteFileOrDirectory(iosChangelogFile); changesMade = true; } } } // Check if any obsolete networks are installed foreach (var obsoleteNetwork in ObsoleteNetworks) { var networkDir = Path.Combine("Assets", "MaxSdk/Mediation/" + obsoleteNetwork); if (CheckExistence(networkDir)) { MaxSdkLogger.UserDebug("Deleting obsolete network " + obsoleteNetwork + " from path " + networkDir + "..."); FileUtil.DeleteFileOrDirectory(networkDir); changesMade = true; } } // Refresh UI if (changesMade) { AssetDatabase.Refresh(); MaxSdkLogger.UserDebug("AppLovin MAX Migration completed"); } }
private static void InvokeEvent <T1, T2>(Action <T1, T2> evt, T1 param1, T2 param2) { if (!CanInvokeEvent(evt)) { return; } MaxSdkLogger.UserDebug("Invoking event: " + evt + ". Params: " + param1 + ", " + param2); evt(param1, param2); }
private static void InvokeEvent <T>(Action <T> evt, T param) { if (!CanInvokeEvent(evt)) { return; } MaxSdkLogger.UserDebug("Invoking event: " + evt + ". Param: " + param); evt(param); }
private static void InvokeEvent(Action evt) { if (!CanInvokeEvent(evt)) { return; } MaxSdkLogger.UserDebug("Invoking event: " + evt); evt(); }
private AppLovinIntegrationManager() { // Add asset import callbacks. AssetDatabase.importPackageCompleted += packageName => { if (!IsImportingNetwork(packageName)) { return; } var pluginParentDir = PluginParentDirectory; var isPluginOutsideAssetsDir = IsPluginOutsideAssetsDirectory; MovePluginFilesIfNeeded(pluginParentDir, isPluginOutsideAssetsDir); AddLabelsToAssetsIfNeeded(pluginParentDir, isPluginOutsideAssetsDir); AssetDatabase.Refresh(); CallImportPackageCompletedCallback(importingNetwork); importingNetwork = null; }; AssetDatabase.importPackageCancelled += packageName => { if (!IsImportingNetwork(packageName)) { return; } MaxSdkLogger.UserDebug("Package import cancelled."); importingNetwork = null; }; AssetDatabase.importPackageFailed += (packageName, errorMessage) => { if (!IsImportingNetwork(packageName)) { return; } MaxSdkLogger.UserError(errorMessage); importingNetwork = null; }; }
private static void ShowPluginUpdateDialogIfNeeded(PluginData data) { // Check if publisher has disabled auto update. if (!EditorPrefs.GetBool(KeyAutoUpdateEnabled, true)) { return; } // Check if the current and latest version are the same or if the publisher is on a newer version (on beta). If so, skip update. var comparison = data.AppLovinMax.CurrentToLatestVersionComparisonResult; if (comparison == MaxSdkUtils.VersionComparisonResult.Equal || comparison == MaxSdkUtils.VersionComparisonResult.Greater) { return; } // A new version of the plugin is available. Show a dialog to the publisher. var option = EditorUtility.DisplayDialogComplex( "AppLovin MAX Plugin Update", "A new version of AppLovin MAX plugin is available for download. Update now?", "Download", "Not Now", "Don't Ask Again"); if (option == 0) // Download { MaxSdkLogger.UserDebug("Downloading plugin..."); AppLovinIntegrationManager.downloadPluginProgressCallback = AppLovinIntegrationManagerWindow.OnDownloadPluginProgress; AppLovinEditorCoroutine.StartCoroutine(AppLovinIntegrationManager.Instance.DownloadPlugin(data.AppLovinMax)); } else if (option == 1) // Not Now { // Do nothing MaxSdkLogger.UserDebug("Update postponed."); } else if (option == 2) // Don't Ask Again { MaxSdkLogger.UserDebug("Auto Update disabled. You can enable it again from the AppLovin Integration Manager"); EditorPrefs.SetBool(KeyAutoUpdateEnabled, false); } }
private AppLovinIntegrationManager() { // Add asset import callbacks. AssetDatabase.importPackageCompleted += packageName => { if (!IsImportingNetwork(packageName)) { return; } CallImportPackageCompletedCallback(importingNetwork); importingNetwork = null; }; AssetDatabase.importPackageCancelled += packageName => { if (!IsImportingNetwork(packageName)) { return; } MaxSdkLogger.UserDebug("Package import cancelled."); importingNetwork = null; }; AssetDatabase.importPackageFailed += (packageName, errorMessage) => { if (!IsImportingNetwork(packageName)) { return; } MaxSdkLogger.UserError(errorMessage); importingNetwork = null; }; }
/// <summary> /// Updates the position of the MREC to the new coordinates provided. /// </summary> /// <param name="adUnitIdentifier">The ad unit identifier of the MREC for which to update the position</param> /// <param name="x">The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen.</param> /// <param name="y">The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen.</param> /// <seealso cref="GetMRecLayout"> /// The MREC is placed within the safe area of the screen. You can use this to get the absolute position Rect of the MREC on screen. /// </seealso> public static void UpdateMRecPosition(string adUnitIdentifier, float x, float y) { MaxSdkLogger.UserDebug("Updating MREC position to '(" + x + "," + y + ")"); }
/// <summary> /// Updates the position of the MREC to the new position provided. /// </summary> /// <param name="adUnitIdentifier">The ad unit identifier of the MREC for which to update the position</param> /// <param name="mrecPosition">A new position for the MREC</param> public static void UpdateMRecPosition(string adUnitIdentifier, AdViewPosition mrecPosition) { MaxSdkLogger.UserDebug("Updating MREC position to '" + mrecPosition + "' for ad unit id '" + adUnitIdentifier + "'"); }
/// <summary> /// Set the MREC placement for an ad unit identifier to tie the future ad events to. /// </summary> /// <param name="adUnitIdentifier">Ad unit identifier of the MREC to set the placement for</param> /// <param name="placement">Placement to set</param> public static void SetMRecPlacement(string adUnitIdentifier, string placement) { MaxSdkLogger.UserDebug("Setting MREC placement to '" + placement + "' for ad unit id '" + adUnitIdentifier + "'"); }
[PostProcessBuild(int.MaxValue)] // We want to run Quality Service script last. public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath) { if (!AppLovinSettings.Instance.QualityServiceEnabled) { return; } var sdkKey = AppLovinSettings.Instance.SdkKey; if (string.IsNullOrEmpty(sdkKey)) { MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. SDK Key is empty. Please enter the AppLovin SDK Key in the Integration Manager."); return; } var outputFilePath = Path.Combine(buildPath, OutputFileName); // Check if Quality Service is already installed. if (File.Exists(outputFilePath) && Directory.Exists(Path.Combine(buildPath, "AppLovinQualityService"))) { // TODO: Check if there is a way to validate if the SDK key matches the script. Else the pub can't use append when/if they change the SDK Key. return; } // Download the ruby script needed to install Quality Service #if UNITY_2017_2_OR_NEWER var downloadHandler = new DownloadHandlerFile(outputFilePath); #else var downloadHandler = new AppLovinDownloadHandler(path); #endif var postJson = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey); var bodyRaw = Encoding.UTF8.GetBytes(postJson); var uploadHandler = new UploadHandlerRaw(bodyRaw); uploadHandler.contentType = "application/json"; var unityWebRequest = new UnityWebRequest("https://api2.safedk.com/v1/build/ios_setup2") { method = UnityWebRequest.kHttpVerbPOST, downloadHandler = downloadHandler, uploadHandler = uploadHandler }; #if UNITY_2017_2_OR_NEWER var operation = unityWebRequest.SendWebRequest(); #else var operation = webRequest.Send(); #endif // Wait for the download to complete or the request to timeout. while (!operation.isDone) { } #if UNITY_2020_1_OR_NEWER if (unityWebRequest.result != UnityWebRequest.Result.Success) #elif UNITY_2017_2_OR_NEWER if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError) #else if (webRequest.isError) #endif { MaxSdkLogger.UserError("AppLovin Quality Service installation failed. Failed to download script with error: " + unityWebRequest.error); return; } // Check if Ruby is installed var rubyVersion = AppLovinCommandLine.Run("ruby", "--version", buildPath); if (rubyVersion.ExitCode != 0) { MaxSdkLogger.UserError("AppLovin Quality Service installation requires Ruby. Please install Ruby, export it to your system PATH and re-export the project."); return; } // Ruby is installed, run `ruby AppLovinQualityServiceSetup.rb` var result = AppLovinCommandLine.Run("ruby", OutputFileName, buildPath); // Check if we have an error. if (result.ExitCode != 0) { MaxSdkLogger.UserError("Failed to set up AppLovin Quality Service"); } MaxSdkLogger.UserDebug(result.Message); }
/// <summary> /// Updates the position of the cross promo ad to the new coordinates provided. /// </summary> /// <param name="adUnitIdentifier">The ad unit identifier of the cross promo ad for which to update the position</param> /// <param name="x">The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen.</param> /// <param name="y">The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen.</param> /// <param name="width">The width of the cross promo ad.</param> /// <param name="height">The height of the cross promo ad.</param> /// <param name="rotation">The rotation of the cross promo ad in degrees.</param> /// <seealso cref="GetCrossPromoAdLayout"> /// The cross promo ad is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. /// </seealso> public static void UpdateCrossPromoAdPosition(string adUnitIdentifier, float x, float y, float width, float height, float rotation) { MaxSdkLogger.UserDebug("Updating cross promo ad position to (" + x + "," + y + ") with size " + width + " x " + height + " and rotation of " + rotation + " degrees"); }
/// <summary> /// Set the cross promo ad placement for an ad unit identifier to tie the future ad events to. /// </summary> /// <param name="adUnitIdentifier">Ad unit identifier of the cross promo ad to set the placement for</param> /// <param name="placement">Placement to set</param> public static void SetCrossPromoAdPlacement(string adUnitIdentifier, string placement) { MaxSdkLogger.UserDebug("Setting cross promo ad placement to '" + placement + "' for ad unit id '" + adUnitIdentifier + "'"); }
static MaxInitialize() { #if UNITY_IOS // Check that the publisher is targeting iOS 9.0+ if (!PlayerSettings.iOS.targetOSVersionString.StartsWith("9.") && !PlayerSettings.iOS.targetOSVersionString.StartsWith("1")) { MaxSdkLogger.UserError("Detected iOS project version less than iOS 9 - The AppLovin MAX SDK WILL NOT WORK ON < iOS9!!!"); } #endif var pluginParentDir = AppLovinIntegrationManager.PluginParentDirectory; var isPluginOutsideAssetsDir = AppLovinIntegrationManager.IsPluginOutsideAssetsDirectory; var changesMade = AppLovinIntegrationManager.MovePluginFilesIfNeeded(pluginParentDir, isPluginOutsideAssetsDir); if (isPluginOutsideAssetsDir) { // If the plugin is not under the assets folder, delete the MaxSdk/Mediation folder in the plugin, so that the adapters are not imported at that location and imported to the default location. var mediationDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation"); if (Directory.Exists(mediationDir)) { FileUtil.DeleteFileOrDirectory(mediationDir); FileUtil.DeleteFileOrDirectory(mediationDir + ".meta"); changesMade = true; } } AppLovinIntegrationManager.AddLabelsToAssetsIfNeeded(pluginParentDir, isPluginOutsideAssetsDir); // Check if we have legacy adapter CHANGELOGs. foreach (var network in Networks) { var mediationAdapterDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation/" + network); // If new directory exists if (CheckExistence(mediationAdapterDir)) { var androidChangelogFile = Path.Combine(mediationAdapterDir, AndroidChangelog); if (CheckExistence(androidChangelogFile)) { FileUtil.DeleteFileOrDirectory(androidChangelogFile); changesMade = true; } var iosChangelogFile = Path.Combine(mediationAdapterDir, IosChangelog); if (CheckExistence(iosChangelogFile)) { FileUtil.DeleteFileOrDirectory(iosChangelogFile); changesMade = true; } } } // Check if any obsolete networks are installed foreach (var obsoleteNetwork in ObsoleteNetworks) { var networkDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation/" + obsoleteNetwork); if (CheckExistence(networkDir)) { MaxSdkLogger.UserDebug("Deleting obsolete network " + obsoleteNetwork + " from path " + networkDir + "..."); FileUtil.DeleteFileOrDirectory(networkDir); changesMade = true; } } // Refresh UI if (changesMade) { AssetDatabase.Refresh(); MaxSdkLogger.UserDebug("AppLovin MAX Migration completed"); } AppLovinAutoUpdater.Update(); }