feat(channel): 同步渠道构建配置

This commit is contained in:
2026-07-08 17:38:36 +08:00
parent 3da65b8cbd
commit 833f68f601
39 changed files with 870 additions and 359 deletions

View File

@@ -6,7 +6,9 @@
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application android:extractNativeLibs="true" android:name="com.unity3d.player.TYApp" android:usesCleartextTraffic="true"> <application android:extractNativeLibs="true" android:name="com.unity3d.player.TYApp"
tools:replace="android:usesCleartextTraffic"
android:usesCleartextTraffic="true">
<activity android:name="com.unity3d.player.TYUnityActivity" <activity android:name="com.unity3d.player.TYUnityActivity"
android:theme="@style/UnityThemeSelector"> android:theme="@style/UnityThemeSelector">
<intent-filter> <intent-filter>
@@ -35,7 +37,12 @@
<meta-data android:name="google_analytics_default_allow_ad_user_data" android:value="true" /> <meta-data android:name="google_analytics_default_allow_ad_user_data" android:value="true" />
<meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="true" /> <meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="true" />
</activity> </activity>
<meta-data android:name="CHANNEL" android:value="EnjoyPay" /> <meta-data android:name="com.arkgame.ft.channel" android:value="EnjoyPay" />
<meta-data android:name="com.sensorsdata.analytics.android.MainProcessName"
android:value="${applicationId}"
tools:replace="android:value" />
</application> </application>
<queries> <queries>
<provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <provider android:authorities="com.facebook.katana.provider.PlatformProvider" />

View File

@@ -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";
}
}

View File

@@ -1,29 +1,39 @@
{ {
"project_info": { "project_info": {
"project_number": "404468630883", "project_number": "550846874481",
"project_id": "fishing-travel-ep-1ab1e", "project_id": "fishing-travel-ep",
"storage_bucket": "fishing-travel-ep-1ab1e.firebasestorage.app" "storage_bucket": "fishing-travel-ep.firebasestorage.app"
}, },
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:404468630883:android:de3cb115158a5e4cdfff56", "mobilesdk_app_id": "1:550846874481:android:800f3c713738b6b51d2cd0",
"android_client_info": { "android_client_info": {
"package_name": "com.arkgame.ft.ep" "package_name": "com.arkgame.ft.ep"
} }
}, },
"oauth_client": [], "oauth_client": [
{
"client_id": "550846874481-8thf5tv2gm5n7b7uui3kts0kajuddhn7.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyAL8YVO4U6A9WRiQ581Et0o-BmtMf3k7Hg" "current_key": "AIzaSyDw8YISM6R6vtHC4IfJtNBFijrKqgxlfcw"
} }
], ],
"services": { "services": {
"appinvite_service": { "appinvite_service": {
"other_platform_oauth_client": [] "other_platform_oauth_client": [
{
"client_id": "550846874481-8thf5tv2gm5n7b7uui3kts0kajuddhn7.apps.googleusercontent.com",
"client_type": 3
}
]
} }
} }
} }
], ],
"configuration_version": "1" "configuration_version": "1"
} }

View File

