diff --git a/ExtraPluginCfgs/AddressableAssetsData/Android/addressables_content_state.bin b/ExtraPluginCfgs/AddressableAssetsData/Android/addressables_content_state.bin new file mode 100644 index 0000000..56de4dc Binary files /dev/null and b/ExtraPluginCfgs/AddressableAssetsData/Android/addressables_content_state.bin differ diff --git a/ExtraPluginCfgs/Android/enjoypay/AndroidManifest.xml b/ExtraPluginCfgs/Android/enjoypay/AndroidManifest.xml index 928bd75..7be0ed5 100644 --- a/ExtraPluginCfgs/Android/enjoypay/AndroidManifest.xml +++ b/ExtraPluginCfgs/Android/enjoypay/AndroidManifest.xml @@ -6,7 +6,9 @@ - + @@ -35,7 +37,12 @@ - + + + + diff --git a/ExtraPluginCfgs/Android/enjoypay/EnjoyPayAdapter.java b/ExtraPluginCfgs/Android/enjoypay/EnjoyPayAdapter.java new file mode 100644 index 0000000..cbbea4c --- /dev/null +++ b/ExtraPluginCfgs/Android/enjoypay/EnjoyPayAdapter.java @@ -0,0 +1,7 @@ +package com.unity3d.player; + +public class EnjoyPayAdapter extends ChannelAdapterBase { + private static class Config { + public String SDK_CLIENTID = "Android_5.00_tyGuest,facebook.googleplay.0-hall20587.googleplay.FishingMasterRussia"; + } +} diff --git a/ExtraPluginCfgs/Android/enjoypay/Files/google-services.json b/ExtraPluginCfgs/Android/enjoypay/Files/google-services.json index b4cce13..5ff18d4 100644 --- a/ExtraPluginCfgs/Android/enjoypay/Files/google-services.json +++ b/ExtraPluginCfgs/Android/enjoypay/Files/google-services.json @@ -1,29 +1,39 @@ { "project_info": { - "project_number": "404468630883", - "project_id": "fishing-travel-ep-1ab1e", - "storage_bucket": "fishing-travel-ep-1ab1e.firebasestorage.app" + "project_number": "550846874481", + "project_id": "fishing-travel-ep", + "storage_bucket": "fishing-travel-ep.firebasestorage.app" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:404468630883:android:de3cb115158a5e4cdfff56", + "mobilesdk_app_id": "1:550846874481:android:800f3c713738b6b51d2cd0", "android_client_info": { "package_name": "com.arkgame.ft.ep" } }, - "oauth_client": [], + "oauth_client": [ + { + "client_id": "550846874481-8thf5tv2gm5n7b7uui3kts0kajuddhn7.apps.googleusercontent.com", + "client_type": 3 + } + ], "api_key": [ { - "current_key": "AIzaSyAL8YVO4U6A9WRiQ581Et0o-BmtMf3k7Hg" + "current_key": "AIzaSyDw8YISM6R6vtHC4IfJtNBFijrKqgxlfcw" } ], "services": { "appinvite_service": { - "other_platform_oauth_client": [] + "other_platform_oauth_client": [ + { + "client_id": "550846874481-8thf5tv2gm5n7b7uui3kts0kajuddhn7.apps.googleusercontent.com", + "client_type": 3 + } + ] } } } ], "configuration_version": "1" -} +} \ No newline at end of file diff --git a/ExtraPluginCfgs/Android/enjoypay/Plugins/Android/tuyoosdk_1.0.0.aar b/ExtraPluginCfgs/Android/enjoypay/Plugins/Android/tuyoosdk_1.0.0.aar index 5dc8d15..e089df3 100644 Binary files a/ExtraPluginCfgs/Android/enjoypay/Plugins/Android/tuyoosdk_1.0.0.aar and b/ExtraPluginCfgs/Android/enjoypay/Plugins/Android/tuyoosdk_1.0.0.aar differ diff --git a/ExtraPluginCfgs/Android/enjoypay/launcherTemplate.gradle b/ExtraPluginCfgs/Android/enjoypay/launcherTemplate.gradle index 8116694..6231ad1 100644 --- a/ExtraPluginCfgs/Android/enjoypay/launcherTemplate.gradle +++ b/ExtraPluginCfgs/Android/enjoypay/launcherTemplate.gradle @@ -3,12 +3,12 @@ apply plugin: 'com.google.gms.google-services' dependencies { implementation project(':unityLibrary') - implementation(platform("com.google.firebase:firebase-bom:33.6.0")) - implementation("com.google.firebase:firebase-analytics") + implementation platform('com.google.firebase:firebase-bom:34.6.0') + implementation 'com.google.firebase:firebase-analytics' } android { - namespace "**NAMESPACE**" + namespace "**NAMESPACE**" ndkPath "**NDKPATH**" compileSdkVersion **APIVERSION** diff --git a/ExtraPluginCfgs/Android/enjoypay/mainTemplate.gradle b/ExtraPluginCfgs/Android/enjoypay/mainTemplate.gradle index 1886c66..4fbd509 100644 --- a/ExtraPluginCfgs/Android/enjoypay/mainTemplate.gradle +++ b/ExtraPluginCfgs/Android/enjoypay/mainTemplate.gradle @@ -21,7 +21,7 @@ dependencies { api "com.android.support:support-v4:28.0.0" api "com.android.support:appcompat-v7:28.0.0" - + api "com.google.code.gson:gson:2.8.6" api "com.squareup.okio:okio:1.15.0" api "com.squareup.okhttp3:okhttp:3.12.13" @@ -31,13 +31,13 @@ dependencies { api "io.reactivex:rxandroid:1.2.1" api "io.reactivex:rxjava:1.1.9" - // Google Play In-App Review + // Google Play In-App Review implementation 'com.google.android.play:review:2.0.1' implementation 'net.aihelp:android-aihelp-aar:5.3.+' - + implementation 'com.google.android.gms:play-services-auth:20.2.0' implementation('com.android.billingclient:billing:7.0.0') - + implementation 'com.google.android.gms:play-services-basement:18.2.0' implementation 'androidx.fragment:fragment:1.3.6' implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.41" @@ -59,21 +59,28 @@ dependencies { implementation "androidx.credentials:credentials-play-services-auth:1.3.0" implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1" - // EnjoyPay SDK dependency goes here after the official Maven/AAR coordinates are confirmed. + coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2" + // EnjoyPay SDK is provided by Plugins/Android/tuyoosdk_1.0.0.aar and copied by ChannelBuildTool. // Android Resolver Dependencies Start + implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9 implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:7 + implementation 'com.applovin.mediation:bytedance-adapter:8.1.0.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:facebook-adapter:[6.18.0.1]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:fyber-adapter:8.4.2.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:google-adapter:[23.6.0.1]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5 implementation 'com.applovin.mediation:ironsource-adapter:8.6.1.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:mintegral-adapter:17.1.61.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:moloco-adapter:4.9.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:unityads-adapter:4.12.3.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:vungle-adapter:7.4.2.2' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4 + implementation 'com.applovin.mediation:yandex-adapter:8.1.0.0' // Assets/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml:4 implementation 'com.applovin:applovin-sdk:13.5.1' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4 implementation 'com.appsflyer:af-android-sdk:6.17.3' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:5 implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8 - implementation 'com.appsflyer:unity-wrapper:6.17.7' // Assets/AppsFlyer/Editor/Dependencies.xml:6 + implementation 'com.appsflyer:unity-wrapper:6.17.7' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:6 implementation 'com.google.android.ump:user-messaging-platform:2.1.0' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:5 + implementation 'com.tapjoy:tapjoy-android-unitybridge:14.5.0' // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:10 // Android Resolver Dependencies End **DEPS**} @@ -85,6 +92,7 @@ android { compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 + coreLibraryDesugaringEnabled true } defaultConfig { diff --git a/ExtraPluginCfgs/Android/enjoypay/settingsTemplate.gradle b/ExtraPluginCfgs/Android/enjoypay/settingsTemplate.gradle index 274cfab..c68dae5 100644 --- a/ExtraPluginCfgs/Android/enjoypay/settingsTemplate.gradle +++ b/ExtraPluginCfgs/Android/enjoypay/settingsTemplate.gradle @@ -19,7 +19,17 @@ dependencyResolutionManagement { // Android Resolver Repos Start def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") maven { - url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Dependencies.xml:8 + url "https://sdk.tapjoy.com/" // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:9 + } + + maven { + url "https://artifact.bytedance.com/repository/pangle" // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 + } + maven { + url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 + } + maven { + url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 } mavenLocal() // Android Resolver Repos End @@ -27,8 +37,8 @@ dependencyResolutionManagement { dirs "${project(':unityLibrary').projectDir}/libs" } - maven { - url "http://sdkck.tuyoo.com/artifactory/tuyoo-component/" + maven { + url "http://sdkck.tuyoo.com/artifactory/tuyoo-component/" allowInsecureProtocol = true } } diff --git a/ExtraPluginCfgs/Android/flexion/AndroidManifest.xml b/ExtraPluginCfgs/Android/flexion/AndroidManifest.xml index ad8231c..5b6df90 100644 --- a/ExtraPluginCfgs/Android/flexion/AndroidManifest.xml +++ b/ExtraPluginCfgs/Android/flexion/AndroidManifest.xml @@ -35,7 +35,7 @@ - + { - Log.i(TAG, "[FLX-INIT] FLX.init result=" + initCode - + " msg=" + initMsg - + " attempt=" + attempt + "/" + FLX_INIT_MAX_ATTEMPTS); + // Log.i(TAG, "[FLX-INIT] FLX.init result=" + initCode + // + " msg=" + initMsg + // + " attempt=" + attempt + "/" + FLX_INIT_MAX_ATTEMPTS); if (initCode == 0) { flexionInitialized = true; notifyFlexionInitResult(true, "ok"); @@ -181,7 +189,7 @@ public class FlexionSDKAdapter implements private static void showFlexionScreensThenInitBilling(Activity activity) { if (flexionScreensShown) { - Log.i(TAG, "[FLX-INIT] showFlexionScreens skipped, already shown"); + // Log.i(TAG, "[FLX-INIT] showFlexionScreens skipped, already shown"); initBillingServiceAfterScreens(activity); return; } @@ -191,21 +199,21 @@ public class FlexionSDKAdapter implements return; } - Log.i(TAG, "[FLX-INIT] showFlexionScreens start"); + // Log.i(TAG, "[FLX-INIT] showFlexionScreens start"); flexionScreensStarted = true; FLX.showFlexionScreens(activity, (screenCode, screenMsg) -> { - Log.i(TAG, "[FLX-INIT] showFlexionScreens result=" + screenCode - + " msg=" + screenMsg); + // Log.i(TAG, "[FLX-INIT] showFlexionScreens result=" + screenCode + // + " msg=" + screenMsg); flexionScreensShown = true; initBillingServiceAfterScreens(activity); }); } private static void initBillingServiceAfterScreens(Activity activity) { - Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens start"); + // Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens start"); initBillingService(activity, () -> { - Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens success"); + // Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens success"); }, () -> { Log.w(TAG, "[FLX-INIT] initBillingServiceAfterScreens failed"); @@ -230,17 +238,14 @@ public class FlexionSDKAdapter implements try { byte[] decoded = Base64.getDecoder().decode(appInfo); JSONObject json = new JSONObject(new String(decoded, StandardCharsets.UTF_8)); - Jsonobject json = new JSONObject(); JSONObject payload = new JSONObject(); String customData = json.optString("customData", ""); payload.put("orderId", prodorderId); payload.put("userId", json.optString("userId", "")); payload.put("pfid", json.optString("pfid", "")); - payload.put("customData", json.optString("customData", "")); - - // if (!customData.isEmpty()) { - // payload.put("customData", parseCustomDataValue(customData)); - // } + if (!customData.isEmpty()) { + payload.put("customData", customData); + } payload.put("prodPrice", productPrice); payload.put("prodCount", productCount); developerPayload = Base64.getEncoder().encodeToString(payload.toString().getBytes(StandardCharsets.UTF_8)); @@ -278,21 +283,6 @@ public class FlexionSDKAdapter implements () -> sendPayCallback(1, "billing_not_ready", null, null, null, null)); } - private static Object parseCustomDataValue(String customData) { - String trimmed = customData == null ? "" : customData.trim(); - try { - if (trimmed.startsWith("{")) { - return new JSONObject(trimmed); - } - if (trimmed.startsWith("[")) { - return new JSONArray(trimmed); - } - } catch (JSONException e) { - Log.w(TAG, "[PAY-CUSTOMDATA] customData json parse failed, keep raw string: " + e.getMessage()); - } - return customData; - } - @Override public void queryProducts() { // Flexion 渠道不通过 thirdExtend 获取商品列表,由 queryProducts(String) 替代 @@ -300,9 +290,11 @@ public class FlexionSDKAdapter implements @Override public void queryProducts(String productIds) { - // Log.i(TAG, "queryProducts(productIds) called, billingConnected=" + billingConnected); List ids = Arrays.asList(productIds.split(",")); - // Log.i(TAG, "queryProductDetails with " + ids.size() + " items from config"); + Log.i(TAG, "[FLEXION-SKU-PRICE] queryProducts productIds=" + productIds + + " count=" + ids.size() + + " billingConnected=" + billingConnected + + " billingReady=" + (billingService != null && billingService.isReady())); ensureBillingReady(null, "queryProducts", bs -> queryProductDetails(bs, ids), () -> sendExtensionError("billing_not_ready")); @@ -442,8 +434,8 @@ public class FlexionSDKAdapter implements JSONArray cached = drainCachedPendingPurchases(); boolean cacheReady = isPendingPurchaseCacheReady(); if (cached.length() > 0 || cacheReady) { - Log.i(TAG, "[PAY-FLOW] queryPendingPurchases use cached result count=" + cached.length() - + " cacheReady=" + cacheReady); + // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases use cached result count=" + cached.length() + // + " cacheReady=" + cacheReady); markPendingPurchaseCacheConsumed(cached); sendPendingPurchasesCallback(0, null, cached); return; @@ -455,18 +447,18 @@ public class FlexionSDKAdapter implements pendingPurchaseUnityCallbackWaiting = true; } if (pendingPurchaseQueryInProgress) { - Log.i(TAG, "[PAY-FLOW] queryPendingPurchases wait running query" - + " sendUnityCallback=" + sendUnityCallback - + " cacheReady=" + pendingPurchaseCacheReady); + // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases wait running query" + // + " sendUnityCallback=" + sendUnityCallback + // + " cacheReady=" + pendingPurchaseCacheReady); return; } pendingPurchaseQueryInProgress = true; pendingPurchaseCacheReady = false; } - Log.i(TAG, "[PAY-FLOW] queryPendingPurchases start: billingService=" + billingService - + " billingConnected=" + billingConnected - + " sendUnityCallback=" + sendUnityCallback); + // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases start: billingService=" + billingService + // + " billingConnected=" + billingConnected + // + " sendUnityCallback=" + sendUnityCallback); ensureBillingReady(null, "queryPendingPurchases", bs -> { billingExecutor.execute(() -> { @@ -476,9 +468,9 @@ public class FlexionSDKAdapter implements (result, purchases) -> { int responseCode = result == null ? -1 : result.getResponseCode(); String debugMessage = result == null ? "billing_result_null" : result.getDebugMessage(); - Log.i(TAG, "[PAY-FLOW] queryPendingPurchases result: code=" + responseCode - + " debugMsg=" + debugMessage - + " count=" + (purchases == null ? 0 : purchases.size())); + // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases result: code=" + responseCode + // + " debugMsg=" + debugMessage + // + " count=" + (purchases == null ? 0 : purchases.size())); if (responseCode != QUERY_PURCHASES_SUCCESS_CODE) { boolean shouldCallback = finishPendingQueryFailed(); if (shouldCallback) { @@ -512,7 +504,7 @@ public class FlexionSDKAdapter implements }); }, () -> { - Log.w(TAG, "[PAY-FLOW] queryPendingPurchases skipped: billing not connected"); + // Log.w(TAG, "[PAY-FLOW] queryPendingPurchases skipped: billing not connected"); boolean shouldCallback = finishPendingQueryFailed(); if (shouldCallback) sendPendingPurchasesCallback(1, "billing_not_ready", new JSONArray()); }); @@ -578,9 +570,9 @@ public class FlexionSDKAdapter implements private static JSONArray drainCachedPendingPurchases() { synchronized (pendingPurchases) { - Log.i(TAG, "[PAY-FLOW] drainCachedPendingPurchases start cachedCount=" + pendingPurchases.size() - + " queryInProgress=" + pendingPurchaseQueryInProgress - + " cacheReady=" + pendingPurchaseCacheReady); + // Log.i(TAG, "[PAY-FLOW] drainCachedPendingPurchases start cachedCount=" + pendingPurchases.size() + // + " queryInProgress=" + pendingPurchaseQueryInProgress + // + " cacheReady=" + pendingPurchaseCacheReady); JSONArray result = new JSONArray(); for (String item : pendingPurchases) { try { @@ -602,7 +594,7 @@ public class FlexionSDKAdapter implements JSONObject item = purchases.optJSONObject(i); if (item != null) pendingPurchases.add(item.toString()); } - Log.i(TAG, "[PAY-FLOW] replaceCachedPendingPurchases count=" + pendingPurchases.size()); + // Log.i(TAG, "[PAY-FLOW] replaceCachedPendingPurchases count=" + pendingPurchases.size()); } } @@ -618,8 +610,8 @@ public class FlexionSDKAdapter implements result.put("code", code); if (errStr != null) result.put("errStr", errStr); result.put("respObj", purchases == null ? "[]" : purchases.toString()); - Log.i(TAG, "[PAY-FLOW] PendingPurchasesResult callback: code=" + code - + " count=" + (purchases == null ? 0 : purchases.length())); + // Log.i(TAG, "[PAY-FLOW] PendingPurchasesResult callback: code=" + code + // + " count=" + (purchases == null ? 0 : purchases.length())); UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME, "PendingPurchasesResult", result.toString()); } catch (JSONException e) { @@ -641,6 +633,9 @@ public class FlexionSDKAdapter implements private static void queryProductDetails(BillingService service, List productIds) { final AtomicBoolean completed = new AtomicBoolean(false); + Log.i(TAG, "[FLEXION-SKU-PRICE] queryProductDetails start count=" + productIds.size() + + " productIds=" + productIds + + " serviceReady=" + (service != null && service.isReady())); mainHandler.postDelayed(() -> { if (!completed.compareAndSet(false, true)) return; Log.w(TAG, "[PAY-FLOW] queryProductDetails timeout count=" + productIds.size()); @@ -656,6 +651,11 @@ public class FlexionSDKAdapter implements Log.w(TAG, "[PAY-FLOW] queryProductDetails callback ignored after timeout"); return; } + Log.i(TAG, "[FLEXION-SKU-PRICE] queryProductDetails callback code=" + + (billingResult == null ? "null" : billingResult.getResponseCode()) + + " debugMsg=" + + (billingResult == null ? "billing_result_null" : billingResult.getDebugMessage()) + + " count=" + (productDetails == null ? 0 : productDetails.size())); try { JSONObject result = new JSONObject(); if (billingResult != null @@ -672,10 +672,17 @@ public class FlexionSDKAdapter implements item.put("price_amount_micros", detail.getPriceAmountMicros()); item.put("price_currency_code", detail.getPriceCurrencyCode()); item.put("type", detail.getType()); + Log.i(TAG, "[FLEXION-SKU-PRICE] sdk product id=" + detail.getId() + + " title=" + detail.getTitle() + + " price=" + detail.getPrice() + + " priceAmountMicros=" + detail.getPriceAmountMicros() + + " currency=" + detail.getPriceCurrencyCode() + + " type=" + detail.getType()); arr.put(item); } result.put("code", 0); result.put("respObj", arr.toString()); + Log.i(TAG, "[FLEXION-SKU-PRICE] send Unity SKUListResult respObj=" + arr.toString()); } else { result.put("code", 1); result.put("thirdExtend_errStr", @@ -731,12 +738,18 @@ public class FlexionSDKAdapter implements } // Log.i(TAG, "[PAY-FLOW] consumePurchase: token=" + token); ensureBillingReady(null, "consumePurchase", - bs -> bs.consumeAsync( - new ConsumeParams(token), - r -> { - // Log.i(TAG, "[PAY-FLOW] consume result: " + - // (r.getResponseCode() == BillingResults.ResultCode.CONSUME_SUCCESS_CODE ? "ok" : "fail")); - }), + bs -> billingExecutor.execute(() -> { + try { + bs.consumeAsync( + new ConsumeParams(token), + r -> { + // Log.i(TAG, "[PAY-FLOW] consume result: " + + // (r.getResponseCode() == BillingResults.ResultCode.CONSUME_SUCCESS_CODE ? "ok" : "fail")); + }); + } catch (Exception e) { + Log.e(TAG, "[PAY-FLOW] consumePurchase exception: " + e.getMessage()); + } + }), () -> Log.w(TAG, "[PAY-FLOW] consumePurchase skipped: billing not connected")); } @@ -744,6 +757,49 @@ public class FlexionSDKAdapter implements // Log.i(TAG, "[PAY-FLOW] cancelPurchase: TODO - dismiss billing dialog"); } + @Override + public void review(Activity activity) { + String storePageUri = getStorePageUri(activity); + Log.w(TAG, "[ReviewDebug] review uri=" + storePageUri); + if (TextUtils.isEmpty(storePageUri)) { + Log.w(TAG, "review skipped: store page uri is empty"); + return; + } + + Activity targetActivity = activity != null ? activity : billingActivity; + if (targetActivity == null) targetActivity = UnityPlayer.currentActivity; + if (targetActivity == null) { + Log.w(TAG, "review skipped: activity is null"); + return; + } + + try { + targetActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(storePageUri))); + } catch (Throwable e) { + Log.w(TAG, "review exception: " + e.getMessage()); + } + } + + @Override + public String getStorePageUri(Activity activity) { + try { + Activity targetActivity = activity != null ? activity : billingActivity; + if (targetActivity == null) targetActivity = UnityPlayer.currentActivity; + if (targetActivity == null) { + Log.w(TAG, "getStorePageUri skipped: activity is null"); + return ""; + } + + Object storePageUri = FLX.createChannelInfoService(targetActivity) + .getCurrentChannelInfo(targetActivity) + .getStorePageUri(); + return storePageUri != null ? storePageUri.toString() : ""; + } catch (Throwable e) { + Log.w(TAG, "getStorePageUri exception: " + e.getMessage()); + return ""; + } + } + private static void sendExtensionError(String errStr) { try { JSONObject result = new JSONObject(); diff --git a/ExtraPluginCfgs/Android/flexion/gradleTemplate.properties b/ExtraPluginCfgs/Android/flexion/gradleTemplate.properties index cc49b2a..0b94027 100644 --- a/ExtraPluginCfgs/Android/flexion/gradleTemplate.properties +++ b/ExtraPluginCfgs/Android/flexion/gradleTemplate.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M +org.gradle.jvmargs=-Xmx8192m org.gradle.parallel=true unityStreamingAssets=**STREAMING_ASSETS** # Android Resolver Properties Start diff --git a/ExtraPluginCfgs/Android/flexion/launcherTemplate.gradle b/ExtraPluginCfgs/Android/flexion/launcherTemplate.gradle index 31efa26..6231ad1 100644 --- a/ExtraPluginCfgs/Android/flexion/launcherTemplate.gradle +++ b/ExtraPluginCfgs/Android/flexion/launcherTemplate.gradle @@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services' dependencies { implementation project(':unityLibrary') - implementation(platform("com.google.firebase:firebase-bom:33.6.0")) - implementation("com.google.firebase:firebase-analytics") + implementation platform('com.google.firebase:firebase-bom:34.6.0') + implementation 'com.google.firebase:firebase-analytics' } android { @@ -17,7 +17,6 @@ android { compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 - } defaultConfig { diff --git a/ExtraPluginCfgs/Android/flexion/mainTemplate.gradle b/ExtraPluginCfgs/Android/flexion/mainTemplate.gradle index a1916bb..798a65a 100644 --- a/ExtraPluginCfgs/Android/flexion/mainTemplate.gradle +++ b/ExtraPluginCfgs/Android/flexion/mainTemplate.gradle @@ -13,7 +13,7 @@ android { } // Android Resolver Exclusions End android { - namespace "com.unity3d.player" + namespace "com.unity3d.player" } dependencies { @@ -31,17 +31,16 @@ dependencies { api "io.reactivex:rxandroid:1.2.1" api "io.reactivex:rxjava:1.1.9" - // Google Play In-App Review + // Google Play In-App Review implementation 'com.google.android.play:review:2.0.1' - // Google Play Billing — tuyoosdk AAR references BillingManager during init - implementation 'com.android.billingclient:billing:7.0.0' implementation 'net.aihelp:android-aihelp-aar:5.3.+' implementation 'com.google.android.gms:play-services-auth:20.2.0' // Flexion SDK (includes wrapped billing) implementation("com.flexionmobile:sdk:4.0.1") - + implementation('com.android.billingclient:billing:7.0.0') + implementation 'com.google.android.gms:play-services-basement:18.2.0' implementation 'androidx.fragment:fragment:1.3.6' implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.41" @@ -66,13 +65,18 @@ dependencies { coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2" // Android Resolver Dependencies Start + implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9 implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:7 + implementation 'com.applovin.mediation:bytedance-adapter:8.1.0.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:facebook-adapter:[6.18.0.1]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:fyber-adapter:8.4.2.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:google-adapter:[23.6.0.1]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5 implementation 'com.applovin.mediation:ironsource-adapter:8.6.1.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:mintegral-adapter:17.1.61.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:moloco-adapter:4.9.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:unityads-adapter:4.12.3.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:vungle-adapter:7.4.2.2' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4 + implementation 'com.applovin.mediation:yandex-adapter:8.1.0.0' // Assets/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml:4 implementation 'com.applovin:applovin-sdk:13.5.1' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4 implementation 'com.appsflyer:af-android-sdk:6.17.3' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:5 implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8 diff --git a/ExtraPluginCfgs/Android/flexion/settingsTemplate.gradle b/ExtraPluginCfgs/Android/flexion/settingsTemplate.gradle index 8310899..6637c13 100644 --- a/ExtraPluginCfgs/Android/flexion/settingsTemplate.gradle +++ b/ExtraPluginCfgs/Android/flexion/settingsTemplate.gradle @@ -26,15 +26,20 @@ dependencyResolutionManagement { password = "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" } } - // Android Resolver Repos Start - def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") - maven { + def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") + maven { url "https://sdk.tapjoy.com/" // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:9 } + maven { + url "https://artifact.bytedance.com/repository/pangle" // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 + } maven { url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 } + maven { + url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + } mavenLocal() // Android Resolver Repos End flatDir { diff --git a/ExtraPluginCfgs/Android/googleplay/AndroidManifest.xml b/ExtraPluginCfgs/Android/googleplay/AndroidManifest.xml index ebd9b2e..a1fa4fc 100644 --- a/ExtraPluginCfgs/Android/googleplay/AndroidManifest.xml +++ b/ExtraPluginCfgs/Android/googleplay/AndroidManifest.xml @@ -36,7 +36,7 @@ - + diff --git a/ExtraPluginCfgs/Android/googleplay/launcherTemplate.gradle b/ExtraPluginCfgs/Android/googleplay/launcherTemplate.gradle index 31efa26..6231ad1 100644 --- a/ExtraPluginCfgs/Android/googleplay/launcherTemplate.gradle +++ b/ExtraPluginCfgs/Android/googleplay/launcherTemplate.gradle @@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services' dependencies { implementation project(':unityLibrary') - implementation(platform("com.google.firebase:firebase-bom:33.6.0")) - implementation("com.google.firebase:firebase-analytics") + implementation platform('com.google.firebase:firebase-bom:34.6.0') + implementation 'com.google.firebase:firebase-analytics' } android { @@ -17,7 +17,6 @@ android { compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 - } defaultConfig { diff --git a/ExtraPluginCfgs/Android/googleplay/mainTemplate.gradle b/ExtraPluginCfgs/Android/googleplay/mainTemplate.gradle index 814c5c6..28d7325 100644 --- a/ExtraPluginCfgs/Android/googleplay/mainTemplate.gradle +++ b/ExtraPluginCfgs/Android/googleplay/mainTemplate.gradle @@ -60,18 +60,24 @@ dependencies { implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1" // Android Resolver Dependencies Start + implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9 implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:7 + implementation 'com.applovin.mediation:bytedance-adapter:8.1.0.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:facebook-adapter:[6.18.0.1]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:fyber-adapter:8.4.2.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:google-adapter:[23.6.0.1]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5 implementation 'com.applovin.mediation:ironsource-adapter:8.6.1.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:mintegral-adapter:17.1.61.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:moloco-adapter:4.9.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:unityads-adapter:4.12.3.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:vungle-adapter:7.4.2.2' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4 + implementation 'com.applovin.mediation:yandex-adapter:8.1.0.0' // Assets/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml:4 implementation 'com.applovin:applovin-sdk:13.5.1' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4 implementation 'com.appsflyer:af-android-sdk:6.17.3' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:5 implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8 implementation 'com.appsflyer:unity-wrapper:6.17.7' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:6 implementation 'com.google.android.ump:user-messaging-platform:2.1.0' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:5 + implementation 'com.tapjoy:tapjoy-android-unitybridge:14.5.0' // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:10 // Android Resolver Dependencies End **DEPS**} diff --git a/ExtraPluginCfgs/Android/googleplay/settingsTemplate.gradle b/ExtraPluginCfgs/Android/googleplay/settingsTemplate.gradle index 73133c1..fa73a11 100644 --- a/ExtraPluginCfgs/Android/googleplay/settingsTemplate.gradle +++ b/ExtraPluginCfgs/Android/googleplay/settingsTemplate.gradle @@ -18,9 +18,18 @@ dependencyResolutionManagement { mavenCentral() // Android Resolver Repos Start def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") + maven { + url "https://sdk.tapjoy.com/" // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:9 + } + maven { + url "https://artifact.bytedance.com/repository/pangle" // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 + } maven { url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 } + maven { + url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + } mavenLocal() // Android Resolver Repos End flatDir { diff --git a/ExtraPluginCfgs/Android/rustore/AndroidManifest.xml b/ExtraPluginCfgs/Android/rustore/AndroidManifest.xml index ad0b932..158c23e 100644 --- a/ExtraPluginCfgs/Android/rustore/AndroidManifest.xml +++ b/ExtraPluginCfgs/Android/rustore/AndroidManifest.xml @@ -33,7 +33,7 @@ - + diff --git a/ExtraPluginCfgs/Android/rustore/Plugins/Android/tuyoosdk_1.0.0.aar b/ExtraPluginCfgs/Android/rustore/Plugins/Android/tuyoosdk_1.0.0.aar index 6e24f7d..44e48c8 100644 Binary files a/ExtraPluginCfgs/Android/rustore/Plugins/Android/tuyoosdk_1.0.0.aar and b/ExtraPluginCfgs/Android/rustore/Plugins/Android/tuyoosdk_1.0.0.aar differ diff --git a/ExtraPluginCfgs/Android/rustore/RustoreAdapter.java b/ExtraPluginCfgs/Android/rustore/RustoreAdapter.java new file mode 100644 index 0000000..65004d8 --- /dev/null +++ b/ExtraPluginCfgs/Android/rustore/RustoreAdapter.java @@ -0,0 +1,46 @@ +package com.unity3d.player; + +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.Locale; + +public class RustoreAdapter extends ChannelAdapterBase { + private static final String TAG = "RustoreAdapter"; + + @Override + public String normalizeSkuList(String msg) { + if (msg == null || msg.isEmpty()) { + return msg; + } + + try { + JSONArray products = new JSONArray(msg); + for (int i = 0; i < products.length(); i++) { + JSONObject p = products.getJSONObject(i); + + String price = p.optString("price", "0"); + long micros = Long.parseLong(price) * 10000; + p.put("price_amount_micros", String.valueOf(micros)); + + String currency = p.optString("currency", ""); + if (!currency.isEmpty()) { + p.put("price_currency_code", currency); + } + + float rubles = Float.parseFloat(price) / 100; + p.put("price", String.format(Locale.US, "RUB %.2f", rubles)); + } + return products.toString(); + } catch (Exception e) { + Log.e(TAG, "normalizeSkuList error: " + e.getMessage()); + return msg; + } + } + + private static class Config { + public String SDK_CLIENTID = "Android_5.00_tyGuest,facebook.googleplay.0-hall20587.rustore.FishingTravel"; + } +} diff --git a/ExtraPluginCfgs/Android/rustore/launcherTemplate.gradle b/ExtraPluginCfgs/Android/rustore/launcherTemplate.gradle index af21b33..87c4030 100644 --- a/ExtraPluginCfgs/Android/rustore/launcherTemplate.gradle +++ b/ExtraPluginCfgs/Android/rustore/launcherTemplate.gradle @@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services' dependencies { implementation project(':unityLibrary') - implementation(platform("com.google.firebase:firebase-bom:33.6.0")) - implementation("com.google.firebase:firebase-analytics") + implementation platform('com.google.firebase:firebase-bom:34.6.0') + implementation 'com.google.firebase:firebase-analytics' } android { diff --git a/ExtraPluginCfgs/Android/rustore/mainTemplate.gradle b/ExtraPluginCfgs/Android/rustore/mainTemplate.gradle index 3310dbe..fa27a5b 100644 --- a/ExtraPluginCfgs/Android/rustore/mainTemplate.gradle +++ b/ExtraPluginCfgs/Android/rustore/mainTemplate.gradle @@ -13,7 +13,7 @@ android { } // Android Resolver Exclusions End android { - namespace "com.unity3d.player" + namespace "com.unity3d.player" } dependencies { @@ -36,7 +36,7 @@ dependencies { implementation 'net.aihelp:android-aihelp-aar:5.3.+' implementation 'com.google.android.gms:play-services-auth:20.2.0' - implementation('com.android.billingclient:billing:6.0.1') + implementation('com.android.billingclient:billing:7.0.0') implementation 'com.google.android.gms:play-services-basement:18.2.0' implementation 'androidx.fragment:fragment:1.3.6' @@ -48,7 +48,7 @@ dependencies { implementation 'com.miui.referrer:homereferrer:1.0.0.6' - implementation platform('com.google.firebase:firebase-bom:32.7.4') + implementation platform('com.google.firebase:firebase-bom:34.6.0') implementation 'com.google.firebase:firebase-analytics' implementation('com.facebook.android:facebook-android-sdk:16.2.0') @@ -65,20 +65,25 @@ dependencies { implementation "ru.rustore.sdk:review:10.0.0" implementation "com.vk.id:vkid:2.5.1" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2" - // Android Resolver Dependencies Start + implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9 implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:7 + implementation 'com.applovin.mediation:bytedance-adapter:8.1.0.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:facebook-adapter:[6.18.0.1]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:fyber-adapter:8.4.2.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:google-adapter:[23.6.0.1]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5 implementation 'com.applovin.mediation:ironsource-adapter:8.6.1.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:mintegral-adapter:17.1.61.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:moloco-adapter:4.9.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:unityads-adapter:4.12.3.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:vungle-adapter:7.4.2.2' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4 + implementation 'com.applovin.mediation:yandex-adapter:8.1.0.0' // Assets/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml:4 implementation 'com.applovin:applovin-sdk:13.5.1' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4 implementation 'com.appsflyer:af-android-sdk:6.17.3' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:5 implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8 implementation 'com.appsflyer:unity-wrapper:6.17.7' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:6 implementation 'com.google.android.ump:user-messaging-platform:2.1.0' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:5 + implementation 'com.tapjoy:tapjoy-android-unitybridge:14.5.0' // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:10 // Android Resolver Dependencies End **DEPS**} diff --git a/sdk-intergration/Assets/Editor/BuildTool.cs b/sdk-intergration/Assets/Editor/BuildTool.cs index 355de8a..25e683d 100644 --- a/sdk-intergration/Assets/Editor/BuildTool.cs +++ b/sdk-intergration/Assets/Editor/BuildTool.cs @@ -58,13 +58,21 @@ public class BuildTool [MenuItem("Tools/Build Android")] public static void BuildAndroid() { - ChannelBuildTool.Build_GooglePlay(); + ChannelBuildTool.SwitchChannel("GooglePlay"); + BuildAndroid(new BuildParams + { + outPath = "../Bin/tysdkTest_GooglePlay.apk" + }); } [MenuItem("Tools/Build Android With Debug")] public static void BuildAndroidWithDebug() { - ChannelBuildTool.Build_GooglePlay_Debug(); + ChannelBuildTool.SwitchChannel("GooglePlay"); + BuildAndroid(new BuildParams + { + outPath = "../Bin/tysdkTest_GooglePlay_debug.apk" + }, BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.WaitForPlayerConnection); } public static void CIBuildAndroid() diff --git a/sdk-intergration/Assets/Editor/ChannelBuildTool.cs b/sdk-intergration/Assets/Editor/ChannelBuildTool.cs index df00156..c0e090d 100644 --- a/sdk-intergration/Assets/Editor/ChannelBuildTool.cs +++ b/sdk-intergration/Assets/Editor/ChannelBuildTool.cs @@ -1,103 +1,71 @@ +using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; +using UnityEditor.AddressableAssets; using UnityEngine; public class ChannelBuildTool { - public static readonly string[] SupportedChannels = { "GooglePlay", "Rustore", "Flexion", "EnjoyPay" }; - - private const string DefaultChannel = "GooglePlay"; - private const string DefaultAndroidBundleIdentifier = "com.arkgame.ft"; private const string ExtraCfgRoot = "../ExtraPluginCfgs/Android"; private const string TysdkPlugins = "Packages/tysdk/Plugins/Android"; private const string TysdkFiles = "Packages/tysdk/Files"; private const string AssetsPlugins = "Assets/Plugins/Android"; - private static readonly string[] GradleFiles = - { - "mainTemplate.gradle", - "launcherTemplate.gradle", - "settingsTemplate.gradle", - "gradleTemplate.properties", - "AndroidManifest.xml" - }; + private const string AddressablesContentState = "AddressableAssetsData/Android/addressables_content_state.bin"; + private const string AndroidAddressablesContentState = "Assets/AddressableAssetsData/Android/addressables_content_state.bin"; + private const string DefaultProductName = "Fishing Travel"; + private const string EnjoyPayProductName = "Fishing Travel: Hook & Explore"; // ==================== Channel Switching ==================== - private static void SwitchChannel(string channel) + public static void SwitchChannel(string channel) { - var channelDir = channel.ToLower(); - var cfgDir = Path.Combine(ExtraCfgRoot, channelDir); + channel = NormalizeChannelName(channel); + var cfgDir = Path.Combine(ExtraCfgRoot, channel.ToLowerInvariant()); if (!Directory.Exists(cfgDir)) { - Debug.LogError($"[ChannelSwitch] Channel config not found: {cfgDir}"); - return; + throw new DirectoryNotFoundException($"[ChannelSwitch] Channel config not found: {cfgDir}"); } Debug.Log($"[ChannelSwitch] Switching to {channel}..."); - currentChannel = channel; - // 1. Sync AAR - var srcAarDir = Path.Combine(cfgDir, "Plugins/Android"); - if (Directory.Exists(srcAarDir)) - { - foreach (var oldAar in Directory.GetFiles(TysdkPlugins, "tuyoosdk_*.aar")) - File.Delete(oldAar); - foreach (var oldJar in Directory.GetFiles(TysdkPlugins, "tuyoosdk_*.jar")) - File.Delete(oldJar); - foreach (var aar in Directory.GetFiles(srcAarDir, "*.aar")) - { - var dest = Path.Combine(TysdkPlugins, Path.GetFileName(aar)); - File.Copy(aar, dest, true); - Debug.Log($"[ChannelSwitch] AAR: {aar} → {dest}"); - } - } + // 1. Sync root Android config files + SyncRootAndroidConfigFiles(cfgDir); - // 2. Clean up previous channel Java files - foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "ChannelHelpers.java")) - File.Delete(oldJava); - foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "ChannelEntry.java")) - File.Delete(oldJava); - foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*SDKHelper.java")) - File.Delete(oldJava); - foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*SDKService.java")) - File.Delete(oldJava); - foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*SDKAdapter.java")) - File.Delete(oldJava); - var oldConfig = Path.Combine(TysdkPlugins, "ConfigManager.java"); - if (File.Exists(oldConfig)) File.Delete(oldConfig); + // 2. Sync channel SDK adapter Java files to tysdk package + SyncChannelAdapterFiles(cfgDir); - // 3. Sync Gradle + Manifest - foreach (var fileName in GradleFiles) - { - var src = Path.Combine(cfgDir, fileName); - if (File.Exists(src)) - { - var dest = Path.Combine(AssetsPlugins, fileName); - File.Copy(src, dest, true); - Debug.Log($"[ChannelSwitch] Config: {src} → {dest}"); - } - } - - // 4. Sync channel Java files to tysdk package - foreach (var javaFile in Directory.GetFiles(cfgDir, "*.java")) - { - var fileName = Path.GetFileName(javaFile); - var dest = Path.Combine(TysdkPlugins, fileName); - File.Copy(javaFile, dest, true); - Debug.Log($"[ChannelSwitch] Java: {javaFile} → {dest}"); - } - - // 5. Sync google-services.json (fallback to GooglePlay default) + // 3. Sync google-services.json var srcGoogleServices = Path.Combine(cfgDir, "Files/google-services.json"); - if (!File.Exists(srcGoogleServices)) - srcGoogleServices = Path.Combine(ExtraCfgRoot, "googleplay/Files/google-services.json"); - var destGoogleServices = Path.Combine(TysdkFiles, "google-services.json"); - File.Copy(srcGoogleServices, destGoogleServices, true); - Debug.Log($"[ChannelSwitch] google-services.json: {srcGoogleServices} → {destGoogleServices}"); + if (File.Exists(srcGoogleServices)) + { + var destDir = Path.Combine(TysdkFiles); + if (!Directory.Exists(destDir)) Directory.CreateDirectory(destDir); + var destGoogleServices = Path.Combine(destDir, "google-services.json"); + File.Copy(srcGoogleServices, destGoogleServices, true); + Debug.Log($"[ChannelSwitch] google-services.json -> {destGoogleServices}"); + } - // 6. Set Bundle Identifier per channel + // 4. Sync channel plugin files (.aar, .jar, etc.) to tysdk package + var pluginsSrcDir = Path.Combine(cfgDir, "Plugins/Android"); + var pluginsDestDir = TysdkPlugins; + if (Directory.Exists(pluginsSrcDir)) + { + foreach (var oldPlugin in Directory.GetFiles(pluginsDestDir, "tuyoosdk_*.aar")) + File.Delete(oldPlugin); + + foreach (var pluginFile in Directory.GetFiles(pluginsSrcDir)) + { + if (pluginFile.EndsWith(".meta")) continue; + var fileName = Path.GetFileName(pluginFile); + var dest = Path.Combine(pluginsDestDir, fileName); + File.Copy(pluginFile, dest, true); + Debug.Log($"[ChannelSwitch] Plugin: {pluginFile} -> {dest}"); + } + } + + // 5. Set Bundle Identifier per channel var bundleId = channel switch { "Flexion" => "com.arkgame.ft.flexion", @@ -105,25 +73,38 @@ public class ChannelBuildTool _ => "com.arkgame.ft" }; PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, bundleId); - Debug.Log($"[CHANNEL-VERIFY] Bundle Identifier → {bundleId}"); + Debug.Log($"[ChannelSwitch] Bundle Identifier -> {bundleId}"); - // 7. Set runtime channel + var productName = channel == "EnjoyPay" ? EnjoyPayProductName : DefaultProductName; + PlayerSettings.productName = productName; + Debug.Log($"[ChannelSwitch] Product Name -> {productName}"); + + // 6. Set runtime channel tysdk.ChannelConfig.SetChannel(channel); + // 7. Set Addressables profile and optional channel content state + SetAddressablesProfile(channel); + SyncAddressablesContentState(channel, cfgDir); + AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); Debug.Log($"[ChannelSwitch] Done. Channel: {channel}"); } - // ==================== Build ==================== + // ==================== Menu ==================== - private static void RestoreDefaultChannel() - { - Debug.Log($"[ChannelBuild] Restore default channel -> {DefaultChannel}"); - SwitchChannel(DefaultChannel); - PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, DefaultAndroidBundleIdentifier); - Debug.Log($"[ChannelBuild] Restore bundle identifier -> {DefaultAndroidBundleIdentifier}"); - AssetDatabase.SaveAssets(); - } + [MenuItem("Tools/Channel/Switch Channel/GooglePlay", false, 10000)] + public static void Switch_GooglePlay() => SwitchChannel("GooglePlay"); + + [MenuItem("Tools/Channel/Switch Channel/Flexion", false, 10001)] + public static void Switch_Flexion() => SwitchChannel("Flexion"); + + [MenuItem("Tools/Channel/Switch Channel/Rustore", false, 10002)] + public static void Switch_Rustore() => SwitchChannel("Rustore"); + + [MenuItem("Tools/Channel/Switch Channel/EnjoyPay", false, 10003)] + public static void Switch_EnjoyPay() => SwitchChannel("EnjoyPay"); + + // ==================== Build ==================== private static void BuildAndroidForChannel(string channel, bool debug) { @@ -131,8 +112,8 @@ public class ChannelBuildTool { SwitchChannel(channel); - string fileName = debug ? $"tysdkTest_{channel}_debug.apk" : $"tysdkTest_{channel}.apk"; - string outPath = $"../Bin/{fileName}"; + var fileName = debug ? $"tysdkTest_{channel}_debug.apk" : $"tysdkTest_{channel}.apk"; + var outPath = $"../Bin/{fileName}"; var buildOptions = debug ? BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.WaitForPlayerConnection : BuildOptions.None; @@ -145,7 +126,7 @@ public class ChannelBuildTool options = buildOptions, }; - Debug.Log($"[ChannelBuild] Building {channel} → {outPath}"); + Debug.Log($"[ChannelBuild] Building {channel} -> {outPath}"); var buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions); if (buildReport?.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded) @@ -160,49 +141,157 @@ public class ChannelBuildTool } finally { - RestoreDefaultChannel(); + SwitchChannel("GooglePlay"); + AssetDatabase.SaveAssets(); } } - private static string currentChannel = ""; - - // ==================== Menu: Switch Channel ==================== - - [MenuItem("Tools/Switch Channel/GooglePlay")] - public static void Switch_GooglePlay() => SwitchChannel("GooglePlay"); - - [MenuItem("Tools/Switch Channel/Rustore")] - public static void Switch_Rustore() => SwitchChannel("Rustore"); - - [MenuItem("Tools/Switch Channel/Flexion")] - public static void Switch_Flexion() => SwitchChannel("Flexion"); - - [MenuItem("Tools/Switch Channel/EnjoyPay")] - public static void Switch_EnjoyPay() => SwitchChannel("EnjoyPay"); - - // ==================== Menu: Build ==================== - - [MenuItem("Tools/Build Android (Channel)/GooglePlay")] + [MenuItem("Tools/Channel/Build Android (Channel)/GooglePlay", false, 10100)] public static void Build_GooglePlay() => BuildAndroidForChannel("GooglePlay", false); - [MenuItem("Tools/Build Android (Channel)/GooglePlay Debug")] + [MenuItem("Tools/Channel/Build Android (Channel)/GooglePlay Debug", false, 10101)] public static void Build_GooglePlay_Debug() => BuildAndroidForChannel("GooglePlay", true); - [MenuItem("Tools/Build Android (Channel)/Rustore")] + [MenuItem("Tools/Channel/Build Android (Channel)/Rustore", false, 10102)] public static void Build_Rustore() => BuildAndroidForChannel("Rustore", false); - [MenuItem("Tools/Build Android (Channel)/Rustore Debug")] + [MenuItem("Tools/Channel/Build Android (Channel)/Rustore Debug", false, 10103)] public static void Build_Rustore_Debug() => BuildAndroidForChannel("Rustore", true); - [MenuItem("Tools/Build Android (Channel)/Flexion")] + [MenuItem("Tools/Channel/Build Android (Channel)/Flexion", false, 10104)] public static void Build_Flexion() => BuildAndroidForChannel("Flexion", false); - [MenuItem("Tools/Build Android (Channel)/Flexion Debug")] + [MenuItem("Tools/Channel/Build Android (Channel)/Flexion Debug", false, 10105)] public static void Build_Flexion_Debug() => BuildAndroidForChannel("Flexion", true); - [MenuItem("Tools/Build Android (Channel)/EnjoyPay")] + [MenuItem("Tools/Channel/Build Android (Channel)/EnjoyPay", false, 10106)] public static void Build_EnjoyPay() => BuildAndroidForChannel("EnjoyPay", false); - [MenuItem("Tools/Build Android (Channel)/EnjoyPay Debug")] + [MenuItem("Tools/Channel/Build Android (Channel)/EnjoyPay Debug", false, 10107)] public static void Build_EnjoyPay_Debug() => BuildAndroidForChannel("EnjoyPay", true); + + private static string NormalizeChannelName(string channel) + { + if (string.IsNullOrEmpty(channel)) + return channel; + + switch (channel.Trim().ToLowerInvariant()) + { + case "googleplay": + return "GooglePlay"; + case "flexion": + return "Flexion"; + case "enjoypay": + return "EnjoyPay"; + case "rustore": + return "Rustore"; + default: + return channel.Trim(); + } + } + + private static void SyncRootAndroidConfigFiles(string cfgDir) + { + CopyRootConfigFiles(cfgDir, "*.gradle"); + CopyRootConfigFiles(cfgDir, "*.properties"); + CopyRootConfigFile(cfgDir, "AndroidManifest.xml"); + } + + private static void SyncChannelAdapterFiles(string cfgDir) + { + // ChannelAdapterManager, ChannelAdapterBase, ConfigManager and SDKManager + // are fixed platform files and are not copied per channel. + foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*Adapter.java")) + { + File.Delete(oldJava); + } + + foreach (var javaFile in Directory.GetFiles(cfgDir, "*Adapter.java")) + { + var fileName = Path.GetFileName(javaFile); + var dest = Path.Combine(TysdkPlugins, fileName); + File.Copy(javaFile, dest, true); + Debug.Log($"[ChannelSwitch] Adapter: {javaFile} -> {dest}"); + } + } + + private static void CopyRootConfigFiles(string cfgDir, string searchPattern) + { + foreach (var src in Directory.GetFiles(cfgDir, searchPattern, SearchOption.TopDirectoryOnly)) + { + CopyRootConfigFile(src); + } + } + + private static void CopyRootConfigFile(string cfgDir, string fileName) + { + var src = Path.Combine(cfgDir, fileName); + if (File.Exists(src)) + { + CopyRootConfigFile(src); + } + } + + private static void CopyRootConfigFile(string src) + { + var fileName = Path.GetFileName(src); + var dest = Path.Combine(AssetsPlugins, fileName); + File.Copy(src, dest, true); + Debug.Log($"[ChannelSwitch] Config: {src} -> {dest}"); + } + + private static void SetAddressablesProfile(string channel) + { + var settings = AddressableAssetSettingsDefaultObject.Settings; + if (settings == null) + { + Debug.LogWarning("[ChannelSwitch] Addressables settings not found."); + return; + } + + var profileName = UsesRustoreAddressablesProfile(channel) ? "arksgameru" : "arksgamecos"; + var profileId = settings.profileSettings.GetProfileId(profileName); + if (string.IsNullOrEmpty(profileId)) + { + Debug.LogError($"[ChannelSwitch] Addressables profile not found: {profileName}"); + return; + } + + settings.activeProfileId = profileId; + var remoteLoadPath = settings.RemoteCatalogLoadPath.GetValue(settings); + var remoteBuildPath = settings.RemoteCatalogBuildPath.GetValue(settings); + Debug.Log($"[ChannelSwitch] Addressables profile -> {profileName}, profileId={profileId}, Remote.LoadPath={remoteLoadPath}, Remote.BuildPath={remoteBuildPath}"); + } + + private static void SyncAddressablesContentState(string channel, string cfgDir) + { + var src = Path.Combine(cfgDir, AddressablesContentState); + if (!File.Exists(src) && UsesRustoreAddressablesContentState(channel)) + { + Debug.Log($"[ChannelSwitch] Channel content state not found, try legacy Rustore content state path. Channel={channel}, checked={src}"); + src = Path.Combine("../ExtraPluginCfgs", AddressablesContentState); + } + + if (!File.Exists(src)) + { + Debug.Log($"[ChannelSwitch] Addressables content state not copied. Channel={channel}, checked={src}"); + return; + } + + var destDir = Path.GetDirectoryName(AndroidAddressablesContentState); + if (!Directory.Exists(destDir)) Directory.CreateDirectory(destDir); + + File.Copy(src, AndroidAddressablesContentState, true); + Debug.Log($"[ChannelSwitch] Addressables content state: {src} -> {AndroidAddressablesContentState}"); + } + + private static bool UsesRustoreAddressablesContentState(string channel) + { + return channel == "Rustore" || channel == "EnjoyPay"; + } + + private static bool UsesRustoreAddressablesProfile(string channel) + { + return channel == "Rustore" || channel == "EnjoyPay"; + } } diff --git a/sdk-intergration/Assets/Plugins/Android/AndroidManifest.xml b/sdk-intergration/Assets/Plugins/Android/AndroidManifest.xml index ebd9b2e..a1fa4fc 100644 --- a/sdk-intergration/Assets/Plugins/Android/AndroidManifest.xml +++ b/sdk-intergration/Assets/Plugins/Android/AndroidManifest.xml @@ -36,7 +36,7 @@ - + diff --git a/sdk-intergration/Assets/Plugins/Android/launcherTemplate.gradle b/sdk-intergration/Assets/Plugins/Android/launcherTemplate.gradle index 31efa26..6231ad1 100644 --- a/sdk-intergration/Assets/Plugins/Android/launcherTemplate.gradle +++ b/sdk-intergration/Assets/Plugins/Android/launcherTemplate.gradle @@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services' dependencies { implementation project(':unityLibrary') - implementation(platform("com.google.firebase:firebase-bom:33.6.0")) - implementation("com.google.firebase:firebase-analytics") + implementation platform('com.google.firebase:firebase-bom:34.6.0') + implementation 'com.google.firebase:firebase-analytics' } android { @@ -17,7 +17,6 @@ android { compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 - } defaultConfig { diff --git a/sdk-intergration/Assets/Plugins/Android/mainTemplate.gradle b/sdk-intergration/Assets/Plugins/Android/mainTemplate.gradle index 814c5c6..28d7325 100644 --- a/sdk-intergration/Assets/Plugins/Android/mainTemplate.gradle +++ b/sdk-intergration/Assets/Plugins/Android/mainTemplate.gradle @@ -60,18 +60,24 @@ dependencies { implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1" // Android Resolver Dependencies Start + implementation 'androidx.recyclerview:recyclerview:1.2.1' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:9 implementation 'com.android.installreferrer:installreferrer:2.1' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:7 + implementation 'com.applovin.mediation:bytedance-adapter:8.1.0.3.0' // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:facebook-adapter:[6.18.0.1]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8 implementation 'com.applovin.mediation:fyber-adapter:8.4.2.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:google-adapter:[23.6.0.1]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5 implementation 'com.applovin.mediation:ironsource-adapter:8.6.1.0.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:mintegral-adapter:17.1.61.0' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + implementation 'com.applovin.mediation:moloco-adapter:4.9.0.0' // Assets/MaxSdk/Mediation/Moloco/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:unityads-adapter:4.12.3.0' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4 implementation 'com.applovin.mediation:vungle-adapter:7.4.2.2' // Assets/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml:4 + implementation 'com.applovin.mediation:yandex-adapter:8.1.0.0' // Assets/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml:4 implementation 'com.applovin:applovin-sdk:13.5.1' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4 implementation 'com.appsflyer:af-android-sdk:6.17.3' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:5 implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8 implementation 'com.appsflyer:unity-wrapper:6.17.7' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:6 implementation 'com.google.android.ump:user-messaging-platform:2.1.0' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:5 + implementation 'com.tapjoy:tapjoy-android-unitybridge:14.5.0' // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:10 // Android Resolver Dependencies End **DEPS**} diff --git a/sdk-intergration/Assets/Plugins/Android/settingsTemplate.gradle b/sdk-intergration/Assets/Plugins/Android/settingsTemplate.gradle index 73133c1..fa73a11 100644 --- a/sdk-intergration/Assets/Plugins/Android/settingsTemplate.gradle +++ b/sdk-intergration/Assets/Plugins/Android/settingsTemplate.gradle @@ -18,9 +18,18 @@ dependencyResolutionManagement { mavenCentral() // Android Resolver Repos Start def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") + maven { + url "https://sdk.tapjoy.com/" // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:9 + } + maven { + url "https://artifact.bytedance.com/repository/pangle" // Assets/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml:8 + } maven { url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 } + maven { + url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:8 + } mavenLocal() // Android Resolver Repos End flatDir { diff --git a/sdk-intergration/Assets/Scripts/SDKTest.cs b/sdk-intergration/Assets/Scripts/SDKTest.cs index 4af9430..30ed239 100644 --- a/sdk-intergration/Assets/Scripts/SDKTest.cs +++ b/sdk-intergration/Assets/Scripts/SDKTest.cs @@ -73,8 +73,8 @@ public class SDKTest : MonoBehaviour IConfig config = new Config(serializer); GContext.container.RegisterInstance(config); - Debug.Log("SDKTest Start"); - UpdateChannelTitle(); + Debug.Log("SDKTest Start"); + ClearChannelTitle(); //=============================================================================== //====================== Test Server =========================== // UnityBridgeFunc.UnityResetServerUrl("https://128-hwsfsdk-sdk-test01.qijihdhk.com"); @@ -82,12 +82,13 @@ public class SDKTest : MonoBehaviour //====================== Test Server =========================== //=============================================================================== // - _InitBtn.onClick.AddListener(Init); - TYSdkFacade.OnInitComplete += (success, msg) => - { - _messageTxt.text = success ? $"Init OK: {msg}" : $"Init Failed: {msg}"; - }; - _loginGuestBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGuest)); + _InitBtn.onClick.AddListener(Init); + TYSdkFacade.OnInitComplete += (success, msg) => + { + _messageTxt.text = success ? $"Init OK: {msg}" : $"Init Failed: {msg}"; + UpdateChannelTitle(); + }; + _loginGuestBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGuest)); _loginGoogleBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGoogle)); _loginFbBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwFacebook)); _loginVkBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwVkid)); @@ -111,11 +112,11 @@ public class SDKTest : MonoBehaviour _signoutBtn.onClick.AddListener(OnSignoutBtn); _fbShareLinkBtn.onClick.AddListener(OnFBShareLinkBtn); _mfbShareLinkBtn.onClick.AddListener(OnMessengerShareLinkBtn); - _reviewBtn.onClick.AddListener(OnReview); - Debug.Log("SDKTest Started"); - } - - void Init() + _reviewBtn.onClick.AddListener(OnReview); + Debug.Log("SDKTest Started"); + } + + void Init() { _messageTxt.text = "Initializing..."; TYSdkFacade.Instance.Init(); @@ -140,19 +141,21 @@ public class SDKTest : MonoBehaviour GContext.container.Resolve().Set("PAY_VERIFY_URL", "https://192.168.9.91:7036/api/FlexionCallback"); } - private void UpdateChannelTitle() - { -#if UNITY_ANDROID - using (var cls = new AndroidJavaClass("com.unity3d.player.ChannelEntry")) - { - string channel = cls.GetStatic("CHANNEL"); - Debug.Log($"[SDKTest] Channel from Java: {channel}"); - _titleText.text = $" {channel}"; - } -#endif - } - - int retryAttempt; + private void UpdateChannelTitle() + { +#if UNITY_ANDROID + string channel = ChannelConfig.Channel; + Debug.Log($"[SDKTest] Channel from ChannelConfig: {channel}"); + _titleText.text = $" {channel}"; +#endif + } + + private void ClearChannelTitle() + { + _titleText.text = string.Empty; + } + + int retryAttempt; public void InitializeRewardedAds() { @@ -211,10 +214,11 @@ public class SDKTest : MonoBehaviour { _messageTxt.text = ""; - if (ChannelConfig.Channel.Equals("Flexion")) - { - sku = new SKUDetail - { + var channel = ChannelConfig.Channel; + if (string.Equals(channel, "Flexion")) + { + sku = new SKUDetail + { productId = "com.arkgame.ft.pack0199", ourProductId = "com.arkgame.ft.pack0199", price = "1.99", @@ -223,10 +227,10 @@ public class SDKTest : MonoBehaviour type = "inapp" }; } - else if (ChannelConfig.Channel.Equals("EnjoyPay")) - { - sku = new SKUDetail - { + else if (string.Equals(channel, "EnjoyPay")) + { + sku = new SKUDetail + { productId = "comarkgameftpack0199", ourProductId = "comarkgameftpack0199", price = "1.99", @@ -235,13 +239,19 @@ public class SDKTest : MonoBehaviour type = "inapp" }; } - if (sku == null){ - _messageTxt.text = "no product"; - return; - } - -#if !UNITY_EDITOR && UNITY_IOS - sku.productId = "comarkgameftpack0199"; + if (sku == null){ + _messageTxt.text = "no product"; + return; + } + + if (!TYSdkFacade.IsLoggedIn) + { + _messageTxt.text = "not logged in"; + return; + } + +#if !UNITY_EDITOR && UNITY_IOS + sku.productId = "comarkgameftpack0199"; sku.title = "商店-体力直充1.99" ; sku.price = "1.99"; #endif diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterBase.java b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterBase.java new file mode 100644 index 0000000..f68dc18 --- /dev/null +++ b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterBase.java @@ -0,0 +1,83 @@ +package com.unity3d.player; + +import android.app.Activity; +import android.util.Log; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; + +public class ChannelAdapterBase implements SDKManager.IChannelSDKAdapter { + private static final String TAG = "ChannelAdapterBase"; + protected Activity activity; + protected String channel = "GooglePlay"; + + final ChannelAdapterBase setup(Activity activity, String channel) { + this.activity = activity; + this.channel = channel; + return this; + } + + @Override + public final SDKManager.IChannelSDKAdapter loadConfig() { + applyConfig(); + return this; + } + + protected void applyConfig() { + applyConfigObject(createConfig()); + } + + @Override + public String getChannel() { + return channel; + } + + @Override + public void init() { + SDKManager.initDefault(activity); + } + + protected void applyConfigObject(Object source) { + if (source == null) { + return; + } + + for (Field sourceField : source.getClass().getDeclaredFields()) { + sourceField.setAccessible(true); + try { + Object value = sourceField.get(source); + if (value == null) { + continue; + } + + Field targetField = ConfigManager.class.getDeclaredField(sourceField.getName()); + targetField.setAccessible(true); + targetField.set(null, value); + Log.i(TAG, "apply config: " + sourceField.getName() + "=" + value); + } catch (NoSuchFieldException ignored) { + try { + Object value = sourceField.get(source); + Log.w(TAG, "ignore extra config: " + sourceField.getName() + "=" + value); + } catch (Exception e) { + Log.w(TAG, "ignore extra config: " + sourceField.getName()); + } + } catch (Exception e) { + Log.e(TAG, "apply config failed: " + sourceField.getName(), e); + } + } + } + + private Object createConfig() { + try { + Class configClass = Class.forName(this.getClass().getName() + "$Config"); + Constructor constructor = configClass.getDeclaredConstructor(); + constructor.setAccessible(true); + return constructor.newInstance(); + } catch (ClassNotFoundException ignored) { + return null; + } catch (Exception e) { + Log.e(TAG, "create config failed: " + this.getClass().getName(), e); + return null; + } + } +} diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterBase.java.meta b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterBase.java.meta new file mode 100644 index 0000000..1a1db89 --- /dev/null +++ b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterBase.java.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 045e7597d96519641ae97bf542955d42 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 1 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Android: Android + second: + enabled: 1 + settings: {} + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterManager.java b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterManager.java new file mode 100644 index 0000000..8306893 --- /dev/null +++ b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterManager.java @@ -0,0 +1,86 @@ +package com.unity3d.player; + +import android.app.Activity; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; + +import java.lang.reflect.Constructor; + +public class ChannelAdapterManager { + private static final String TAG = "ChannelAdapterManager"; + private static final String DEFAULT_CHANNEL = "GooglePlay"; + private static final String META_CHANNEL = "com.arkgame.ft.channel"; + + private static SDKManager.IChannelSDKAdapter adapter; + + public static SDKManager.IChannelSDKAdapter createSdkAdapter(Activity activity) { + String channel = readChannel(activity); + adapter = createAdapter(channel); + if (adapter instanceof ChannelAdapterBase) { + ((ChannelAdapterBase) adapter).setup(activity, channel); + } + return adapter; + } + + public static String normalizeSkuList(String msg) { + if (adapter == null) { + return msg; + } + return adapter.normalizeSkuList(msg); + } + + private static SDKManager.IChannelSDKAdapter createAdapter(String channel) { + if (TextUtils.isEmpty(channel) || DEFAULT_CHANNEL.equals(channel)) { + return new ChannelAdapterBase(); + } + + SDKManager.IChannelSDKAdapter adapter = tryCreateAdapter( + "com.unity3d.player." + channel + "Adapter"); + if (adapter != null) { + return adapter; + } + + return new ChannelAdapterBase(); + } + + private static SDKManager.IChannelSDKAdapter tryCreateAdapter(String adapterClassName) { + try { + Class adapterClass = Class.forName(adapterClassName); + Constructor constructor = adapterClass.getDeclaredConstructor(); + constructor.setAccessible(true); + Object instance = constructor.newInstance(); + if (instance instanceof SDKManager.IChannelSDKAdapter) { + return (SDKManager.IChannelSDKAdapter) instance; + } + Log.e(TAG, "adapter does not implement IChannelSDKAdapter: " + adapterClassName); + } catch (Exception e) { + Log.e(TAG, "create adapter failed: " + adapterClassName, e); + } + + return null; + } + + private static String readChannel(Activity activity) { + if (activity == null) { + return DEFAULT_CHANNEL; + } + + try { + ApplicationInfo appInfo = activity.getPackageManager().getApplicationInfo( + activity.getPackageName(), + PackageManager.GET_META_DATA); + Bundle metaData = appInfo.metaData; + if (metaData == null) { + return DEFAULT_CHANNEL; + } + String value = metaData.getString(META_CHANNEL); + return TextUtils.isEmpty(value) ? DEFAULT_CHANNEL : value; + } catch (Exception e) { + Log.e(TAG, "read channel failed", e); + return DEFAULT_CHANNEL; + } + } +} diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelEntry.java.meta b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterManager.java.meta similarity index 100% rename from sdk-intergration/Packages/tysdk/Plugins/Android/ChannelEntry.java.meta rename to sdk-intergration/Packages/tysdk/Plugins/Android/ChannelAdapterManager.java.meta diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelEntry.java b/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelEntry.java deleted file mode 100644 index 3c61fc0..0000000 --- a/sdk-intergration/Packages/tysdk/Plugins/Android/ChannelEntry.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.unity3d.player; - -public class ChannelEntry { - public static final String CHANNEL = "GooglePlay"; - - public static SDKManager.IChannelSDKAdapter createSDKAdapter() { - return null; - } - - public static String normalizeSkuList(String msg) { - return msg; - } -} diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/SDKManager.java b/sdk-intergration/Packages/tysdk/Plugins/Android/SDKManager.java index e278231..0fdea2f 100644 --- a/sdk-intergration/Packages/tysdk/Plugins/Android/SDKManager.java +++ b/sdk-intergration/Packages/tysdk/Plugins/Android/SDKManager.java @@ -43,7 +43,7 @@ import java.util.HashMap; import java.util.Map; /** - * Unified SDKManager for all channels (GooglePlay / Flexion / RuStore / EnjoyPay). + * Unified SDKManager for all channels (GooglePlay / Flexion / RuStore). * C# passes the channel string via InitSDK(activity, channel); Java dispatches * internally via switch. All login/link/GA/share logic is shared. * Channel-specific behaviour is limited to: Init, Pay, thirdExtend, Review. @@ -59,7 +59,17 @@ public class SDKManager { // Channel SDK adapter public interface IChannelSDKAdapter { - void init(Activity activity); + default IChannelSDKAdapter loadConfig() { + return this; + } + + String getChannel(); + + void init(); + + default String normalizeSkuList(String msg) { + return msg; + } } public interface IPaymentAdapter { @@ -82,9 +92,19 @@ public class SDKManager { void refreshBilling(); } + public interface IChannelInfoAdapter { + String getStorePageUri(Activity activity); + } + + public interface IReviewAdapter { + void review(Activity activity); + } + private static IChannelSDKAdapter sdkAdapter; public static void queryProductsByIDs(String productIds) { + Log.i(TAG, "[FLEXION-SKU-PRICE] queryProductsByIDs productIds=" + productIds + + " adapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getName() : "null")); if (sdkAdapter instanceof IProductQueryAdapter) { ((IProductQueryAdapter) sdkAdapter).queryProducts(productIds); return; @@ -125,7 +145,17 @@ public class SDKManager { public static void CancelBillingFlow() { Log.w(TAG, "CancelBillingFlow"); -// FlexionSDKAdapter.cancelPurchase(); + } + + public static String GetStorePageUri() { + if (sdkAdapter instanceof IChannelInfoAdapter) { + try { + return ((IChannelInfoAdapter) sdkAdapter).getStorePageUri(UnityPlayer.currentActivity); + } catch (Throwable e) { + Log.w(TAG, "GetStorePageUri exception: " + e.getMessage()); + } + } + return ""; } public static boolean IsGooglePlayServicesAvailable() { @@ -147,29 +177,26 @@ public class SDKManager { } // ------------------------------------------------------------------------- - // Init — with channel helper support + // Init with channel helper support // ------------------------------------------------------------------------- public static void InitSDK(Activity activity, String ch) { - channel = ChannelEntry.CHANNEL; - sdkAdapter = ChannelEntry.createSDKAdapter(); + sdkAdapter = ChannelAdapterManager.createSdkAdapter(activity); + sdkAdapter.loadConfig(); - // Log.i(TAG, "[CHANNEL-VERIFY] Java InitSDK channel=" + channel - // + " fromCSharp=" + ch - // + " adapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getSimpleName() : "default")); + channel = sdkAdapter.getChannel(); + + Log.i(TAG, "[CHANNEL-VERIFY] Java InitSDK channel=" + channel + + " fromCSharp=" + ch + + " adapter=" + sdkAdapter.getClass().getName()); - // Sync channel to C# ChannelConfig UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME, "SetChannelFromNative", channel); - if (sdkAdapter != null) { - sdkAdapter.init(activity); - } else { - initDefault(activity); - } + sdkAdapter.init(); } - private static void initDefault(Activity activity) { + static void initDefault(Activity activity) { activity.runOnUiThread(() -> { SDKAPI.getIns().lightModeEnable(); try { @@ -258,6 +285,7 @@ public class SDKManager { public static void UnityResetServerUrl(String url) { SDKLog.i("UnityResetServerUrl : " + url); + SetDNSIPsEnable(false); SDKAPI.getIns().updateServer(url); } @@ -446,7 +474,7 @@ public class SDKManager { } // ------------------------------------------------------------------------- - // Payment — channel dispatch + // Payment channel dispatch // ------------------------------------------------------------------------- public static void UnityKnow(String productId, String productName, String productCount, @@ -461,7 +489,9 @@ public class SDKManager { public static void UnityKnowNew(String productId, String productPrice, String productName, String productCount, String prodorderId, String appInfo, String ptype) { - SDKLog.i("[SDKManager.UnityKnowNew] channel=" + channel + String currentChannel = getCurrentChannelForLog(); + SDKLog.i("[SDKManager.UnityKnowNew] channel=" + currentChannel + + ", adapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getName() : "null") + ", ptype=" + ptype + ", productId=" + productId + ", productPrice=" + productPrice @@ -489,8 +519,19 @@ public class SDKManager { SDKAPI.getIns().payNew(payData, payType, mPay); } + private static String getCurrentChannelForLog() { + try { + if (sdkAdapter != null && !TextUtils.isEmpty(sdkAdapter.getChannel())) { + return sdkAdapter.getChannel(); + } + } catch (Throwable ignored) { + } + + return TextUtils.isEmpty(channel) ? "GooglePlay" : channel; + } + // ------------------------------------------------------------------------- - // thirdExtend — with channel helper support + // thirdExtend with channel helper support // ------------------------------------------------------------------------- public static void thirdExtend() { @@ -518,7 +559,7 @@ public class SDKManager { JSONObject result = new JSONObject(); result.put("code", code); if (code == SDKCallBack.Extend.EXTEND_CODE_SUCCESS) { - result.put("respObj", ChannelEntry.normalizeSkuList(msg)); + result.put("respObj", ChannelAdapterManager.normalizeSkuList(msg)); } else { Log.e(TAG, "thirdExtend failed: " + msg); result.put("thirdExtend_errStr", msg); @@ -594,12 +635,19 @@ public class SDKManager { } // ------------------------------------------------------------------------- - // Review — channel dispatch + // Review channel dispatch // ------------------------------------------------------------------------- public static void Review() { + Log.w(TAG, "[ReviewDebug] Review called channel=" + channel); if ("Rustore".equals(channel)) { RuStoreReview(); + } else if ("Flexion".equals(channel)) { + if (sdkAdapter instanceof IReviewAdapter) { + ((IReviewAdapter) sdkAdapter).review(UnityPlayer.currentActivity); + } else { + Log.w(TAG, "Review skipped: no Flexion review adapter"); + } } else { GooglePlayReview(); } @@ -693,4 +741,34 @@ public class SDKManager { Log.e(TAG, "Messenger ShareDialog can not show"); } } + + public static void SetDNSIPsEnable(boolean enable) { + if ("Flexion".equals(channel)) { + return; + } + + if(enable) { + SetDNSIPs(true, new String[]{ + "34.111.1.231", + "2600:1901:0:c31b::" + }); + } + else{ + SetDNSIPs(false, new String[0]); + } + } + + private static void SetDNSIPs(boolean enable, String[] ips) { + InvokeSDKAPIStaticMethod("enableDoh", new Class[]{boolean.class}, new Object[]{enable}); + InvokeSDKAPIStaticMethod("setHttpDnsIps", new Class[]{String[].class}, new Object[]{ips}); + } + + private static void InvokeSDKAPIStaticMethod(String methodName, Class[] parameterTypes, Object[] args) { + try { + SDKAPI.class.getMethod(methodName, parameterTypes).invoke(null, args); + } catch (NoSuchMethodException ignored) { + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/sdk-intergration/Packages/tysdk/Plugins/Android/TYApp.java b/sdk-intergration/Packages/tysdk/Plugins/Android/TYApp.java index 979c7e7..f459dad 100644 --- a/sdk-intergration/Packages/tysdk/Plugins/Android/TYApp.java +++ b/sdk-intergration/Packages/tysdk/Plugins/Android/TYApp.java @@ -12,6 +12,7 @@ public class TYApp extends Application { public void onCreate() { super.onCreate(); SDKAPI.getIns().onApplicationCreate(this); + SDKManager.SetDNSIPsEnable(true); } @Override @@ -19,4 +20,5 @@ public class TYApp extends Application { super.attachBaseContext(base); SDKAPI.getIns().onAttachBaseContext(base, this); } + }