update:逻辑更新
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -5,4 +5,7 @@ sdk-intergration/.vscode
|
|||||||
sdk-intergration/'
|
sdk-intergration/'
|
||||||
sdk-intergration/Assets/.claude/settings.json
|
sdk-intergration/Assets/.claude/settings.json
|
||||||
sdk-intergration/.idea
|
sdk-intergration/.idea
|
||||||
.worktrees/*
|
.worktrees/*
|
||||||
|
.docs/*
|
||||||
|
.claude/*
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.unity3d.player;
|
package com.unity3d.player;
|
||||||
|
|
||||||
public class ChannelHelpers {
|
public class ChannelEntry {
|
||||||
|
|
||||||
public static final String CHANNEL = "Flexion";
|
public static final String CHANNEL = "Flexion";
|
||||||
|
|
||||||
static void register() {
|
public static SDKManager.IChannelSDKAdapter createSDKAdapter() {
|
||||||
SDKManager.registerHelper(new FlexionSDKHelper());
|
return new FlexionSDKService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ public class ChannelHelpers {
|
|||||||
public static String normalizeSkuList(String msg) {
|
public static String normalizeSkuList(String msg) {
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public SDKExtBuilder;
|
//public SDKExtBuilder;
|
||||||
}
|
}
|
||||||
@@ -17,35 +17,41 @@ import com.flexionmobile.ddpx.service.BillingService;
|
|||||||
import com.flexionmobile.fdk.FLX;
|
import com.flexionmobile.fdk.FLX;
|
||||||
|
|
||||||
import com.tuyoo.gamesdk.api.SDKAPI;
|
import com.tuyoo.gamesdk.api.SDKAPI;
|
||||||
import com.tuyoo.gamesdk.api.SDKCallBack;
|
|
||||||
import com.tuyoo.gamesdk.model.InitParam;
|
import com.tuyoo.gamesdk.model.InitParam;
|
||||||
import com.tuyoo.gamesdk.util.SDKLog;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
public class FlexionSDKService implements
|
||||||
private static final String TAG = "FlexionSDKHelper";
|
SDKManager.IChannelSDKAdapter,
|
||||||
|
SDKManager.IPaymentAdapter,
|
||||||
|
SDKManager.IProductQueryAdapter,
|
||||||
|
SDKManager.IPendingPurchaseAdapter {
|
||||||
|
private static final String TAG = "FlexionSDKService";
|
||||||
private static BillingService billingService;
|
private static BillingService billingService;
|
||||||
private static boolean billingConnected = false;
|
private static boolean billingConnected = false;
|
||||||
|
private static final List<String> pendingPurchases = new ArrayList<>();
|
||||||
|
private static final ExecutorService billingExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, "FlexionBillingThread"));
|
||||||
|
|
||||||
private static final PurchasesUpdateListener purchasesListener = (billingResult, purchase) -> {
|
private static final PurchasesUpdateListener purchasesListener = (billingResult, purchase) -> {
|
||||||
|
Log.w(TAG, "[PAY-FLOW] PurchasesUpdateListener: code=" + billingResult.getResponseCode()
|
||||||
|
|
||||||
Log.i(TAG, "[PAY-FLOW] PurchasesUpdateListener: code=" + billingResult.getResponseCode()
|
|
||||||
+ " hasPurchase=" + (purchase != null));
|
+ " hasPurchase=" + (purchase != null));
|
||||||
if (billingResult.getResponseCode() == BillingResults.ResultCode.PURCHASE_SUCCESS_CODE) {
|
if (billingResult.getResponseCode() == BillingResults.ResultCode.PURCHASE_SUCCESS_CODE) {
|
||||||
if (purchase != null) handlePurchase(purchase);
|
if (purchase != null) handlePurchase(purchase);
|
||||||
} else if (billingResult.getResponseCode() == BillingResults.ResultCode.PURCHASE_USER_CANCELLED_CODE) {
|
} else if (billingResult.getResponseCode() == BillingResults.ResultCode.PURCHASE_USER_CANCELLED_CODE) {
|
||||||
Log.i(TAG, "[PAY-FLOW] user cancelled");
|
Log.i(TAG, "[PAY-FLOW] user cancelled");
|
||||||
sendPayCallback(1, "user_cancelled", null, null, null);
|
sendPayCallback(1, "user_cancelled", null, null, null, null);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "[PAY-FLOW] purchase failed: code=" + billingResult.getResponseCode());
|
Log.e(TAG, "[PAY-FLOW] purchase failed: code=" + billingResult.getResponseCode());
|
||||||
sendPayCallback(1, "purchase_failed_" + billingResult.getResponseCode(), null, null, null);
|
sendPayCallback(1, "purchase_failed_" + billingResult.getResponseCode(), null, null, null, null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,9 +101,9 @@ public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
|||||||
String productName, String productCount, String prodorderId,
|
String productName, String productCount, String prodorderId,
|
||||||
String appInfo) {
|
String appInfo) {
|
||||||
Log.i(TAG, "[PAY-FLOW] pay called: productId=" + productId + " billingReady=" + billingConnected);
|
Log.i(TAG, "[PAY-FLOW] pay called: productId=" + productId + " billingReady=" + billingConnected);
|
||||||
if (billingService == null || !billingConnected) {
|
if (billingService == null || !billingConnected || !billingService.isReady()) {
|
||||||
Log.e(TAG, "[PAY-FLOW] billing not ready");
|
Log.e(TAG, "[PAY-FLOW] billing not ready");
|
||||||
sendPayCallback(1, "billing_not_ready", null, null, null);
|
sendPayCallback(1, "billing_not_ready", null, null, null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String developerPayload = "";
|
String developerPayload = "";
|
||||||
@@ -105,97 +111,66 @@ public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
|||||||
byte[] decoded = Base64.getDecoder().decode(appInfo);
|
byte[] decoded = Base64.getDecoder().decode(appInfo);
|
||||||
JSONObject json = new JSONObject(new String(decoded, "UTF-8"));
|
JSONObject json = new JSONObject(new String(decoded, "UTF-8"));
|
||||||
JSONObject payload = new JSONObject();
|
JSONObject payload = new JSONObject();
|
||||||
|
String customData = json.optString("customData", "");
|
||||||
|
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("customDataB64", Base64.getEncoder().encodeToString(customData.getBytes("UTF-8")));
|
||||||
|
}
|
||||||
payload.put("prodPrice", productPrice);
|
payload.put("prodPrice", productPrice);
|
||||||
payload.put("prodCount", productCount);
|
payload.put("prodCount", productCount);
|
||||||
developerPayload = payload.toString();
|
developerPayload = payload.toString();
|
||||||
|
Log.i(TAG, "[PAY-CUSTOMDATA] customData length=" + customData.length()
|
||||||
|
+ " developerPayload length=" + developerPayload.length());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, "Failed to extract payload fields from appInfo: " + e.getMessage());
|
Log.w(TAG, "Failed to extract payload fields from appInfo: " + e.getMessage());
|
||||||
}
|
}
|
||||||
String finalPayload = developerPayload;
|
String finalPayload = developerPayload;
|
||||||
activity.runOnUiThread(() -> {
|
billingExecutor.execute(() -> {
|
||||||
Log.i(TAG, "[PAY-FLOW] launching billing flow for: " + productId + " payload=" + finalPayload);
|
|
||||||
Log.i(TAG, "[PAY-FLOW] billingService=" + billingService + " billingConnected=" + billingConnected);
|
|
||||||
try {
|
try {
|
||||||
BillingResult result = billingService.launchBillingFlow(activity,
|
BillingService bs = billingService;
|
||||||
|
if (bs == null || !bs.isReady()) {
|
||||||
|
Log.e(TAG, "[PAY-FLOW] billingService became null or not ready");
|
||||||
|
sendPayCallback(1, "billing_not_ready", null, null, null, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.i(TAG, "[PAY-FLOW] launching billing flow for: " + productId + " payload=" + finalPayload);
|
||||||
|
BillingResult result = bs.launchBillingFlow(activity,
|
||||||
new BillingFlowParams(productId, "inapp", finalPayload));
|
new BillingFlowParams(productId, "inapp", finalPayload));
|
||||||
Log.i(TAG, "[PAY-FLOW] launchBillingFlow result: code=" + result.getResponseCode()
|
Log.i(TAG, "[PAY-FLOW] launchBillingFlow result: code=" + result.getResponseCode()
|
||||||
+ " debugMsg=" + result.getDebugMessage());
|
+ " debugMsg=" + result.getDebugMessage());
|
||||||
if (result.getResponseCode() == 2001) {
|
|
||||||
Log.i(TAG, "[PAY-FLOW] service not ready, retry after 3s...");
|
|
||||||
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
|
|
||||||
try {
|
|
||||||
BillingResult retryResult = billingService.launchBillingFlow(activity,
|
|
||||||
new BillingFlowParams(productId, "inapp", finalPayload));
|
|
||||||
Log.i(TAG, "[PAY-FLOW] launchBillingFlow retry result: code=" + retryResult.getResponseCode()
|
|
||||||
+ " debugMsg=" + retryResult.getDebugMessage());
|
|
||||||
if (retryResult.getResponseCode() != 2000) {
|
|
||||||
sendPayCallback(1, "billing_flow_error_" + retryResult.getResponseCode()
|
|
||||||
+ "_" + retryResult.getDebugMessage(), null, null, null);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
sendPayCallback(1, "launch_billing_failed: " + ex.getMessage(), null, null, null);
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (result.getResponseCode() != 2000) {
|
if (result.getResponseCode() != 2000) {
|
||||||
Log.e(TAG, "[PAY-FLOW] launchBillingFlow error: code=" + result.getResponseCode()
|
Log.e(TAG, "[PAY-FLOW] launchBillingFlow error: code=" + result.getResponseCode()
|
||||||
+ " debugMsg=" + result.getDebugMessage());
|
+ " debugMsg=" + result.getDebugMessage());
|
||||||
sendPayCallback(1, "billing_flow_error_" + result.getResponseCode()
|
sendPayCallback(1, "billing_flow_error_" + result.getResponseCode()
|
||||||
+ "_" + result.getDebugMessage(), null, null, null);
|
+ "_" + result.getDebugMessage(), null, null, null, null);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "[PAY-FLOW] launchBillingFlow exception: " + e.getClass().getName()
|
Log.e(TAG, "[PAY-FLOW] launchBillingFlow exception: " + e.getClass().getName()
|
||||||
+ " msg=" + e.getMessage());
|
+ " msg=" + e.getMessage());
|
||||||
sendPayCallback(1, "launch_billing_failed: " + e.getMessage(), null, null, null);
|
sendPayCallback(1, "launch_billing_failed: " + e.getMessage(), null, null, null, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void queryProducts() {
|
public void queryProducts() {
|
||||||
Log.i(TAG, "queryProducts called, billingConnected=" + billingConnected);
|
// Flexion 渠道不通过 thirdExtend 获取商品列表,由 queryProducts(String) 替代
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryProducts(String productIds) {
|
||||||
|
Log.i(TAG, "queryProducts(productIds) called, billingConnected=" + billingConnected);
|
||||||
if (billingService == null || !billingConnected) {
|
if (billingService == null || !billingConnected) {
|
||||||
Log.w(TAG, "queryProducts: billing not ready");
|
|
||||||
sendExtensionError("billing_not_ready");
|
sendExtensionError("billing_not_ready");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JSONObject jsonObject = new JSONObject();
|
List<String> ids = Arrays.asList(productIds.split(","));
|
||||||
try {
|
Log.i(TAG, "queryProductDetails with " + ids.size() + " items from config");
|
||||||
jsonObject.put("action", "ACTION_GET_SKU_DETAILS_LIST");
|
queryProductDetails(ids);
|
||||||
} catch (JSONException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
SDKAPI.getIns().thirdExtend(jsonObject.toString(), new SDKCallBack.Extend() {
|
|
||||||
@Override
|
|
||||||
public void callback(int code, String msg) {
|
|
||||||
Log.i(TAG, "TuYoo thirdExtend callback: code=" + code + " msg=" + msg);
|
|
||||||
if (code == SDKCallBack.Extend.EXTEND_CODE_SUCCESS && msg != null) {
|
|
||||||
try {
|
|
||||||
JSONArray products = new JSONArray(msg);
|
|
||||||
List<String> productIds = new java.util.ArrayList<>();
|
|
||||||
for (int i = 0; i < products.length(); i++) {
|
|
||||||
JSONObject p = products.getJSONObject(i);
|
|
||||||
String pid = p.optString("productId", "");
|
|
||||||
if (!pid.isEmpty()) productIds.add(pid);
|
|
||||||
}
|
|
||||||
Log.i(TAG, "queryProductDetails with " + productIds.size() + " items: " + productIds);
|
|
||||||
queryProductDetails(productIds);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
sendExtensionError("parse_error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendExtensionError("tuyoo_query_failed: " + msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Billing Infrastructure ----
|
|
||||||
|
|
||||||
private static void initBillingService(Activity activity) {
|
private static void initBillingService(Activity activity) {
|
||||||
Log.i(TAG, "[PAY-FLOW] initBillingService");
|
Log.i(TAG, "[PAY-FLOW] initBillingService");
|
||||||
billingService = FLX.createBillingService(activity, purchasesListener);
|
billingService = FLX.createBillingService(activity, purchasesListener);
|
||||||
@@ -208,6 +183,7 @@ public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
|||||||
queryPendingPurchases();
|
queryPendingPurchases();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBillingServiceDisconnected() {
|
public void onBillingServiceDisconnected() {
|
||||||
Log.w(TAG, "[PAY-FLOW] billing service disconnected");
|
Log.w(TAG, "[PAY-FLOW] billing service disconnected");
|
||||||
@@ -218,29 +194,84 @@ public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
|||||||
|
|
||||||
private static void handlePurchase(Purchase purchase) {
|
private static void handlePurchase(Purchase purchase) {
|
||||||
Log.i(TAG, "[PAY-FLOW] handlePurchase: state=" + purchase.getPurchaseState()
|
Log.i(TAG, "[PAY-FLOW] handlePurchase: state=" + purchase.getPurchaseState()
|
||||||
|
+ " orderId=" + purchase.getOrderId()
|
||||||
+ " token=" + purchase.getToken());
|
+ " token=" + purchase.getToken());
|
||||||
if (purchase.getPurchaseState() == 0) {
|
if (purchase.getPurchaseState() == 0) {
|
||||||
// 支付成功 → 回传数据给 Unity 做服务端验签,验签通过后由 C# 调 ConsumePurchase
|
|
||||||
Log.i(TAG, "[PAY-FLOW] purchase success, sending to Unity for verification");
|
Log.i(TAG, "[PAY-FLOW] purchase success, sending to Unity for verification");
|
||||||
sendPayCallback(0, "success",
|
sendPayCallback(0, "success", purchase.getOrderId(),
|
||||||
purchase.getPurchaseJson(), purchase.getSignature(), purchase.getToken());
|
purchase.getPurchaseJson(), purchase.getSignature(), purchase.getToken());
|
||||||
// [旧逻辑] 直接消费,跳过验签
|
|
||||||
// Log.i(TAG, "[PAY-FLOW] auto-consuming pending purchase: " + purchase.getToken());
|
|
||||||
// consumePurchase(purchase.getToken());
|
|
||||||
} else if (purchase.getPurchaseState() == 2) {
|
} else if (purchase.getPurchaseState() == 2) {
|
||||||
Log.i(TAG, "[PAY-FLOW] purchase state=2 (pending), skip");
|
Log.i(TAG, "[PAY-FLOW] purchase state=2 (pending), skip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void queryPendingPurchases() {
|
private static void queryPendingPurchases() {
|
||||||
if (billingService == null || !billingConnected) return;
|
Log.i(TAG, "[PAY-FLOW] queryPendingPurchases start: billingService=" + billingService
|
||||||
|
+ " billingConnected=" + billingConnected);
|
||||||
|
if (billingService == null || !billingConnected) {
|
||||||
|
Log.w(TAG, "[PAY-FLOW] queryPendingPurchases skipped: billing not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
billingService.queryPurchasesAsync(
|
billingService.queryPurchasesAsync(
|
||||||
new QueryPurchasesParams("inapp"),
|
new QueryPurchasesParams("inapp"),
|
||||||
(result, purchases) -> {
|
(result, purchases) -> {
|
||||||
if (purchases != null) for (Purchase p : purchases) handlePurchase(p);
|
Log.i(TAG, "[PAY-FLOW] queryPendingPurchases result: code=" + result.getResponseCode()
|
||||||
|
+ " count=" + (purchases == null ? 0 : purchases.size()));
|
||||||
|
if (purchases != null) for (Purchase p : purchases) cachePendingPurchase(p);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void cachePendingPurchase(Purchase purchase) {
|
||||||
|
if (purchase == null) {
|
||||||
|
Log.w(TAG, "[PAY-FLOW] cachePendingPurchase skipped: purchase is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.i(TAG, "[PAY-FLOW] cachePendingPurchase state=" + purchase.getPurchaseState()
|
||||||
|
+ " orderId=" + purchase.getOrderId() + " token=" + purchase.getToken());
|
||||||
|
if (purchase.getPurchaseState() != 0) return;
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (purchase.getOrderId() != null) result.put("orderId", purchase.getOrderId());
|
||||||
|
if (purchase.getPurchaseJson() != null) result.put("purchaseJson", purchase.getPurchaseJson());
|
||||||
|
if (purchase.getSignature() != null) result.put("signature", purchase.getSignature());
|
||||||
|
if (purchase.getToken() != null) result.put("purchaseToken", purchase.getToken());
|
||||||
|
|
||||||
|
synchronized (pendingPurchases) {
|
||||||
|
String token = purchase.getToken();
|
||||||
|
for (String item : pendingPurchases) {
|
||||||
|
JSONObject cached = new JSONObject(item);
|
||||||
|
if (token != null && token.equals(cached.optString("purchaseToken", null))) {
|
||||||
|
Log.i(TAG, "[PAY-FLOW] pending purchase already cached token=" + token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pendingPurchases.add(result.toString());
|
||||||
|
}
|
||||||
|
Log.i(TAG, "[PAY-FLOW] cached pending purchase: orderId=" + purchase.getOrderId()
|
||||||
|
+ " cachedCount=" + pendingPurchases.size());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "[PAY-FLOW] cachePendingPurchase json error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPendingPurchases() {
|
||||||
|
synchronized (pendingPurchases) {
|
||||||
|
Log.i(TAG, "[PAY-FLOW] getPendingPurchases start cachedCount=" + pendingPurchases.size());
|
||||||
|
JSONArray result = new JSONArray();
|
||||||
|
for (String item : pendingPurchases) {
|
||||||
|
try {
|
||||||
|
result.put(new JSONObject(item));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "[PAY-FLOW] getPendingPurchases json error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pendingPurchases.clear();
|
||||||
|
Log.i(TAG, "[PAY-FLOW] getPendingPurchases count=" + result.length());
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void queryProductDetails(List<String> productIds) {
|
private static void queryProductDetails(List<String> productIds) {
|
||||||
billingService.queryProductDetailsAsync(
|
billingService.queryProductDetailsAsync(
|
||||||
new ProductDetailsParams("inapp", productIds),
|
new ProductDetailsParams("inapp", productIds),
|
||||||
@@ -278,17 +309,17 @@ public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Callbacks to Unity ----
|
private static void sendPayCallback(int code, String errStr, String storeOrderId,
|
||||||
|
|
||||||
private static void sendPayCallback(int code, String errStr,
|
|
||||||
String purchaseJson, String signature, String purchaseToken) {
|
String purchaseJson, String signature, String purchaseToken) {
|
||||||
Log.i(TAG, "[PAY-FLOW] sendPayCallback: code=" + code + " errStr=" + errStr
|
Log.i(TAG, "[PAY-FLOW] sendPayCallback: code=" + code + " errStr=" + errStr
|
||||||
|
+ " storeOrderId=" + storeOrderId
|
||||||
+ " hasPurchaseJson=" + (purchaseJson != null) + " hasSignature=" + (signature != null)
|
+ " hasPurchaseJson=" + (purchaseJson != null) + " hasSignature=" + (signature != null)
|
||||||
+ " hasToken=" + (purchaseToken != null));
|
+ " hasToken=" + (purchaseToken != null));
|
||||||
try {
|
try {
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
result.put("code", code);
|
result.put("code", code);
|
||||||
result.put("errStr", errStr != null ? errStr : "");
|
result.put("errStr", errStr != null ? errStr : "");
|
||||||
|
if (storeOrderId != null) result.put("orderId", storeOrderId);
|
||||||
if (purchaseJson != null) result.put("purchaseJson", purchaseJson);
|
if (purchaseJson != null) result.put("purchaseJson", purchaseJson);
|
||||||
if (signature != null) result.put("signature", signature);
|
if (signature != null) result.put("signature", signature);
|
||||||
if (purchaseToken != null) result.put("purchaseToken", purchaseToken);
|
if (purchaseToken != null) result.put("purchaseToken", purchaseToken);
|
||||||
@@ -318,6 +349,10 @@ public class FlexionSDKHelper implements SDKManager.ISDKHelper {
|
|||||||
(r.getResponseCode() == BillingResults.ResultCode.CONSUME_SUCCESS_CODE ? "ok" : "fail")));
|
(r.getResponseCode() == BillingResults.ResultCode.CONSUME_SUCCESS_CODE ? "ok" : "fail")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void cancelPurchase() {
|
||||||
|
Log.i(TAG, "[PAY-FLOW] cancelPurchase: TODO - dismiss billing dialog");
|
||||||
|
}
|
||||||
|
|
||||||
private static void sendExtensionError(String errStr) {
|
private static void sendExtensionError(String errStr) {
|
||||||
try {
|
try {
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
@@ -16,13 +16,6 @@ android {
|
|||||||
namespace "com.unity3d.player"
|
namespace "com.unity3d.player"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flexion 渠道专用:排除不需要的 AppsFlyer 模块
|
|
||||||
// - purchase-connector: 基于 Google Play Billing,Flexion 不走 GP 计费,没用还增大包
|
|
||||||
// 即使 Unity Android Resolver 下次又把 implementation 行写回来,这里的 exclude 也兜底排除
|
|
||||||
configurations.all {
|
|
||||||
exclude group: 'com.appsflyer', module: 'purchase-connector'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
@@ -82,9 +75,7 @@ dependencies {
|
|||||||
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: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
|
||||||
// Flexion: purchase-connector removed — Flexion does not use Google Play Billing.
|
implementation 'com.appsflyer:purchase-connector:2.2.0' // Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml:8
|
||||||
// Also covered by top-level `configurations.all { exclude ... }` as a safety net.
|
|
||||||
// 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
|
||||||
// Android Resolver Dependencies End
|
// Android Resolver Dependencies End
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.unity3d.player;
|
package com.unity3d.player;
|
||||||
|
|
||||||
public class ChannelHelpers {
|
public class ChannelEntry {
|
||||||
public static final String CHANNEL = "GooglePlay";
|
public static final String CHANNEL = "GooglePlay";
|
||||||
|
|
||||||
static void register() {
|
public static SDKManager.IChannelSDKAdapter createSDKAdapter() {
|
||||||
// GooglePlay uses default behavior, no additional SDKHelper
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String normalizeSkuList(String msg) {
|
public static String normalizeSkuList(String msg) {
|
||||||
@@ -72,7 +72,6 @@ dependencies {
|
|||||||
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**}
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ 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 {
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class ChannelHelpers {
|
public class ChannelEntry {
|
||||||
public static final String CHANNEL = "Rustore";
|
public static final String CHANNEL = "Rustore";
|
||||||
|
|
||||||
static void register() {
|
public static SDKManager.IChannelSDKAdapter createSDKAdapter() {
|
||||||
// Rustore uses default behavior, no additional SDKHelper
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String normalizeSkuList(String msg) {
|
public static String normalizeSkuList(String msg) {
|
||||||
@@ -37,7 +37,7 @@ public class ChannelHelpers {
|
|||||||
}
|
}
|
||||||
return products.toString();
|
return products.toString();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e("ChannelHelpers", "normalizeSkuList error: " + e.getMessage());
|
Log.e("ChannelEntry", "normalizeSkuList error: " + e.getMessage());
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
ExtraPluginCfgs/Android/rustore/baseProjectTemplate.gradle
Normal file
14
ExtraPluginCfgs/Android/rustore/baseProjectTemplate.gradle
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
plugins {
|
||||||
|
// If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity
|
||||||
|
// See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html
|
||||||
|
// See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
|
||||||
|
// To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version
|
||||||
|
id 'com.android.application' version '7.4.2' apply false
|
||||||
|
id 'com.android.library' version '7.4.2' apply false
|
||||||
|
id 'com.google.gms.google-services' version '4.3.3' apply false
|
||||||
|
**BUILD_SCRIPT_DEPS**
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
7
docs/.claude/settings.local.json
Normal file
7
docs/.claude/settings.local.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"WebSearch"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,8 @@ public class ChannelBuildTool
|
|||||||
{
|
{
|
||||||
foreach (var oldAar in Directory.GetFiles(TysdkPlugins, "tuyoosdk_*.aar"))
|
foreach (var oldAar in Directory.GetFiles(TysdkPlugins, "tuyoosdk_*.aar"))
|
||||||
File.Delete(oldAar);
|
File.Delete(oldAar);
|
||||||
|
foreach (var oldJar in Directory.GetFiles(TysdkPlugins, "tuyoosdk_*.jar"))
|
||||||
|
File.Delete(oldJar);
|
||||||
foreach (var aar in Directory.GetFiles(srcAarDir, "*.aar"))
|
foreach (var aar in Directory.GetFiles(srcAarDir, "*.aar"))
|
||||||
{
|
{
|
||||||
var dest = Path.Combine(TysdkPlugins, Path.GetFileName(aar));
|
var dest = Path.Combine(TysdkPlugins, Path.GetFileName(aar));
|
||||||
@@ -53,8 +55,12 @@ public class ChannelBuildTool
|
|||||||
// 2. Clean up previous channel Java files
|
// 2. Clean up previous channel Java files
|
||||||
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "ChannelHelpers.java"))
|
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "ChannelHelpers.java"))
|
||||||
File.Delete(oldJava);
|
File.Delete(oldJava);
|
||||||
|
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "ChannelEntry.java"))
|
||||||
|
File.Delete(oldJava);
|
||||||
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*SDKHelper.java"))
|
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*SDKHelper.java"))
|
||||||
File.Delete(oldJava);
|
File.Delete(oldJava);
|
||||||
|
foreach (var oldJava in Directory.GetFiles(TysdkPlugins, "*SDKService.java"))
|
||||||
|
File.Delete(oldJava);
|
||||||
var oldConfig = Path.Combine(TysdkPlugins, "ConfigManager.java");
|
var oldConfig = Path.Combine(TysdkPlugins, "ConfigManager.java");
|
||||||
if (File.Exists(oldConfig)) File.Delete(oldConfig);
|
if (File.Exists(oldConfig)) File.Delete(oldConfig);
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ dependencies {
|
|||||||
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**}
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ 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 {
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,10 +82,10 @@ 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}";
|
||||||
};
|
};
|
||||||
_loginGuestBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGuest));
|
_loginGuestBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGuest));
|
||||||
_loginGoogleBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGoogle));
|
_loginGoogleBtn.onClick.AddListener(() => OnLogin(EAccoutType.hwGoogle));
|
||||||
@@ -143,7 +143,7 @@ public class SDKTest : MonoBehaviour
|
|||||||
private void UpdateChannelTitle()
|
private void UpdateChannelTitle()
|
||||||
{
|
{
|
||||||
#if UNITY_ANDROID
|
#if UNITY_ANDROID
|
||||||
using (var cls = new AndroidJavaClass("com.unity3d.player.ChannelHelpers"))
|
using (var cls = new AndroidJavaClass("com.unity3d.player.ChannelEntry"))
|
||||||
{
|
{
|
||||||
string channel = cls.GetStatic<string>("CHANNEL");
|
string channel = cls.GetStatic<string>("CHANNEL");
|
||||||
Debug.Log($"[SDKTest] Channel from Java: {channel}");
|
Debug.Log($"[SDKTest] Channel from Java: {channel}");
|
||||||
@@ -237,11 +237,22 @@ public class SDKTest : MonoBehaviour
|
|||||||
var purchaseInfo = new JObject();
|
var purchaseInfo = new JObject();
|
||||||
purchaseInfo["pfid"] = "TestPlayer";
|
purchaseInfo["pfid"] = "TestPlayer";
|
||||||
purchaseInfo["customData"] = "{\"test\":\"test\"}";
|
purchaseInfo["customData"] = "{\"test\":\"test\"}";
|
||||||
|
// purchaseInfo["customData"] ="{\"BuyType\":{\"type\":1,\"ID\":100502,\"key\":null,\"endDay\":0,\"extraPurcheData\":null,\"IsHide\":false},\"IAPID\":302,\"ItemData\":[{\"id\":1005,\"curCount\":22728,\"count\":260}],\"ShowType\":8,\"CONTENT_ID\":\"com.arkgame.ft.pack0499\",\"PRICE\":4.99,\"CURRENCY\":\"USD\",\"ProdPrice\":4.99,\"extraPurcheData\":{\"purchase_count\":9,\"trade_name\":\"商店-钻石直充4.99\",\"trade_type\":\"商店-钻石直充\",\"usd_price\":4.99,\"iap_id\":302,\"drop_id\":1005,\"trade_group\":\"商店\",\"item_1005\":260},\"orderId\":null,\"time\":\"5/20/2026 3:59:07 AM\"}";
|
||||||
purchaseInfo["userId"] = TYSdkFacade.TYAccountInfo.strUserId;
|
purchaseInfo["userId"] = TYSdkFacade.TYAccountInfo.strUserId;
|
||||||
|
|
||||||
PaymentInfo payResult = await TYSdkFacade.Instance.Pay(sku, 1, sku.ProdPrice, purchaseInfo);
|
PaymentInfo payResult = await TYSdkFacade.Instance.Pay(sku, 1, sku.ProdPrice, purchaseInfo);
|
||||||
_messageTxt.text = "\n" + $"Success : {payResult.isSuccess}";
|
_messageTxt.text = "\n" + $"Success : {payResult.isSuccess}";
|
||||||
_messageTxt.text += "\n" + $"message : {payResult.msg}";
|
_messageTxt.text += "\n" + $"message : {payResult.msg}";
|
||||||
|
_messageTxt.text += "\n" + $"orderId : {payResult.orderId}";
|
||||||
|
_messageTxt.text += "\n" + $"storeOrderId : {payResult.storeOrderId}";
|
||||||
|
var consumeToken = payResult.Receipt?.PurchaseToken ?? payResult.purchaseToken;
|
||||||
|
_messageTxt.text += "\n" + $"hasToken : {!string.IsNullOrEmpty(consumeToken)}";
|
||||||
|
if (!string.IsNullOrEmpty(consumeToken))
|
||||||
|
{
|
||||||
|
Debug.Log($"[SDKTest] Consume purchase token after pay result token={consumeToken}");
|
||||||
|
UnityBridgeFunc.ConsumePurchase(consumeToken);
|
||||||
|
_messageTxt.text += "\nconsume requested";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SKUDetail sku = null;
|
SKUDetail sku = null;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.unity3d.player;
|
package com.unity3d.player;
|
||||||
|
|
||||||
public class ChannelHelpers {
|
public class ChannelEntry {
|
||||||
public static final String CHANNEL = "GooglePlay";
|
public static final String CHANNEL = "GooglePlay";
|
||||||
|
|
||||||
static void register() {
|
public static SDKManager.IChannelSDKAdapter createSDKAdapter() {
|
||||||
// GooglePlay uses default behavior, no additional SDKHelper
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String normalizeSkuList(String msg) {
|
public static String normalizeSkuList(String msg) {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 576805d2d0194634b8d235fd6837195e
|
guid: eac9aa9954e93c54fbafd3974ca30a5b
|
||||||
PluginImporter:
|
PluginImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@@ -34,12 +34,10 @@ import com.tuyoo.gamesdk.model.InitParam;
|
|||||||
import com.tuyoo.gamesdk.pay.model.PayType;
|
import com.tuyoo.gamesdk.pay.model.PayType;
|
||||||
import com.tuyoo.gamesdk.util.SDKLog;
|
import com.tuyoo.gamesdk.util.SDKLog;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,57 +55,74 @@ public class SDKManager {
|
|||||||
private static SnsInfo tmpSnsInfo;
|
private static SnsInfo tmpSnsInfo;
|
||||||
private static String channel = "GooglePlay";
|
private static String channel = "GooglePlay";
|
||||||
|
|
||||||
// Channel helper
|
// Channel SDK adapter
|
||||||
public interface ISDKHelper {
|
public interface IChannelSDKAdapter {
|
||||||
void init(Activity activity);
|
void init(Activity activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IPaymentAdapter {
|
||||||
void pay(Activity activity, String productId, String productPrice,
|
void pay(Activity activity, String productId, String productPrice,
|
||||||
String productName, String productCount, String prodorderId,
|
String productName, String productCount, String prodorderId,
|
||||||
String appInfo);
|
String appInfo);
|
||||||
void queryProducts();
|
|
||||||
void consume(String token);
|
void consume(String token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ISDKHelper sdkHelper;
|
public interface IProductQueryAdapter {
|
||||||
|
void queryProducts();
|
||||||
|
void queryProducts(String productIds);
|
||||||
|
}
|
||||||
|
|
||||||
public static void registerHelper(ISDKHelper helper) {
|
public interface IPendingPurchaseAdapter {
|
||||||
sdkHelper = helper;
|
String getPendingPurchases();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IChannelSDKAdapter sdkAdapter;
|
||||||
|
|
||||||
|
public static void queryProductsByIDs(String productIds) {
|
||||||
|
if (sdkAdapter instanceof IProductQueryAdapter) {
|
||||||
|
((IProductQueryAdapter) sdkAdapter).queryProducts(productIds);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.e(TAG, "queryProductsByIDs: no product query adapter");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ConsumePurchase(String token) {
|
public static void ConsumePurchase(String token) {
|
||||||
Log.i(TAG, "ConsumePurchase: token=" + token);
|
Log.i(TAG, "ConsumePurchase: token=" + token);
|
||||||
if (sdkHelper != null) {
|
if (sdkAdapter instanceof IPaymentAdapter) {
|
||||||
sdkHelper.consume(token);
|
((IPaymentAdapter) sdkAdapter).consume(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String GetPendingPurchases() {
|
||||||
|
if (sdkAdapter instanceof IPendingPurchaseAdapter) {
|
||||||
|
return ((IPendingPurchaseAdapter) sdkAdapter).getPendingPurchases();
|
||||||
|
}
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CancelBillingFlow() {
|
||||||
|
Log.w(TAG, "CancelBillingFlow");
|
||||||
|
// FlexionSDKService.cancelPurchase();
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// 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 = ChannelHelpers.CHANNEL;
|
channel = ChannelEntry.CHANNEL;
|
||||||
ChannelHelpers.register();
|
sdkAdapter = ChannelEntry.createSDKAdapter();
|
||||||
|
|
||||||
// var builder = SDKManager.ExtendBuilder()
|
|
||||||
// .WithChannel(SDKManagerExt.CHANNEL)
|
|
||||||
// .WithInit(SDKManagerExt.GetInit())
|
|
||||||
// .WithPay(SDKManagerExt.GetPay())
|
|
||||||
// .WithQuery(SDKManagerExt.GetQuery())
|
|
||||||
// .Builder()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Log.i(TAG, "[CHANNEL-VERIFY] Java InitSDK channel=" + channel
|
Log.i(TAG, "[CHANNEL-VERIFY] Java InitSDK channel=" + channel
|
||||||
+ " fromCSharp=" + ch
|
+ " fromCSharp=" + ch
|
||||||
+ " helper=" + (sdkHelper != null ? sdkHelper.getClass().getSimpleName() : "default"));
|
+ " adapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getSimpleName() : "default"));
|
||||||
|
|
||||||
// Sync channel to C# ChannelConfig
|
// Sync channel to C# ChannelConfig
|
||||||
UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME,
|
UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME,
|
||||||
"SetChannelFromNative", channel);
|
"SetChannelFromNative", channel);
|
||||||
|
|
||||||
// build.init(activity)
|
if (sdkAdapter != null) {
|
||||||
if (sdkHelper != null) {
|
sdkAdapter.init(activity);
|
||||||
sdkHelper.init(activity);
|
|
||||||
} else {
|
} else {
|
||||||
initDefault(activity);
|
initDefault(activity);
|
||||||
}
|
}
|
||||||
@@ -394,7 +409,7 @@ public class SDKManager {
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
public static void UnityKnow(String productId, String productName, String productCount,
|
public static void UnityKnow(String productId, String productName, String productCount,
|
||||||
String prodorderId, String appInfo) {
|
String prodorderId, String appInfo) {
|
||||||
SDKLog.i("UnityKnow : " + productId);
|
SDKLog.i("UnityKnow : " + productId);
|
||||||
HashMap<String, String> extraInfo = new HashMap<String, String>();
|
HashMap<String, String> extraInfo = new HashMap<String, String>();
|
||||||
extraInfo.put("appInfo", appInfo);
|
extraInfo.put("appInfo", appInfo);
|
||||||
@@ -405,8 +420,8 @@ 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) {
|
||||||
if (sdkHelper != null) {
|
if (sdkAdapter instanceof IPaymentAdapter) {
|
||||||
sdkHelper.pay(UnityPlayer.currentActivity, productId, productPrice, productName, productCount, prodorderId, appInfo);
|
((IPaymentAdapter) sdkAdapter).pay(UnityPlayer.currentActivity, productId, productPrice, productName, productCount, prodorderId, appInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PayEventData.PayData payData = new PayEventData.PayData();
|
PayEventData.PayData payData = new PayEventData.PayData();
|
||||||
@@ -430,9 +445,9 @@ public class SDKManager {
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
public static void thirdExtend() {
|
public static void thirdExtend() {
|
||||||
Log.e(TAG, "thirdExtend called, sdkHelper=" + (sdkHelper != null ? sdkHelper.getClass().getSimpleName() : "null"));
|
Log.e(TAG, "thirdExtend called, sdkAdapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getSimpleName() : "null"));
|
||||||
if (sdkHelper != null) {
|
if (sdkAdapter instanceof IProductQueryAdapter) {
|
||||||
sdkHelper.queryProducts();
|
((IProductQueryAdapter) sdkAdapter).queryProducts();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
defaultThirdExtend();
|
defaultThirdExtend();
|
||||||
@@ -454,7 +469,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", ChannelHelpers.normalizeSkuList(msg));
|
result.put("respObj", ChannelEntry.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);
|
||||||
@@ -520,7 +535,7 @@ public class SDKManager {
|
|||||||
case 2: GetGameGa().track(EventType.COIN, eventstr, paramsBuilder); break;
|
case 2: GetGameGa().track(EventType.COIN, eventstr, paramsBuilder); break;
|
||||||
case 3: GetGameGa().track(EventType.PAY, eventstr, paramsBuilder); break;
|
case 3: GetGameGa().track(EventType.PAY, eventstr, paramsBuilder); break;
|
||||||
case 4: GetGameGa().track(EventType.GAME, eventstr, paramsBuilder); break;
|
case 4: GetGameGa().track(EventType.GAME, eventstr, paramsBuilder); break;
|
||||||
case 5: GetGameGa().track(EventType.PAY, eventstr, paramsBuilder); break;
|
case 5: GetGameGa().track(EventType.LOGIN, eventstr, paramsBuilder); break;
|
||||||
case 6: GetGameGa().track(EventType.PUSH, eventstr, paramsBuilder); break;
|
case 6: GetGameGa().track(EventType.PUSH, eventstr, paramsBuilder); break;
|
||||||
case 7: GetGameGa().track(EventType.ADBOX, eventstr, paramsBuilder); break;
|
case 7: GetGameGa().track(EventType.ADBOX, eventstr, paramsBuilder); break;
|
||||||
case 8: GetGameGa().track(EventType.PREFORMANCE, eventstr, paramsBuilder); break;
|
case 8: GetGameGa().track(EventType.PREFORMANCE, eventstr, paramsBuilder); break;
|
||||||
|
|||||||
@@ -1,258 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using asap.core;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Networking;
|
|
||||||
|
|
||||||
namespace tysdk
|
|
||||||
{
|
|
||||||
public interface IPaymentVerifier
|
|
||||||
{
|
|
||||||
Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IPurchaseConsumer
|
|
||||||
{
|
|
||||||
Task<PurchaseConsumeResult> ConsumeAsync(string token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PaymentVerifyResult
|
|
||||||
{
|
|
||||||
public bool success;
|
|
||||||
public string msg;
|
|
||||||
public string orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FlexionOrderResult
|
|
||||||
{
|
|
||||||
public int code { get; set; }
|
|
||||||
public string info { get; set; }
|
|
||||||
public string orderId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PurchaseConsumeResult
|
|
||||||
{
|
|
||||||
public bool success;
|
|
||||||
public string msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PaymentProcessor
|
|
||||||
{
|
|
||||||
public IPaymentVerifier verifier;
|
|
||||||
public IPurchaseConsumer consumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PaymentProcessorFactory
|
|
||||||
{
|
|
||||||
private static PaymentProcessor _processor;
|
|
||||||
private static string _cachedChannel;
|
|
||||||
|
|
||||||
public static PaymentProcessor GetProcessor()
|
|
||||||
{
|
|
||||||
var channel = ChannelConfig.Channel;
|
|
||||||
if (_processor != null && _cachedChannel == channel)
|
|
||||||
return _processor;
|
|
||||||
|
|
||||||
_processor = channel switch
|
|
||||||
{
|
|
||||||
"Flexion" => new PaymentProcessor
|
|
||||||
{
|
|
||||||
verifier = new RetryingPaymentVerifier(new FlexionPaymentVerifier()),
|
|
||||||
consumer = new FlexionPurchaseConsumer()
|
|
||||||
},
|
|
||||||
"Dummy" => new PaymentProcessor
|
|
||||||
{
|
|
||||||
verifier = new RetryingPaymentVerifier(new FakePaymentVerifier()),
|
|
||||||
consumer = new FakePurchaseConsumer()
|
|
||||||
},
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
_cachedChannel = channel;
|
|
||||||
return _processor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RetryingPaymentVerifier : IPaymentVerifier
|
|
||||||
{
|
|
||||||
private readonly IPaymentVerifier _inner;
|
|
||||||
private const int MaxRetries = 2;
|
|
||||||
private static readonly TimeSpan RetryInterval = TimeSpan.FromSeconds(2);
|
|
||||||
|
|
||||||
public RetryingPaymentVerifier(IPaymentVerifier inner)
|
|
||||||
{
|
|
||||||
_inner = inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
|
|
||||||
{
|
|
||||||
PaymentVerifyResult lastResult = null;
|
|
||||||
for (int attempt = 0; attempt <= MaxRetries; attempt++)
|
|
||||||
{
|
|
||||||
if (attempt > 0)
|
|
||||||
{
|
|
||||||
Debug.Log($"[RetryingPaymentVerifier] Retry {attempt}/{MaxRetries}, waiting {RetryInterval.TotalSeconds}s");
|
|
||||||
await Task.Delay(RetryInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastResult = await _inner.VerifyAsync(info);
|
|
||||||
if (lastResult.success) return lastResult;
|
|
||||||
|
|
||||||
Debug.LogWarning($"[RetryingPaymentVerifier] Attempt {attempt + 1} failed: {lastResult.msg}");
|
|
||||||
}
|
|
||||||
return lastResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FlexionPaymentVerifier : IPaymentVerifier
|
|
||||||
{
|
|
||||||
private const string DEFAULT_PAY_VERIFY_URL = "http://192.168.9.91:7036/api/FlexionCallback";
|
|
||||||
|
|
||||||
private readonly string _verifyUrl;
|
|
||||||
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30);
|
|
||||||
|
|
||||||
public FlexionPaymentVerifier()
|
|
||||||
{
|
|
||||||
var config = GContext.container.Resolve<IConfig>();
|
|
||||||
_verifyUrl = config.Get<string>("PAY_VERIFY_URL", DEFAULT_PAY_VERIFY_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[FlexionPaymentVerifier] Editor placeholder: auto success");
|
|
||||||
await Task.Yield();
|
|
||||||
return new PaymentVerifyResult { success = true, msg = "editor_placeholder" };
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
|
|
||||||
{
|
|
||||||
var cts = new CancellationTokenSource(Timeout);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Debug.Log($"[FlexionPaymentVerifier] VerifyAsync start: url={_verifyUrl}");
|
|
||||||
Debug.Log($"[FlexionPaymentVerifier] Verify fields: orderId={info.orderId} productId={info.productId}" +
|
|
||||||
$" hasPurchaseJson={!string.IsNullOrEmpty(info.purchaseJson)} hasSignature={!string.IsNullOrEmpty(info.signature)}" +
|
|
||||||
$" purchaseToken={info.purchaseToken}");
|
|
||||||
|
|
||||||
var body = JsonConvert.SerializeObject(info);
|
|
||||||
Debug.Log("[FlexionPaymentVerifier] Request body: " + body);
|
|
||||||
|
|
||||||
using var req = new UnityWebRequest(_verifyUrl, "POST");
|
|
||||||
req.certificateHandler = new BypassCertificateHandler();
|
|
||||||
req.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
|
|
||||||
req.downloadHandler = new DownloadHandlerBuffer();
|
|
||||||
req.SetRequestHeader("Content-Type", "application/json");
|
|
||||||
|
|
||||||
var tcs = new TaskCompletionSource<PaymentVerifyResult>(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
||||||
cts.Token.Register(() => tcs.TrySetResult(new PaymentVerifyResult { success = false, msg = "timeout" }));
|
|
||||||
|
|
||||||
req.SendWebRequest().completed += _ =>
|
|
||||||
{
|
|
||||||
if (req.result == UnityWebRequest.Result.Success)
|
|
||||||
{
|
|
||||||
var respText = req.downloadHandler.text;
|
|
||||||
Debug.Log("[FlexionPaymentVerifier] Response: " + respText);
|
|
||||||
var orderResult = JsonConvert.DeserializeObject<FlexionOrderResult>(respText);
|
|
||||||
if (orderResult == null)
|
|
||||||
{
|
|
||||||
tcs.TrySetResult(new PaymentVerifyResult { success = false, msg = "parse_error" });
|
|
||||||
}
|
|
||||||
else if (orderResult.code == 0)
|
|
||||||
{
|
|
||||||
tcs.TrySetResult(new PaymentVerifyResult
|
|
||||||
{ success = true, msg = orderResult.info, orderId = orderResult.orderId });
|
|
||||||
}
|
|
||||||
else if (orderResult.code == 1)
|
|
||||||
{
|
|
||||||
tcs.TrySetResult(new PaymentVerifyResult
|
|
||||||
{ success = true, msg = orderResult.info, orderId = orderResult.orderId });
|
|
||||||
}
|
|
||||||
else if (orderResult.code == 2)
|
|
||||||
{
|
|
||||||
tcs.TrySetResult(new PaymentVerifyResult
|
|
||||||
{ success = true, msg = orderResult.info, orderId = orderResult.orderId });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// -1: 公钥/签名/玩家验证失败, -2: 写入失败, -3: 数据解析错误
|
|
||||||
tcs.TrySetResult(new PaymentVerifyResult
|
|
||||||
{ success = false, msg = orderResult.info ?? $"code={orderResult.code}" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[FlexionPaymentVerifier] Failed: " + req.error);
|
|
||||||
tcs.TrySetResult(new PaymentVerifyResult { success = false, msg = req.error });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return await tcs.Task;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError("[FlexionPaymentVerifier] Exception: " + e.Message);
|
|
||||||
return new PaymentVerifyResult { success = false, msg = e.Message };
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
cts.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FlexionPurchaseConsumer : IPurchaseConsumer
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
|
|
||||||
{
|
|
||||||
await Task.Yield();
|
|
||||||
return new PurchaseConsumeResult { success = true, msg = "editor_placeholder" };
|
|
||||||
}
|
|
||||||
#elif UNITY_ANDROID
|
|
||||||
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(token))
|
|
||||||
return new PurchaseConsumeResult { success = false, msg = "empty_token" };
|
|
||||||
|
|
||||||
UnityBridgeFunc.ConsumePurchase(token);
|
|
||||||
await Task.Yield();
|
|
||||||
return new PurchaseConsumeResult { success = true, msg = "consume_requested" };
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
|
|
||||||
{
|
|
||||||
await Task.Yield();
|
|
||||||
return new PurchaseConsumeResult { success = false, msg = "unsupported_platform" };
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FakePaymentVerifier : IPaymentVerifier
|
|
||||||
{
|
|
||||||
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
|
|
||||||
{
|
|
||||||
Debug.Log("[FakePaymentVerifier] Verifying purchase: " + info.orderId);
|
|
||||||
await Task.Delay(500);
|
|
||||||
return new PaymentVerifyResult { success = true, msg = "fake_ok" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FakePurchaseConsumer : IPurchaseConsumer
|
|
||||||
{
|
|
||||||
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
|
|
||||||
{
|
|
||||||
Debug.Log("[FakePurchaseConsumer] Consume: " + token);
|
|
||||||
await Task.Yield();
|
|
||||||
return new PurchaseConsumeResult { success = true, msg = "fake_ok" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class BypassCertificateHandler : CertificateHandler
|
|
||||||
{
|
|
||||||
protected override bool ValidateCertificate(byte[] certificateData) => true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1b7f5b1ccc26bf047b00f9b79d7fa3da
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace tysdk
|
|
||||||
{
|
|
||||||
// TYSdkFacade 的登录/链接/ATT 等方法要依赖这些 POCO。
|
|
||||||
|
|
||||||
public enum EAccoutType
|
|
||||||
{
|
|
||||||
hwGoogle,
|
|
||||||
hwFacebook,
|
|
||||||
hwGuest,
|
|
||||||
hwVkid,
|
|
||||||
Apple,
|
|
||||||
none
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LoginInfo
|
|
||||||
{
|
|
||||||
public bool isSuccess;
|
|
||||||
public int userId;
|
|
||||||
public string StrUserId => userId.ToString();
|
|
||||||
public string msg;
|
|
||||||
public int code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LinkResult
|
|
||||||
{
|
|
||||||
// 0: success, 1: fail, -1 exists
|
|
||||||
public int code;
|
|
||||||
// when success and fail userId is current user
|
|
||||||
// when exists userId is 0
|
|
||||||
public int userId;
|
|
||||||
// not none when exists
|
|
||||||
public Dictionary<string, string> bindInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChangeLinkResult
|
|
||||||
{
|
|
||||||
public int code;
|
|
||||||
public int userId;
|
|
||||||
public string msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LinkCheckInfo
|
|
||||||
{
|
|
||||||
public int code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ATTInfo
|
|
||||||
{
|
|
||||||
public bool isAccepted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2d36f2094aa5783423ab1ef40a88ccbe
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -34,20 +34,13 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, EAccoutType> accoutTypeMap = new Dictionary<string, EAccoutType>()
|
private static Dictionary<string, EAccoutType> accoutTypeMap = new Dictionary<string, EAccoutType>(){
|
||||||
{
|
|
||||||
{"google", EAccoutType.hwGoogle},
|
{"google", EAccoutType.hwGoogle},
|
||||||
{"fb", EAccoutType.hwFacebook},
|
{"fb", EAccoutType.hwFacebook},
|
||||||
{"tyGuest", EAccoutType.hwGuest},
|
{"tyGuest", EAccoutType.hwGuest},
|
||||||
{"ios13", EAccoutType.Apple},
|
{"ios13", EAccoutType.Apple}
|
||||||
{"vk.global.app", EAccoutType.hwVkid},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void AddAccoutType(string key, EAccoutType value)
|
|
||||||
{
|
|
||||||
accoutTypeMap[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static EAccoutType ConvertAccoutType(string accountType)
|
private static EAccoutType ConvertAccoutType(string accountType)
|
||||||
{
|
{
|
||||||
if (accoutTypeMap.ContainsKey(accountType))
|
if (accoutTypeMap.ContainsKey(accountType))
|
||||||
@@ -108,10 +101,12 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================== Singleton ==================
|
private static AccountInfo _accountInfo;
|
||||||
private static TYSdkFacade _instance;
|
|
||||||
public static AccountInfo TYAccountInfo => _accountInfo;
|
public static AccountInfo TYAccountInfo => _accountInfo;
|
||||||
protected static AccountInfo _accountInfo;
|
|
||||||
|
private static TYSdkFacade _instance;
|
||||||
|
public static bool IsSdkInited { get; private set; }
|
||||||
|
public static event System.Action<bool, string> OnInitComplete;
|
||||||
|
|
||||||
public static TYSdkFacade Instance
|
public static TYSdkFacade Instance
|
||||||
{
|
{
|
||||||
@@ -125,47 +120,55 @@ namespace tysdk
|
|||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Channel => ChannelConfig.Channel;
|
|
||||||
|
|
||||||
private int LoginTimeoutSeconds => ChannelConfig.LoginTimeoutSeconds;
|
|
||||||
|
|
||||||
public static bool IsSdkInited { get; private set; }
|
|
||||||
public static event System.Action<bool, string> OnInitComplete;
|
|
||||||
|
|
||||||
// ================== Init ==================
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
|
Debug.Log($"[TYSdkFacade] Init()");
|
||||||
#if UNITY_ANDROID
|
#if UNITY_ANDROID
|
||||||
UnityBridgeFunc.InitSDK();
|
UnityBridgeFunc.InitSDK(ChannelConfig.Channel);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetChannelFromNative(string channel)
|
||||||
|
{
|
||||||
|
Debug.Log($"[TYSdkFacade] SetChannelFromNative: {channel}");
|
||||||
|
ChannelConfig.SetChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitResult(string json)
|
public void InitResult(string json)
|
||||||
{
|
{
|
||||||
var data = Newtonsoft.Json.Linq.JObject.Parse(json);
|
Debug.Log($"[TYSdkFacade] InitResult: {json}");
|
||||||
var code = (int)data["code"];
|
var success = false;
|
||||||
var msg = (string)data["msg"];
|
var msg = string.Empty;
|
||||||
IsSdkInited = code == 0;
|
|
||||||
UnityEngine.Debug.Log($"[TYSdkFacade] InitResult: code={code} msg={msg}");
|
try
|
||||||
OnInitComplete?.Invoke(IsSdkInited, msg);
|
{
|
||||||
|
var data = JObject.Parse(json);
|
||||||
|
success = (int)data["code"] == 0;
|
||||||
|
msg = (string)data["msg"];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
msg = e.Message;
|
||||||
|
Debug.LogWarning($"[TYSdkFacade] InitResult parse failed: {e}");
|
||||||
|
}
|
||||||
|
|
||||||
|
IsSdkInited = success;
|
||||||
|
OnInitComplete?.Invoke(success, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from Java SDKManager.InitSDK to sync channel
|
|
||||||
public void SetChannelFromNative(string ch)
|
|
||||||
{
|
|
||||||
ChannelConfig.SetChannel(ch);
|
|
||||||
UnityEngine.Debug.Log($"[CHANNEL-VERIFY] C# SetChannelFromNative → channel={ch}, payType={ChannelConfig.PayType}, loginTimeout={ChannelConfig.LoginTimeoutSeconds}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*================================================
|
/*================================================
|
||||||
|
|
||||||
_ _
|
_ _
|
||||||
/ \ ___ ___ ___ _ _ _ __ | |_
|
/ \ ___ ___ ___ _ _ _ __ | |_
|
||||||
/ _ \ / __/ __/ _ \| | | | '_ \| __|
|
/ _ \ / __/ __/ _ \| | | | '_ \| __|
|
||||||
/ ___ \ (_| (_| (_) | |_| | | | | |_
|
/ ___ \ (_| (_| (_) | |_| | | | | |_
|
||||||
/_/ \_\___\___\___/ \__,_|_| |_|\__|
|
/_/ \_\___\___\___/ \__,_|_| |_|\__|
|
||||||
|
|
||||||
=================================================*/
|
=================================================*/
|
||||||
|
|
||||||
|
|
||||||
public static bool IsLoggedIn => _accountInfo != null;
|
public static bool IsLoggedIn => _accountInfo != null;
|
||||||
|
|
||||||
public void Logout()
|
public void Logout()
|
||||||
@@ -182,7 +185,7 @@ namespace tysdk
|
|||||||
|
|
||||||
public async Task<LoginInfo> Login(EAccoutType accoutType)
|
public async Task<LoginInfo> Login(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
var deviceId = UnityEngine.Device.SystemInfo.deviceUniqueIdentifier.Split('-')[0].Substring(0, 8);
|
var deviceId = UnityEngine.Device.SystemInfo.deviceUniqueIdentifier.Split('-')[0].Substring(0, 8);
|
||||||
|
|
||||||
@@ -200,25 +203,25 @@ namespace tysdk
|
|||||||
};
|
};
|
||||||
|
|
||||||
#elif UNITY_ANDROID || UNITY_IOS
|
#elif UNITY_ANDROID || UNITY_IOS
|
||||||
var task = TYSDKCallbackManager.Instance.RegisterCallback<LoginInfo>(TimeSpan.FromSeconds(LoginTimeoutSeconds));
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<LoginInfo>(TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
UnityBridgeFunc.UnityLogin(accoutType);
|
UnityBridgeFunc.UnityLogin(accoutType);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var loginInfo = await task;
|
var loginInfo = await task;
|
||||||
if (loginInfo.isSuccess)
|
if(loginInfo.isSuccess)
|
||||||
{
|
{
|
||||||
_accountInfo.channel = accoutType;
|
_accountInfo.channel = accoutType;
|
||||||
_accountInfo.AddLinkedAccount(accoutType);
|
_accountInfo.AddLinkedAccount(accoutType);
|
||||||
_accountInfo.Save();
|
_accountInfo.Save();
|
||||||
}
|
}
|
||||||
return loginInfo;
|
return loginInfo;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"[TYSdkFacade] Login failed: {e}");
|
Debug.LogWarning($"[TYSdkFacade] Login failed: {e}");
|
||||||
return new LoginInfo() { isSuccess = false };
|
return new LoginInfo(){isSuccess = false};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -247,7 +250,7 @@ namespace tysdk
|
|||||||
return new LoginInfo() { isSuccess = false };
|
return new LoginInfo() { isSuccess = false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<LoginInfo> LoginBySns()
|
public async Task<LoginInfo> LoginBySns()
|
||||||
{
|
{
|
||||||
Debug.Log("[TYSdkFacade] LoginBySns");
|
Debug.Log("[TYSdkFacade] LoginBySns");
|
||||||
@@ -332,17 +335,18 @@ namespace tysdk
|
|||||||
UnityBridgeFunc.SetGaUserInfo(strUserId);
|
UnityBridgeFunc.SetGaUserInfo(strUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
|
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
await Task.Delay(300);
|
await Task.Delay(300);
|
||||||
return new LinkResult() { code = 1 };
|
return new LinkResult(){code = 1};
|
||||||
}
|
}
|
||||||
#elif UNITY_IOS || UNITY_ANDROID
|
#elif UNITY_IOS || UNITY_ANDROID
|
||||||
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
|
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
if (_accountInfo == null) return new LinkResult() { code = 1 };
|
if (_accountInfo == null) return new LinkResult(){ code = 1};
|
||||||
if (_accountInfo.linkedAccout.Contains(accoutType)) return new LinkResult() { code = 0 };
|
if (_accountInfo.linkedAccout.Contains(accoutType)) return new LinkResult(){ code = 0};
|
||||||
|
|
||||||
var task = TYSDKCallbackManager.Instance.RegisterCallback<LinkResult>(TimeSpan.FromMinutes(1));
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<LinkResult>(TimeSpan.FromMinutes(1));
|
||||||
UnityBridgeFunc.LinkAccount(accoutType);
|
UnityBridgeFunc.LinkAccount(accoutType);
|
||||||
@@ -364,7 +368,6 @@ namespace tysdk
|
|||||||
return new LinkResult() { code = 1 };
|
return new LinkResult() { code = 1 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
public void LinkAccoutResult(string message)
|
public void LinkAccoutResult(string message)
|
||||||
{
|
{
|
||||||
@@ -387,18 +390,21 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
public void CleanLinkTempSnSInfo()
|
public void CleanLinkTempSnSInfo()
|
||||||
{
|
{
|
||||||
UnityBridgeFunc.CleanLinkTmpSnsInfo();
|
UnityBridgeFunc.CleanLinkTmpSnsInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
public async Task<ChangeLinkResult> ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
|
public async Task<ChangeLinkResult> ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
|
||||||
await Task.Delay(300);
|
await Task.Delay(300);
|
||||||
return new ChangeLinkResult() { code = 1 };
|
return new ChangeLinkResult(){code = 1};
|
||||||
#else
|
}
|
||||||
|
#elif UNITY_IOS || UNITY_ANDROID
|
||||||
|
public async Task<ChangeLinkResult> ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
|
||||||
|
{
|
||||||
var task = TYSDKCallbackManager.Instance.RegisterCallback<ChangeLinkResult>(TimeSpan.FromSeconds(30));
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<ChangeLinkResult>(TimeSpan.FromSeconds(30));
|
||||||
UnityBridgeFunc.ChangeLinkAccount(accoutType, oldUserId, newUserId);
|
UnityBridgeFunc.ChangeLinkAccount(accoutType, oldUserId, newUserId);
|
||||||
try
|
try
|
||||||
@@ -420,8 +426,8 @@ namespace tysdk
|
|||||||
{
|
{
|
||||||
CleanLinkTempSnSInfo();
|
CleanLinkTempSnSInfo();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public void ChangeLinkAccountResult(string message)
|
public void ChangeLinkAccountResult(string message)
|
||||||
{
|
{
|
||||||
@@ -435,6 +441,14 @@ namespace tysdk
|
|||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查是否已经绑定
|
||||||
|
/// <returns>
|
||||||
|
/// 1 已经绑定
|
||||||
|
/// 0 未绑定
|
||||||
|
/// -1 失败
|
||||||
|
/// </returns>
|
||||||
|
/// </summary>
|
||||||
public async Task<bool> LinkCheck(EAccoutType accoutType)
|
public async Task<bool> LinkCheck(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
if (_accountInfo == null) return false;
|
if (_accountInfo == null) return false;
|
||||||
@@ -460,7 +474,7 @@ namespace tysdk
|
|||||||
|
|
||||||
return result.code == 1;
|
return result.code == 1;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"[TYSdkFacade] CheckLinkResult error: {e}");
|
Debug.LogWarning($"[TYSdkFacade] CheckLinkResult error: {e}");
|
||||||
return false;
|
return false;
|
||||||
@@ -482,6 +496,7 @@ namespace tysdk
|
|||||||
IConfig config = GContext.container.Resolve<IConfig>();
|
IConfig config = GContext.container.Resolve<IConfig>();
|
||||||
var tyurl = config.Get<string>("AGG_SERVER", defaultTyurl);
|
var tyurl = config.Get<string>("AGG_SERVER", defaultTyurl);
|
||||||
|
|
||||||
|
|
||||||
string tycs = tyurl == defaultTyurl ?
|
string tycs = tyurl == defaultTyurl ?
|
||||||
"https://hwcsh.tygameworld.com/template/appCancel/note.html"
|
"https://hwcsh.tygameworld.com/template/appCancel/note.html"
|
||||||
:
|
:
|
||||||
@@ -503,12 +518,23 @@ namespace tysdk
|
|||||||
string uid = $"uid={_accountInfo.userId}";
|
string uid = $"uid={_accountInfo.userId}";
|
||||||
list.Add(uid);
|
list.Add(uid);
|
||||||
|
|
||||||
list.Add("roleid=0");
|
string roleid = "roleid=0";
|
||||||
list.Add("gameid=20587");
|
list.Add(roleid);
|
||||||
list.Add("cloudid=128");
|
|
||||||
list.Add("gamename=FishingTravel");
|
string gameid = "gameid=20587";
|
||||||
list.Add("certification=0");
|
list.Add(gameid);
|
||||||
list.Add("ischannel=1");
|
|
||||||
|
string cloudid = "cloudid=128";
|
||||||
|
list.Add(cloudid);
|
||||||
|
|
||||||
|
string gamename = "gamename=FishingTravel";
|
||||||
|
list.Add(gamename);
|
||||||
|
|
||||||
|
string certification = "certification=0";
|
||||||
|
list.Add(certification);
|
||||||
|
|
||||||
|
string ischannel = "ischannel=1";
|
||||||
|
list.Add(ischannel);
|
||||||
|
|
||||||
string tysdktoken = $"tysdktoken={_accountInfo.token}";
|
string tysdktoken = $"tysdktoken={_accountInfo.token}";
|
||||||
list.Add(tysdktoken);
|
list.Add(tysdktoken);
|
||||||
@@ -518,6 +544,7 @@ namespace tysdk
|
|||||||
string listStr = string.Join("&", list.ToArray());
|
string listStr = string.Join("&", list.ToArray());
|
||||||
string sign = listStr +
|
string sign = listStr +
|
||||||
"csh-api-6dfa879490a249be9fbc92e97e4d898d-api-csh";
|
"csh-api-6dfa879490a249be9fbc92e97e4d898d-api-csh";
|
||||||
|
//对sign进行MD5加密
|
||||||
string signMd5 = CalculateMD5Hash(sign);
|
string signMd5 = CalculateMD5Hash(sign);
|
||||||
string url = $"{tycs}?{listStr}&sign={signMd5}&isAbroad=1&lan=en";
|
string url = $"{tycs}?{listStr}&sign={signMd5}&isAbroad=1&lan=en";
|
||||||
Debug.Log($"[TYSdkFacade:Signout] url \n{url}");
|
Debug.Log($"[TYSdkFacade:Signout] url \n{url}");
|
||||||
@@ -526,16 +553,25 @@ namespace tysdk
|
|||||||
|
|
||||||
private string CalculateMD5Hash(string input)
|
private string CalculateMD5Hash(string input)
|
||||||
{
|
{
|
||||||
|
// Create a new instance of the MD5CryptoServiceProvider object.
|
||||||
MD5 md5Hasher = MD5.Create();
|
MD5 md5Hasher = MD5.Create();
|
||||||
|
|
||||||
|
// Convert the input string to a byte array and compute the hash.
|
||||||
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
|
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
|
||||||
|
|
||||||
|
// Create a new Stringbuilder to collect the bytes
|
||||||
|
// and create a string.
|
||||||
StringBuilder sBuilder = new StringBuilder();
|
StringBuilder sBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
// Loop through each byte of the hashed data
|
||||||
|
// and format each one as a hexadecimal string.
|
||||||
for (int i = 0; i < data.Length; i++)
|
for (int i = 0; i < data.Length; i++)
|
||||||
{
|
{
|
||||||
sBuilder.Append(data[i].ToString("x2"));
|
sBuilder.Append(data[i].ToString("x2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the hexadecimal string.
|
||||||
return sBuilder.ToString();
|
return sBuilder.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace tysdk
|
namespace tysdk
|
||||||
{
|
{
|
||||||
public partial class TYSdkFacade
|
public partial class TYSdkFacade : MonoBehaviour
|
||||||
{
|
{
|
||||||
/*================================================
|
/*================================================
|
||||||
|
|
||||||
_ _____ _____
|
_ _____ _____
|
||||||
/ \|_ _|_ _|
|
/ \|_ _|_ _|
|
||||||
/ _ \ | | | |
|
/ _ \ | | | |
|
||||||
/ ___ \| | | |
|
/ ___ \| | | |
|
||||||
/_/ \_\_| |_|
|
/_/ \_\_| |_|
|
||||||
|
|
||||||
=================================================*/
|
=================================================*/
|
||||||
|
|
||||||
public bool IsAttAccepted()
|
public bool IsAttAccepted()
|
||||||
{
|
{
|
||||||
@@ -25,25 +25,25 @@ namespace tysdk
|
|||||||
{
|
{
|
||||||
#if UNITY_EDITOR || UNITY_ANDROID
|
#if UNITY_EDITOR || UNITY_ANDROID
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
return new ATTInfo() { isAccepted = true };
|
|
||||||
|
return new ATTInfo(){isAccepted = true};
|
||||||
#elif UNITY_IOS
|
#elif UNITY_IOS
|
||||||
var task = TYSDKCallbackManager.Instance.RegisterCallback<ATTInfo>();
|
var task = tysdk.TYSDKCallbackManager.Instance.RegisterCallback<ATTInfo>();
|
||||||
UnityBridgeFunc.RequestATT();
|
UnityBridgeFunc.RequestATT();
|
||||||
try
|
try{
|
||||||
{
|
return await task;
|
||||||
return await task;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogWarning(e.Message);
|
Debug.LogWarning(e.Message);
|
||||||
return new ATTInfo() { isAccepted = false };
|
return new ATTInfo(){isAccepted = false};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestATTResult(string r)
|
public void RequestATTResult(string r)
|
||||||
{
|
{
|
||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(new ATTInfo() { isAccepted = r == "1" });
|
TYSDKCallbackManager.Instance.TryTriggerCallback(new ATTInfo(){isAccepted = r == "1"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace tysdk
|
namespace tysdk
|
||||||
{
|
{
|
||||||
public partial class TYSdkFacade
|
public partial class TYSdkFacade : MonoBehaviour
|
||||||
{
|
{
|
||||||
/*================================================
|
/*================================================
|
||||||
|
|
||||||
_____ _ _____ _
|
_____ _ _____ _
|
||||||
| ____|_ _____ _ __ | |_ |_ _| __ __ _ ___| | __
|
| ____|_ _____ _ __ | |_ |_ _| __ __ _ ___| | __
|
||||||
| _| \ \ / / _ \ '_ \| __| | || '__/ _` |/ __| |/ /
|
| _| \ \ / / _ \ '_ \| __| | || '__/ _` |/ __| |/ /
|
||||||
| |___ \ V / __/ | | | |_ | || | | (_| | (__| <
|
| |___ \ V / __/ | | | |_ | || | | (_| | (__| <
|
||||||
|_____| \_/ \___|_| |_|\__| |_||_| \__,_|\___|_|\_\
|
|_____| \_/ \___|_| |_|\__| |_||_| \__,_|\___|_|\_\
|
||||||
|
|
||||||
=================================================*/
|
=================================================*/
|
||||||
@@ -21,18 +21,18 @@ namespace tysdk
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum GATrackType
|
public enum GATrackType
|
||||||
{
|
{
|
||||||
GA_TRACK = 1,
|
GA_TRACK = 1, //默认类型
|
||||||
GA_CION = 2,
|
GA_CION = 2, //金流相关事件
|
||||||
GA_PAY = 3,
|
GA_PAY = 3, //支付相关事件
|
||||||
GA_GAME = 4,
|
GA_GAME = 4, //游戏行为
|
||||||
GA_LOGIN = 5,
|
GA_LOGIN = 5, //登录注册相关事件
|
||||||
GA_PUSH = 6,
|
GA_PUSH = 6, //推送相关事件
|
||||||
GA_ADBOX = 7,
|
GA_ADBOX = 7, //adbox相关事件
|
||||||
GA_PREFORMANCE = 8,
|
GA_PREFORMANCE = 8, //性能上报相关事件
|
||||||
GA_SDK = 9,
|
GA_SDK = 9, //SDK相关事件
|
||||||
GA_ABTest = 10,
|
GA_ABTest = 10, //abtest相关事件
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,30 +8,33 @@ using System.Text;
|
|||||||
|
|
||||||
namespace tysdk
|
namespace tysdk
|
||||||
{
|
{
|
||||||
public partial class TYSdkFacade
|
public partial class TYSdkFacade : MonoBehaviour
|
||||||
{
|
{
|
||||||
/*================================================
|
/*================================================
|
||||||
|
|
||||||
____ _
|
____ _
|
||||||
| _ \ __ _ _ _ _ __ ___ ___ _ __ | |_
|
| _ \ __ _ _ _ _ __ ___ ___ _ __ | |_
|
||||||
| |_) / _` | | | | '_ ` _ \ / _ \ '_ \| __|
|
| |_) / _` | | | | '_ ` _ \ / _ \ '_ \| __|
|
||||||
| __/ (_| | |_| | | | | | | __/ | | | |_
|
| __/ (_| | |_| | | | | | | __/ | | | |_
|
||||||
|_| \__,_|\__, |_| |_| |_|\___|_| |_|\__|
|
|_| \__,_|\__, |_| |_| |_|\___|_| |_|\__|
|
||||||
|___/
|
|___/
|
||||||
=================================================*/
|
=================================================*/
|
||||||
|
|
||||||
private bool _payFirstNegativeHandled;
|
private bool _payFirstNegativeHandled;
|
||||||
|
|
||||||
|
//public async Task<PaymentInfo> Pay(string prodId, string prodPrice, string prodName, int count, string pType, string price_amount_micros =null)
|
||||||
public async Task<PaymentInfo> Pay(SKUDetail prod, int count, float usdprice, JObject purchaseInfo)
|
public async Task<PaymentInfo> Pay(SKUDetail prod, int count, float usdprice, JObject purchaseInfo)
|
||||||
{
|
{
|
||||||
if (!IsLoggedIn) return new PaymentInfo() { code = "-1", msg = "未登录" };
|
if (!IsLoggedIn) return new PaymentInfo() { code = "-1", msg = "未登录" };
|
||||||
|
|
||||||
var orderId = System.Guid.NewGuid().ToString();
|
var orderId = System.Guid.NewGuid().ToString();
|
||||||
|
|
||||||
if (purchaseInfo == null)
|
if(purchaseInfo == null)
|
||||||
purchaseInfo = new JObject();
|
purchaseInfo = new JObject();
|
||||||
|
|
||||||
|
purchaseInfo["orderId"] = orderId;
|
||||||
string extraInfo = purchaseInfo.ToString(Newtonsoft.Json.Formatting.None);
|
string extraInfo = purchaseInfo.ToString(Newtonsoft.Json.Formatting.None);
|
||||||
|
//to base64
|
||||||
extraInfo = Convert.ToBase64String(Encoding.UTF8.GetBytes(extraInfo));
|
extraInfo = Convert.ToBase64String(Encoding.UTF8.GetBytes(extraInfo));
|
||||||
Debug.Log("[TYSdk] extraInfo: " + extraInfo);
|
Debug.Log("[TYSdk] extraInfo: " + extraInfo);
|
||||||
var prodId = prod.ProdID;
|
var prodId = prod.ProdID;
|
||||||
@@ -59,7 +62,7 @@ namespace tysdk
|
|||||||
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromSeconds(90));
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromSeconds(90));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo, pType);
|
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo,pType);
|
||||||
var result = await task;
|
var result = await task;
|
||||||
result.count = count;
|
result.count = count;
|
||||||
result.orderId = orderId;
|
result.orderId = orderId;
|
||||||
@@ -103,6 +106,7 @@ namespace tysdk
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//支付的回调
|
||||||
public void PayResult(string json)
|
public void PayResult(string json)
|
||||||
{
|
{
|
||||||
Debug.Log("[TYSdkFacade] pay callback:" + json);
|
Debug.Log("[TYSdkFacade] pay callback:" + json);
|
||||||
@@ -110,11 +114,25 @@ namespace tysdk
|
|||||||
var result = new PaymentInfo();
|
var result = new PaymentInfo();
|
||||||
result.code = jresult["code"].ToString();
|
result.code = jresult["code"].ToString();
|
||||||
result.msg = jresult["errStr"].ToString();
|
result.msg = jresult["errStr"].ToString();
|
||||||
result.purchaseJson = jresult["purchaseJson"]?.ToString();
|
var purchaseJson = jresult["purchaseJson"]?.ToString();
|
||||||
result.signature = jresult["signature"]?.ToString();
|
var signature = jresult["signature"]?.ToString();
|
||||||
result.purchaseToken = jresult["purchaseToken"]?.ToString();
|
var purchaseToken = jresult["purchaseToken"]?.ToString();
|
||||||
|
result.purchaseJson = purchaseJson;
|
||||||
|
result.signature = signature;
|
||||||
|
result.purchaseToken = purchaseToken;
|
||||||
|
if (!string.IsNullOrEmpty(purchaseJson) || !string.IsNullOrEmpty(purchaseToken))
|
||||||
|
{
|
||||||
|
result.Receipt = new PaymentReceipt
|
||||||
|
{
|
||||||
|
Provider = PaymentReceiptProvider.Flexion,
|
||||||
|
PurchaseJson = purchaseJson,
|
||||||
|
Signature = signature,
|
||||||
|
PurchaseToken = purchaseToken
|
||||||
|
};
|
||||||
|
}
|
||||||
|
result.storeOrderId = jresult["orderId"]?.ToString();
|
||||||
result.userId = _accountInfo?.strUserId;
|
result.userId = _accountInfo?.strUserId;
|
||||||
if (result.code == "-1")
|
if(result.code == "-1")
|
||||||
{
|
{
|
||||||
if (!_payFirstNegativeHandled)
|
if (!_payFirstNegativeHandled)
|
||||||
{
|
{
|
||||||
@@ -128,60 +146,15 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var processor = PaymentProcessorFactory.GetProcessor();
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
if (processor?.verifier != null && !string.IsNullOrEmpty(result.purchaseJson))
|
|
||||||
{
|
|
||||||
_VerifyPurchase(result, processor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void _VerifyPurchase(PaymentInfo result, PaymentProcessor processor)
|
|
||||||
{
|
|
||||||
TYSDKCallbackManager.Instance.ResetCallbackTimeout<PaymentInfo>(TimeSpan.FromSeconds(60));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var verifyResult = await processor.verifier.VerifyAsync(result);
|
|
||||||
if (verifyResult.success)
|
|
||||||
{
|
|
||||||
result.verified = true;
|
|
||||||
if (!string.IsNullOrEmpty(verifyResult.orderId))
|
|
||||||
result.serverOrderId = verifyResult.orderId;
|
|
||||||
if (processor.consumer != null && !string.IsNullOrEmpty(result.purchaseToken))
|
|
||||||
{
|
|
||||||
var consumeResult = await processor.consumer.ConsumeAsync(result.purchaseToken);
|
|
||||||
if (!consumeResult.success)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[TYSdkFacade] Purchase consume failed: " + consumeResult.msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[TYSdkFacade] Payment verification failed: " + verifyResult.msg);
|
|
||||||
result.code = "-1";
|
|
||||||
result.msg = "verification_failed: " + verifyResult.msg;
|
|
||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError("[TYSdkFacade] Verification exception: " + e.Message);
|
|
||||||
result.code = "-1";
|
|
||||||
result.msg = "verification_error: " + e.Message;
|
|
||||||
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get Pay list
|
||||||
public async Task<ProductListInfo> GetSKUList()
|
public async Task<ProductListInfo> GetSKUList()
|
||||||
{
|
{
|
||||||
if (!IsLoggedIn) return new ProductListInfo() { code = -1, msg = "未登录" };
|
if (!IsLoggedIn) return new ProductListInfo() { code = -1, msg = "未登录" };
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
|
|
||||||
var result = new ProductListInfo();
|
var result = new ProductListInfo();
|
||||||
@@ -194,6 +167,25 @@ namespace tysdk
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//通过商品ID列表获取商品详情(Flexion 渠道使用)
|
||||||
|
public async Task<ProductListInfo> GetSKUListByIapIds(string productIds)
|
||||||
|
{
|
||||||
|
if (!IsLoggedIn) return new ProductListInfo() { code = -1, msg = "未登录" };
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
await Task.Yield();
|
||||||
|
return new ProductListInfo();
|
||||||
|
#elif UNITY_ANDROID
|
||||||
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<ProductListInfo>();
|
||||||
|
UnityBridgeFunc.GetSKUListByIapIds(productIds);
|
||||||
|
var result = await task;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
return new ProductListInfo() { code = -1, msg = "unsupported platform" };
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//商品列表的回调
|
||||||
public void SKUListResult(string json)
|
public void SKUListResult(string json)
|
||||||
{
|
{
|
||||||
Debug.Log("[TYSdkFacade] GetSKUList callback");
|
Debug.Log("[TYSdkFacade] GetSKUList callback");
|
||||||
@@ -216,3 +208,7 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,82 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace tysdk
|
namespace tysdk
|
||||||
{
|
{
|
||||||
|
public enum EAccoutType
|
||||||
|
{
|
||||||
|
hwGoogle,
|
||||||
|
hwFacebook,
|
||||||
|
hwGuest,
|
||||||
|
hwVkid,
|
||||||
|
Apple,
|
||||||
|
none
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PaymentReceiptProvider
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Flexion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PaymentReceipt
|
||||||
|
{
|
||||||
|
public PaymentReceiptProvider Provider;
|
||||||
|
public string PurchaseJson;
|
||||||
|
public string Signature;
|
||||||
|
public string PurchaseToken;
|
||||||
|
|
||||||
|
public bool HasPayload => !string.IsNullOrEmpty(PurchaseJson);
|
||||||
|
public bool CanConsume => !string.IsNullOrEmpty(PurchaseToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PaymentReceiptVerification
|
||||||
|
{
|
||||||
|
public bool Verified;
|
||||||
|
public string ServerOrderId;
|
||||||
|
public int ProviderCode;
|
||||||
|
public string ProviderMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LoginInfo
|
||||||
|
{
|
||||||
|
public bool isSuccess;
|
||||||
|
public int userId;
|
||||||
|
public string StrUserId => userId.ToString();
|
||||||
|
public string msg;
|
||||||
|
public int code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LinkResult
|
||||||
|
{
|
||||||
|
// 0: success, 1: fail, -1 exists
|
||||||
|
public int code;
|
||||||
|
// when success and fail userId is current user
|
||||||
|
// when exists userId is 0
|
||||||
|
public int userId;
|
||||||
|
// not none when exists
|
||||||
|
public Dictionary<string, string> bindInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ChangeLinkResult
|
||||||
|
{
|
||||||
|
public int code;
|
||||||
|
public int userId;
|
||||||
|
public string msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LinkCheckInfo
|
||||||
|
{
|
||||||
|
public int code;
|
||||||
|
}
|
||||||
|
|
||||||
public class PaymentInfo
|
public class PaymentInfo
|
||||||
{
|
{
|
||||||
public bool isSuccessFromSdk => code == "0";
|
public bool isSuccessFromSdk => code == "0";
|
||||||
public bool isSuccess => isSuccessFromSdk && confirmed;
|
public bool isSuccess => isSuccessFromSdk && confirmed;
|
||||||
private bool confirmed { get; set; } = false;
|
private bool confirmed {get; set;} = false;
|
||||||
public int count;
|
public int count;
|
||||||
public string orderId;
|
public string orderId;
|
||||||
public string productId;
|
public string productId;
|
||||||
@@ -17,6 +85,8 @@ namespace tysdk
|
|||||||
public string code;
|
public string code;
|
||||||
public string msg;
|
public string msg;
|
||||||
|
|
||||||
|
// Compatibility fields for legacy server payload and existing call sites.
|
||||||
|
// New payment flow should read receipt data from Receipt.
|
||||||
// Flexion: purchase.getOriginalJson(), used by server for RSA signature verification
|
// Flexion: purchase.getOriginalJson(), used by server for RSA signature verification
|
||||||
public string purchaseJson;
|
public string purchaseJson;
|
||||||
// Flexion: purchase.getSignature(), used by server for RSA signature verification
|
// Flexion: purchase.getSignature(), used by server for RSA signature verification
|
||||||
@@ -24,6 +94,21 @@ namespace tysdk
|
|||||||
// Flexion: purchase token, used to consume after server verification
|
// Flexion: purchase token, used to consume after server verification
|
||||||
public string purchaseToken;
|
public string purchaseToken;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public PaymentReceipt Receipt;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public PaymentReceiptVerification ReceiptVerification;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool HasReceipt => Receipt != null && Receipt.HasPayload;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool CanConsumeReceipt => Receipt != null && Receipt.CanConsume;
|
||||||
|
|
||||||
|
// Store order ID from Flexion SDK (e.g. GPA.xxx)
|
||||||
|
public string storeOrderId;
|
||||||
|
|
||||||
public bool verified;
|
public bool verified;
|
||||||
|
|
||||||
// Server-side order ID returned from verification
|
// Server-side order ID returned from verification
|
||||||
@@ -36,17 +121,17 @@ namespace tysdk
|
|||||||
{
|
{
|
||||||
confirmed = orderId == this.orderId && productId == this.productId;
|
confirmed = orderId == this.orderId && productId == this.productId;
|
||||||
|
|
||||||
if (!confirmed)
|
if(!confirmed)
|
||||||
UnityEngine.Debug.LogWarning("[TYSdk Pay] order not confirmed");
|
UnityEngine.Debug.LogWarning("[TYSdk Pay] order not confirmed");
|
||||||
return confirmed;
|
return confirmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return JsonConvert.SerializeObject(this);
|
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProductListInfo
|
public class ProductListInfo
|
||||||
{
|
{
|
||||||
public int code = 1;
|
public int code = 1;
|
||||||
@@ -70,6 +155,7 @@ namespace tysdk
|
|||||||
products = prodList;
|
products = prodList;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_IOS
|
#if UNITY_IOS
|
||||||
@@ -90,7 +176,7 @@ namespace tysdk
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return JsonConvert.SerializeObject(this);
|
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -98,24 +184,37 @@ namespace tysdk
|
|||||||
{
|
{
|
||||||
public string description;
|
public string description;
|
||||||
public string ourProductId;
|
public string ourProductId;
|
||||||
public string productId;
|
|
||||||
public string price;
|
public string price;
|
||||||
public string price_amount_micros;
|
public string price_amount_micros;
|
||||||
public string price_currency_code;
|
public string price_currency_code;
|
||||||
|
public string productId;
|
||||||
public string title;
|
public string title;
|
||||||
public string type;
|
public string type;
|
||||||
public string currency;
|
public string currency;
|
||||||
public string price_amount;
|
public string price_amount;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||||
|
}
|
||||||
|
|
||||||
public string ProdPriceStr => price;
|
public string ProdPriceStr => price;
|
||||||
public float ProdPrice => float.Parse(price_amount_micros) / 1000000;
|
public float ProdPrice => float.Parse(price_amount_micros) / 1000000;
|
||||||
public string ProdID => ourProductId;
|
public string ProdID => ourProductId;
|
||||||
public string ProdKey => productId;
|
public string ProdKey => productId;
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return JsonConvert.SerializeObject(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public class ATTInfo
|
||||||
|
{
|
||||||
|
public bool isAccepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FlexionOrderResult
|
||||||
|
{
|
||||||
|
public int code { get; set; }
|
||||||
|
public string info { get; set; }
|
||||||
|
public string orderId { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,87 +4,96 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace tysdk
|
namespace tysdk
|
||||||
{
|
{
|
||||||
|
|
||||||
public static class UnityBridgeFunc
|
public static class UnityBridgeFunc
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
|
||||||
public static void InitSDK() { }
|
#if UNITY_EDITOR
|
||||||
|
//初始化sdk
|
||||||
|
public static void InitSDK(string channel){}
|
||||||
|
|
||||||
public static void UnityResetServerUrl(string url) { }
|
//更新登录支付域名
|
||||||
|
public static void UnityResetServerUrl(string url){}
|
||||||
|
|
||||||
public static void UnityLoginByTokenFun(string token) { }
|
//登录
|
||||||
|
public static void UnityLoginByTokenFun(string token){}
|
||||||
|
|
||||||
public static string UnityLoginBySnsInfoFun() => null;
|
public static string UnityLoginBySnsInfoFun() => null;
|
||||||
|
|
||||||
public static void UnityLogin(EAccoutType accoutType) { }
|
public static void UnityLogin(EAccoutType accoutType){}
|
||||||
|
|
||||||
public static void CleanLinkTmpSnsInfo() { }
|
public static void CleanLinkTmpSnsInfo() { }
|
||||||
|
|
||||||
public static void LinkAccount(EAccoutType accoutType) { }
|
|
||||||
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId) { }
|
|
||||||
public static void LinkCheck(EAccoutType accoutType) { }
|
|
||||||
|
|
||||||
public static void UnityGetIdentityFun(string type) { }
|
public static void LinkAccount(EAccoutType accoutType){}
|
||||||
|
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId){}
|
||||||
|
public static void LinkCheck(EAccoutType accoutType){}
|
||||||
|
|
||||||
public static void UnityLogOutByChannel(EAccoutType accoutType) { }
|
public static void UnityGetIdentityFun(string type){}
|
||||||
|
|
||||||
|
public static void UnityLogOutByChannel(EAccoutType accoutType){}
|
||||||
|
//支付new
|
||||||
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 pType) { }
|
string productCount, string prodorderId, string appInfo, string pType) { }
|
||||||
|
|
||||||
|
//支付
|
||||||
|
|
||||||
public static void UnityKnow(String productId, String productName, String productCount,
|
public static void UnityKnow(String productId, String productName, String productCount,
|
||||||
String prodorderId, String appInfo) { }
|
String prodorderId, String appInfo) {}
|
||||||
|
|
||||||
|
//获取商品列表
|
||||||
public static void GetSKUList() { }
|
public static void GetSKUList() { }
|
||||||
|
|
||||||
public static void SetGaUserInfo(string userId) { }
|
|
||||||
|
|
||||||
public static void SetGaCommonInfo(string SetGaCommonInfo) { }
|
|
||||||
|
|
||||||
public static void GAReportParams(int type, string eventstr, string paramstr) { }
|
|
||||||
|
|
||||||
public static void RequestATT() { }
|
|
||||||
|
|
||||||
public static int GetATT() { return 1; }
|
|
||||||
|
|
||||||
public static void Review() { }
|
|
||||||
|
|
||||||
public static void ConsumePurchase(string token) { }
|
public static void ConsumePurchase(string token) { }
|
||||||
|
|
||||||
|
public static string GetPendingPurchases() => "[]";
|
||||||
|
|
||||||
|
//打点
|
||||||
|
public static void SetGaUserInfo(string userId){}
|
||||||
|
public static void SetGaCommonInfo(string SetGaCommonInfo){}
|
||||||
|
|
||||||
|
public static void GAReportParams(int type, string eventstr, string paramstr){}
|
||||||
|
|
||||||
|
//ATT
|
||||||
|
public static void RequestATT(){}
|
||||||
|
|
||||||
|
public static int GetATT() {return 1;}
|
||||||
|
|
||||||
|
public static void Review() { }
|
||||||
|
|
||||||
public static void FBShareLink(string title, string content, string url) { }
|
public static void FBShareLink(string title, string content, string url) { }
|
||||||
public static void MessengerShareLink(string title, string content, string url) { }
|
public static void MessengerShareLink(string title, string content, string url) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#elif UNITY_ANDROID
|
#elif UNITY_ANDROID
|
||||||
|
|
||||||
private static string SDK_CLASS = "com.unity3d.player.SDKManager";
|
private static string SDK_CLASS = "com.unity3d.player.SDKManager";
|
||||||
|
|
||||||
private static string EAccountTypeToStr(EAccoutType accoutType)
|
//初始化sdk
|
||||||
{
|
public static void InitSDK(string channel){
|
||||||
return accoutType == EAccoutType.hwVkid ? "vk.global.app" : accoutType.ToString();
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
}
|
|
||||||
|
|
||||||
public static void InitSDK()
|
|
||||||
{
|
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
{
|
||||||
using (var activityCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
using(var activityCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
||||||
{
|
{
|
||||||
var activity = activityCls.GetStatic<AndroidJavaObject>("currentActivity");
|
var activity = activityCls.GetStatic<AndroidJavaObject>("currentActivity");
|
||||||
UnityEngine.Debug.Log("[CHANNEL-VERIFY] C# InitSDK → ChannelConfig.Channel=" + ChannelConfig.Channel);
|
sdkManager.CallStatic("InitSDK", activity, channel);
|
||||||
sdkManager.CallStatic("InitSDK", activity, ChannelConfig.Channel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//更新登录支付域名
|
||||||
public static void UnityResetServerUrl(string url)
|
public static void UnityResetServerUrl(string url)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("UnityResetServerUrl", url);
|
sdkManager.CallStatic("UnityResetServerUrl", url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//登录
|
||||||
public static void UnityLoginByTokenFun(string token)
|
public static void UnityLoginByTokenFun(string token)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("UnityLoginByTokenFun", token);
|
sdkManager.CallStatic("UnityLoginByTokenFun", token);
|
||||||
}
|
}
|
||||||
@@ -92,7 +101,7 @@ namespace tysdk
|
|||||||
|
|
||||||
public static String UnityLoginBySnsInfoFun()
|
public static String UnityLoginBySnsInfoFun()
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
return sdkManager.CallStatic<string>("UnityLoginBySnsInfo");
|
return sdkManager.CallStatic<string>("UnityLoginBySnsInfo");
|
||||||
}
|
}
|
||||||
@@ -100,16 +109,15 @@ namespace tysdk
|
|||||||
|
|
||||||
public static void UnityLogin(EAccoutType accoutType)
|
public static void UnityLogin(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
var accountInfo = EAccountTypeToStr(accoutType);
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("UnityLogin", accountInfo);
|
sdkManager.CallStatic("UnityLogin", accoutType.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnityGetIdentityFun(string type)
|
public static void UnityGetIdentityFun(string type)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("UnityGetIdentityFun", type);
|
sdkManager.CallStatic("UnityGetIdentityFun", type);
|
||||||
}
|
}
|
||||||
@@ -117,87 +125,118 @@ namespace tysdk
|
|||||||
|
|
||||||
public static void UnityLogOutByChannel(EAccoutType accoutType)
|
public static void UnityLogOutByChannel(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
var accountInfo = EAccountTypeToStr(accoutType);
|
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("UnityLogOutByChannel", accountInfo);
|
sdkManager.CallStatic("UnityLogOutByChannel", accoutType.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LinkAccount(EAccoutType accoutType)
|
public static void LinkAccount(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
string userId = TYSdkFacade.TYAccountInfo.strUserId;
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
var accountInfo = EAccountTypeToStr(accoutType);
|
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("LinkAccount", accountInfo, userId);
|
string userId = TYSdkFacade.TYAccountInfo.strUserId;
|
||||||
|
sdkManager.CallStatic("LinkAccount", accoutType.ToString(), userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CleanLinkTmpSnsInfo()
|
public static void CleanLinkTmpSnsInfo(){
|
||||||
{
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("CleanLinkTmpSnsInfo");
|
using(var activityCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
||||||
|
{
|
||||||
|
sdkManager.CallStatic("CleanLinkTmpSnsInfo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
|
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
|
||||||
{
|
{
|
||||||
var accountInfo = EAccountTypeToStr(accoutType);
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("ChangeLinkAccount", accountInfo, oldUserId, newUserId);
|
sdkManager.CallStatic("ChangeLinkAccount", accoutType.ToString(), oldUserId, newUserId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LinkCheck(EAccoutType accoutType)
|
public static void LinkCheck(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
var accountInfo = EAccountTypeToStr(accoutType);
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("LinkCheck", accountInfo);
|
sdkManager.CallStatic("LinkCheck", accoutType.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//支付new
|
||||||
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 pType)
|
string productCount, string prodorderId, string appInfo,string pType)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("UnityKnowNew", productId, productPrice, productName,
|
sdkManager.CallStatic("UnityKnowNew", productId, productPrice, productName,
|
||||||
productCount, prodorderId, appInfo, pType);
|
productCount, prodorderId, appInfo,pType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ConsumePurchase(string token)
|
//支付
|
||||||
|
|
||||||
|
public static void UnityKnow(String productId, String productName, String productCount, String prodorderId, String appInfo)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("ConsumePurchase", token);
|
sdkManager.CallStatic("UnityKnow", productId, productName, productCount, prodorderId, appInfo);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UnityKnow(String productId, String productName, String productCount, String prodorderId, String appInfo)
|
|
||||||
{
|
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
|
||||||
{
|
|
||||||
sdkManager.CallStatic("UnityKnow", productId, productName, productCount, prodorderId, appInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取商品列表
|
||||||
public static void GetSKUList()
|
public static void GetSKUList()
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.Log("UnityBridgeFunc.GetSKUList()");
|
UnityEngine.Debug.Log("UnityBridgeFunc.GetSKUList()");
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("thirdExtend");
|
sdkManager.CallStatic("thirdExtend");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//通过商品ID列表获取商品详情(Flexion 渠道使用)
|
||||||
|
public static void GetSKUListByIapIds(string productIds)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log("UnityBridgeFunc.GetSKUListByIapIds(productIds)");
|
||||||
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
|
{
|
||||||
|
sdkManager.CallStatic("queryProductsByIDs", productIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConsumePurchase(string token)
|
||||||
|
{
|
||||||
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
|
{
|
||||||
|
sdkManager.CallStatic("ConsumePurchase", token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetPendingPurchases()
|
||||||
|
{
|
||||||
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
|
{
|
||||||
|
return sdkManager.CallStatic<string>("GetPendingPurchases");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CancelBillingFlow()
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log("UnityBridgeFunc.CancelBillingFlow");
|
||||||
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
|
{
|
||||||
|
sdkManager.CallStatic("CancelBillingFlow");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//打点
|
||||||
public static void SetGaUserInfo(string userId)
|
public static void SetGaUserInfo(string userId)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("SetGaUserInfo", userId);
|
sdkManager.CallStatic("SetGaUserInfo", userId);
|
||||||
}
|
}
|
||||||
@@ -205,7 +244,7 @@ namespace tysdk
|
|||||||
|
|
||||||
public static void SetGaCommonInfo(string SetGaCommonInfo)
|
public static void SetGaCommonInfo(string SetGaCommonInfo)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("SetGaCommonInfo", SetGaCommonInfo);
|
sdkManager.CallStatic("SetGaCommonInfo", SetGaCommonInfo);
|
||||||
}
|
}
|
||||||
@@ -213,35 +252,37 @@ namespace tysdk
|
|||||||
|
|
||||||
public static void GAReportParams(int type, string eventstr, string paramstr)
|
public static void GAReportParams(int type, string eventstr, string paramstr)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("GAReportParams", type, eventstr, paramstr);
|
sdkManager.CallStatic("GAReportParams", type, eventstr, paramstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RequestATT() { }
|
|
||||||
|
|
||||||
public static int GetATT() { return 1; }
|
//ATT
|
||||||
|
public static void RequestATT(){}
|
||||||
|
|
||||||
|
public static int GetATT() {return 1;}
|
||||||
|
|
||||||
public static void Review()
|
public static void Review()
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("Review");
|
sdkManager.CallStatic("Review");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FBShareLink(string title, string content, string url)
|
public static void FBShareLink(string title, string content, string url)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("FBShareLink", title, content, url);
|
sdkManager.CallStatic("FBShareLink", title, content, url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MessengerShareLink(string title, string content, string url)
|
public static void MessengerShareLink(string title, string content, string url)
|
||||||
{
|
{
|
||||||
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
|
||||||
{
|
{
|
||||||
sdkManager.CallStatic("MessengerShareLink", title, content, url);
|
sdkManager.CallStatic("MessengerShareLink", title, content, url);
|
||||||
}
|
}
|
||||||
@@ -249,9 +290,11 @@ namespace tysdk
|
|||||||
|
|
||||||
#elif UNITY_IOS
|
#elif UNITY_IOS
|
||||||
|
|
||||||
|
//更新登录支付域名
|
||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void UnityResetServerUrl(string url);
|
public static extern void UnityResetServerUrl(string url);
|
||||||
|
|
||||||
|
//登录
|
||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void UnityLoginByTokenFun(string token);
|
public static extern void UnityLoginByTokenFun(string token);
|
||||||
|
|
||||||
@@ -267,6 +310,7 @@ namespace tysdk
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert C string to C# string
|
||||||
string result = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr);
|
string result = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr);
|
||||||
return result ?? string.Empty;
|
return result ?? string.Empty;
|
||||||
}
|
}
|
||||||
@@ -357,6 +401,7 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[DllImport("__Internal")] private static extern void LinkGoogle(int userId);
|
[DllImport("__Internal")] private static extern void LinkGoogle(int userId);
|
||||||
[DllImport("__Internal")] private static extern void LinkFacebook(int userId);
|
[DllImport("__Internal")] private static extern void LinkFacebook(int userId);
|
||||||
[DllImport("__Internal")] private static extern void LinkApple(int userId);
|
[DllImport("__Internal")] private static extern void LinkApple(int userId);
|
||||||
@@ -374,25 +419,31 @@ namespace tysdk
|
|||||||
case EAccoutType.hwFacebook:
|
case EAccoutType.hwFacebook:
|
||||||
IsLinkedFacebook();
|
IsLinkedFacebook();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EAccoutType.Apple:
|
case EAccoutType.Apple:
|
||||||
IsLinkedApple();
|
IsLinkedApple();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[DllImport("__Internal")] public static extern void CleanLinkTmpSnsInfo();
|
[DllImport("__Internal")] public static extern void CleanLinkTmpSnsInfo();
|
||||||
|
|
||||||
[DllImport("__Internal")] private static extern void IsLinkedGoogle();
|
[DllImport("__Internal")] private static extern void IsLinkedGoogle();
|
||||||
[DllImport("__Internal")] private static extern void IsLinkedFacebook();
|
[DllImport("__Internal")] private static extern void IsLinkedFacebook();
|
||||||
[DllImport("__Internal")] private static extern void IsLinkedApple();
|
[DllImport("__Internal")] private static extern void IsLinkedApple();
|
||||||
|
|
||||||
|
|
||||||
|
//支付
|
||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void UnityKnow(string userId, string productId, string productPrice, string productName,
|
public static extern void UnityKnow(string userId, string productId, string productPrice, string productName,
|
||||||
string productCount, string prodorderId, string appInfo);
|
string productCount, string prodorderId, string appInfo);
|
||||||
|
|
||||||
|
//获取商品列表
|
||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void GetSKUList();
|
public static extern void GetSKUList();
|
||||||
|
|
||||||
|
//打点
|
||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void SetGaUserInfo(string userId);
|
public static extern void SetGaUserInfo(string userId);
|
||||||
|
|
||||||
@@ -402,6 +453,7 @@ namespace tysdk
|
|||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void GAReportParams(int type, string eventstr, string paramstr);
|
public static extern void GAReportParams(int type, string eventstr, string paramstr);
|
||||||
|
|
||||||
|
//ATT
|
||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void RequestATT();
|
public static extern void RequestATT();
|
||||||
|
|
||||||
@@ -414,6 +466,10 @@ namespace tysdk
|
|||||||
[DllImport("__Internal")]
|
[DllImport("__Internal")]
|
||||||
public static extern void MessengerShareLink(string title, string content, string url);
|
public static extern void MessengerShareLink(string title, string content, string url);
|
||||||
|
|
||||||
|
public static void ConsumePurchase(string token) { }
|
||||||
|
|
||||||
|
public static string GetPendingPurchases() => "[]";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
{
|
{
|
||||||
"MonoBehaviour": {
|
"MonoBehaviour": {
|
||||||
"Version": 3,
|
"Version": 5,
|
||||||
"EnableBurstCompilation": true,
|
"EnableBurstCompilation": true,
|
||||||
"EnableOptimisations": true,
|
"EnableOptimisations": true,
|
||||||
"EnableSafetyChecks": false,
|
"EnableSafetyChecks": false,
|
||||||
"EnableDebugInAllBuilds": false,
|
"EnableDebugInAllBuilds": false,
|
||||||
"UsePlatformSDKLinker": false,
|
"DebugDataKind": 0,
|
||||||
|
"EnableArmv9SecurityFeatures": false,
|
||||||
"CpuMinTargetX32": 0,
|
"CpuMinTargetX32": 0,
|
||||||
"CpuMaxTargetX32": 0,
|
"CpuMaxTargetX32": 0,
|
||||||
"CpuMinTargetX64": 0,
|
"CpuMinTargetX64": 0,
|
||||||
"CpuMaxTargetX64": 0,
|
"CpuMaxTargetX64": 0,
|
||||||
"CpuTargetsX32": 6,
|
"CpuTargetsX32": 6,
|
||||||
"CpuTargetsX64": 72
|
"CpuTargetsX64": 72,
|
||||||
|
"OptimizeFor": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ PlayerSettings:
|
|||||||
androidSupportedAspectRatio: 1
|
androidSupportedAspectRatio: 1
|
||||||
androidMaxAspectRatio: 2.1
|
androidMaxAspectRatio: 2.1
|
||||||
applicationIdentifier:
|
applicationIdentifier:
|
||||||
Android: com.arkgame.ft
|
Android: com.arkgame.ft.flexion
|
||||||
Standalone: com.Unity-Technologies.com.unity.template.urp-blank
|
Standalone: com.Unity-Technologies.com.unity.template.urp-blank
|
||||||
iPhone: com.arkgame.ft
|
iPhone: com.arkgame.ft
|
||||||
buildNumber:
|
buildNumber:
|
||||||
@@ -932,4 +932,4 @@ PlayerSettings:
|
|||||||
hmiLoadingImage: {fileID: 0}
|
hmiLoadingImage: {fileID: 0}
|
||||||
platformRequiresReadableAssets: 0
|
platformRequiresReadableAssets: 0
|
||||||
virtualTexturingSupportEnabled: 0
|
virtualTexturingSupportEnabled: 0
|
||||||
insecureHttpOption: 0
|
insecureHttpOption: 2
|
||||||
|
|||||||
Reference in New Issue
Block a user