@@ -3,12 +3,12 @@ apply plugin: 'com.google.gms.google-services'
dependencies { dependencies {
implementation project(':unityLibrary') implementation project(':unityLibrary')
implementation(platform("com.google.firebase:firebase-bom:33.6.0")) implementation platform('com.google.firebase:firebase-bom:34.6.0')
implementation("com.google.firebase:firebase-analytics") implementation 'com.google.firebase:firebase-analytics'
} }
android { android {
namespace "**NAMESPACE**" namespace "**NAMESPACE**"
ndkPath "**NDKPATH**" ndkPath "**NDKPATH**"
compileSdkVersion **APIVERSION** compileSdkVersion **APIVERSION**

View File

@@ -21,7 +21,7 @@ dependencies {
api "com.android.support:support-v4:28.0.0" api "com.android.support:support-v4:28.0.0"
api "com.android.support:appcompat-v7:28.0.0" api "com.android.support:appcompat-v7:28.0.0"
api "com.google.code.gson:gson:2.8.6" api "com.google.code.gson:gson:2.8.6"
api "com.squareup.okio:okio:1.15.0" api "com.squareup.okio:okio:1.15.0"
api "com.squareup.okhttp3:okhttp:3.12.13" api "com.squareup.okhttp3:okhttp:3.12.13"
@@ -31,13 +31,13 @@ dependencies {
api "io.reactivex:rxandroid:1.2.1" api "io.reactivex:rxandroid:1.2.1"
api "io.reactivex:rxjava:1.1.9" 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 'com.google.android.play:review:2.0.1'
implementation 'net.aihelp:android-aihelp-aar:5.3.+' implementation 'net.aihelp:android-aihelp-aar:5.3.+'
implementation 'com.google.android.gms:play-services-auth:20.2.0' implementation 'com.google.android.gms:play-services-auth:20.2.0'
implementation('com.android.billingclient:billing:7.0.0') implementation('com.android.billingclient:billing:7.0.0')
implementation 'com.google.android.gms:play-services-basement:18.2.0' implementation 'com.google.android.gms:play-services-basement:18.2.0'
implementation 'androidx.fragment:fragment:1.3.6' implementation 'androidx.fragment:fragment:1.3.6'
implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.41" 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 "androidx.credentials:credentials-play-services-auth:1.3.0"
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1" 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 // 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.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: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: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: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: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: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: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.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: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: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.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 // Android Resolver Dependencies End
**DEPS**} **DEPS**}
@@ -85,6 +92,7 @@ android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
coreLibraryDesugaringEnabled true
} }
defaultConfig { defaultConfig {

View File

@@ -19,7 +19,17 @@ dependencyResolutionManagement {
// Android Resolver Repos Start // Android Resolver Repos Start
def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
maven { 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() mavenLocal()
// Android Resolver Repos End // Android Resolver Repos End
@@ -27,8 +37,8 @@ dependencyResolutionManagement {
dirs "${project(':unityLibrary').projectDir}/libs" dirs "${project(':unityLibrary').projectDir}/libs"
} }
maven { maven {
url "http://sdkck.tuyoo.com/artifactory/tuyoo-component/" url "http://sdkck.tuyoo.com/artifactory/tuyoo-component/"
allowInsecureProtocol = true allowInsecureProtocol = true
} }
} }

View File

@@ -35,7 +35,7 @@
</activity> </activity>
<!-- 渠道标识ChannelManager 读取此值以识别 Flexion 渠道 --> <!-- 渠道标识ChannelManager 读取此值以识别 Flexion 渠道 -->
<meta-data android:name="CHANNEL" android:value="Flexion" /> <meta-data android:name="com.arkgame.ft.channel" android:value="Flexion" />
<!-- 覆盖 gasdk 与 tuyoosdk 的 MainProcessName 冲突 --> <!-- 覆盖 gasdk 与 tuyoosdk 的 MainProcessName 冲突 -->
<meta-data android:name="com.sensorsdata.analytics.android.MainProcessName" <meta-data android:name="com.sensorsdata.analytics.android.MainProcessName"

View File

@@ -1,20 +0,0 @@
package com.unity3d.player;
public class ChannelEntry {
public static final String CHANNEL = "Flexion";
public static SDKManager.IChannelSDKAdapter createSDKAdapter() {
return new FlexionSDKAdapter();
}
// Flexion provides price in micros and currency code, so no normalization needed
// 支付的变化,可能会修改这里
public static String normalizeSkuList(String msg) {
return msg;
}
//public SDKExtBuilder;
}

View File

@@ -1,29 +0,0 @@
package com.unity3d.player;
public class ConfigManager {
// Common SDK parameters
public static int SDK_APPID = 20587;
public static String SDK_GAMEID = "20587";
public static String SDK_PROJECTID = "20587";
public static String SDK_CLOUDID = "128";
public static String SDK_CLIENTID = "Android_5.00_tyGuest,facebook.googleplay.0-hall20587.flexion.FishingMaster";
public static String SDK_LOGIN_SERVER_URL = "https://128-hwsfsdk-sdk-online01.qijihdhk.com";
// FCM (anti-addiction system)
public static String FCM_NAMESPACE = "128";
public static String FCM_IAM_HOST = "tcp://fcmtcp.tuyoo.com:3563";
public static String FCM_ANTISERVERURL = "https://fcmapi.tuyoo.com";
// Unity Facade callback names
public static final String UNITY_FACADE_NAME = "TYSdkFacade";
public static final String LOGIN_CALLBACK_FUNCTION_NAME = "LoginResult";
public static final String LINKACCOUT_CALLBACK_FUNCTION_NAME = "LinkAccoutResult";
public static final String CHANGELINK_CALLBACK_FUNCTION_NAME = "ChangeLinkAccountResult";
public static final String CHECKLINK_CALLBACK_FUNCTION_NAME = "CheckLinkResult";
public static final String PAY_CALLBACK_FUNCTION_NAME = "PayResult";
public static final String PAY_TYPE_CALLBACK_FUNCTION_NAME = "SKUListResult";
public static final String FCM_NOTICE_FUNCTION_NAME = "FCMCallback";
public static final String FCM_REALNAME_CALLBACK_FUNCTION_NAME = "RealNameCallback";
public static final String INIT_CALLBACK_FUNCTION_NAME = "InitResult";
}

View File

@@ -1,8 +1,11 @@
package com.unity3d.player; package com.unity3d.player;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.flexionmobile.ddpx.listener.ConnectionStateListener; import com.flexionmobile.ddpx.listener.ConnectionStateListener;
@@ -34,13 +37,14 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public class FlexionSDKAdapter implements public class FlexionAdapter extends ChannelAdapterBase implements
SDKManager.IChannelSDKAdapter,
SDKManager.IPaymentAdapter, SDKManager.IPaymentAdapter,
SDKManager.IProductQueryAdapter, SDKManager.IProductQueryAdapter,
SDKManager.IPendingPurchaseAdapter, SDKManager.IPendingPurchaseAdapter,
SDKManager.IBillingLifecycleAdapter { SDKManager.IBillingLifecycleAdapter,
private static final String TAG = "FlexionSDKAdapter"; SDKManager.IChannelInfoAdapter,
SDKManager.IReviewAdapter {
private static final String TAG = "FlexionAdapter";
private static final int FLX_INIT_MAX_ATTEMPTS = 3; private static final int FLX_INIT_MAX_ATTEMPTS = 3;
private static final int QUERY_PURCHASES_SUCCESS_CODE = 5000; private static final int QUERY_PURCHASES_SUCCESS_CODE = 5000;
private static BillingService billingService; private static BillingService billingService;
@@ -64,6 +68,10 @@ public class FlexionSDKAdapter implements
void run(BillingService service); void run(BillingService service);
} }
private static class Config {
public String SDK_CLIENTID = "Android_5.00_tyGuest,facebook.googleplay.0-hall20587.flexion.FishingMaster";
}
private static class PendingBillingOperation { private static class PendingBillingOperation {
final String operation; final String operation;
final BillingReadyOperation onReady; final BillingReadyOperation onReady;
@@ -91,10 +99,10 @@ public class FlexionSDKAdapter implements
}; };
@Override @Override
public void init(Activity activity) { public void init() {
Log.i(TAG, "[FLX-INIT] adapter init flexionInitialized=" + flexionInitialized // Log.i(TAG, "[FLX-INIT] adapter init flexionInitialized=" + flexionInitialized
+ " flexionScreensStarted=" + flexionScreensStarted // + " flexionScreensStarted=" + flexionScreensStarted
+ " flexionScreensShown=" + flexionScreensShown); // + " flexionScreensShown=" + flexionScreensShown);
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
SDKAPI.getIns().lightModeEnable(); SDKAPI.getIns().lightModeEnable();
if (ensureTuYooSdkInitialized(activity)) { if (ensureTuYooSdkInitialized(activity)) {
@@ -110,12 +118,12 @@ public class FlexionSDKAdapter implements
private static boolean ensureTuYooSdkInitialized(Activity activity) { private static boolean ensureTuYooSdkInitialized(Activity activity) {
if (tuyooSdkInitialized) { if (tuyooSdkInitialized) {
Log.i(TAG, "[FLX-INIT] TuYoo SDK already initialized, skip SDKAPI.init"); // Log.i(TAG, "[FLX-INIT] TuYoo SDK already initialized, skip SDKAPI.init");
return true; return true;
} }
try { try {
Log.i(TAG, "[FLX-INIT] TuYoo SDK init start"); // Log.i(TAG, "[FLX-INIT] TuYoo SDK init start");
SDKAPI.getIns().init(new InitParam.Builder() SDKAPI.getIns().init(new InitParam.Builder()
.withActivity(activity) .withActivity(activity)
.withAppId(ConfigManager.SDK_APPID) .withAppId(ConfigManager.SDK_APPID)
@@ -125,7 +133,7 @@ public class FlexionSDKAdapter implements
SDKAPI.getIns().onActivityStart(activity); SDKAPI.getIns().onActivityStart(activity);
SDKAPI.getIns().onActivityResume(activity); SDKAPI.getIns().onActivityResume(activity);
tuyooSdkInitialized = true; tuyooSdkInitialized = true;
Log.i(TAG, "[FLX-INIT] TuYoo SDK init success"); // Log.i(TAG, "[FLX-INIT] TuYoo SDK init success");
return true; return true;
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "TuYoo SDK init failed, skip FLX init: " + e); Log.e(TAG, "TuYoo SDK init failed, skip FLX init: " + e);
@@ -142,12 +150,12 @@ public class FlexionSDKAdapter implements
return; return;
} }
Log.i(TAG, "[FLX-INIT] FLX.init start attempt=" + attempt + "/" + FLX_INIT_MAX_ATTEMPTS); // Log.i(TAG, "[FLX-INIT] FLX.init start attempt=" + attempt + "/" + FLX_INIT_MAX_ATTEMPTS);
try { try {
FLX.init(activity, (initCode, initMsg) -> { FLX.init(activity, (initCode, initMsg) -> {
Log.i(TAG, "[FLX-INIT] FLX.init result=" + initCode // Log.i(TAG, "[FLX-INIT] FLX.init result=" + initCode
+ " msg=" + initMsg // + " msg=" + initMsg
+ " attempt=" + attempt + "/" + FLX_INIT_MAX_ATTEMPTS); // + " attempt=" + attempt + "/" + FLX_INIT_MAX_ATTEMPTS);
if (initCode == 0) { if (initCode == 0) {
flexionInitialized = true; flexionInitialized = true;
notifyFlexionInitResult(true, "ok"); notifyFlexionInitResult(true, "ok");
@@ -181,7 +189,7 @@ public class FlexionSDKAdapter implements
private static void showFlexionScreensThenInitBilling(Activity activity) { private static void showFlexionScreensThenInitBilling(Activity activity) {
if (flexionScreensShown) { if (flexionScreensShown) {
Log.i(TAG, "[FLX-INIT] showFlexionScreens skipped, already shown"); // Log.i(TAG, "[FLX-INIT] showFlexionScreens skipped, already shown");
initBillingServiceAfterScreens(activity); initBillingServiceAfterScreens(activity);
return; return;
} }
@@ -191,21 +199,21 @@ public class FlexionSDKAdapter implements
return; return;
} }
Log.i(TAG, "[FLX-INIT] showFlexionScreens start"); // Log.i(TAG, "[FLX-INIT] showFlexionScreens start");
flexionScreensStarted = true; flexionScreensStarted = true;
FLX.showFlexionScreens(activity, (screenCode, screenMsg) -> { FLX.showFlexionScreens(activity, (screenCode, screenMsg) -> {
Log.i(TAG, "[FLX-INIT] showFlexionScreens result=" + screenCode // Log.i(TAG, "[FLX-INIT] showFlexionScreens result=" + screenCode
+ " msg=" + screenMsg); // + " msg=" + screenMsg);
flexionScreensShown = true; flexionScreensShown = true;
initBillingServiceAfterScreens(activity); initBillingServiceAfterScreens(activity);
}); });
} }
private static void initBillingServiceAfterScreens(Activity activity) { private static void initBillingServiceAfterScreens(Activity activity) {
Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens start"); // Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens start");
initBillingService(activity, initBillingService(activity,
() -> { () -> {
Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens success"); // Log.i(TAG, "[FLX-INIT] initBillingServiceAfterScreens success");
}, },
() -> { () -> {
Log.w(TAG, "[FLX-INIT] initBillingServiceAfterScreens failed"); Log.w(TAG, "[FLX-INIT] initBillingServiceAfterScreens failed");
@@ -230,17 +238,14 @@ public class FlexionSDKAdapter implements
try { try {
byte[] decoded = Base64.getDecoder().decode(appInfo); byte[] decoded = Base64.getDecoder().decode(appInfo);
JSONObject json = new JSONObject(new String(decoded, StandardCharsets.UTF_8)); JSONObject json = new JSONObject(new String(decoded, StandardCharsets.UTF_8));
Jsonobject json = new JSONObject();
JSONObject payload = new JSONObject(); JSONObject payload = new JSONObject();
String customData = json.optString("customData", ""); String customData = json.optString("customData", "");
payload.put("orderId", prodorderId); payload.put("orderId", prodorderId);
payload.put("userId", json.optString("userId", "")); payload.put("userId", json.optString("userId", ""));
payload.put("pfid", json.optString("pfid", "")); payload.put("pfid", json.optString("pfid", ""));
payload.put("customData", json.optString("customData", "")); if (!customData.isEmpty()) {
payload.put("customData", customData);
// if (!customData.isEmpty()) { }
// payload.put("customData", parseCustomDataValue(customData));
// }
payload.put("prodPrice", productPrice); payload.put("prodPrice", productPrice);
payload.put("prodCount", productCount); payload.put("prodCount", productCount);
developerPayload = Base64.getEncoder().encodeToString(payload.toString().getBytes(StandardCharsets.UTF_8)); 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)); () -> 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 @Override
public void queryProducts() { public void queryProducts() {
// Flexion 渠道不通过 thirdExtend 获取商品列表 queryProducts(String) 替代 // Flexion 渠道不通过 thirdExtend 获取商品列表 queryProducts(String) 替代
@@ -300,9 +290,11 @@ public class FlexionSDKAdapter implements
@Override @Override
public void queryProducts(String productIds) { public void queryProducts(String productIds) {
// Log.i(TAG, "queryProducts(productIds) called, billingConnected=" + billingConnected);
List<String> ids = Arrays.asList(productIds.split(",")); List<String> 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", ensureBillingReady(null, "queryProducts",
bs -> queryProductDetails(bs, ids), bs -> queryProductDetails(bs, ids),
() -> sendExtensionError("billing_not_ready")); () -> sendExtensionError("billing_not_ready"));
@@ -442,8 +434,8 @@ public class FlexionSDKAdapter implements
JSONArray cached = drainCachedPendingPurchases(); JSONArray cached = drainCachedPendingPurchases();
boolean cacheReady = isPendingPurchaseCacheReady(); boolean cacheReady = isPendingPurchaseCacheReady();
if (cached.length() > 0 || cacheReady) { if (cached.length() > 0 || cacheReady) {
Log.i(TAG, "[PAY-FLOW] queryPendingPurchases use cached result count=" + cached.length() // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases use cached result count=" + cached.length()
+ " cacheReady=" + cacheReady); // + " cacheReady=" + cacheReady);
markPendingPurchaseCacheConsumed(cached); markPendingPurchaseCacheConsumed(cached);
sendPendingPurchasesCallback(0, null, cached); sendPendingPurchasesCallback(0, null, cached);
return; return;
@@ -455,18 +447,18 @@ public class FlexionSDKAdapter implements
pendingPurchaseUnityCallbackWaiting = true; pendingPurchaseUnityCallbackWaiting = true;
} }
if (pendingPurchaseQueryInProgress) { if (pendingPurchaseQueryInProgress) {
Log.i(TAG, "[PAY-FLOW] queryPendingPurchases wait running query" // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases wait running query"
+ " sendUnityCallback=" + sendUnityCallback // + " sendUnityCallback=" + sendUnityCallback
+ " cacheReady=" + pendingPurchaseCacheReady); // + " cacheReady=" + pendingPurchaseCacheReady);
return; return;
} }
pendingPurchaseQueryInProgress = true; pendingPurchaseQueryInProgress = true;
pendingPurchaseCacheReady = false; pendingPurchaseCacheReady = false;
} }
Log.i(TAG, "[PAY-FLOW] queryPendingPurchases start: billingService=" + billingService // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases start: billingService=" + billingService
+ " billingConnected=" + billingConnected // + " billingConnected=" + billingConnected
+ " sendUnityCallback=" + sendUnityCallback); // + " sendUnityCallback=" + sendUnityCallback);
ensureBillingReady(null, "queryPendingPurchases", ensureBillingReady(null, "queryPendingPurchases",
bs -> { bs -> {
billingExecutor.execute(() -> { billingExecutor.execute(() -> {
@@ -476,9 +468,9 @@ public class FlexionSDKAdapter implements
(result, purchases) -> { (result, purchases) -> {
int responseCode = result == null ? -1 : result.getResponseCode(); int responseCode = result == null ? -1 : result.getResponseCode();
String debugMessage = result == null ? "billing_result_null" : result.getDebugMessage(); String debugMessage = result == null ? "billing_result_null" : result.getDebugMessage();
Log.i(TAG, "[PAY-FLOW] queryPendingPurchases result: code=" + responseCode // Log.i(TAG, "[PAY-FLOW] queryPendingPurchases result: code=" + responseCode
+ " debugMsg=" + debugMessage // + " debugMsg=" + debugMessage
+ " count=" + (purchases == null ? 0 : purchases.size())); // + " count=" + (purchases == null ? 0 : purchases.size()));
if (responseCode != QUERY_PURCHASES_SUCCESS_CODE) { if (responseCode != QUERY_PURCHASES_SUCCESS_CODE) {
boolean shouldCallback = finishPendingQueryFailed(); boolean shouldCallback = finishPendingQueryFailed();
if (shouldCallback) { 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(); boolean shouldCallback = finishPendingQueryFailed();
if (shouldCallback) sendPendingPurchasesCallback(1, "billing_not_ready", new JSONArray()); if (shouldCallback) sendPendingPurchasesCallback(1, "billing_not_ready", new JSONArray());
}); });
@@ -578,9 +570,9 @@ public class FlexionSDKAdapter implements
private static JSONArray drainCachedPendingPurchases() { private static JSONArray drainCachedPendingPurchases() {
synchronized (pendingPurchases) { synchronized (pendingPurchases) {
Log.i(TAG, "[PAY-FLOW] drainCachedPendingPurchases start cachedCount=" + pendingPurchases.size() // Log.i(TAG, "[PAY-FLOW] drainCachedPendingPurchases start cachedCount=" + pendingPurchases.size()
+ " queryInProgress=" + pendingPurchaseQueryInProgress // + " queryInProgress=" + pendingPurchaseQueryInProgress
+ " cacheReady=" + pendingPurchaseCacheReady); // + " cacheReady=" + pendingPurchaseCacheReady);
JSONArray result = new JSONArray(); JSONArray result = new JSONArray();
for (String item : pendingPurchases) { for (String item : pendingPurchases) {
try { try {
@@ -602,7 +594,7 @@ public class FlexionSDKAdapter implements
JSONObject item = purchases.optJSONObject(i); JSONObject item = purchases.optJSONObject(i);
if (item != null) pendingPurchases.add(item.toString()); 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); result.put("code", code);
if (errStr != null) result.put("errStr", errStr); if (errStr != null) result.put("errStr", errStr);
result.put("respObj", purchases == null ? "[]" : purchases.toString()); result.put("respObj", purchases == null ? "[]" : purchases.toString());
Log.i(TAG, "[PAY-FLOW] PendingPurchasesResult callback: code=" + code // Log.i(TAG, "[PAY-FLOW] PendingPurchasesResult callback: code=" + code
+ " count=" + (purchases == null ? 0 : purchases.length())); // + " count=" + (purchases == null ? 0 : purchases.length()));
UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME, UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME,
"PendingPurchasesResult", result.toString()); "PendingPurchasesResult", result.toString());
} catch (JSONException e) { } catch (JSONException e) {
@@ -641,6 +633,9 @@ public class FlexionSDKAdapter implements
private static void queryProductDetails(BillingService service, List<String> productIds) { private static void queryProductDetails(BillingService service, List<String> productIds) {
final AtomicBoolean completed = new AtomicBoolean(false); 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(() -> { mainHandler.postDelayed(() -> {
if (!completed.compareAndSet(false, true)) return; if (!completed.compareAndSet(false, true)) return;
Log.w(TAG, "[PAY-FLOW] queryProductDetails timeout count=" + productIds.size()); 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"); Log.w(TAG, "[PAY-FLOW] queryProductDetails callback ignored after timeout");
return; 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 { try {
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
if (billingResult != null if (billingResult != null
@@ -672,10 +672,17 @@ public class FlexionSDKAdapter implements
item.put("price_amount_micros", detail.getPriceAmountMicros()); item.put("price_amount_micros", detail.getPriceAmountMicros());
item.put("price_currency_code", detail.getPriceCurrencyCode()); item.put("price_currency_code", detail.getPriceCurrencyCode());
item.put("type", detail.getType()); 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); arr.put(item);
} }
result.put("code", 0); result.put("code", 0);
result.put("respObj", arr.toString()); result.put("respObj", arr.toString());
Log.i(TAG, "[FLEXION-SKU-PRICE] send Unity SKUListResult respObj=" + arr.toString());
} else { } else {
result.put("code", 1); result.put("code", 1);
result.put("thirdExtend_errStr", result.put("thirdExtend_errStr",
@@ -731,12 +738,18 @@ public class FlexionSDKAdapter implements
} }
// Log.i(TAG, "[PAY-FLOW] consumePurchase: token=" + token); // Log.i(TAG, "[PAY-FLOW] consumePurchase: token=" + token);
ensureBillingReady(null, "consumePurchase", ensureBillingReady(null, "consumePurchase",
bs -> bs.consumeAsync( bs -> billingExecutor.execute(() -> {
new ConsumeParams(token), try {
r -> { bs.consumeAsync(
// Log.i(TAG, "[PAY-FLOW] consume result: " + new ConsumeParams(token),
// (r.getResponseCode() == BillingResults.ResultCode.CONSUME_SUCCESS_CODE ? "ok" : "fail")); 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")); () -> 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"); // 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) { private static void sendExtensionError(String errStr) {
try { try {
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();

View File

@@ -1,4 +1,4 @@
org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M org.gradle.jvmargs=-Xmx8192m
org.gradle.parallel=true org.gradle.parallel=true
unityStreamingAssets=**STREAMING_ASSETS** unityStreamingAssets=**STREAMING_ASSETS**
# Android Resolver Properties Start # Android Resolver Properties Start

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services'
dependencies { dependencies {
implementation project(':unityLibrary') implementation project(':unityLibrary')
implementation(platform("com.google.firebase:firebase-bom:33.6.0")) implementation platform('com.google.firebase:firebase-bom:34.6.0')
implementation("com.google.firebase:firebase-analytics") implementation 'com.google.firebase:firebase-analytics'
} }
android { android {
@@ -17,7 +17,6 @@ android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
} }
defaultConfig { defaultConfig {

View File

@@ -13,7 +13,7 @@ android {
} }
// Android Resolver Exclusions End // Android Resolver Exclusions End
android { android {
namespace "com.unity3d.player" namespace "com.unity3d.player"
} }
dependencies { dependencies {
@@ -31,17 +31,16 @@ dependencies {
api "io.reactivex:rxandroid:1.2.1" api "io.reactivex:rxandroid:1.2.1"
api "io.reactivex:rxjava:1.1.9" 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 '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 'net.aihelp:android-aihelp-aar:5.3.+'
implementation 'com.google.android.gms:play-services-auth:20.2.0' implementation 'com.google.android.gms:play-services-auth:20.2.0'
// Flexion SDK (includes wrapped billing) // Flexion SDK (includes wrapped billing)
implementation("com.flexionmobile:sdk:4.0.1") 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 'com.google.android.gms:play-services-basement:18.2.0'
implementation 'androidx.fragment:fragment:1.3.6' implementation 'androidx.fragment:fragment:1.3.6'
implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.41" implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.41"
@@ -66,13 +65,18 @@ dependencies {
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2"
// Android Resolver Dependencies Start // 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.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: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: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: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: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: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: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.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: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:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8

View File

@@ -26,15 +26,20 @@ dependencyResolutionManagement {
password = "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" password = "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"
} }
} }
// Android Resolver Repos Start // Android Resolver Repos Start
def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
maven { maven {
url "https://sdk.tapjoy.com/" // Packages/com.unity.package-offerwall/Editor/TJPluginDependencies.xml:9 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 { maven {
url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 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() mavenLocal()
// Android Resolver Repos End // Android Resolver Repos End
flatDir { flatDir {

View File

@@ -36,7 +36,7 @@
<meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="true" /> <meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="true" />
</activity> </activity>
<meta-data android:name="CHANNEL" android:value="GooglePlay" /> <meta-data android:name="com.arkgame.ft.channel" android:value="GooglePlay" />
</application> </application>
<queries> <queries>
<provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <!-- allows app to access Facebook app features --> <provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <!-- allows app to access Facebook app features -->

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services'
dependencies { dependencies {
implementation project(':unityLibrary') implementation project(':unityLibrary')
implementation(platform("com.google.firebase:firebase-bom:33.6.0")) implementation platform('com.google.firebase:firebase-bom:34.6.0')
implementation("com.google.firebase:firebase-analytics") implementation 'com.google.firebase:firebase-analytics'
} }
android { android {
@@ -17,7 +17,6 @@ android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
} }
defaultConfig { defaultConfig {

View File

@@ -60,18 +60,24 @@ dependencies {
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1" implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1"
// Android Resolver Dependencies Start // 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.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: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: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: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: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: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: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.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: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: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.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.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 // Android Resolver Dependencies End
**DEPS**} **DEPS**}

View File

@@ -18,9 +18,18 @@ dependencyResolutionManagement {
mavenCentral() mavenCentral()
// Android Resolver Repos Start // Android Resolver Repos Start
def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") 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 { maven {
url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 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() mavenLocal()
// Android Resolver Repos End // Android Resolver Repos End
flatDir { flatDir {

View File

@@ -33,7 +33,7 @@
<meta-data android:name="unityplayer.UnityActivity" android:value="true" /> <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity> </activity>
<meta-data android:name="CHANNEL" android:value="Rustore" /> <meta-data android:name="com.arkgame.ft.channel" android:value="Rustore" />
</application> </application>
<queries> <queries>
<provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <!-- allows app to access Facebook app features --> <provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <!-- allows app to access Facebook app features -->

View File

@@ -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";
}
}

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services'
dependencies { dependencies {
implementation project(':unityLibrary') implementation project(':unityLibrary')
implementation(platform("com.google.firebase:firebase-bom:33.6.0")) implementation platform('com.google.firebase:firebase-bom:34.6.0')
implementation("com.google.firebase:firebase-analytics") implementation 'com.google.firebase:firebase-analytics'
} }
android { android {

View File

@@ -13,7 +13,7 @@ android {
} }
// Android Resolver Exclusions End // Android Resolver Exclusions End
android { android {
namespace "com.unity3d.player" namespace "com.unity3d.player"
} }
dependencies { dependencies {
@@ -36,7 +36,7 @@ dependencies {
implementation 'net.aihelp:android-aihelp-aar:5.3.+' implementation 'net.aihelp:android-aihelp-aar:5.3.+'
implementation 'com.google.android.gms:play-services-auth:20.2.0' 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 'com.google.android.gms:play-services-basement:18.2.0'
implementation 'androidx.fragment:fragment:1.3.6' implementation 'androidx.fragment:fragment:1.3.6'
@@ -48,7 +48,7 @@ dependencies {
implementation 'com.miui.referrer:homereferrer:1.0.0.6' 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.google.firebase:firebase-analytics'
implementation('com.facebook.android:facebook-android-sdk:16.2.0') implementation('com.facebook.android:facebook-android-sdk:16.2.0')
@@ -65,20 +65,25 @@ dependencies {
implementation "ru.rustore.sdk:review:10.0.0" implementation "ru.rustore.sdk:review:10.0.0"
implementation "com.vk.id:vkid:2.5.1" implementation "com.vk.id:vkid:2.5.1"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2"
// Android Resolver Dependencies Start // 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.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: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: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: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: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: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: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.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: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: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.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.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 // Android Resolver Dependencies End
**DEPS**} **DEPS**}

View File

@@ -58,13 +58,21 @@ public class BuildTool
[MenuItem("Tools/Build Android")] [MenuItem("Tools/Build Android")]
public static void BuildAndroid() public static void BuildAndroid()
{ {
ChannelBuildTool.Build_GooglePlay(); ChannelBuildTool.SwitchChannel("GooglePlay");
BuildAndroid(new BuildParams
{
outPath = "../Bin/tysdkTest_GooglePlay.apk"
});
} }
[MenuItem("Tools/Build Android With Debug")] [MenuItem("Tools/Build Android With Debug")]
public static void BuildAndroidWithDebug() 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() public static void CIBuildAndroid()

View File

@@ -1,103 +1,71 @@
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEngine; using UnityEngine;
public class ChannelBuildTool 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 ExtraCfgRoot = "../ExtraPluginCfgs/Android";
private const string TysdkPlugins = "Packages/tysdk/Plugins/Android"; private const string TysdkPlugins = "Packages/tysdk/Plugins/Android";
private const string TysdkFiles = "Packages/tysdk/Files"; private const string TysdkFiles = "Packages/tysdk/Files";
private const string AssetsPlugins = "Assets/Plugins/Android"; private const string AssetsPlugins = "Assets/Plugins/Android";
private static readonly string[] GradleFiles = private const string AddressablesContentState = "AddressableAssetsData/Android/addressables_content_state.bin";
{ private const string AndroidAddressablesContentState = "Assets/AddressableAssetsData/Android/addressables_content_state.bin";
"mainTemplate.gradle", private const string DefaultProductName = "Fishing Travel";
"launcherTemplate.gradle", private const string EnjoyPayProductName = "Fishing Travel: Hook & Explore";
"settingsTemplate.gradle",
"gradleTemplate.properties",
"AndroidManifest.xml"
};
// ==================== Channel Switching ==================== // ==================== Channel Switching ====================
private static void SwitchChannel(string channel) public static void SwitchChannel(string channel)
{ {
var channelDir = channel.ToLower(); channel = NormalizeChannelName(channel);
var cfgDir = Path.Combine(ExtraCfgRoot, channelDir); var cfgDir = Path.Combine(ExtraCfgRoot, channel.ToLowerInvariant());
if (!Directory.Exists(cfgDir)) if (!Directory.Exists(cfgDir))
{ {
Debug.LogError($"[ChannelSwitch] Channel config not found: {cfgDir}"); throw new DirectoryNotFoundException($"[ChannelSwitch] Channel config not found: {cfgDir}");
return;
} }
Debug.Log($"[ChannelSwitch] Switching to {channel}..."); Debug.Log($"[ChannelSwitch] Switching to {channel}...");
currentChannel = channel;
// 1. Sync AAR // 1. Sync root Android config files
var srcAarDir = Path.Combine(cfgDir, "Plugins/Android"); SyncRootAndroidConfigFiles(cfgDir);
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}");
}
}
// 2. Clean up previous channel Java files // 2. Sync channel SDK adapter Java files to tysdk package
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "ChannelHelpers.java")) SyncChannelAdapterFiles(cfgDir);
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);
// 3. Sync Gradle + Manifest // 3. Sync google-services.json
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)
var srcGoogleServices = Path.Combine(cfgDir, "Files/google-services.json"); var srcGoogleServices = Path.Combine(cfgDir, "Files/google-services.json");
if (!File.Exists(srcGoogleServices)) if (File.Exists(srcGoogleServices))
srcGoogleServices = Path.Combine(ExtraCfgRoot, "googleplay/Files/google-services.json"); {
var destGoogleServices = Path.Combine(TysdkFiles, "google-services.json"); var destDir = Path.Combine(TysdkFiles);
File.Copy(srcGoogleServices, destGoogleServices, true); if (!Directory.Exists(destDir)) Directory.CreateDirectory(destDir);
Debug.Log($"[ChannelSwitch] google-services.json: {srcGoogleServices} → {destGoogleServices}"); 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 var bundleId = channel switch
{ {
"Flexion" => "com.arkgame.ft.flexion", "Flexion" => "com.arkgame.ft.flexion",
@@ -105,25 +73,38 @@ public class ChannelBuildTool
_ => "com.arkgame.ft" _ => "com.arkgame.ft"
}; };
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, bundleId); 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); tysdk.ChannelConfig.SetChannel(channel);
// 7. Set Addressables profile and optional channel content state
SetAddressablesProfile(channel);
SyncAddressablesContentState(channel, cfgDir);
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
Debug.Log($"[ChannelSwitch] Done. Channel: {channel}"); Debug.Log($"[ChannelSwitch] Done. Channel: {channel}");
} }
// ==================== Build ==================== // ==================== Menu ====================
private static void RestoreDefaultChannel() [MenuItem("Tools/Channel/Switch Channel/GooglePlay", false, 10000)]
{ public static void Switch_GooglePlay() => SwitchChannel("GooglePlay");
Debug.Log($"[ChannelBuild] Restore default channel -> {DefaultChannel}");
SwitchChannel(DefaultChannel); [MenuItem("Tools/Channel/Switch Channel/Flexion", false, 10001)]
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, DefaultAndroidBundleIdentifier); public static void Switch_Flexion() => SwitchChannel("Flexion");
Debug.Log($"[ChannelBuild] Restore bundle identifier -> {DefaultAndroidBundleIdentifier}");
AssetDatabase.SaveAssets(); [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) private static void BuildAndroidForChannel(string channel, bool debug)
{ {
@@ -131,8 +112,8 @@ public class ChannelBuildTool
{ {
SwitchChannel(channel); SwitchChannel(channel);
string fileName = debug ? $"tysdkTest_{channel}_debug.apk" : $"tysdkTest_{channel}.apk"; var fileName = debug ? $"tysdkTest_{channel}_debug.apk" : $"tysdkTest_{channel}.apk";
string outPath = $"../Bin/{fileName}"; var outPath = $"../Bin/{fileName}";
var buildOptions = debug var buildOptions = debug
? BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.WaitForPlayerConnection ? BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.WaitForPlayerConnection
: BuildOptions.None; : BuildOptions.None;
@@ -145,7 +126,7 @@ public class ChannelBuildTool
options = buildOptions, options = buildOptions,
}; };
Debug.Log($"[ChannelBuild] Building {channel} {outPath}"); Debug.Log($"[ChannelBuild] Building {channel} -> {outPath}");
var buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions); var buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions);
if (buildReport?.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded) if (buildReport?.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded)
@@ -160,49 +141,157 @@ public class ChannelBuildTool
} }
finally finally
{ {
RestoreDefaultChannel(); SwitchChannel("GooglePlay");
AssetDatabase.SaveAssets();
} }
} }
private static string currentChannel = ""; [MenuItem("Tools/Channel/Build Android (Channel)/GooglePlay", false, 10100)]
// ==================== 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")]
public static void Build_GooglePlay() => BuildAndroidForChannel("GooglePlay", false); 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); 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); 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); 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); 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); 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); 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); 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";
}
} }

View File

@@ -36,7 +36,7 @@
<meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="true" /> <meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="true" />
</activity> </activity>
<meta-data android:name="CHANNEL" android:value="GooglePlay" /> <meta-data android:name="com.arkgame.ft.channel" android:value="GooglePlay" />
</application> </application>
<queries> <queries>
<provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <!-- allows app to access Facebook app features --> <provider android:authorities="com.facebook.katana.provider.PlatformProvider" /> <!-- allows app to access Facebook app features -->

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.google.gms.google-services'
dependencies { dependencies {
implementation project(':unityLibrary') implementation project(':unityLibrary')
implementation(platform("com.google.firebase:firebase-bom:33.6.0")) implementation platform('com.google.firebase:firebase-bom:34.6.0')
implementation("com.google.firebase:firebase-analytics") implementation 'com.google.firebase:firebase-analytics'
} }
android { android {
@@ -17,7 +17,6 @@ android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
} }
defaultConfig { defaultConfig {

View File

@@ -60,18 +60,24 @@ dependencies {
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1" implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1"
// Android Resolver Dependencies Start // 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.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: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: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: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: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: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: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.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: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: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.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.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 // Android Resolver Dependencies End
**DEPS**} **DEPS**}

View File

@@ -18,9 +18,18 @@ dependencyResolutionManagement {
mavenCentral() mavenCentral()
// Android Resolver Repos Start // Android Resolver Repos Start
def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") 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 { maven {
url "https://android-sdk.is.com/" // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8 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() mavenLocal()
// Android Resolver Repos End // Android Resolver Repos End
flatDir { flatDir {

View File

@@ -73,8 +73,8 @@ public class SDKTest : MonoBehaviour
IConfig config = new Config(serializer); IConfig config = new Config(serializer);
GContext.container.RegisterInstance<IConfig>(config); GContext.container.RegisterInstance<IConfig>(config);
Debug.Log("SDKTest Start"); Debug.Log("SDKTest Start");
UpdateChannelTitle(); ClearChannelTitle();
//=============================================================================== //===============================================================================
//====================== Test Server =========================== //====================== Test Server ===========================
// UnityBridgeFunc.UnityResetServerUrl("https://128-hwsfsdk-sdk-test01.qijihdhk.com"); // UnityBridgeFunc.UnityResetServerUrl("https://128-hwsfsdk-sdk-test01.qijihdhk.com");
@@ -82,12 +82,13 @@ public class SDKTest : MonoBehaviour
//====================== Test Server =========================== //====================== Test Server ===========================
//=============================================================================== //===============================================================================
// //
_InitBtn.onClick.AddListener(Init); _InitBtn.onClick.AddListener(Init);
TYSdkFacade.OnInitComplete += (success, msg) => TYSdkFacade.OnInitComplete += (success, msg) =>
{ {
_messageTxt.text = success ? $"Init OK: {msg}" : $"Init Failed: {msg}"; _messageTxt.text = success ? $"Init OK: {msg}" : $"Init Failed: {msg}";
}; UpdateChannelTitle();
_loginGuestBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGuest)); };
_loginGuestBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGuest));
_loginGoogleBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGoogle)); _loginGoogleBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGoogle));
_loginFbBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwFacebook)); _loginFbBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwFacebook));
_loginVkBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwVkid)); _loginVkBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwVkid));
@@ -111,11 +112,11 @@ public class SDKTest : MonoBehaviour
_signoutBtn.onClick.AddListener(OnSignoutBtn); _signoutBtn.onClick.AddListener(OnSignoutBtn);
_fbShareLinkBtn.onClick.AddListener(OnFBShareLinkBtn); _fbShareLinkBtn.onClick.AddListener(OnFBShareLinkBtn);
_mfbShareLinkBtn.onClick.AddListener(OnMessengerShareLinkBtn); _mfbShareLinkBtn.onClick.AddListener(OnMessengerShareLinkBtn);
_reviewBtn.onClick.AddListener(OnReview); _reviewBtn.onClick.AddListener(OnReview);
Debug.Log("SDKTest Started"); Debug.Log("SDKTest Started");
} }
void Init() void Init()
{ {
_messageTxt.text = "Initializing..."; _messageTxt.text = "Initializing...";
TYSdkFacade.Instance.Init(); TYSdkFacade.Instance.Init();
@@ -140,19 +141,21 @@ public class SDKTest : MonoBehaviour
GContext.container.Resolve<IConfig>().Set("PAY_VERIFY_URL", "https://192.168.9.91:7036/api/FlexionCallback"); GContext.container.Resolve<IConfig>().Set("PAY_VERIFY_URL", "https://192.168.9.91:7036/api/FlexionCallback");
} }
private void UpdateChannelTitle() private void UpdateChannelTitle()
{ {
#if UNITY_ANDROID #if UNITY_ANDROID
using (var cls = new AndroidJavaClass("com.unity3d.player.ChannelEntry")) string channel = ChannelConfig.Channel;
{ Debug.Log($"[SDKTest] Channel from ChannelConfig: {channel}");
string channel = cls.GetStatic<string>("CHANNEL"); _titleText.text = $" {channel}";
Debug.Log($"[SDKTest] Channel from Java: {channel}"); #endif
_titleText.text = $" {channel}"; }
}
#endif private void ClearChannelTitle()
} {
_titleText.text = string.Empty;
int retryAttempt; }
int retryAttempt;
public void InitializeRewardedAds() public void InitializeRewardedAds()
{ {
@@ -211,10 +214,11 @@ public class SDKTest : MonoBehaviour
{ {
_messageTxt.text = ""; _messageTxt.text = "";
if (ChannelConfig.Channel.Equals("Flexion")) var channel = ChannelConfig.Channel;
{ if (string.Equals(channel, "Flexion"))
sku = new SKUDetail {
{ sku = new SKUDetail
{
productId = "com.arkgame.ft.pack0199", productId = "com.arkgame.ft.pack0199",
ourProductId = "com.arkgame.ft.pack0199", ourProductId = "com.arkgame.ft.pack0199",
price = "1.99", price = "1.99",
@@ -223,10 +227,10 @@ public class SDKTest : MonoBehaviour
type = "inapp" type = "inapp"
}; };
} }
else if (ChannelConfig.Channel.Equals("EnjoyPay")) else if (string.Equals(channel, "EnjoyPay"))
{ {
sku = new SKUDetail sku = new SKUDetail
{ {
productId = "comarkgameftpack0199", productId = "comarkgameftpack0199",
ourProductId = "comarkgameftpack0199", ourProductId = "comarkgameftpack0199",
price = "1.99", price = "1.99",
@@ -235,13 +239,19 @@ public class SDKTest : MonoBehaviour
type = "inapp" type = "inapp"
}; };
} }
if (sku == null){ if (sku == null){
_messageTxt.text = "no product"; _messageTxt.text = "no product";
return; return;
} }
#if !UNITY_EDITOR && UNITY_IOS if (!TYSdkFacade.IsLoggedIn)
sku.productId = "comarkgameftpack0199"; {
_messageTxt.text = "not logged in";
return;
}
#if !UNITY_EDITOR && UNITY_IOS
sku.productId = "comarkgameftpack0199";
sku.title = "商店-体力直充1.99" ; sku.title = "商店-体力直充1.99" ;
sku.price = "1.99"; sku.price = "1.99";
#endif #endif

View File

@@ -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;
}
}
}

View File

@@ -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:

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -43,7 +43,7 @@ import java.util.HashMap;
import java.util.Map; 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 * C# passes the channel string via InitSDK(activity, channel); Java dispatches
* internally via switch. All login/link/GA/share logic is shared. * internally via switch. All login/link/GA/share logic is shared.
* Channel-specific behaviour is limited to: Init, Pay, thirdExtend, Review. * Channel-specific behaviour is limited to: Init, Pay, thirdExtend, Review.
@@ -59,7 +59,17 @@ public class SDKManager {
// Channel SDK adapter // Channel SDK adapter
public interface IChannelSDKAdapter { 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 { public interface IPaymentAdapter {
@@ -82,9 +92,19 @@ public class SDKManager {
void refreshBilling(); void refreshBilling();
} }
public interface IChannelInfoAdapter {
String getStorePageUri(Activity activity);
}
public interface IReviewAdapter {
void review(Activity activity);
}
private static IChannelSDKAdapter sdkAdapter; private static IChannelSDKAdapter sdkAdapter;
public static void queryProductsByIDs(String productIds) { 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) { if (sdkAdapter instanceof IProductQueryAdapter) {
((IProductQueryAdapter) sdkAdapter).queryProducts(productIds); ((IProductQueryAdapter) sdkAdapter).queryProducts(productIds);
return; return;
@@ -125,7 +145,17 @@ public class SDKManager {
public static void CancelBillingFlow() { public static void CancelBillingFlow() {
Log.w(TAG, "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() { 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) { public static void InitSDK(Activity activity, String ch) {
channel = ChannelEntry.CHANNEL; sdkAdapter = ChannelAdapterManager.createSdkAdapter(activity);
sdkAdapter = ChannelEntry.createSDKAdapter(); sdkAdapter.loadConfig();
// Log.i(TAG, "[CHANNEL-VERIFY] Java InitSDK channel=" + channel channel = sdkAdapter.getChannel();
// + " fromCSharp=" + ch
// + " adapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getSimpleName() : "default")); 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, UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME,
"SetChannelFromNative", channel); "SetChannelFromNative", channel);
if (sdkAdapter != null) { sdkAdapter.init();
sdkAdapter.init(activity);
} else {
initDefault(activity);
}
} }
private static void initDefault(Activity activity) { static void initDefault(Activity activity) {
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
SDKAPI.getIns().lightModeEnable(); SDKAPI.getIns().lightModeEnable();
try { try {
@@ -258,6 +285,7 @@ public class SDKManager {
public static void UnityResetServerUrl(String url) { public static void UnityResetServerUrl(String url) {
SDKLog.i("UnityResetServerUrl : " + url); SDKLog.i("UnityResetServerUrl : " + url);
SetDNSIPsEnable(false);
SDKAPI.getIns().updateServer(url); 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, 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, public static void UnityKnowNew(String productId, String productPrice, String productName,
String productCount, String prodorderId, String appInfo, String productCount, String prodorderId, String appInfo,
String ptype) { 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 + ", ptype=" + ptype
+ ", productId=" + productId + ", productId=" + productId
+ ", productPrice=" + productPrice + ", productPrice=" + productPrice
@@ -489,8 +519,19 @@ public class SDKManager {
SDKAPI.getIns().payNew(payData, payType, mPay); 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() { public static void thirdExtend() {
@@ -518,7 +559,7 @@ public class SDKManager {
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
result.put("code", code); result.put("code", code);
if (code == SDKCallBack.Extend.EXTEND_CODE_SUCCESS) { if (code == SDKCallBack.Extend.EXTEND_CODE_SUCCESS) {
result.put("respObj", ChannelEntry.normalizeSkuList(msg)); result.put("respObj", ChannelAdapterManager.normalizeSkuList(msg));
} else { } else {
Log.e(TAG, "thirdExtend failed: " + msg); Log.e(TAG, "thirdExtend failed: " + msg);
result.put("thirdExtend_errStr", msg); result.put("thirdExtend_errStr", msg);
@@ -594,12 +635,19 @@ public class SDKManager {
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Review channel dispatch // Review channel dispatch
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
public static void Review() { public static void Review() {
Log.w(TAG, "[ReviewDebug] Review called channel=" + channel);
if ("Rustore".equals(channel)) { if ("Rustore".equals(channel)) {
RuStoreReview(); 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 { } else {
GooglePlayReview(); GooglePlayReview();
} }
@@ -693,4 +741,34 @@ public class SDKManager {
Log.e(TAG, "Messenger ShareDialog can not show"); 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);
}
}
} }

View File

@@ -12,6 +12,7 @@ public class TYApp extends Application {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
SDKAPI.getIns().onApplicationCreate(this); SDKAPI.getIns().onApplicationCreate(this);
SDKManager.SetDNSIPsEnable(true);
} }
@Override @Override
@@ -19,4 +20,5 @@ public class TYApp extends Application {
super.attachBaseContext(base); super.attachBaseContext(base);
SDKAPI.getIns().onAttachBaseContext(base, this); SDKAPI.getIns().onAttachBaseContext(base, this);
} }
} }