From 299a720575802bb3537c8fb9a88a67ecf72a3a23 Mon Sep 17 00:00:00 2001 From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> Date: Tue, 10 Jun 2025 14:52:06 +0300 Subject: [PATCH] mobile: multiiple fixes to `admob` and `iapcore` code. --- source/funkin/mobile/util/AdMobUtil.hx | 27 ++++++++---- .../funkin/mobile/util/InAppPurchasesUtil.hx | 41 ++++++++++++++----- source/funkin/ui/mainmenu/MainMenuState.hx | 9 ++-- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/source/funkin/mobile/util/AdMobUtil.hx b/source/funkin/mobile/util/AdMobUtil.hx index 44b5f22a7..9ac5bfce9 100644 --- a/source/funkin/mobile/util/AdMobUtil.hx +++ b/source/funkin/mobile/util/AdMobUtil.hx @@ -10,11 +10,9 @@ import funkin.play.cutscene.VideoCutscene; import funkin.util.macro.EnvironmentConfigMacro; /** - * Utility class for managing AdMob advertisements in a mobile application. - * This class provides functions to initialize AdMob, manage ad events, - * and control the display of different ad types, including banners, - * interstitial ads, and rewarded ads. + * Provides utility functions for working with admob advertisements. */ +@:nullSafety class AdMobUtil { /** @@ -141,7 +139,9 @@ class AdMobUtil */ public static inline function addBanner(size:Int = AdmobBannerSize.BANNER, align:Int = AdmobBannerAlign.BOTTOM_CENTER):Void { - if (InAppPurchasesUtil.isPurchased("no_ads")) return; + #if FEATURE_MOBILE_IAP + if (InAppPurchasesUtil.isPurchased(InAppPurchasesUtil.UPGRADE_PRODUCT_ID)) return; + #end Admob.showBanner([AdMobUtil.ADMOB_PUBLISHER, AdMobUtil.BANNER_AD_UNIT_ID].join('/'), size, align); } @@ -150,6 +150,9 @@ class AdMobUtil */ public static inline function removeBanner():Void { + #if FEATURE_MOBILE_IAP + if (InAppPurchasesUtil.isPurchased(InAppPurchasesUtil.UPGRADE_PRODUCT_ID)) return; + #end Admob.hideBanner(); } @@ -160,11 +163,14 @@ class AdMobUtil */ public static function loadInterstitial(onInterstitialFinish:Void->Void):Void { - if (InAppPurchasesUtil.isPurchased("no_ads")) + #if FEATURE_MOBILE_IAP + if (InAppPurchasesUtil.isPurchased(InAppPurchasesUtil.UPGRADE_PRODUCT_ID)) { - onInterstitialFinish(); + if (onInterstitialFinish != null) onInterstitialFinish(); + return; } + #end function interstitialEvent(event:AdmobEvent):Void { @@ -194,11 +200,14 @@ class AdMobUtil */ public static function loadRewarded(onRewardedFinish:Void->Void):Void { - if (InAppPurchasesUtil.isPurchased("no_ads")) + #if FEATURE_MOBILE_IAP + if (InAppPurchasesUtil.isPurchased(InAppPurchasesUtil.UPGRADE_PRODUCT_ID)) { - onRewardedFinish(); + if (onRewardedFinish != null) onRewardedFinish(); + return; } + #end function rewardedEvent(event:AdmobEvent):Void { diff --git a/source/funkin/mobile/util/InAppPurchasesUtil.hx b/source/funkin/mobile/util/InAppPurchasesUtil.hx index 035cde6c0..16323af6d 100644 --- a/source/funkin/mobile/util/InAppPurchasesUtil.hx +++ b/source/funkin/mobile/util/InAppPurchasesUtil.hx @@ -17,15 +17,17 @@ import extension.iapcore.ios.IAPPurchaseState; #end /** - * Utility class for managing in-app purchases. + * Provides utility functions for working with in-app purchases. */ +@:nullSafety class InAppPurchasesUtil { - #if android - static final FETCH_PRODUCT_DETAILS_IDS:Array = ['test_product_0']; - #elseif ios - static final FETCH_PRODUCT_DETAILS_IDS:Array = ['adfree']; - #end + /** + * The product ID used for the "No Ads" in-app purchase upgrade. + */ + @:allow(funkin.mobile.util.AdMobUtil) + @:allow(funkin.ui.mainmenu.MainMenuState) + static final UPGRADE_PRODUCT_ID:String = 'no_ads'; /** * The maximum number of attempts to reconnect in case of a failure. @@ -35,12 +37,12 @@ class InAppPurchasesUtil /** * A static variable that holds an array of currently loaded product details for in-app purchases. */ - public static var currentProductDetails:Array = []; + static var currentProductDetails:Array = []; /** * A static variable that holds an array of currently purchased for in-app purchases. */ - public static var currentPurchased:Array = []; + static var currentPurchased:Array = []; /** * A static variable to track the number of attempts made to reconnect. @@ -73,7 +75,7 @@ class InAppPurchasesUtil IAPAndroid.queryPurchases(); - IAPAndroid.queryProductDetails(FETCH_PRODUCT_DETAILS_IDS); + IAPAndroid.queryProductDetails([UPGRADE_PRODUCT_ID]); }); IAPAndroid.onBillingServiceDisconnected.add(function():Void { @@ -145,7 +147,7 @@ class InAppPurchasesUtil IAPIOS.restorePurchases(); - IAPIOS.requestProducts(FETCH_PRODUCT_DETAILS_IDS); + IAPIOS.requestProducts([UPGRADE_PRODUCT_ID]); #end } @@ -165,20 +167,37 @@ class InAppPurchasesUtil * Initiates the purchase process for the specified item. * * @param id The identifier of the item to be purchased. + * @param onPurchasesUpdated Callback function to be called when the purchases have been updated. */ - public static function purchase(id:String):Void + public static function purchase(id:String, onPurchasesUpdated:Void->Void):Void { for (product in currentProductDetails) { #if android if (product.getProductId() == id) { + function purchasesUpdatedEvent(result:IAPResult, purchases:Array):Void + { + if (onPurchasesUpdated != null) onPurchasesUpdated(); + + IAPAndroid.onPurchasesUpdated.remove(purchasesUpdatedEvent); + } + + IAPAndroid.onPurchasesUpdated.add(purchasesUpdatedEvent); IAPAndroid.launchPurchaseFlow(product); return; } #elseif ios if (product.getProductIdentifier() == id) { + function purchasesUpdatedEvent(purchases:Array):Void + { + if (onPurchasesUpdated != null) onPurchasesUpdated(); + + IAPIOS.onPurchasesUpdated.remove(purchasesUpdatedEvent); + } + + IAPIOS.onPurchasesUpdated.add(purchasesUpdatedEvent); IAPIOS.purchaseProduct(product); return; } diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index f56fe2434..7aa3e5ca3 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -70,8 +70,8 @@ class MainMenuState extends MusicBeatState transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; - #if mobile - hasUpgraded = InAppPurchasesUtil.isPurchased("no_ads"); + #if FEATURE_MOBILE_IAP + hasUpgraded = InAppPurchasesUtil.isPurchased(InAppPurchasesUtil.UPGRADE_PRODUCT_ID); #else // just to make sure its never accidentally turned off hasUpgraded = true; @@ -170,9 +170,8 @@ class MainMenuState extends MusicBeatState add(upgradeSparkles); createMenuItem('upgrade', 'mainmenu/upgrade', function() { - #if mobile - InAppPurchasesUtil.purchase("no_ads"); - FlxG.resetState(); + #if FEATURE_MOBILE_IAP + InAppPurchasesUtil.purchase(InAppPurchasesUtil.UPGRADE_PRODUCT_ID, FlxG.resetState); #end }); }