fix:1、删除部分不用的资源代码。2、a面修复bug
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e75e79cc47ddbb8409cf3ea5f29211ce
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +0,0 @@
|
||||
# ApplePay
|
||||
|
||||
2025 年 05 月 24 日 V1.0.0 提交初始版本 applepay 模块,该模块功能依赖通用模块,网络模块和数据模块,请一起拉取
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f92f9691c788c414a82e03722722293e
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10ce64fc727c4edeb97e73ad29ef5eab
|
||||
timeCreated: 1747906541
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2da583c874f4b13acc3eb54eaf5a428
|
||||
timeCreated: 1747996053
|
||||
@@ -1,43 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SGModule.ApplePay
|
||||
{
|
||||
public class ApplePayData
|
||||
{
|
||||
[JsonProperty("innerOrderId")]
|
||||
public string innerOrderId;
|
||||
[JsonProperty("amount")]
|
||||
public int amount;
|
||||
[JsonProperty("sku")]
|
||||
public string sku;
|
||||
[JsonProperty("currency")]
|
||||
public string currency = "USD";
|
||||
[JsonProperty("shopName")]
|
||||
public string shopName;
|
||||
[JsonProperty("type")]
|
||||
public string type;
|
||||
|
||||
}
|
||||
|
||||
public class AppleCheckData
|
||||
{
|
||||
[JsonProperty("signedPayload")]
|
||||
public string signedPayload;
|
||||
[JsonProperty("innerOrderId")]
|
||||
public string innerOrderId;
|
||||
}
|
||||
|
||||
public class AppleSubscribeData
|
||||
{
|
||||
[JsonProperty("signedPayload")]
|
||||
public string signedPayload;
|
||||
[JsonProperty("sku")]
|
||||
public string sku;
|
||||
[JsonProperty("currency")]
|
||||
public string currency;
|
||||
[JsonProperty("amount")]
|
||||
public int amount;
|
||||
[JsonProperty("expires_time")]
|
||||
public long expires_time;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dcbc72e1537449aaea5b71d67e7bf85
|
||||
timeCreated: 1747996070
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69666ded8fdc4244a0d43d25f7831bca
|
||||
timeCreated: 1747906570
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace SGModule.ApplePay
|
||||
{
|
||||
public enum ApplePayBackType
|
||||
{
|
||||
/// <summary>
|
||||
///创建支付订单
|
||||
/// </summary>
|
||||
Create,
|
||||
/// <summary>
|
||||
///验证支付订单
|
||||
/// </summary>
|
||||
Check,
|
||||
/// <summary>
|
||||
///取消支付订单
|
||||
/// </summary>
|
||||
Cancel,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e83ae38d5d0e4880836c55d708e7083c
|
||||
timeCreated: 1747995062
|
||||
@@ -1,905 +0,0 @@
|
||||
using SGModule.Common.Base;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RedHotRoast;
|
||||
using SGModule.NetKit;
|
||||
|
||||
|
||||
#if UNITY_IOS && UNITY_IAP
|
||||
using System.Collections;
|
||||
using DG.Tweening;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Purchasing;
|
||||
|
||||
namespace SGModule.ApplePay
|
||||
{
|
||||
public class ApplePayManager : SingletonMonoBehaviour<ApplePayManager>, IDetailedStoreListener
|
||||
{
|
||||
private IStoreController _storeController;
|
||||
private static IExtensionProvider _extensionProvider;
|
||||
private static IAppleExtensions _appleExtension;
|
||||
|
||||
private Action<string> _failedCallback;
|
||||
|
||||
private Action<ApplePayBackType, AppleResponseData> _successCallback;
|
||||
|
||||
private Dictionary<string, (string id, string type)> _products = new Dictionary<string, (string, string)>();
|
||||
|
||||
private ApplePayData _payData;
|
||||
|
||||
private string _packageName;
|
||||
|
||||
private float _lastPayAttemptTime;
|
||||
private Dictionary<string, string> _innerData = new();
|
||||
|
||||
|
||||
public void SendDebugToServer(string error, string stackTrace)
|
||||
{
|
||||
|
||||
ErrorLogKit.Send("debug", error, stackTrace, SuperApplication.Instance.attribution);
|
||||
}
|
||||
|
||||
private Dictionary<string, ProductConfig> _productConfigs = new Dictionary<string, ProductConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// 通过 ProductConfig 数组初始化商品
|
||||
/// </summary>
|
||||
public void InitProduct(List<ProductConfig> configs, string packageName, Action<ApplePayBackType, AppleResponseData> successCallback)
|
||||
{
|
||||
var module = StandardPurchasingModule.Instance();
|
||||
ConfigurationBuilder builder = ConfigurationBuilder.Instance(module);
|
||||
|
||||
_successCallback = successCallback;
|
||||
_packageName = packageName;
|
||||
SendDebugToServer("[Apple pay] InitProduct 开始------", Environment.StackTrace);
|
||||
try
|
||||
{
|
||||
foreach (var config in configs)
|
||||
{
|
||||
Debug.Log($"[Apple pay] InitProduct ------{config.sku} , {config.type} ");
|
||||
if (Enum.TryParse<UnityEngine.Purchasing.ProductType>(config.type, true, out var productType))
|
||||
{
|
||||
_productConfigs.Add(config.sku, config);
|
||||
|
||||
builder.AddProduct(config.sku, productType);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDebugToServer($"无法解析 ProductType: {config.type}", Environment.StackTrace);
|
||||
Debug.LogError($"无法解析 ProductType: {config.type}");
|
||||
// 可根据需要处理默认类型或跳过该商品
|
||||
}
|
||||
}
|
||||
|
||||
SendDebugToServer("[Apple pay] InitProduct 结束------", Environment.StackTrace);
|
||||
UnityPurchasing.Initialize(this, builder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
SendDebugToServer($" 初始化商品 失败 InitProduct: {e.Message}", Environment.StackTrace);
|
||||
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
|
||||
Debug.Log($"[Apple pay] InitProduct -----2 ");
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SetPayData(string sku)
|
||||
{
|
||||
var payData = GetPayData(sku);
|
||||
_payData = payData;
|
||||
|
||||
}
|
||||
|
||||
private ApplePayData GetPayData(string sku)
|
||||
{
|
||||
if (_productConfigs.TryGetValue(sku, out var data))
|
||||
{
|
||||
Debug.Log($"[Apple pay] InitProduct ------{data.sku} , {data.type} ");
|
||||
return new ApplePayData
|
||||
{
|
||||
sku = sku,
|
||||
currency = "USD",
|
||||
amount = (int)Math.Round(data.price * 100),
|
||||
};
|
||||
}
|
||||
Debug.LogError($" set _payData error------_payData is null ");
|
||||
return null;
|
||||
}
|
||||
|
||||
private Coroutine _payDataCheckCoroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 启动_payData超时检测协程
|
||||
/// </summary>
|
||||
private void StartPayDataTimeoutCheck()
|
||||
{
|
||||
if (_payDataCheckCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_payDataCheckCoroutine);
|
||||
}
|
||||
_payDataCheckCoroutine = StartCoroutine(PayDataTimeoutCheck());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测_payData是否超时的协程
|
||||
/// </summary>
|
||||
private IEnumerator PayDataTimeoutCheck()
|
||||
{
|
||||
float startTime = Time.time;
|
||||
float timeout = 60f; // 1分钟超时
|
||||
|
||||
while (Time.time - startTime < timeout)
|
||||
{
|
||||
// 如果_payData已经为null,停止检测
|
||||
if (_payData == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// 1分钟后检查,如果_payData仍然不为null,则设为null
|
||||
if (_payData != null)
|
||||
{
|
||||
_innerData = null;
|
||||
_payData = null;
|
||||
Debug.Log("[Apple Pay] _payData超时,已自动设为null");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 购买接口
|
||||
/// </summary>
|
||||
/// <param name="payData">购买需要的字段存放</param>
|
||||
/// <param name="successCallback">成功回调(ApplePayBackType为订单返回的类型:具体看 ApplePayBackType 枚举),作用:用来打点</param>
|
||||
/// <param name="failedCallback">失败回调 (string为失败原因)</param>
|
||||
public void Purchase(string sku, Action<ApplePayBackType, AppleResponseData> successCallback, Action<string> failedCallback)
|
||||
{
|
||||
Debug.Log($"[Apple Pay] Purchase: {JsonConvert.SerializeObject(_payData)}");
|
||||
|
||||
SendDebugToServer("[Apple pay] 购买 Purchase ------", Environment.StackTrace);
|
||||
|
||||
if (Time.time - _lastPayAttemptTime < 5)
|
||||
{
|
||||
failedCallback?.Invoke("Clicks are too frequent");
|
||||
return;
|
||||
}
|
||||
|
||||
_lastPayAttemptTime = Time.time;
|
||||
Debug.Log($"[Apple Pay] Purchase-00---------{JsonConvert.SerializeObject(_payData)}");
|
||||
if (_payData != null)
|
||||
{
|
||||
if (_payData.sku.Contains("sub"))//假如是订阅直接清理
|
||||
{
|
||||
_payData = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 启动超时检测
|
||||
StartPayDataTimeoutCheck();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"[Apple Pay] Purchase-1---------");
|
||||
|
||||
if (!IsInitialized())
|
||||
{
|
||||
failedCallback?.Invoke("Not Initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[Apple Pay] Purchase-2---------");
|
||||
|
||||
var product = _storeController.products.WithID(sku);
|
||||
if (product == null || !product.availableToPurchase)
|
||||
{
|
||||
failedCallback?.Invoke("Either is not found or is not available for purchase");
|
||||
return;
|
||||
}
|
||||
|
||||
_successCallback = successCallback;
|
||||
_failedCallback = failedCallback;
|
||||
|
||||
SetPayData(sku);
|
||||
|
||||
_storeController.InitiatePurchase(product);
|
||||
|
||||
Debug.Log($"[Apple Pay] Purchase-3---------");
|
||||
|
||||
if (_payData != null)
|
||||
{
|
||||
var payData = new ApplePayData
|
||||
{
|
||||
sku = sku,
|
||||
currency = "USD",
|
||||
amount = _payData.amount,
|
||||
};
|
||||
|
||||
ApplePayNet.ApplePayCreate<ApplePayData>(payData, (response) =>
|
||||
{
|
||||
Debug.Log($"[Apple Pay] Purchase-4---------");
|
||||
|
||||
if (response.IsSuccess)
|
||||
{
|
||||
_successCallback?.Invoke(ApplePayBackType.Create, null);
|
||||
|
||||
if (_innerData == null) _innerData = new();
|
||||
Debug.Log($"[Apple pay] Purchase--5-innerOrderId-------{response.Data.innerOrderId}");
|
||||
if (_payData != null && response.Data.innerOrderId != null)
|
||||
{
|
||||
Debug.Log($"[Apple pay] Purchase-555555-innerOrderId");
|
||||
_payData.innerOrderId = response.Data.innerOrderId;
|
||||
_innerData[response.Data.innerOrderId] = sku;
|
||||
SaveInnerIdData(_innerData);
|
||||
}
|
||||
}
|
||||
|
||||
// if (_payData != null) _payData.innerOrderId = response.Data.innerOrderId;
|
||||
SendDebugToServer($"[Apple Pay] Purchase-5-------创建内部ID innerOrderId--{_payData.innerOrderId}", Environment.StackTrace);
|
||||
|
||||
Debug.Log($"[Apple Pay] Purchase-5-------innerOrderId--{_payData.innerOrderId}");
|
||||
if (payData.sku.Contains("sub") && DataMgr.VipLevel.Value >= 1)
|
||||
{
|
||||
// PlayerPrefs.SetInt("need_getvip", 1);
|
||||
DOVirtual.DelayedCall(10, () =>
|
||||
{
|
||||
GetVipHistory();
|
||||
}).SetLoops(3);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public static void GetVipHistory()
|
||||
{
|
||||
// if (PlayerPrefs.GetInt("need_getvip", 1) == 0) return;
|
||||
// PlayerPrefs.DeleteAll();
|
||||
string orig_tx_id = PlayerPrefs.GetString("orig_tx_id", "");
|
||||
HistoryObject obj_ = new HistoryObject() { id = orig_tx_id };
|
||||
if (string.IsNullOrEmpty(orig_tx_id))
|
||||
{
|
||||
ApplePayNet.ApplePaySubscriptionHistory<List<SubscriptionList>>((response) =>
|
||||
{
|
||||
// Debug.Log(JsonConvert.SerializeObject(response.Data));
|
||||
string tx_id_ = null;
|
||||
for (int i = 0; i < response.Data.Count; i++)
|
||||
{
|
||||
PlayerPrefs.SetString("orig_tx_id", response.Data[i].orig_tx_id);
|
||||
tx_id_ = response.Data[i].orig_tx_id;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(tx_id_))
|
||||
{
|
||||
obj_.id = tx_id_;
|
||||
SubscriptionCheck(obj_);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubscriptionCheck(obj_);
|
||||
}
|
||||
|
||||
}
|
||||
public static void SubscriptionCheck(HistoryObject obj_)
|
||||
{
|
||||
ApplePayNet.ApplePaySubscriptionCheck<SubscriptionList>(obj_, (response) =>
|
||||
{
|
||||
int vip_level = -1;
|
||||
long end_time = 0;
|
||||
if (response != null && response.Data != null)
|
||||
{
|
||||
Debug.Log(JsonConvert.SerializeObject(response.Data));
|
||||
if (response.Data.renew_time > end_time)
|
||||
{
|
||||
end_time = response.Data.renew_time;
|
||||
if (response.Data.renew_sku == PurchasingManager.GetPaySku(PayType.yearly_subscription))
|
||||
{
|
||||
vip_level = 3;
|
||||
}
|
||||
else if (response.Data.renew_sku == PurchasingManager.GetPaySku(PayType.monthly_subscription))
|
||||
{
|
||||
vip_level = 2;
|
||||
}
|
||||
else if (response.Data.renew_sku == PurchasingManager.GetPaySku(PayType.weekly_subscription))
|
||||
{
|
||||
vip_level = 1;
|
||||
}
|
||||
DataMgr.VipExpirationTime.Value = end_time;
|
||||
if (DataMgr.VipLevel.Value != vip_level)
|
||||
{
|
||||
DataMgr.VipLevel.Value = vip_level;
|
||||
GameDispatcher.Instance.Dispatch(GameMsg.BuyVip);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// IOS恢复内购
|
||||
/// 会在删除应用后,第一次安装是自动恢复
|
||||
/// </summary>
|
||||
/// <param name="restoreCallback">恢复回调</param>
|
||||
public void AppleRestore(Action<bool, string> restoreCallback)
|
||||
{
|
||||
if (!IsInitialized())
|
||||
{
|
||||
Debug.LogWarning("[ApplePay] IAppleExtensions 未初始化");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("[ApplePay] 用户手动恢复购买");
|
||||
_appleExtension.RestoreTransactions((success, error) =>
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
Debug.Log("[Apple Pay] Restore Transactions 成功");
|
||||
// 这里会触发 ProcessPurchase 回调
|
||||
restoreCallback(true, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[Apple Pay] Restore Transactions 失败: {error}");
|
||||
// 可以提示用户重试
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#region 购买成功回调
|
||||
|
||||
private Dictionary<string, Product> _pendingProducts = new Dictionary<string, Product>();
|
||||
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
|
||||
{
|
||||
SendDebugToServer($"[Apple pay] 购买成功回调 Purchase ---{JsonConvert.SerializeObject(purchaseEvent.purchasedProduct)}---", Environment.StackTrace);
|
||||
|
||||
var product = purchaseEvent.purchasedProduct;
|
||||
var productType = product.definition.type;
|
||||
var sku = product.definition.id;
|
||||
var receipt = product.receipt;
|
||||
|
||||
Debug.Log(
|
||||
$" ProcessPurchase 1 Purchase: {JsonConvert.SerializeObject(purchaseEvent.purchasedProduct)}");
|
||||
|
||||
|
||||
Debug.Log(
|
||||
$" ProcessPurchase 1 receipt: {receipt}");
|
||||
|
||||
if (purchaseEvent is not { purchasedProduct: not null })
|
||||
{
|
||||
Debug.LogError("[Apple Pay] ProcessPurchase 2 : purchaseEvent 或 purchasedProduct 为 null");
|
||||
return PurchaseProcessingResult.Complete;
|
||||
}
|
||||
|
||||
Debug.Log($"购买商品类型: {productType}, SKU: {sku}");
|
||||
if (productType == ProductType.NonConsumable)
|
||||
{
|
||||
Debug.Log(
|
||||
$" 识别到非消耗性商品 ----{DataMgr.ApplePayTransactionID.Value.Contains(product.transactionID)}");
|
||||
var innerdata = GetInnerIdData();
|
||||
if (innerdata == null) // 重启情况
|
||||
{
|
||||
Debug.Log("innerdata----" + innerdata);
|
||||
_successCallback(ApplePayBackType.Check, new AppleResponseData()
|
||||
{
|
||||
sku = sku
|
||||
});
|
||||
DataMgr.ApplePayTransactionID.Value.Add(product.transactionID);
|
||||
return PurchaseProcessingResult.Complete;
|
||||
}
|
||||
Debug.Log("innerdata---2-");
|
||||
if (DataMgr.ApplePayTransactionID.Value.Contains(product.transactionID))
|
||||
{
|
||||
return PurchaseProcessingResult.Complete;
|
||||
}
|
||||
DataMgr.ApplePayTransactionID.Value.Add(product.transactionID);
|
||||
}
|
||||
|
||||
if (DataMgr.clearAllOrder.Value)
|
||||
{
|
||||
_innerData = null;
|
||||
_payData = null;
|
||||
// 保存更新后的数据
|
||||
SaveApplePayData(null);
|
||||
SaveInnerIdData(null);
|
||||
return PurchaseProcessingResult.Complete;
|
||||
}
|
||||
|
||||
string txId = product.transactionID;
|
||||
_pendingProducts[txId] = product; // ✅ 安全暂存
|
||||
|
||||
if (productType == ProductType.Subscription)
|
||||
{
|
||||
SendDebugToServer($"[Apple pay] 购买商品类型 Purchase ---{productType}-{sku}--", Environment.StackTrace);
|
||||
|
||||
// 服务器验证
|
||||
UploadReceiptForValidation(sku, product.transactionID, isSuccess =>
|
||||
{
|
||||
if (isSuccess)
|
||||
{
|
||||
var product_temp = FindPendingProductByTransactionId(purchaseEvent.purchasedProduct.transactionID);
|
||||
// 验证成功后的逻辑
|
||||
// 验证成功,完成购买
|
||||
_storeController.ConfirmPendingPurchase(product_temp);
|
||||
}
|
||||
});
|
||||
|
||||
return PurchaseProcessingResult.Pending;
|
||||
}
|
||||
|
||||
// 普通商品直接处理
|
||||
HandlePurchaseSuccess(purchaseEvent, isSuccess =>
|
||||
{
|
||||
if (isSuccess)
|
||||
{
|
||||
var product_temp = FindPendingProductByTransactionId(purchaseEvent.purchasedProduct.transactionID);
|
||||
var productType = product_temp.definition.type;
|
||||
Debug.Log(
|
||||
$"ConfirmPendingPurchase : {purchaseEvent.purchasedProduct.transactionID}, sku: {product_temp.definition.id}");
|
||||
// 验证成功,完成购买
|
||||
_storeController.ConfirmPendingPurchase(product_temp);
|
||||
}
|
||||
});
|
||||
|
||||
return PurchaseProcessingResult.Pending;
|
||||
}
|
||||
|
||||
private Product FindPendingProductByTransactionId(string txId)
|
||||
{
|
||||
_pendingProducts.TryGetValue(txId, out var product);
|
||||
_pendingProducts.Remove(txId); // ✅ 用完即删,避免内存泄漏
|
||||
return product;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 支付测试代码
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="sku"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
public void ApplePayTest(ProductType type, string sku, string transactionID, Action<ApplePayBackType, AppleResponseData> successCallback)
|
||||
{
|
||||
|
||||
SetPayData(sku);
|
||||
Debug.Log($"[ApplePay] 测试支付 type: {type}, sku: {sku}, transactionID: {transactionID}");
|
||||
|
||||
_successCallback = successCallback;
|
||||
|
||||
if (type == ProductType.Subscription)
|
||||
{
|
||||
// 服务器验证
|
||||
UploadReceiptForValidation(sku, transactionID, isSuccess =>
|
||||
{
|
||||
if (isSuccess)
|
||||
{
|
||||
Debug.Log("订阅商品验证成功");
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == ProductType.NonConsumable)
|
||||
{
|
||||
Debug.Log(
|
||||
$" 识别到非消耗性商品 ----{DataMgr.ApplePayTransactionID.Value.Contains(transactionID)}");
|
||||
if (DataMgr.ApplePayTransactionID.Value.Contains(transactionID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DataMgr.ApplePayTransactionID.Value.Add(transactionID);
|
||||
}
|
||||
|
||||
// 普通商品直接处理
|
||||
// HandlePurchaseSuccess(transactionID, isSuccess =>
|
||||
// {
|
||||
// if (isSuccess)
|
||||
// {
|
||||
// Debug.Log("普通商品验证成功");
|
||||
// }
|
||||
// }, true);
|
||||
}
|
||||
|
||||
//服务器验证
|
||||
private void UploadReceiptForValidation(string sku, string transactionID, Action<bool> onValidationComplete)
|
||||
{
|
||||
Debug.Log("识别到订阅商品,准备进行订阅验证");
|
||||
SendDebugToServer($"[Apple pay] 识别到订阅商品,准备进行订阅验证", Environment.StackTrace);
|
||||
|
||||
var productConfig = GetPayData(sku);
|
||||
if (productConfig != null)
|
||||
{
|
||||
Debug.Log($"订阅商品ID: {sku} transactionID: {transactionID} _payData.amount: {productConfig.amount}");
|
||||
|
||||
SendDebugToServer($"订阅商品ID: {sku} transactionID: {transactionID} _payData.amount: {productConfig.amount}", Environment.StackTrace);
|
||||
|
||||
ApplePayNet.AppleSubscribeCheck<AppleSubscribeData>(
|
||||
transactionID,
|
||||
sku,
|
||||
productConfig.amount,
|
||||
_packageName,
|
||||
response =>
|
||||
{
|
||||
bool isSuccess = response.IsSuccess;
|
||||
|
||||
// 在这里返回验证结果
|
||||
onValidationComplete?.Invoke(isSuccess);
|
||||
_payData = null;
|
||||
if (isSuccess)
|
||||
{
|
||||
Debug.Log("订阅验证成功");
|
||||
SendDebugToServer($"订阅验证成功", Environment.StackTrace);
|
||||
|
||||
_successCallback?.Invoke(ApplePayBackType.Check, new AppleResponseData()
|
||||
{
|
||||
expires_time = response.Data.expires_time,
|
||||
sku = sku
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[Apple Pay] 订阅验证失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 支付成功后的本地处理(订阅和普通商品共用)
|
||||
/// </summary>
|
||||
private void HandlePurchaseSuccess(PurchaseEventArgs purchaseEvent, Action<bool> onValidationComplete, bool isTest = false)
|
||||
{
|
||||
var payDataJson = GetApplePayData();
|
||||
Debug.Log($" HandlePurchaseSuccess payDataJson: {JsonConvert.SerializeObject(payDataJson)}");
|
||||
|
||||
var statusDictionary = JsonConvert.DeserializeObject<Dictionary<string, ApplePayData>>(payDataJson)
|
||||
?? new Dictionary<string, ApplePayData>();
|
||||
|
||||
string transactionID = purchaseEvent.purchasedProduct.transactionID;
|
||||
string sku = purchaseEvent.purchasedProduct.definition.id;
|
||||
Debug.Log($"[Apple pay] 购买成功: transactionID: {transactionID} sku: {sku}");
|
||||
// var receiptObj = JObject.Parse(purchaseEvent.purchasedProduct.receipt);
|
||||
|
||||
// var payload = JObject.Parse((string)receiptObj["Payload"]);
|
||||
// var jsonData = JObject.Parse((string)payload["json"]);
|
||||
|
||||
SendDebugToServer($"普通商品 HandlePurchaseSuccess: {transactionID}", Environment.StackTrace);
|
||||
|
||||
if (!statusDictionary.ContainsKey(transactionID))
|
||||
{
|
||||
Debug.Log($"记录新交易 transactionID: {transactionID}");
|
||||
Debug.Log($"-----_payData: {JsonConvert.SerializeObject(_payData)}");
|
||||
|
||||
if (_payData == null || string.IsNullOrWhiteSpace(_payData.innerOrderId))
|
||||
{
|
||||
Debug.Log("[Apple pay] _payData 为空或 innerOrderId 无效");
|
||||
var innerdata = GetInnerIdData();
|
||||
var isFind = false;
|
||||
Debug.Log($" HandlePurchaseSuccess innerdata: {JsonConvert.SerializeObject(innerdata)}");
|
||||
if (innerdata != null)
|
||||
{
|
||||
foreach (var item in innerdata)
|
||||
{
|
||||
Debug.Log(
|
||||
$" HandlePurchaseSuccess item: {item.Key} {item.Value} jsonData productId=={sku}");
|
||||
if (item.Value == sku)
|
||||
{
|
||||
SetPayData(purchaseEvent.purchasedProduct.definition.id);
|
||||
_payData.innerOrderId = item.Key;
|
||||
// _payData = new()
|
||||
// {
|
||||
// innerOrderId = item.Key,
|
||||
// };
|
||||
isFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFind)
|
||||
{
|
||||
Debug.LogWarning("[Apple pay] 内部订单ID 无效");
|
||||
onValidationComplete?.Invoke(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
statusDictionary.Add(transactionID, _payData);
|
||||
SaveApplePayData(statusDictionary);
|
||||
_innerData = null;
|
||||
_payData = null;
|
||||
}
|
||||
|
||||
if (statusDictionary.TryGetValue(transactionID, out var cValue))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(cValue.innerOrderId) || isTest)
|
||||
{
|
||||
ApplePaySuccess(transactionID, onValidationComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveApplePayData(Dictionary<string, ApplePayData> payData)
|
||||
{
|
||||
// 保存更新后的数据
|
||||
string json = JsonConvert.SerializeObject(payData);
|
||||
PlayerPrefs.SetString("SGModule_apple_pay_data", json);
|
||||
}
|
||||
|
||||
private string GetApplePayData()
|
||||
{
|
||||
string json = PlayerPrefs.GetString("SGModule_apple_pay_data", "");
|
||||
// GetString if (json == "")
|
||||
// {
|
||||
// json = DataWrapper.ApplePayData;
|
||||
// }
|
||||
return json;
|
||||
}
|
||||
|
||||
private void SaveInnerIdData(Dictionary<string, string> innerData)
|
||||
{
|
||||
// 保存更新后的数据
|
||||
string json = JsonConvert.SerializeObject(innerData);
|
||||
Debug.Log($"[Inner save Data] ==: {json}");
|
||||
PlayerPrefs.SetString("SGModule_inner_order_id", json);
|
||||
}
|
||||
|
||||
private Dictionary<string, string> GetInnerIdData()
|
||||
{
|
||||
string json = PlayerPrefs.GetString("SGModule_inner_order_id", "");
|
||||
Debug.Log($"[Inner get Data] ==: {json}");
|
||||
return JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
|
||||
}
|
||||
|
||||
private Queue<(string transactionID, Action<bool> onValidationComplete)> _pendingRequests = new Queue<(string, Action<bool>)>();
|
||||
private bool _isProcessing = false; // 标记是否正在处理中
|
||||
private HashSet<string> _processedOrPendingTx = new HashSet<string>();
|
||||
private void ApplePaySuccess(string transactionID, Action<bool> onValidationComplete)
|
||||
{
|
||||
// 入队前去重
|
||||
if (_processedOrPendingTx.Contains(transactionID))
|
||||
{
|
||||
Debug.LogWarning($"Duplicate TX ignored: {transactionID}");
|
||||
onValidationComplete?.Invoke(false);
|
||||
return;
|
||||
}
|
||||
_processedOrPendingTx.Add(transactionID);
|
||||
|
||||
Debug.Log($"[ApplePaySuccess] Received transaction: {transactionID}");
|
||||
_pendingRequests.Enqueue((transactionID, onValidationComplete));
|
||||
TryProcessNext();
|
||||
|
||||
}
|
||||
|
||||
private void TryProcessNext()
|
||||
{
|
||||
if (_isProcessing || _pendingRequests.Count == 0)
|
||||
return;
|
||||
|
||||
var (txId, callback) = _pendingRequests.Dequeue();
|
||||
_isProcessing = true;
|
||||
Debug.Log("apple 支付 StartCoroutine------" + txId);
|
||||
StartCoroutine(ProcessPayData(txId, callback));
|
||||
}
|
||||
|
||||
private IEnumerator ProcessPayData(string orderId, Action<bool> onValidationComplete)
|
||||
{
|
||||
// 发起请求
|
||||
ApplePayRequest(orderId, onValidationComplete);
|
||||
|
||||
yield return null; // 等待本次请求完成
|
||||
}
|
||||
|
||||
private void ApplePayRequest(string transactionID, Action<bool> onValidationComplete)
|
||||
{
|
||||
var payDataJson = GetApplePayData();
|
||||
Debug.Log($"ApplePayRequest 1 payDataJson: {JsonConvert.SerializeObject(payDataJson)}");
|
||||
SendDebugToServer($"验单 普通商品: {transactionID}", Environment.StackTrace);
|
||||
|
||||
var statusDictionary = JsonConvert.DeserializeObject<Dictionary<string, ApplePayData>>(payDataJson);
|
||||
|
||||
if (statusDictionary.ContainsKey(transactionID))
|
||||
{
|
||||
var data = statusDictionary[transactionID];
|
||||
Debug.Log($"ApplePayRequest 2 transactionID: {transactionID}, innerOrderId:{data.innerOrderId}");
|
||||
|
||||
|
||||
ApplePayNet.ApplePayCheck<ApplePayData>(transactionID, data.innerOrderId, _packageName, (response) =>
|
||||
{
|
||||
Debug.Log(
|
||||
$"ApplePayRequest 3 response.IsSuccess: {JsonConvert.SerializeObject(response)}");
|
||||
_isProcessing = false;
|
||||
TryProcessNext();
|
||||
|
||||
if (response.IsSuccess || response.Code == 1026 || (response.Code == 1007 && data.sku == PurchasingManager.GetPaySku(PayType.buy_one)))
|
||||
{
|
||||
onValidationComplete?.Invoke(true);
|
||||
_processedOrPendingTx.Remove(transactionID);
|
||||
_successCallback(ApplePayBackType.Check, new AppleResponseData()
|
||||
{
|
||||
sku = data.sku
|
||||
});
|
||||
|
||||
var innerdata = GetInnerIdData();
|
||||
innerdata.Remove(data.innerOrderId);
|
||||
SaveInnerIdData(innerdata);
|
||||
|
||||
statusDictionary.Remove(transactionID);
|
||||
// 保存更新后的数据
|
||||
SaveApplePayData(statusDictionary);
|
||||
|
||||
_innerData = null;
|
||||
_payData = null;
|
||||
}
|
||||
else if (response.Code == 1007)
|
||||
{
|
||||
GameHelper.ShowTips("no_network", true);
|
||||
onValidationComplete?.Invoke(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
onValidationComplete?.Invoke(response.IsSuccess);
|
||||
}
|
||||
|
||||
if (!new List<int>() { 1021, 1027, 1028 }.Contains(response.Code))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
statusDictionary.Remove(transactionID);
|
||||
// 保存更新后的数据
|
||||
SaveApplePayData(statusDictionary);
|
||||
|
||||
var innerdata = GetInnerIdData();
|
||||
innerdata.Remove(data.innerOrderId);
|
||||
SaveInnerIdData(innerdata);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 初始化
|
||||
|
||||
private bool IsInitialized()
|
||||
{
|
||||
Debug.Log("[barry] check IsInitialized======:");
|
||||
return _storeController != null && _extensionProvider != null;
|
||||
}
|
||||
|
||||
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
|
||||
{
|
||||
_storeController = controller;
|
||||
_extensionProvider = extensions;
|
||||
_appleExtension = extensions.GetExtension<IAppleExtensions>();
|
||||
GetVipHistory();
|
||||
}
|
||||
|
||||
public void OnInitializeFailed(InitializationFailureReason error)
|
||||
{
|
||||
Debug.Log("[barry] OnInitializeFailed1 Reason:" + error);
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnInitializeFailed(InitializationFailureReason error, string message)
|
||||
{
|
||||
Debug.Log("[barry] OnInitializeFailed2 Reason:" + error);
|
||||
Debug.Log("[barry] OnInitializeFailed2 message:" + message);
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 购买失败回调
|
||||
|
||||
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
|
||||
{
|
||||
Debug.Log(" OnPurchaseFailed===1==:");
|
||||
HandleOnPurchaseFail(failureReason);
|
||||
}
|
||||
|
||||
|
||||
public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
|
||||
{
|
||||
Debug.Log("OnPurchaseFailed===2==:");
|
||||
HandleOnPurchaseFail(failureDescription.reason);
|
||||
}
|
||||
|
||||
private void HandleOnPurchaseFail(PurchaseFailureReason failureReason)
|
||||
{
|
||||
Debug.Log($" HandleOnPurchaseFail 1 ");
|
||||
|
||||
if (_payData == null) return;
|
||||
|
||||
GameHelper.ShowTips("purchase_fail", true);
|
||||
Debug.Log($" HandleOnPurchaseFail 2 ");
|
||||
|
||||
ApplePayNet.ApplePayCancel<ApplePayData>(_payData, (response) =>
|
||||
{
|
||||
string msg = ToFriendlyString(failureReason);
|
||||
Debug.Log("[barry] HandleOnPurchaseFail:" + response.IsSuccess + " reason: " + msg);
|
||||
|
||||
if (!_payData.sku.Contains(".sub"))
|
||||
{
|
||||
var innerdata = GetInnerIdData();
|
||||
Debug.Log(
|
||||
$"[Apple pay] HandleOnPurchaseFail----- _payData.innerOrderId: {_payData.innerOrderId}");
|
||||
|
||||
innerdata.Remove(_payData.innerOrderId);
|
||||
SaveInnerIdData(innerdata);
|
||||
}
|
||||
|
||||
_failedCallback?.Invoke(msg);
|
||||
_payData = null;
|
||||
_innerData = null;
|
||||
|
||||
_successCallback?.Invoke(ApplePayBackType.Cancel, null);
|
||||
});
|
||||
}
|
||||
|
||||
private static string ToFriendlyString(PurchaseFailureReason reason)
|
||||
{
|
||||
Debug.Log($"ToFriendlyString 1 reason==={reason}");
|
||||
|
||||
return reason switch
|
||||
{
|
||||
PurchaseFailureReason.ProductUnavailable => "商品不可用",
|
||||
PurchaseFailureReason.PurchasingUnavailable => "购买功能不可用",
|
||||
PurchaseFailureReason.ExistingPurchasePending => "已有未完成的购买",
|
||||
PurchaseFailureReason.SignatureInvalid => "签名验证失败",
|
||||
PurchaseFailureReason.UserCancelled => "用户取消",
|
||||
PurchaseFailureReason.PaymentDeclined => "支付被拒绝",
|
||||
PurchaseFailureReason.DuplicateTransaction => "重复的交易ID",
|
||||
PurchaseFailureReason.Unknown => "未知错误",
|
||||
_ => $"未识别的错误: {(int)reason}"
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#else
|
||||
namespace SGModule.ApplePay {
|
||||
public class ApplePayManager: SingletonMonoBehaviour<ApplePayManager>{
|
||||
public void StartPay() {
|
||||
}
|
||||
|
||||
public string GetApplePayName(string key)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public void Purchase(ApplePayData payData, Action<ApplePayBackType> successCallback,
|
||||
Action<string> failedCallback) {
|
||||
var msg = "Apple Pay: Purchase Failed, No plugin is installed.";
|
||||
Log.Info("[Apple IOS]",msg);
|
||||
failedCallback?.Invoke(msg);
|
||||
}
|
||||
|
||||
public void AppleRestore(Action<bool, string> restoreCallback)
|
||||
{
|
||||
|
||||
}
|
||||
public void InitProduct(List<ProductConfig>configs, string packageName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
public class AppleResponseData
|
||||
{
|
||||
[JsonProperty("expires_time")]
|
||||
public long expires_time;
|
||||
[JsonProperty("sku")]
|
||||
public string sku;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8478e5310ad64f23a3805cd8a3fa024f
|
||||
timeCreated: 1747907338
|
||||
@@ -1,95 +0,0 @@
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.Net;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace SGModule.ApplePay
|
||||
{
|
||||
public static class ApplePayNet
|
||||
{
|
||||
#region IOSPay
|
||||
/// <summary>
|
||||
/// ios支付创建订单
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="onCompleted"></param>
|
||||
public static void ApplePayCreate<T>(ApplePayData data, UnityAction<ResponseData<T>> onCompleted = null)
|
||||
{
|
||||
NetKit.NetKit.Instance.Post<T>("shop/applePayCreate", data,
|
||||
response => { onCompleted?.Invoke(response); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ios支付取消订单
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="onCompleted"></param>
|
||||
public static void ApplePayCancel<T>(ApplePayData data, UnityAction<ResponseData<T>> onCompleted = null)
|
||||
{
|
||||
NetKit.NetKit.Instance.Post<T>("shop/applePayCancel", data,
|
||||
response => { onCompleted?.Invoke(response); });
|
||||
}
|
||||
public static void ApplePaySubscriptionHistory<T>(UnityAction<ResponseData<T>> onCompleted = null)
|
||||
{
|
||||
NetKit.NetKit.Instance.Post<T>("shop/subscribeHistory", null,
|
||||
response => { onCompleted?.Invoke(response); });
|
||||
}
|
||||
public static void ApplePaySubscriptionCheck<T>(HistoryObject obj,UnityAction<ResponseData<T>> onCompleted = null)
|
||||
{
|
||||
NetKit.NetKit.Instance.Post<T>("shop/subscribeCheck", obj,
|
||||
response => { onCompleted?.Invoke(response); });
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ios支付验证订单
|
||||
/// </summary>
|
||||
/// <param name="transactionID">apple支付返回的订单id</param>
|
||||
/// <param name="innerOrderId">内部订单id,创建订单时返回的</param>
|
||||
/// <param name="key">包名</param>
|
||||
/// <param name="onCompleted">回调</param>
|
||||
public static void ApplePayCheck<T>(string transactionID, string innerOrderId,
|
||||
string key, UnityAction<ResponseData<T>> onCompleted = null)
|
||||
{
|
||||
var test = new AppleCheckData
|
||||
{
|
||||
signedPayload = Common.Helper.Cryptor.Encrypt(transactionID, key),
|
||||
innerOrderId = innerOrderId
|
||||
};
|
||||
|
||||
NetKit.NetKit.Instance.Post<T>("shop/applePayCheck", test,
|
||||
response => { onCompleted?.Invoke(response); });
|
||||
}
|
||||
/// <summary>
|
||||
/// ios支付订阅
|
||||
/// </summary>
|
||||
/// <param name="transactionID">apple支付返回的订单id</param>
|
||||
/// <param name="sku">商品id</param>
|
||||
/// <param name="amount">价格</param>
|
||||
/// <param name="key">包名</param>
|
||||
/// <param name="onCompleted">回调</param>
|
||||
public static void AppleSubscribeCheck<T>(string transactionID, string sku, int amount,
|
||||
string key, UnityAction<ResponseData<T>> onCompleted = null)
|
||||
{
|
||||
var test = new AppleSubscribeData
|
||||
{
|
||||
signedPayload = Common.Helper.Cryptor.Encrypt(transactionID, key),
|
||||
sku = sku,
|
||||
amount = amount,
|
||||
currency = "USD"
|
||||
};
|
||||
Log.Info("[Apple pay]", $" AppleSubscribeCheck 开始...{sku}");
|
||||
|
||||
NetKit.NetKit.Instance.Post<T>(
|
||||
"shop/appleSubscribe",
|
||||
test,
|
||||
response =>
|
||||
{
|
||||
Log.Info("[Apple pay]", $"AppleSubscribeCheck 结束...{response.IsSuccess}");
|
||||
onCompleted?.Invoke(response);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 760f78942ee949a9af90bc8ac6710be7
|
||||
timeCreated: 1747996461
|
||||
@@ -1,22 +0,0 @@
|
||||
#if UNITY_IOS && UNITY_IAP
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Purchasing;
|
||||
|
||||
namespace SGModule.ApplePay
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ProductConfig
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string name;
|
||||
[JsonProperty("sku")]
|
||||
public string sku;
|
||||
[JsonProperty("price")]
|
||||
public float price;
|
||||
[JsonProperty("type")]
|
||||
public string type;
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bab80a35d16a48e6856d995e175b82d3
|
||||
timeCreated: 1747911023
|
||||
@@ -1,2 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 121d8e1769529b440bc85f03a485ec10
|
||||
guid: 121d8e1769529b440bc85f03a485ec10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace SGModule.Common.Helper {
|
||||
public static readonly ModuleLogger DataStorage = new("DataStorage");
|
||||
public static readonly ModuleLogger IAP = new("IAP");
|
||||
|
||||
private static bool IsEnabled => ConfigManager.GameConfig?.enabledLog ?? false;
|
||||
private static bool IsEnabled => true;//ConfigManager.GameConfig?.enabledLog ?? false;
|
||||
|
||||
public static void Info(string label, string msg, bool showStack = true) {
|
||||
if (IsEnabled) {
|
||||
|
||||
@@ -1,2 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acd6a7aa2034443549cb53d6ae963143
|
||||
guid: acd6a7aa2034443549cb53d6ae963143
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -104,6 +104,32 @@ namespace SGModule.NetKit {
|
||||
|
||||
|
||||
public LoginModel LoginModel => _loginModel;
|
||||
//
|
||||
// public LoginModel LoginModel {
|
||||
// get {
|
||||
// if (_loginModel == null) {
|
||||
// _loginModel = new LoginModel {
|
||||
// CdnURL = string.Empty,
|
||||
// Country = string.Empty,
|
||||
// DebugLog = true,
|
||||
// Enwp = 0,
|
||||
// ExpiresAt = 0,
|
||||
// InviteCode = string.Empty,
|
||||
// IsMagic = false,
|
||||
// LastLoginTime = 0,
|
||||
// LoginTime = 0,
|
||||
// NewPlayer = false,
|
||||
// PlayData = string.Empty,
|
||||
// PlayDataVer = 0,
|
||||
// RegTime = 0,
|
||||
// Setting = string.Empty,
|
||||
// Token = string.Empty,
|
||||
// Uid = 0
|
||||
// };
|
||||
// }
|
||||
// return _loginModel;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public bool LoginSuccess => _loginSuccess;
|
||||
|
||||
Reference in New Issue
Block a user