local SDKManager = { startLoginTime = 0 } -- 新版本SDK部分 ******************************************************** SDKManager.BF_LOGIN_TYPE = { NONE = 0, TOKEN = 1, GUEST = 2, FACEBOOK = 3, TEST = 4, GOOGLE = 5, APPLE = 6, VKID = 7, FACEBOOK_LIMITED = 8, } SDKManager.BF_LOGIN_RESULT = { Success = 0, -- 成功 TokenInvalid = 100, -- token失效 NotAccount = 101, -- 账号不存在 NotBinding = 102, -- 绑定失败 Data = 103, -- 数据错误 RepeatBinding = 104, -- 重复绑定 BindOtherAccount = 105, -- 已绑定其他账号 CheckToken = 106, -- 检查口令失败 } -- 用于LoginReq SDKManager.LOGIN_TYPE = { [0] = "none", [1] = "token", [2] = "guest", -- 游客 [3] = "facebook", [4] = "test", [5] = "google", [6] = "apple", [7] = "vk", [8] = "facebook_limited" } -- 支付方式 SDKManager.PAY_TYPE = { NONE = 0, GOOGLE = 1, IOS = 2, Coda = 3, RuStore = 4, ENJOY = 5, DUKPAY = 6, HW = 7, DEBUG = 10, DEPRECATED_APPLE = 11, } local PAY_TYPE_IN_APP = "inapp" local PAY_TYPE_SUBS = "subs" local SDKPayMgr if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then SDKPayMgr = require "app/common/sdk_pay_google_manager" elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then SDKPayMgr = require "app/common/sdk_pay_ios_manager" else SDKPayMgr = require "app/common/sdk_pay_default_manager" end function SDKManager:init() Logger.logHighlight("SDK INIT ---------------") -- 标记状态 self.isLogining = false self.isLogouting = false self.isWatchingAD = false self.isThirdPay = false if Platform:getPlatformIsThirdPay() then self.isThirdPay = true end self.iosPayInfos = LocalData:getIosPayInfo() self.iosOrders = LocalData:getIosOrders() -- lazy init local SDKMgr = CS.BF.BFMain.Instance.SDKMgr self:initPay() self:initPayListener() self:initAdsListener() -- 拿到firebasetoken -- self:initFireBaseToken() -- 尝试拿取AF的ConversionData -- self:tryGetAFConversionData() -- 初始化deeplink if VersionCompatible:supportDeepLink() then self:initDeepLink() end self:tryGetAFConversionData() end function SDKManager:refreshThirdPay() self.isThirdPay = false if Platform:getPlatformIsThirdPay() then self.isThirdPay = true end end -- 支付相关接口 ********************************************************************** 开始 function SDKManager:initPay() SDKPayMgr:init() end function SDKManager:initPayListener() -- 设置支付回调,平时支付走正常回调,如果延迟到账则走延迟到账的回调 if not SDKPayMgr:needInit() then return end if self.paySid then SchedulerManager:unscheduleGlobal(self.paySid) self.paySid = nil end self.paySid = SchedulerManager:performWithDelayGlobal(function() self:initPayListener() end, 5) SDKPayMgr:initPay(function() if self.paySid then SchedulerManager:unscheduleGlobal(self.paySid) self.paySid = nil end self:queryProducePrice() end) end function SDKManager:queryProducePrice() if self.priceSid then SchedulerManager:unscheduleGlobal(self.priceSid) self.priceSid = nil end Logger.log("queryProducePrice") if SDKPayMgr:gotProduct() then return end local products = SDKPayMgr:queryProducePrice() or {} if #products <= 0 then self.priceSid = SchedulerManager:performWithDelayGlobal(function() self:queryProducePrice() end, 5) end end -- 查询付费产品信息 function SDKManager:queryProducts(callback) SDKPayMgr:queryProducts(callback) end -- 处理未完成的订单 function SDKManager:doUncompleteOrder(callback, productId, freeShowRewards) SDKPayMgr:doUncompleteOrder(callback, productId, freeShowRewards) end -- sdk接口 得到特定商品的price function SDKManager:getProductPrice(skuId) return SDKPayMgr:getProductPrice(skuId) end -- sdk接口 得到特定商品的priceAmountMicros function SDKManager:getProductPriceAmountMicros(skuId) return SDKPayMgr:getProductPriceAmountMicros(skuId) end -- sdk接口 得到特定商品的currency_code function SDKManager:getPriceCurrencyCode(skuId) return SDKPayMgr:getPriceCurrencyCode(skuId) end -- 获取支付方式,目前只有google支付 function SDKManager:getSDKPayType() return SDKPayMgr:getSDKPayType() end function SDKManager:getIsSupportSDKPay() return SDKPayMgr:getIsSupportSDKPay() end -- 获取支付参数 function SDKManager:getPurchaseArgs(purchaseToken, uuid, channelOrderId, productId) return SDKPayMgr:getPurchaseArgs(purchaseToken, uuid, channelOrderId, productId) end -- ios补单专用 function SDKManager:getPurchaseArgs2(purchaseToken, uuid, channelOrderId, productId) return SDKPayMgr:getPurchaseArgs2(purchaseToken, uuid, channelOrderId, productId) end -- sdk将已完成的订单消耗掉 function SDKManager:consumePurchase(token, callback, debugInfo) SDKPayMgr:consumePurchase(token, callback, debugInfo) end -- 检查是否可以支付 function SDKManager:checkPay(productId, callback) if not productId or not Platform:getIsPublishChannel() or not SDKManager:getIsSupportSDKPay() then -- 没有productId、非正式渠道、不支持sdk支付的直接返回可支付 callback(0) return end SDKPayMgr:checkPay(productId, callback) end -- 支付 function SDKManager:pay(productId, orderId, rechargeId, giftType, purchaseType, giftId, callback, freeShowRewards) SDKPayMgr:pay(productId, orderId, rechargeId, giftType, purchaseType, giftId, callback, freeShowRewards) end function SDKManager:doUncompletePay(callback) SDKPayMgr:doUncompletePay(callback) end function SDKManager:getIosPayInfo(transactionID) if SDKPayMgr.getIosPayInfo then return SDKPayMgr:getIosPayInfo(transactionID) end end function SDKManager:delIosPayInfo(transactionID) if SDKPayMgr.delIosPayInfo then return SDKPayMgr:delIosPayInfo(transactionID) end end function SDKManager:delIosOrder(productId) if SDKPayMgr.delIosOrder then return SDKPayMgr:delIosOrder(productId) end end -- 支付相关接口 ********************************************************************** 结束 -- 获取设备语言 function SDKManager:getLanguage() return CS.BF.BFMain.Instance.SDKMgr:GetLanguage() end -- 获取设备时区 function SDKManager:getTimeZone() return CS.BF.BFMain.Instance.SDKMgr:GetTimeZone() end function SDKManager:initFireBaseToken() CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetFirebaseToken(function(token) self.firebaseToken = token end) end function SDKManager:getFirebaseToken() CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetFirebaseToken(function(token) self.firebaseToken = token end) return self.firebaseToken end function SDKManager:doNextFrame(callback) SchedulerManager:performWithDelayGlobal(callback, 0) end --- 广告 function SDKManager:isAdLoaded() if VersionCompatible:getIsPackageRUHW() then if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then return CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr.AdLoaded elseif EDITOR_MODE then return true else return false end else if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android or CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then return CS.AdManager.Instance:IsRewardedAdReady() elseif EDITOR_MODE then return true end end return true end function SDKManager:tryLoadRewardedAdDelay() if self.adDelaySid then SchedulerManager:unscheduleGlobal(self.adDelaySid) self.adDelaySid = nil end self.adDelaySid = SchedulerManager:performWithDelayGlobal(function() self.adDelaySid = nil if VersionCompatible:getIsPackageRUHW() then CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr:TryLoadRewardedAd() end end, 5) end function SDKManager:tryLoadInterstitialAdDelay() if self.interstitialAdDelaySid then SchedulerManager:unscheduleGlobal(self.interstitialAdDelaySid) self.interstitialAdDelaySid = nil end self.interstitialAdDelaySid = SchedulerManager:performWithDelayGlobal(function() self.interstitialAdDelaySid = nil end, 5) end function SDKManager:initAdsListener() if VersionCompatible:getIsPackageRUHW() then CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr:SetAdShowCallback(function (code) -- code 为0 表示广告播放成功 if code == 0 then BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.PLAY_SUCCESS, self.adsClickType) else self:tryLoadRewardedAdDelay() end end) CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr:SetAdLoadedCallback(function (code) -- code 为0 表示广告加载成功 if code ~= 0 then self:tryLoadRewardedAdDelay() end end) CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr:SetAdEarnedRewardCallback(function (code, result) if self.adCallback then self:adRewradAd() self.adCallback() self.isWatchingAD = false -- 标记看广告 BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.GET_REWARD, self.adsClickType) self.adsClickType = nil self.adCallback = nil end end) else if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android or CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then -- 初始化一下 local adManager = CS.AdManager.Instance adManager:SetAdRevenuePaidEventCallback(function (result) if result and result ~= GConst.EMPTY_STRING then BIReport:postAppLovinAdRevenue(result) end end) end end end function SDKManager:showFullScreenAds(adsClickType, adCallback, ignoreShowMessageBox) if NetManager:isNotReachable() then -- 没有网 GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NO_NETWORK)) return false end if NetManager:getIsBusy() then GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NETWORK_ERROE_1)) return false end BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.CLICK, adsClickType) if DataManager.PaymentData:getIsSkipAd() then self:adRewradAd() if adCallback then adCallback() end BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.GET_REWARD_SKIP_AD, adsClickType) return true end if not ignoreShowMessageBox and DataManager.PrivilegeCardData:getIsOpen(GConst.ShopConst.PRIVILEGE_CARD_ID.CARD_AD) then -- local params = {} -- params.content = I18N:getGlobalText(I18N.GlobalConst.ADS_DESC_13) -- params.boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL -- params.showToday = GConst.MESSAGE_BOX_SHOW_TODAY.MONTHLY_CARD_AD -- params.okText = I18N:getGlobalText(I18N.GlobalConst.SKIN_FORCE_DESC_8) -- params.cancelText = I18N:getGlobalText(I18N.GlobalConst.AD_FREE_DESC_9) -- params.notShowCallCancel = true -- params.okFunc = function() -- self:_showFullScreenAds(adsClickType, adCallback) -- end -- GFunc.showMessageBox(params) local params = {} params.content = I18N:getGlobalText(I18N.GlobalConst.ADS_DESC_13) params.showToday = GConst.MESSAGE_BOX_SHOW_TODAY.MONTHLY_CARD_AD params.okFunc = function() if DataManager.PaymentData:getIsSkipAd() then self:adRewradAd() if adCallback then adCallback() end BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.GET_REWARD_SKIP_AD, adsClickType) return end self:_showFullScreenAds(adsClickType, adCallback) end GFunc.showAdMesssageBox(params) else self:_showFullScreenAds(adsClickType, adCallback) end return true end function SDKManager:_showFullScreenAds(adsClickType, adCallback) if EDITOR_MODE then self:adRewradAd() if adCallback then adCallback() end return true end if VersionCompatible:getIsPackageRUHW() then if not CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr.AdLoaded then GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NO_ADS)) return false end -- CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr:SetAdPlacement(adsClickType) CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr.AdLoaded = false self.adCallback = adCallback self.adsClickType = adsClickType CS.BF.BFMain.Instance.SDKMgr.BFHWAdSDKMgr:ShowFullScreenAds() self.isWatchingAD = true -- 标记看广告 else if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android or CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then if not CS.AdManager.Instance:IsRewardedAdReady() then GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NO_ADS)) return false end self.adsClickType = adsClickType BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.PLAY_SUCCESS, self.adsClickType) CS.AdManager.Instance:ShowRewardedAd(function (code) if code == 0 then if not self.watchAdCount then self.watchAdCount = 1 end self:adRewradAd() if adCallback then adCallback() end self.isWatchingAD = false -- 标记看广告 BIReport:postVideoAdOpt(BIReport.VIDEO_AD_OPT_TYPE.GET_REWARD, self.adsClickType) self.adsClickType = nil end end) self.isWatchingAD = true -- 标记看广告 return true end end return true end function SDKManager:getIsWatchingAD() return self.isWatchingAD end function SDKManager:clearWatchAdCount() self.watchAdCount = nil end function SDKManager:adRewradAd(noReport) -- 看广告 ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_WATCH_AD) if not noReport then DataManager.PlayerData:addAdCount() BIReport:postAdEvent() end end function SDKManager:showInterstitial(interstitialAdType, adCallback) if EDITOR_MODE then if not interstitialAdType then local params = { content = "SDKManager showInterstitial has no adsClickType", boxType = GConst.MESSAGE_BOX_TYPE.MB_OK, okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK), } GFunc.showMessageBox(params) Logger.log("SDKManager showInterstitial has no adsClickType") end end BIReport:postInterstitialAdOpt(BIReport.INTERSTITIAL_AD_OPT_TYPE.SHOW, interstitialAdType) if EDITOR_MODE then if adCallback then adCallback() end return end if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android or CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then if not CS.AdManager.Instance:IsInterstitialReady() then if adCallback then adCallback() end return end BIReport:postInterstitialAdOpt(BIReport.INTERSTITIAL_AD_OPT_TYPE.SUCCESS, interstitialAdType) self.isWatchingAD = true CS.AdManager.Instance:ShowInterstitial(function(code) self.isWatchingAD = false if adCallback then adCallback() adCallback = nil end end) elseif EDITOR_MODE then if adCallback then adCallback() adCallback = nil end end end --- 广告 -- function SDKManager:getProjectId() -- return CS.BF.BFMain.ProjectId -- end -- function SDKManager:getEnv() -- return CS.BF.BFMain.ProjectEnv -- end function SDKManager:getServerList(callback) local postData = { project_id = "c1", bundle_id = Platform:getIdentifier(), version = Platform:getClientVersion(), device_id = DeviceHelper:getDeviceId(), language = I18N:getLanguageAndArea(), env = "release",-- 暂时写死 } local loginCenterUrl = CS.BF.BFPlatform.GetLoginCenterURL() loginCenterUrl = loginCenterUrl .. "?platform=" .. CS.System.Uri.EscapeDataString(Platform:getPlatformStr()) -- lua这边直接构建好参数 for k, v in pairs(postData) do loginCenterUrl = loginCenterUrl .. "&" .. k .. "=" .. CS.System.Uri.EscapeDataString(v) end local guid = CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetNewPlayerGuid() loginCenterUrl = loginCenterUrl .. "&random=" .. CS.System.Uri.EscapeDataString(guid) CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:SetLuaServerListCallback(function(isSuccess, data) if callback then callback(isSuccess, data) end end) CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetServerList(loginCenterUrl) end function SDKManager:_login(callback, loginType) CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:SetLuaLoginCallback(callback) CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:Login(loginType) end function SDKManager:login(callback, loginType) self:logout(function() if self.isLogining then -- 正在登陆中 Logger.log("三方当前正在登陆中") return end self.isLogining = true self:_login(function(code, msg) if code == SDKManager.BF_LOGIN_RESULT.Success then if not msg then self.isLogining = false return end local msgTab = json.decode(msg) if msgTab == nil or type(msgTab) ~= "table" then self.isLogining = false return end local loginResult = json.decode(msgTab.msg) if loginResult == nil or type(loginResult) ~= "table" then self.isLogining = false return end local userId = loginResult.UserId local token = loginResult.Token local params = {} if loginType == SDKManager.BF_LOGIN_TYPE.APPLE then params = { type = "apple", id = tostring(userId), token = tostring(token) } elseif loginType == SDKManager.BF_LOGIN_TYPE.GOOGLE then params = { type = "google", id = tostring(userId), token = tostring(token) } elseif loginType == SDKManager.BF_LOGIN_TYPE.FACEBOOK then params = { type = "facebook", id = tostring(userId), token = tostring(token) } elseif loginType == SDKManager.BF_LOGIN_TYPE.VKID then params = { type = "vkid", id = tostring(userId), token = tostring(token) } end if callback then callback(params) end end self.isLogining = false end, loginType) end, loginType) end function SDKManager:getLoginTypeFacebook() -- if Platform:isIosPlatform() then -- return NetManager.LOGIN_TYPE.FACEBOOK_LIMITED -- else return NetManager.LOGIN_TYPE.FACEBOOK -- end end function SDKManager:getServerLoginType(loginType) -- if Platform:isIosPlatform() then -- if loginType == SDKManager.BF_LOGIN_TYPE.FACEBOOK then -- return SDKManager.LOGIN_TYPE[SDKManager.BF_LOGIN_TYPE.FACEBOOK_LIMITED] -- else -- return SDKManager.LOGIN_TYPE[loginType] -- end -- else return SDKManager.LOGIN_TYPE[loginType] -- end end function SDKManager:_logout(callback, loginType) if loginType == SDKManager.BF_LOGIN_TYPE.FACEBOOK or loginType == SDKManager.BF_LOGIN_TYPE.GOOGLE or loginType == SDKManager.BF_LOGIN_TYPE.VKID then CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:SetLuaLogoutCallback(callback) CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:Logout(loginType) else if callback then callback(SDKManager.BF_LOGIN_RESULT.Success, nil) end end end function SDKManager:logout(callback, loginType) if self.isLogouting then -- 正在登出 Logger.log("当前正在登出中") return end self.isLogouting = true self:_logout(function(code, msg) if (code == SDKManager.BF_LOGIN_RESULT.Success) then if callback then callback() end else if msg and msg ~= "" then local jData = json.decode(msg) if jData then local type = jData.loginType local msg = jData.msg Logger.logError("登出失败 result:%s type:%s msg:%s", code, type, msg) else Logger.logError("登出失败 result:%s", code) end else Logger.logError("登出失败") end if callback then callback() end end self.isLogouting = false end, loginType) end function SDKManager:tryGetAFConversionData() -- if CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:IsGetConversionDataOver() then -- BIReport:postDebugInfo(BIReport.DEBUG_INFO_TYPE.AF_CONVERSION_DATA, CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:GetAFConversionData()) -- end end function SDKManager:tryPostAFRequestResponse() -- if CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:IsGetAFOnRequestResponse() then -- local msg = string.format("code:%s, msg:%s", CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:GetAFOnRequestResponseStatusCode(), CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:GetAFOnRequestResponseErrorDescription()) -- BIReport:postDebugInfo(BIReport.DEBUG_INFO_TYPE.AF_ON_REQUEST_RESPONSE, msg) -- end end function SDKManager:getAFConversionObj() -- if self._afConversionObj == nil then -- if CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:IsGetConversionDataOver() then -- local data = CS.BF.BFMain.Instance.SDKMgr.BFThirdReportSDKMgr:GetAFConversionData() -- if data and data ~= "" then -- self._afConversionObj = json.decode(data) -- end -- end -- end -- return self._afConversionObj end -- 是否显示GDPR条例 function SDKManager:isPrivacyOptionsRequired() return false -- if EDITOR_MODE then -- return false -- end -- if not VersionCompatible:getIsSupportGDPR() then -- return false -- end -- if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then -- return CS.AdManager.Instance:IsPrivacyOptionsRequired() -- elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then -- return CS.AdManager.Instance:IsPrivacyOptionsRequired() -- else -- return false -- end end -- 展示GDPR隐私条款 function SDKManager:showPrivacyOptionsForm() -- if not VersionCompatible:getIsSupportGDPR() then -- return -- end -- if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then -- CS.AdManager.Instance:ShowPrivacyOptionsForm() -- elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then -- CS.AdManager.Instance:ShowPrivacyOptionsForm() -- end end function SDKManager:requestStoreReview() if VersionCompatible:supportRuStoreReview() then CS.BF.BFMain.Instance.SDKMgr.BFNativeSDKMgr:RuRequestStoreReview() else CS.BF.BFMain.Instance.SDKMgr.BFNativeSDKMgr:RequestStoreReview() end end --@region dukpay function SDKManager:initDukpayOrders(orders) if SDKPayMgr.initUncompleteOrders then SDKPayMgr:initUncompleteOrders(orders) end end function SDKManager:onServerPushDukpay(data) if data and SDKPayMgr.handleCompleteOrder then SDKPayMgr:handleCompleteOrder(data.order) end end --@endregion -- 初始化deeplink function SDKManager:initDeepLink() -- 注册监听 CS.BF.BFMain.Instance.SDKMgr.DeepLinkMgr:SetLuaDeepLinkActiveCallback(function(deeplinkUrl) local deeplinkParams if deeplinkUrl and deeplinkUrl ~= "" then deeplinkParams = GFunc.getUrlParams(deeplinkUrl) end if deeplinkParams then Logger.printTable(deeplinkParams) end end) end -- 获取deeplink url function SDKManager:getDeepLinkUrl() if VersionCompatible:supportDeepLink() then return CS.BF.BFMain.Instance.SDKMgr.DeepLinkMgr:GetDeepLinkURL() else return "" end end return SDKManager